mirror of
https://github.com/torvalds/linux.git
synced 2024-12-18 00:53:40 +00:00
Automatic merge of ../scsi-misc-2.6-old/
This commit is contained in:
commit
153b1e1fd9
@ -8,7 +8,7 @@
|
||||
|
||||
DOCBOOKS := wanbook.xml z8530book.xml mcabook.xml videobook.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 \
|
||||
gadget.xml libata.xml mtdnand.xml librs.xml
|
||||
|
||||
|
@ -1,193 +0,0 @@
|
||||
<?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>
|
@ -1,3 +1,69 @@
|
||||
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>
|
||||
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)
|
||||
|
180
Documentation/scsi/scsi-changer.txt
Normal file
180
Documentation/scsi/scsi-changer.txt
Normal file
@ -0,0 +1,180 @@
|
||||
|
||||
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>
|
@ -290,6 +290,13 @@ void elv_requeue_request(request_queue_t *q, struct request *rq)
|
||||
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
|
||||
* just put the request at the front of the queue
|
||||
@ -386,6 +393,12 @@ struct request *elv_next_request(request_queue_t *q)
|
||||
if (ret == BLKPREP_OK) {
|
||||
break;
|
||||
} 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;
|
||||
break;
|
||||
} else if (ret == BLKPREP_KILL) {
|
||||
|
@ -2038,7 +2038,6 @@ EXPORT_SYMBOL(blk_requeue_request);
|
||||
* @rq: request to be inserted
|
||||
* @at_head: insert request at head or tail of queue
|
||||
* @data: private data
|
||||
* @reinsert: true if request it a reinsertion of previously processed one
|
||||
*
|
||||
* Description:
|
||||
* Many block devices need to execute commands asynchronously, so they don't
|
||||
@ -2053,8 +2052,9 @@ EXPORT_SYMBOL(blk_requeue_request);
|
||||
* host that is unable to accept a particular command.
|
||||
*/
|
||||
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;
|
||||
|
||||
/*
|
||||
@ -2071,20 +2071,12 @@ void blk_insert_request(request_queue_t *q, struct request *rq,
|
||||
/*
|
||||
* If command is tagged, release the tag
|
||||
*/
|
||||
if (reinsert)
|
||||
blk_requeue_request(q, rq);
|
||||
else {
|
||||
int where = ELEVATOR_INSERT_BACK;
|
||||
if (blk_rq_tagged(rq))
|
||||
blk_queue_end_tag(q, rq);
|
||||
|
||||
if (at_head)
|
||||
where = ELEVATOR_INSERT_FRONT;
|
||||
drive_stat_acct(rq, rq->nr_sectors, 1);
|
||||
__elv_add_request(q, rq, where, 0);
|
||||
|
||||
if (blk_rq_tagged(rq))
|
||||
blk_queue_end_tag(q, rq);
|
||||
|
||||
drive_stat_acct(rq, rq->nr_sectors, 1);
|
||||
__elv_add_request(q, rq, where, 0);
|
||||
}
|
||||
if (blk_queue_plugged(q))
|
||||
__generic_unplug_device(q);
|
||||
else
|
||||
|
@ -723,7 +723,7 @@ static int pd_special_command(struct pd_unit *disk,
|
||||
rq.ref_count = 1;
|
||||
rq.waiting = &wait;
|
||||
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);
|
||||
rq.waiting = NULL;
|
||||
if (rq.errors)
|
||||
|
@ -614,7 +614,7 @@ static int carm_array_info (struct carm_host *host, unsigned int array_idx)
|
||||
spin_unlock_irq(&host->lock);
|
||||
|
||||
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;
|
||||
|
||||
@ -653,7 +653,7 @@ static int carm_send_special (struct carm_host *host, carm_sspc_t func)
|
||||
crq->msg_bucket = (u32) rc;
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -1070,7 +1070,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)
|
||||
{
|
||||
return (((device_type == TYPE_DISK) ||
|
||||
(device_type == TYPE_SDAD) ||
|
||||
(device_type == TYPE_RBC) ||
|
||||
(device_type == TYPE_ROM)) ? 1:0);
|
||||
}
|
||||
|
||||
@ -2111,102 +2111,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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2247,7 +2151,6 @@ static void sbp2_check_sbp2_response(struct scsi_id_instance_data *scsi_id,
|
||||
struct scsi_cmnd *SCpnt)
|
||||
{
|
||||
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");
|
||||
|
||||
@ -2271,14 +2174,6 @@ static void sbp2_check_sbp2_response(struct scsi_id_instance_data *scsi_id,
|
||||
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
|
||||
*/
|
||||
@ -2287,27 +2182,6 @@ static void sbp2_check_sbp2_response(struct scsi_id_instance_data *scsi_id,
|
||||
|
||||
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:
|
||||
break;
|
||||
}
|
||||
@ -2690,7 +2564,8 @@ static void sbp2scsi_complete_command(struct scsi_id_instance_data *scsi_id,
|
||||
static int sbp2scsi_slave_configure (struct scsi_device *sdev)
|
||||
{
|
||||
blk_queue_dma_alignment(sdev->request_queue, (512 - 1));
|
||||
|
||||
sdev->use_10_for_rw = 1;
|
||||
sdev->use_10_for_ms = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -266,10 +266,6 @@ struct sbp2_status_block {
|
||||
#define SBP2_MAX_UDS_PER_NODE 16 /* Maximum scsi devices per node */
|
||||
#define SBP2_MAX_SECTORS 255 /* Max sectors supported */
|
||||
|
||||
#ifndef TYPE_SDAD
|
||||
#define TYPE_SDAD 0x0e /* simplified direct access device */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* SCSI direction table...
|
||||
* (now used as a back-up in case the direction passed down from above is "unknown")
|
||||
|
@ -2,34 +2,54 @@
|
||||
menu "Fusion MPT device support"
|
||||
|
||||
config FUSION
|
||||
tristate "Fusion MPT (base + ScsiHost) drivers"
|
||||
depends on PCI && SCSI
|
||||
---help---
|
||||
LSI Logic Fusion(TM) Message Passing Technology (MPT) device support
|
||||
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.
|
||||
bool
|
||||
default n
|
||||
|
||||
[1] LAN is not supported on parallel SCSI medium.
|
||||
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
|
||||
select FUSION
|
||||
---help---
|
||||
SCSI HOST support for a Fiber Channel host adapters.
|
||||
|
||||
List of supported controllers:
|
||||
|
||||
LSIFC909
|
||||
LSIFC919
|
||||
LSIFC919X
|
||||
LSIFC929
|
||||
LSIFC929X
|
||||
LSIFC929XL
|
||||
|
||||
config FUSION_MAX_SGE
|
||||
int "Maximum number of scatter gather entries"
|
||||
int "Maximum number of scatter gather entries (16 - 128)"
|
||||
depends on FUSION
|
||||
default "40"
|
||||
default "128"
|
||||
range 16 128
|
||||
help
|
||||
This option allows you to specify the maximum number of scatter-
|
||||
gather entries per I/O. The driver defaults to 40, a reasonable number
|
||||
for most systems. However, the user may increase this up to 128.
|
||||
Increasing this parameter will require significantly more memory
|
||||
on a per controller instance. Increasing the parameter is not
|
||||
necessary (or recommended) unless the user will be running
|
||||
large I/O's via the raw interface.
|
||||
gather entries per I/O. The driver default is 128, which matches
|
||||
SCSI_MAX_PHYS_SEGMENTS. However, it may decreased down to 16.
|
||||
Decreasing this parameter will reduce memory requirements
|
||||
on a per controller instance.
|
||||
|
||||
config FUSION_CTL
|
||||
tristate "Fusion MPT misc device (ioctl) driver"
|
||||
depends on FUSION
|
||||
depends on FUSION_SPI || FUSION_FC
|
||||
---help---
|
||||
The Fusion MPT misc device driver provides specialized control
|
||||
of MPT adapters via system ioctl calls. Use of ioctl calls to
|
||||
@ -48,7 +68,7 @@ config FUSION_CTL
|
||||
|
||||
config FUSION_LAN
|
||||
tristate "Fusion MPT LAN driver"
|
||||
depends on FUSION && NET_FC
|
||||
depends on FUSION_FC && NET_FC
|
||||
---help---
|
||||
This module supports LAN IP traffic over Fibre Channel port(s)
|
||||
on Fusion MPT compatible hardware (LSIFC9xx chips).
|
||||
|
@ -1,52 +1,38 @@
|
||||
#
|
||||
# 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...
|
||||
# MPT general:
|
||||
#EXTRA_CFLAGS += -DMPT_DEBUG_SCSI
|
||||
#EXTRA_CFLAGS += -DMPT_DEBUG
|
||||
#EXTRA_CFLAGS += -DMPT_DEBUG_MSG_FRAME
|
||||
#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...
|
||||
#
|
||||
# For mptbase:
|
||||
#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_RESET
|
||||
#
|
||||
# For mptscsih:
|
||||
#CFLAGS_mptscsih.o += -DMPT_DEBUG_SCANDV
|
||||
#CFLAGS_mptscsih.o += -DMPT_DEBUG_RESET
|
||||
#CFLAGS_mptscsih.o += -DMPT_DEBUG_NEH
|
||||
#CFLAGS_mptscsih.o += -DMPT_DEBUG_DV
|
||||
#CFLAGS_mptscsih.o += -DMPT_DEBUG_NEGO
|
||||
#CFLAGS_mptscsih.o += -DMPT_DEBUG_TM
|
||||
#CFLAGS_mptscsih.o += -DMPT_DEBUG_SCSI
|
||||
#CFLAGS_mptscsih.o += -DMPT_DEBUG_REPLY
|
||||
#
|
||||
# For mptctl:
|
||||
#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
|
||||
|
||||
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_LAN) += mptlan.o
|
||||
|
@ -1,12 +1,12 @@
|
||||
/*
|
||||
* Copyright (c) 2000-2003 LSI Logic Corporation.
|
||||
* Copyright (c) 2000-2005 LSI Logic Corporation.
|
||||
*
|
||||
*
|
||||
* Name: mpi.h
|
||||
* Title: MPI Message independent structures and definitions
|
||||
* Creation Date: July 27, 2000
|
||||
*
|
||||
* mpi.h Version: 01.05.xx
|
||||
* mpi.h Version: 01.05.07
|
||||
*
|
||||
* Version History
|
||||
* ---------------
|
||||
@ -52,6 +52,25 @@
|
||||
* obsoleted define MPI_IOCSTATUS_TARGET_INVALID_IOCINDEX.
|
||||
* 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.
|
||||
* 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 @@
|
||||
/* Note: The major versions of 0xe0 through 0xff are reserved */
|
||||
|
||||
/* 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_UNIT_MASK (0xFF00)
|
||||
#define MPI_HEADER_VERSION_UNIT_SHIFT (8)
|
||||
@ -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_ACTIVE (0x08000000) /* DoorbellUsed */
|
||||
#define MPI_DOORBELL_USED (MPI_DOORBELL_ACTIVE)
|
||||
@ -134,6 +157,13 @@
|
||||
#define MPI_DOORBELL_ADD_DWORDS_MASK (0x00FF0000)
|
||||
#define MPI_DOORBELL_ADD_DWORDS_SHIFT (16)
|
||||
#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)
|
||||
@ -257,16 +287,18 @@
|
||||
|
||||
#define MPI_FUNCTION_SMP_PASSTHROUGH (0x1A)
|
||||
#define MPI_FUNCTION_SAS_IO_UNIT_CONTROL (0x1B)
|
||||
#define MPI_FUNCTION_SATA_PASSTHROUGH (0x1C)
|
||||
|
||||
#define MPI_DIAG_BUFFER_POST (0x1D)
|
||||
#define MPI_DIAG_RELEASE (0x1E)
|
||||
|
||||
#define MPI_FUNCTION_SCSI_IO_32 (0x1F)
|
||||
#define MPI_FUNCTION_DIAG_BUFFER_POST (0x1D)
|
||||
#define MPI_FUNCTION_DIAG_RELEASE (0x1E)
|
||||
|
||||
#define MPI_FUNCTION_LAN_SEND (0x20)
|
||||
#define MPI_FUNCTION_LAN_RECEIVE (0x21)
|
||||
#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_SEND (0x29)
|
||||
#define MPI_FUNCTION_INBAND_RSP (0x2A)
|
||||
@ -276,6 +308,7 @@
|
||||
#define MPI_FUNCTION_IO_UNIT_RESET (0x41)
|
||||
#define MPI_FUNCTION_HANDSHAKE (0x42)
|
||||
#define MPI_FUNCTION_REPLY_FRAME_REMOVAL (0x43)
|
||||
#define MPI_FUNCTION_HOST_PAGEBUF_ACCESS_CONTROL (0x44)
|
||||
|
||||
|
||||
/* standard version format */
|
||||
@ -328,8 +361,8 @@ typedef struct _SGE_SIMPLE_UNION
|
||||
U32 Address32;
|
||||
U64 Address64;
|
||||
}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 */
|
||||
@ -648,27 +681,21 @@ typedef struct _MSG_DEFAULT_REPLY
|
||||
#define MPI_IOCSTATUS_SCSI_EXT_TERMINATED (0x004C)
|
||||
|
||||
/****************************************************************************/
|
||||
/* For use by SCSI Initiator and SCSI Target end-to-end data protection */
|
||||
/****************************************************************************/
|
||||
|
||||
#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 */
|
||||
/* SCSI Target values */
|
||||
/****************************************************************************/
|
||||
|
||||
#define MPI_IOCSTATUS_TARGET_PRIORITY_IO (0x0060)
|
||||
#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_ABORTED (0x0063)
|
||||
#define MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE (0x0064)
|
||||
#define MPI_IOCSTATUS_TARGET_NO_CONNECTION (0x0065)
|
||||
#define MPI_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH (0x006A)
|
||||
#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) */
|
||||
@ -707,6 +734,7 @@ typedef struct _MSG_DEFAULT_REPLY
|
||||
/****************************************************************************/
|
||||
|
||||
#define MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED (0x0090)
|
||||
#define MPI_IOCSTATUS_SAS_SMP_DATA_OVERRUN (0x0091)
|
||||
|
||||
/****************************************************************************/
|
||||
/* Inband values */
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,12 +1,12 @@
|
||||
/*
|
||||
* Copyright (c) 2000-2003 LSI Logic Corporation.
|
||||
* Copyright (c) 2000-2004 LSI Logic Corporation.
|
||||
*
|
||||
*
|
||||
* Name: mpi_fc.h
|
||||
* Title: MPI Fibre Channel messages and structures
|
||||
* Creation Date: June 12, 2000
|
||||
*
|
||||
* mpi_fc.h Version: 01.05.xx
|
||||
* mpi_fc.h Version: 01.05.01
|
||||
*
|
||||
* Version History
|
||||
* ---------------
|
||||
@ -36,6 +36,9 @@
|
||||
* 09-28-01 01.02.02 Change name of reserved field in
|
||||
* MSG_LINK_SERVICE_RSP_REPLY.
|
||||
* 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.
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
@ -3,25 +3,28 @@
|
||||
MPI Header File Change History
|
||||
==============================
|
||||
|
||||
Copyright (c) 2000-2001 LSI Logic Corporation.
|
||||
Copyright (c) 2000-2005 LSI Logic Corporation.
|
||||
|
||||
---------------------------------------
|
||||
Header Set Release Version: 01.01.10
|
||||
Header Set Release Date: 04-09-01
|
||||
Header Set Release Version: 01.05.09
|
||||
Header Set Release Date: 03-11-05
|
||||
---------------------------------------
|
||||
|
||||
Filename Current version Prior version
|
||||
---------- --------------- -------------
|
||||
mpi.h 01.01.07 01.01.06
|
||||
mpi_ioc.h 01.01.07 01.01.06
|
||||
mpi_cnfg.h 01.01.11 01.01.10
|
||||
mpi_init.h 01.01.05 01.01.04
|
||||
mpi_targ.h 01.01.04 01.01.04
|
||||
mpi_fc.h 01.01.07 01.01.06
|
||||
mpi_lan.h 01.01.03 01.01.03
|
||||
mpi_raid.h 01.01.02 01.01.02
|
||||
mpi_type.h 01.01.02 01.01.02
|
||||
mpi_history.txt 01.01.09 01.01.09
|
||||
mpi.h 01.05.07 01.05.06
|
||||
mpi_ioc.h 01.05.08 01.05.07
|
||||
mpi_cnfg.h 01.05.08 01.05.07
|
||||
mpi_init.h 01.05.04 01.05.03
|
||||
mpi_targ.h 01.05.04 01.05.03
|
||||
mpi_fc.h 01.05.01 01.05.01
|
||||
mpi_lan.h 01.05.01 01.05.01
|
||||
mpi_raid.h 01.05.02 01.05.02
|
||||
mpi_tool.h 01.05.03 01.05.03
|
||||
mpi_inb.h 01.05.01 01.05.01
|
||||
mpi_sas.h 01.05.01 01.05.01
|
||||
mpi_type.h 01.05.01 01.05.01
|
||||
mpi_history.txt 01.05.09 01.05.08
|
||||
|
||||
|
||||
* Date Version Description
|
||||
@ -53,6 +56,38 @@ mpi.h
|
||||
* Added function codes for RAID.
|
||||
* 04-09-01 01.01.07 Added alternate define for MPI_DOORBELL_ACTIVE,
|
||||
* MPI_DOORBELL_USED, to better match the spec.
|
||||
* 08-08-01 01.02.01 Original release for v1.2 work.
|
||||
* Changed MPI_VERSION_MINOR from 0x01 to 0x02.
|
||||
* Added define MPI_FUNCTION_TOOLBOX.
|
||||
* 09-28-01 01.02.02 New function code MPI_SCSI_ENCLOSURE_PROCESSOR.
|
||||
* 11-01-01 01.02.03 Changed name to MPI_FUNCTION_SCSI_ENCLOSURE_PROCESSOR.
|
||||
* 03-14-02 01.02.04 Added MPI_HEADER_VERSION_ defines.
|
||||
* 05-31-02 01.02.05 Bumped MPI_HEADER_VERSION_UNIT.
|
||||
* 07-12-02 01.02.06 Added define for MPI_FUNCTION_MAILBOX.
|
||||
* 09-16-02 01.02.07 Bumped value for MPI_HEADER_VERSION_UNIT.
|
||||
* 11-15-02 01.02.08 Added define MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX and
|
||||
* obsoleted define MPI_IOCSTATUS_TARGET_INVALID_IOCINDEX.
|
||||
* 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.
|
||||
* 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.
|
||||
* --------------------------------------------------------------------------
|
||||
|
||||
mpi_ioc.h
|
||||
@ -81,6 +116,49 @@ mpi_ioc.h
|
||||
* 03-27-01 01.01.06 Added defines for ProductId field of MPI_FW_HEADER.
|
||||
* Added structure offset comments.
|
||||
* 04-09-01 01.01.07 Added structure EVENT_DATA_EVENT_CHANGE.
|
||||
* 08-08-01 01.02.01 Original release for v1.2 work.
|
||||
* New format for FWVersion and ProductId in
|
||||
* MSG_IOC_FACTS_REPLY and MPI_FW_HEADER.
|
||||
* 08-31-01 01.02.02 Addded event MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE and
|
||||
* related structure and defines.
|
||||
* Added event MPI_EVENT_ON_BUS_TIMER_EXPIRED.
|
||||
* Added MPI_IOCINIT_FLAGS_DISCARD_FW_IMAGE.
|
||||
* Replaced a reserved field in MSG_IOC_FACTS_REPLY with
|
||||
* IOCExceptions and changed DataImageSize to reserved.
|
||||
* Added MPI_FW_DOWNLOAD_ITYPE_NVSTORE_DATA and
|
||||
* MPI_FW_UPLOAD_ITYPE_NVDATA.
|
||||
* 09-28-01 01.02.03 Modified Event Data for Integrated RAID.
|
||||
* 11-01-01 01.02.04 Added defines for MPI_EXT_IMAGE_HEADER ImageType field.
|
||||
* 03-14-02 01.02.05 Added HeaderVersion field to MSG_IOC_FACTS_REPLY.
|
||||
* 05-31-02 01.02.06 Added define for
|
||||
* MPI_IOCFACTS_EXCEPT_RAID_CONFIG_INVALID.
|
||||
* Added AliasIndex to EVENT_DATA_LOGOUT structure.
|
||||
* 04-01-03 01.02.07 Added defines for MPI_FW_HEADER_SIGNATURE_.
|
||||
* 06-26-03 01.02.08 Added new values to the product family defines.
|
||||
* 04-29-04 01.02.09 Added IOCCapabilities field to MSG_IOC_FACTS_REPLY and
|
||||
* added related defines.
|
||||
* 05-11-04 01.03.01 Original release for MPI v1.3.
|
||||
* 08-19-04 01.05.01 Added four new fields to MSG_IOC_INIT.
|
||||
* Added three new fields to MSG_IOC_FACTS_REPLY.
|
||||
* Defined four new bits for the IOCCapabilities field of
|
||||
* the IOCFacts reply.
|
||||
* Added two new PortTypes for the PortFacts reply.
|
||||
* Added six new events along with their EventData
|
||||
* structures.
|
||||
* Added a new MsgFlag to the FwDownload request to
|
||||
* indicate last segment.
|
||||
* Defined a new image type of boot loader.
|
||||
* Added FW family codes for SAS product families.
|
||||
* 10-05-04 01.05.02 Added ReplyFifoHostSignalingAddr field to
|
||||
* MSG_IOC_FACTS_REPLY.
|
||||
* 12-07-04 01.05.03 Added more defines for SAS Discovery Error event.
|
||||
* 12-09-04 01.05.04 Added Unsupported device to SAS Device event.
|
||||
* 01-15-05 01.05.05 Added event data for SAS SES Event.
|
||||
* 02-09-05 01.05.06 Added MPI_FW_UPLOAD_ITYPE_FW_BACKUP define.
|
||||
* 02-22-05 01.05.07 Added Host Page Buffer Persistent flag to IOC Facts
|
||||
* Reply and IOC Init Request.
|
||||
* 03-11-05 01.05.08 Added family code for 1068E family.
|
||||
* Removed IOCFacts Reply EEDP Capability bit.
|
||||
* --------------------------------------------------------------------------
|
||||
|
||||
mpi_cnfg.h
|
||||
@ -142,6 +220,166 @@ mpi_cnfg.h
|
||||
* Added IO Unit Page 3.
|
||||
* Modified defines for Scsi Port Page 2.
|
||||
* Modified RAID Volume Pages.
|
||||
* 08-08-01 01.02.01 Original release for v1.2 work.
|
||||
* Added SepID and SepBus to RVP2 IMPhysicalDisk struct.
|
||||
* Added defines for the SEP bits in RVP2 VolumeSettings.
|
||||
* Modified the DeviceSettings field in RVP2 to use the
|
||||
* proper structure.
|
||||
* Added defines for SES, SAF-TE, and cross channel for
|
||||
* IOCPage2 CapabilitiesFlags.
|
||||
* Removed define for MPI_IOUNITPAGE2_FLAGS_RAID_DISABLE.
|
||||
* Removed define for
|
||||
* MPI_SCSIPORTPAGE2_PORT_FLAGS_PARITY_ENABLE.
|
||||
* Added define for MPI_CONFIG_PAGEATTR_RO_PERSISTENT.
|
||||
* 08-29-01 01.02.02 Fixed value for MPI_MANUFACTPAGE_DEVID_53C1035.
|
||||
* Added defines for MPI_FCPORTPAGE1_FLAGS_HARD_ALPA_ONLY
|
||||
* and MPI_FCPORTPAGE1_FLAGS_IMMEDIATE_ERROR_REPLY.
|
||||
* Removed MPI_SCSIPORTPAGE0_CAP_PACING_TRANSFERS,
|
||||
* MPI_SCSIDEVPAGE0_NP_PACING_TRANSFERS, and
|
||||
* MPI_SCSIDEVPAGE1_RP_PACING_TRANSFERS, and
|
||||
* MPI_SCSIDEVPAGE1_CONF_PPR_ALLOWED.
|
||||
* Added defines for MPI_SCSIDEVPAGE1_CONF_WDTR_DISALLOWED
|
||||
* and MPI_SCSIDEVPAGE1_CONF_SDTR_DISALLOWED.
|
||||
* Added OnBusTimerValue to CONFIG_PAGE_SCSI_PORT_1.
|
||||
* Added rejected bits to SCSI Device Page 0 Information.
|
||||
* Increased size of ALPA array in FC Port Page 2 by one
|
||||
* and removed a one byte reserved field.
|
||||
* 09-28-01 01.02.03 Swapped NegWireSpeedLow and NegWireSpeedLow in
|
||||
* CONFIG_PAGE_LAN_1 to match preferred 64-bit ordering.
|
||||
* Added structures for Manufacturing Page 4, IO Unit
|
||||
* Page 3, IOC Page 3, IOC Page 4, RAID Volume Page 0, and
|
||||
* RAID PhysDisk Page 0.
|
||||
* 10-04-01 01.02.04 Added define for MPI_CONFIG_PAGETYPE_RAID_PHYSDISK.
|
||||
* Modified some of the new defines to make them 32
|
||||
* character unique.
|
||||
* Modified how variable length pages (arrays) are defined.
|
||||
* Added generic defines for hot spare pools and RAID
|
||||
* volume types.
|
||||
* 11-01-01 01.02.05 Added define for MPI_IOUNITPAGE1_DISABLE_IR.
|
||||
* 03-14-02 01.02.06 Added PCISlotNum field to CONFIG_PAGE_IOC_1 along with
|
||||
* related define, and bumped the page version define.
|
||||
* 05-31-02 01.02.07 Added a Flags field to CONFIG_PAGE_IOC_2_RAID_VOL in a
|
||||
* reserved byte and added a define.
|
||||
* Added define for
|
||||
* MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE.
|
||||
* Added new config page: CONFIG_PAGE_IOC_5.
|
||||
* Added MaxAliases, MaxHardAliases, and NumCurrentAliases
|
||||
* fields to CONFIG_PAGE_FC_PORT_0.
|
||||
* Added AltConnector and NumRequestedAliases fields to
|
||||
* CONFIG_PAGE_FC_PORT_1.
|
||||
* Added new config page: CONFIG_PAGE_FC_PORT_10.
|
||||
* 07-12-02 01.02.08 Added more MPI_MANUFACTPAGE_DEVID_ defines.
|
||||
* Added additional MPI_SCSIDEVPAGE0_NP_ defines.
|
||||
* Added more MPI_SCSIDEVPAGE1_RP_ defines.
|
||||
* Added define for
|
||||
* MPI_SCSIDEVPAGE1_CONF_EXTENDED_PARAMS_ENABLE.
|
||||
* Added new config page: CONFIG_PAGE_SCSI_DEVICE_3.
|
||||
* Modified MPI_FCPORTPAGE5_FLAGS_ defines.
|
||||
* 09-16-02 01.02.09 Added MPI_SCSIDEVPAGE1_CONF_FORCE_PPR_MSG define.
|
||||
* 11-15-02 01.02.10 Added ConnectedID defines for CONFIG_PAGE_SCSI_PORT_0.
|
||||
* Added more Flags defines for CONFIG_PAGE_FC_PORT_1.
|
||||
* Added more Flags defines for CONFIG_PAGE_FC_DEVICE_0.
|
||||
* 04-01-03 01.02.11 Added RR_TOV field and additional Flags defines for
|
||||
* CONFIG_PAGE_FC_PORT_1.
|
||||
* Added define MPI_FCPORTPAGE5_FLAGS_DISABLE to disable
|
||||
* an alias.
|
||||
* Added more device id defines.
|
||||
* 06-26-03 01.02.12 Added MPI_IOUNITPAGE1_IR_USE_STATIC_VOLUME_ID define.
|
||||
* Added TargetConfig and IDConfig fields to
|
||||
* CONFIG_PAGE_SCSI_PORT_1.
|
||||
* Added more PortFlags defines for CONFIG_PAGE_SCSI_PORT_2
|
||||
* to control DV.
|
||||
* Added more Flags defines for CONFIG_PAGE_FC_PORT_1.
|
||||
* In CONFIG_PAGE_FC_DEVICE_0, replaced Reserved1 field
|
||||
* with ADISCHardALPA.
|
||||
* Added MPI_FC_DEVICE_PAGE0_PROT_FCP_RETRY define.
|
||||
* 01-16-04 01.02.13 Added InitiatorDeviceTimeout and InitiatorIoPendTimeout
|
||||
* fields and related defines to CONFIG_PAGE_FC_PORT_1.
|
||||
* Added define for
|
||||
* MPI_FCPORTPAGE1_FLAGS_SOFT_ALPA_FALLBACK.
|
||||
* Added new fields to the substructures of
|
||||
* CONFIG_PAGE_FC_PORT_10.
|
||||
* 04-29-04 01.02.14 Added define for IDP bit for CONFIG_PAGE_SCSI_PORT_0,
|
||||
* CONFIG_PAGE_SCSI_DEVICE_0, and
|
||||
* CONFIG_PAGE_SCSI_DEVICE_1. Also bumped Page Version for
|
||||
* these pages.
|
||||
* 05-11-04 01.03.01 Added structure for CONFIG_PAGE_INBAND_0.
|
||||
* 08-19-04 01.05.01 Modified MSG_CONFIG request to support extended config
|
||||
* pages.
|
||||
* Added a new structure for extended config page header.
|
||||
* Added new extended config pages types and structures for
|
||||
* SAS IO Unit, SAS Expander, SAS Device, and SAS PHY.
|
||||
* Replaced a reserved byte in CONFIG_PAGE_MANUFACTURING_4
|
||||
* to add a Flags field.
|
||||
* Two new Manufacturing config pages (5 and 6).
|
||||
* Two new bits defined for IO Unit Page 1 Flags field.
|
||||
* Modified CONFIG_PAGE_IO_UNIT_2 to add three new fields
|
||||
* to specify the BIOS boot device.
|
||||
* Four new Flags bits defined for IO Unit Page 2.
|
||||
* Added IO Unit Page 4.
|
||||
* Added EEDP Flags settings to IOC Page 1.
|
||||
* Added new BIOS Page 1 config page.
|
||||
* 10-05-04 01.05.02 Added define for
|
||||
* MPI_IOCPAGE1_INITIATOR_CONTEXT_REPLY_DISABLE.
|
||||
* Added new Flags field to CONFIG_PAGE_MANUFACTURING_5 and
|
||||
* associated defines.
|
||||
* Added more defines for SAS IO Unit Page 0
|
||||
* DiscoveryStatus field.
|
||||
* Added define for MPI_SAS_IOUNIT0_DS_SUBTRACTIVE_LINK
|
||||
* and MPI_SAS_IOUNIT0_DS_TABLE_LINK.
|
||||
* Added defines for Physical Mapping Modes to SAS IO Unit
|
||||
* Page 2.
|
||||
* Added define for
|
||||
* MPI_SAS_DEVICE0_FLAGS_PORT_SELECTOR_ATTACH.
|
||||
* 10-27-04 01.05.03 Added defines for new SAS PHY page addressing mode.
|
||||
* Added defines for MaxTargetSpinUp to BIOS Page 1.
|
||||
* Added 5 new ControlFlags defines for SAS IO Unit
|
||||
* Page 1.
|
||||
* Added MaxNumPhysicalMappedIDs field to SAS IO Unit
|
||||
* Page 2.
|
||||
* Added AccessStatus field to SAS Device Page 0 and added
|
||||
* new Flags bits for supported SATA features.
|
||||
* 12-07-04 01.05.04 Added config page structures for BIOS Page 2, RAID
|
||||
* Volume Page 1, and RAID Physical Disk Page 1.
|
||||
* Replaced IO Unit Page 1 BootTargetID,BootBus, and
|
||||
* BootAdapterNum with reserved field.
|
||||
* Added DataScrubRate and ResyncRate to RAID Volume
|
||||
* Page 0.
|
||||
* Added MPI_SAS_IOUNIT2_FLAGS_RESERVE_ID_0_FOR_BOOT
|
||||
* define.
|
||||
* 12-09-04 01.05.05 Added Target Mode Large CDB Enable to FC Port Page 1
|
||||
* Flags field.
|
||||
* Added Auto Port Config flag define for SAS IOUNIT
|
||||
* Page 1 ControlFlags.
|
||||
* Added Disabled bad Phy define to Expander Page 1
|
||||
* Discovery Info field.
|
||||
* Added SAS/SATA device support to SAS IOUnit Page 1
|
||||
* ControlFlags.
|
||||
* Added Unsupported device to SAS Dev Page 0 Flags field
|
||||
* Added disable use SATA Hash Address for SAS IOUNIT
|
||||
* page 1 in ControlFields.
|
||||
* 01-15-05 01.05.06 Added defaults for data scrub rate and resync rate to
|
||||
* Manufacturing Page 4.
|
||||
* Added new defines for BIOS Page 1 IOCSettings field.
|
||||
* Added ExtDiskIdentifier field to RAID Physical Disk
|
||||
* Page 0.
|
||||
* Added new defines for SAS IO Unit Page 1 ControlFlags
|
||||
* and to SAS Device Page 0 Flags to control SATA devices.
|
||||
* Added defines and structures for the new Log Page 0, a
|
||||
* new type of configuration page.
|
||||
* 02-09-05 01.05.07 Added InactiveStatus field to RAID Volume Page 0.
|
||||
* Added WWID field to RAID Volume Page 1.
|
||||
* Added PhysicalPort field to SAS Expander pages 0 and 1.
|
||||
* 03-11-05 01.05.08 Removed the EEDP flags from IOC Page 1.
|
||||
* Added Enclosure/Slot boot device format to BIOS Page 2.
|
||||
* New status value for RAID Volume Page 0 VolumeStatus
|
||||
* (VolumeState subfield).
|
||||
* New value for RAID Physical Page 0 InactiveStatus.
|
||||
* Added Inactive Volume Member flag RAID Physical Disk
|
||||
* Page 0 PhysDiskStatus field.
|
||||
* New physical mapping mode in SAS IO Unit Page 2.
|
||||
* Added CONFIG_PAGE_SAS_ENCLOSURE_0.
|
||||
* Added Slot and Enclosure fields to SAS Device Page 0.
|
||||
* --------------------------------------------------------------------------
|
||||
|
||||
mpi_init.h
|
||||
@ -154,6 +392,32 @@ mpi_init.h
|
||||
* 02-20-01 01.01.03 Started using MPI_POINTER.
|
||||
* 03-27-01 01.01.04 Added structure offset comments.
|
||||
* 04-10-01 01.01.05 Added new MsgFlag for MSG_SCSI_TASK_MGMT.
|
||||
* 08-08-01 01.02.01 Original release for v1.2 work.
|
||||
* 08-29-01 01.02.02 Added MPI_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET.
|
||||
* Added MPI_SCSI_STATE_QUEUE_TAG_REJECTED for
|
||||
* MSG_SCSI_IO_REPLY.
|
||||
* 09-28-01 01.02.03 Added structures and defines for SCSI Enclosure
|
||||
* Processor messages.
|
||||
* 10-04-01 01.02.04 Added defines for SEP request Action field.
|
||||
* 05-31-02 01.02.05 Added MPI_SCSIIO_MSGFLGS_CMD_DETERMINES_DATA_DIR define
|
||||
* for SCSI IO requests.
|
||||
* 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.
|
||||
* 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.
|
||||
* --------------------------------------------------------------------------
|
||||
|
||||
mpi_targ.h
|
||||
@ -170,6 +434,33 @@ mpi_targ.h
|
||||
* Added structures for MPI_TARGET_SCSI_SPI_CMD_BUFFER and
|
||||
* MPI_TARGET_FCP_CMD_BUFFER.
|
||||
* 03-27-01 01.01.04 Added structure offset comments.
|
||||
* 08-08-01 01.02.01 Original release for v1.2 work.
|
||||
* 09-28-01 01.02.02 Added structure for MPI_TARGET_SCSI_SPI_STATUS_IU.
|
||||
* Added PriorityReason field to some replies and
|
||||
* defined more PriorityReason codes.
|
||||
* Added some defines for to support previous version
|
||||
* of MPI.
|
||||
* 10-04-01 01.02.03 Added PriorityReason to MSG_TARGET_ERROR_REPLY.
|
||||
* 11-01-01 01.02.04 Added define for TARGET_STATUS_SEND_FLAGS_HIGH_PRIORITY.
|
||||
* 03-14-02 01.02.05 Modified MPI_TARGET_FCP_RSP_BUFFER to get the proper
|
||||
* byte ordering.
|
||||
* 05-31-02 01.02.06 Modified TARGET_MODE_REPLY_ALIAS_MASK to only include
|
||||
* one bit.
|
||||
* Added AliasIndex field to MPI_TARGET_FCP_CMD_BUFFER.
|
||||
* 09-16-02 01.02.07 Added flags for confirmed completion.
|
||||
* Added PRIORITY_REASON_TARGET_BUSY.
|
||||
* 11-15-02 01.02.08 Added AliasID field to MPI_TARGET_SCSI_SPI_CMD_BUFFER.
|
||||
* 04-01-03 01.02.09 Added OptionalOxid field to MPI_TARGET_FCP_CMD_BUFFER.
|
||||
* 05-11-04 01.03.01 Original release for MPI v1.3.
|
||||
* 08-19-04 01.05.01 Added new request message structures for
|
||||
* MSG_TARGET_CMD_BUF_POST_BASE_REQUEST,
|
||||
* MSG_TARGET_CMD_BUF_POST_LIST_REQUEST, and
|
||||
* MSG_TARGET_ASSIST_EXT_REQUEST.
|
||||
* Added new structures for SAS SSP Command buffer, SSP
|
||||
* Task buffer, and SSP Status IU.
|
||||
* 10-05-04 01.05.02 MSG_TARGET_CMD_BUFFER_POST_BASE_LIST_REPLY added.
|
||||
* 02-22-05 01.05.03 Changed a comment.
|
||||
* 03-11-05 01.05.04 Removed TargetAssistExtended Request.
|
||||
* --------------------------------------------------------------------------
|
||||
|
||||
mpi_fc.h
|
||||
@ -192,6 +483,13 @@ mpi_fc.h
|
||||
* Added MPI_FC_PRIM_SEND_FLAGS_RESET_LINK define.
|
||||
* Added structure offset comments.
|
||||
* 04-09-01 01.01.07 Added RspLength field to MSG_LINK_SERVICE_RSP_REQUEST.
|
||||
* 08-08-01 01.02.01 Original release for v1.2 work.
|
||||
* 09-28-01 01.02.02 Change name of reserved field in
|
||||
* MSG_LINK_SERVICE_RSP_REPLY.
|
||||
* 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.
|
||||
* --------------------------------------------------------------------------
|
||||
|
||||
mpi_lan.h
|
||||
@ -209,11 +507,56 @@ mpi_lan.h
|
||||
* 11-02-00 01.01.01 Original release for post 1.0 work
|
||||
* 02-20-01 01.01.02 Started using MPI_POINTER.
|
||||
* 03-27-01 01.01.03 Added structure offset comments.
|
||||
* 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.
|
||||
* --------------------------------------------------------------------------
|
||||
|
||||
mpi_raid.h
|
||||
* 02-27-01 01.01.01 Original release for this file.
|
||||
* 03-27-01 01.01.02 Added structure offset comments.
|
||||
* 08-08-01 01.02.01 Original release for v1.2 work.
|
||||
* 08-29-01 01.02.02 Added DIAG_DATA_UPLOAD_HEADER and related defines.
|
||||
* 09-28-01 01.02.02 Major rework for MPI v1.2 Integrated RAID changes.
|
||||
* 10-04-01 01.02.03 Added ActionData defines for
|
||||
* MPI_RAID_ACTION_DELETE_VOLUME action.
|
||||
* 11-01-01 01.02.04 Added define for MPI_RAID_ACTION_ADATA_DO_NOT_SYNC.
|
||||
* 03-14-02 01.02.05 Added define for MPI_RAID_ACTION_ADATA_LOW_LEVEL_INIT.
|
||||
* 05-07-02 01.02.06 Added define for MPI_RAID_ACTION_ACTIVATE_VOLUME,
|
||||
* MPI_RAID_ACTION_INACTIVATE_VOLUME, and
|
||||
* MPI_RAID_ACTION_ADATA_INACTIVATE_ALL.
|
||||
* 07-12-02 01.02.07 Added structures for Mailbox request and reply.
|
||||
* 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
|
||||
* 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.
|
||||
* --------------------------------------------------------------------------
|
||||
|
||||
mpi_tool.h
|
||||
* 08-08-01 01.02.01 Original release.
|
||||
* 08-29-01 01.02.02 Added DIAG_DATA_UPLOAD_HEADER and related defines.
|
||||
* 01-16-04 01.02.03 Added defines and structures for new tools
|
||||
*. MPI_TOOLBOX_ISTWI_READ_WRITE_TOOL and
|
||||
* MPI_TOOLBOX_FC_MANAGEMENT_TOOL.
|
||||
* 04-29-04 01.02.04 Added message structures for Diagnostic Buffer Post and
|
||||
* Diagnostic Release requests and replies.
|
||||
* 05-11-04 01.03.01 Original release for MPI v1.3.
|
||||
* 08-19-04 01.05.01 Original release for MPI v1.5.
|
||||
* 10-06-04 01.05.02 Added define for MPI_DIAG_BUF_TYPE_COUNT.
|
||||
* 02-09-05 01.05.03 Added frame size option to FC management tool.
|
||||
* Added Beacon tool to the Toolbox.
|
||||
* --------------------------------------------------------------------------
|
||||
|
||||
mpi_inb.h
|
||||
* 05-11-04 01.03.01 Original release.
|
||||
* 08-19-04 01.05.01 Original release for MPI v1.5.
|
||||
* --------------------------------------------------------------------------
|
||||
|
||||
mpi_sas.h
|
||||
* 08-19-04 01.05.01 Original release.
|
||||
* --------------------------------------------------------------------------
|
||||
|
||||
mpi_type.h
|
||||
@ -221,21 +564,83 @@ mpi_type.h
|
||||
* 06-06-00 01.00.01 Update version number for 1.0 release.
|
||||
* 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.
|
||||
* 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.
|
||||
* --------------------------------------------------------------------------
|
||||
|
||||
mpi_history.txt Parts list history
|
||||
|
||||
Filename 01.01.10
|
||||
Filename 01.05.09
|
||||
---------- --------
|
||||
mpi.h 01.01.07
|
||||
mpi_ioc.h 01.01.07
|
||||
mpi_cnfg.h 01.01.11
|
||||
mpi_init.h 01.01.05
|
||||
mpi_targ.h 01.01.04
|
||||
mpi_fc.h 01.01.07
|
||||
mpi_lan.h 01.01.03
|
||||
mpi_raid.h 01.01.02
|
||||
mpi_type.h 01.01.02
|
||||
mpi.h 01.05.07
|
||||
mpi_ioc.h 01.05.08
|
||||
mpi_cnfg.h 01.05.08
|
||||
mpi_init.h 01.05.04
|
||||
mpi_targ.h 01.05.04
|
||||
mpi_fc.h 01.05.01
|
||||
mpi_lan.h 01.05.01
|
||||
mpi_raid.h 01.05.02
|
||||
mpi_tool.h 01.05.03
|
||||
mpi_inb.h 01.05.01
|
||||
mpi_sas.h 01.05.01
|
||||
mpi_type.h 01.05.01
|
||||
|
||||
Filename 01.05.08 01.05.07 01.05.06 01.05.05 01.05.04 01.05.03
|
||||
---------- -------- -------- -------- -------- -------- --------
|
||||
mpi.h 01.05.06 01.05.05 01.05.04 01.05.03 01.05.02 01.05.01
|
||||
mpi_ioc.h 01.05.07 01.05.06 01.05.05 01.05.04 01.05.03 01.05.02
|
||||
mpi_cnfg.h 01.05.07 01.05.07 01.05.06 01.05.05 01.05.04 01.05.03
|
||||
mpi_init.h 01.05.03 01.05.03 01.05.03 01.05.02 01.05.02 01.05.01
|
||||
mpi_targ.h 01.05.03 01.05.02 01.05.02 01.05.02 01.05.02 01.05.02
|
||||
mpi_fc.h 01.05.01 01.05.01 01.05.01 01.05.01 01.05.01 01.05.01
|
||||
mpi_lan.h 01.05.01 01.05.01 01.05.01 01.05.01 01.05.01 01.05.01
|
||||
mpi_raid.h 01.05.02 01.05.02 01.05.02 01.05.01 01.05.01 01.05.01
|
||||
mpi_tool.h 01.05.03 01.05.03 01.05.02 01.05.02 01.05.02 01.05.02
|
||||
mpi_inb.h 01.05.01 01.05.01 01.05.01 01.05.01 01.05.01 01.05.01
|
||||
mpi_sas.h 01.05.01 01.05.01 01.05.01 01.05.01 01.05.01 01.05.01
|
||||
mpi_type.h 01.05.01 01.05.01 01.05.01 01.05.01 01.05.01 01.05.01
|
||||
|
||||
Filename 01.05.02 01.05.01 01.03.01 01.02.14 01.02.13 01.02.12
|
||||
---------- -------- -------- -------- -------- -------- --------
|
||||
mpi.h 01.05.01 01.05.01 01.03.01 01.02.12 01.02.11 01.02.10
|
||||
mpi_ioc.h 01.05.02 01.05.01 01.03.01 01.02.09 01.02.08 01.02.08
|
||||
mpi_cnfg.h 01.05.02 01.05.01 01.03.01 01.02.14 01.02.13 01.02.12
|
||||
mpi_init.h 01.05.01 01.05.01 01.03.01 01.02.07 01.02.07 01.02.07
|
||||
mpi_targ.h 01.05.02 01.05.01 01.03.01 01.02.09 01.02.09 01.02.09
|
||||
mpi_fc.h 01.05.01 01.05.01 01.03.01 01.02.04 01.02.04 01.02.03
|
||||
mpi_lan.h 01.05.01 01.05.01 01.03.01 01.02.01 01.02.01 01.02.01
|
||||
mpi_raid.h 01.05.01 01.05.01 01.03.01 01.02.09 01.02.09 01.02.09
|
||||
mpi_tool.h 01.05.02 01.05.01 01.03.01 01.02.01 01.02.01 01.02.01
|
||||
mpi_inb.h 01.05.01 01.05.01 01.03.01
|
||||
mpi_sas.h 01.05.01 01.05.01
|
||||
mpi_type.h 01.05.01 01.05.01 01.03.01 01.02.04 01.02.03 01.02.02
|
||||
|
||||
Filename 01.02.11 01.02.10 01.02.09 01.02.08 01.02.07 01.02.06
|
||||
---------- -------- -------- -------- -------- -------- --------
|
||||
mpi.h 01.02.09 01.02.08 01.02.07 01.02.06 01.02.05 01.02.04
|
||||
mpi_ioc.h 01.02.07 01.02.06 01.02.06 01.02.06 01.02.06 01.02.05
|
||||
mpi_cnfg.h 01.02.11 01.02.10 01.02.09 01.02.08 01.02.07 01.02.06
|
||||
mpi_init.h 01.02.06 01.02.06 01.02.05 01.02.05 01.02.05 01.02.04
|
||||
mpi_targ.h 01.02.09 01.02.08 01.02.07 01.02.06 01.02.06 01.02.05
|
||||
mpi_fc.h 01.02.03 01.02.03 01.02.03 01.02.03 01.02.03 01.02.02
|
||||
mpi_lan.h 01.02.01 01.02.01 01.02.01 01.02.01 01.02.01 01.02.01
|
||||
mpi_raid.h 01.02.09 01.02.08 01.02.07 01.02.07 01.02.06 01.02.05
|
||||
mpi_tool.h 01.02.01 01.02.01 01.02.01 01.02.01 01.02.01 01.02.01
|
||||
mpi_type.h 01.02.02 01.02.02 01.02.02 01.02.02 01.02.02 01.02.02
|
||||
|
||||
Filename 01.02.05 01.02.04 01.02.03 01.02.02 01.02.01 01.01.10
|
||||
---------- -------- -------- -------- -------- -------- --------
|
||||
mpi.h 01.02.03 01.02.02 01.02.02 01.02.01 01.02.01 01.01.07
|
||||
mpi_ioc.h 01.02.04 01.02.03 01.02.03 01.02.02 01.02.01 01.01.07
|
||||
mpi_cnfg.h 01.02.05 01.02.04 01.02.03 01.02.02 01.02.01 01.01.11
|
||||
mpi_init.h 01.02.04 01.02.04 01.02.03 01.02.02 01.02.01 01.01.05
|
||||
mpi_targ.h 01.02.04 01.02.03 01.02.02 01.02.01 01.02.01 01.01.04
|
||||
mpi_fc.h 01.02.02 01.02.02 01.02.02 01.02.01 01.02.01 01.01.07
|
||||
mpi_lan.h 01.02.01 01.02.01 01.02.01 01.02.01 01.02.01 01.01.03
|
||||
mpi_raid.h 01.02.04 01.02.03 01.02.02 01.02.01 01.02.01 01.01.02
|
||||
mpi_tool.h 01.02.02 01.02.02 01.02.02 01.02.02 01.02.01
|
||||
mpi_type.h 01.02.02 01.02.02 01.02.02 01.02.02 01.02.01 01.01.02
|
||||
|
||||
Filename 01.01.09 01.01.08 01.01.07 01.01.06 01.01.05 01.01.04
|
||||
---------- -------- -------- -------- -------- -------- --------
|
||||
|
@ -1,19 +1,20 @@
|
||||
/*
|
||||
* Copyright (c) 2003 LSI Logic Corporation.
|
||||
* Copyright (c) 2003-2004 LSI Logic Corporation.
|
||||
*
|
||||
*
|
||||
* Name: mpi_inb.h
|
||||
* Title: MPI Inband structures and definitions
|
||||
* Creation Date: September 30, 2003
|
||||
*
|
||||
* mpi_inb.h Version: 01.03.xx
|
||||
* mpi_inb.h Version: 01.05.01
|
||||
*
|
||||
* Version History
|
||||
* ---------------
|
||||
*
|
||||
* 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.
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
@ -1,12 +1,12 @@
|
||||
/*
|
||||
* Copyright (c) 2000-2003 LSI Logic Corporation.
|
||||
* Copyright (c) 2000-2005 LSI Logic Corporation.
|
||||
*
|
||||
*
|
||||
* Name: mpi_init.h
|
||||
* Title: MPI initiator mode messages and structures
|
||||
* Creation Date: June 8, 2000
|
||||
*
|
||||
* mpi_init.h Version: 01.05.xx
|
||||
* mpi_init.h Version: 01.05.04
|
||||
*
|
||||
* Version History
|
||||
* ---------------
|
||||
@ -33,6 +33,21 @@
|
||||
* for SCSI IO requests.
|
||||
* 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.
|
||||
* 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
|
||||
#define MPI_SCSIIO_MSGFLGS_SENSE_WIDTH (0x01)
|
||||
#define MPI_SCSIIO_MSGFLGS_SENSE_WIDTH_32 (0x00)
|
||||
#define MPI_SCSIIO_MSGFLGS_SENSE_WIDTH_64 (0x01)
|
||||
|
||||
#define MPI_SCSIIO_MSGFLGS_SENSE_LOCATION (0x02)
|
||||
#define MPI_SCSIIO_MSGFLGS_SENSE_LOC_HOST (0x00)
|
||||
#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 */
|
||||
|
||||
@ -148,6 +155,8 @@ typedef struct _MSG_SCSI_IO_REPLY
|
||||
U32 TransferCount; /* 14h */
|
||||
U32 SenseCount; /* 18h */
|
||||
U32 ResponseInfo; /* 1Ch */
|
||||
U16 TaskTag; /* 20h */
|
||||
U16 Reserved1; /* 22h */
|
||||
} MSG_SCSI_IO_REPLY, MPI_POINTER PTR_MSG_SCSI_IO_REPLY,
|
||||
SCSIIOReply_t, MPI_POINTER pSCSIIOReply_t;
|
||||
|
||||
@ -190,32 +199,7 @@ typedef struct _MSG_SCSI_IO_REPLY
|
||||
#define MPI_SCSI_RSP_INFO_TASK_MGMT_FAILED (0x05000000)
|
||||
#define MPI_SCSI_RSP_INFO_SPI_LQ_INVALID_TYPE (0x06000000)
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/* 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 */
|
||||
#define MPI_SCSI_TASKTAG_UNKNOWN (0xFFFF)
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
@ -247,6 +231,7 @@ typedef struct _MSG_SCSI_TASK_MGMT
|
||||
#define MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS (0x04)
|
||||
#define MPI_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET (0x05)
|
||||
#define MPI_SCSITASKMGMT_TASKTYPE_CLEAR_TASK_SET (0x06)
|
||||
#define MPI_SCSITASKMGMT_TASKTYPE_QUERY_TASK (0x07)
|
||||
|
||||
/* MsgFlags bits */
|
||||
#define MPI_SCSITASKMGMT_MSGFLAGS_TARGET_RESET_OPTION (0x00)
|
||||
@ -260,7 +245,7 @@ typedef struct _MSG_SCSI_TASK_MGMT_REPLY
|
||||
U8 Bus; /* 01h */
|
||||
U8 MsgLength; /* 02h */
|
||||
U8 Function; /* 03h */
|
||||
U8 Reserved; /* 04h */
|
||||
U8 ResponseCode; /* 04h */
|
||||
U8 TaskType; /* 05h */
|
||||
U8 Reserved1; /* 06h */
|
||||
U8 MsgFlags; /* 07h */
|
||||
@ -272,6 +257,15 @@ typedef struct _MSG_SCSI_TASK_MGMT_REPLY
|
||||
} MSG_SCSI_TASK_MGMT_REPLY, MPI_POINTER PTR_MSG_SCSI_TASK_MGMT_REPLY,
|
||||
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 */
|
||||
@ -284,11 +278,16 @@ typedef struct _MSG_SEP_REQUEST
|
||||
U8 ChainOffset; /* 02h */
|
||||
U8 Function; /* 03h */
|
||||
U8 Action; /* 04h */
|
||||
U8 Reserved1; /* 05h */
|
||||
U8 Reserved2; /* 06h */
|
||||
U8 Flags; /* 05h */
|
||||
U8 Reserved1; /* 06h */
|
||||
U8 MsgFlags; /* 07h */
|
||||
U32 MsgContext; /* 08h */
|
||||
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,
|
||||
SEPRequest_t, MPI_POINTER pSEPRequest_t;
|
||||
|
||||
@ -296,6 +295,10 @@ typedef struct _MSG_SEP_REQUEST
|
||||
#define MPI_SEP_REQ_ACTION_WRITE_STATUS (0x00)
|
||||
#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 */
|
||||
#define MPI_SEP_REQ_SLOTSTATUS_NO_ERROR (0x00000001)
|
||||
#define MPI_SEP_REQ_SLOTSTATUS_DEV_FAULTY (0x00000002)
|
||||
@ -332,6 +335,9 @@ typedef struct _MSG_SEP_REPLY
|
||||
U16 IOCStatus; /* 0Eh */
|
||||
U32 IOCLogInfo; /* 10h */
|
||||
U32 SlotStatus; /* 14h */
|
||||
U32 Reserved4; /* 18h */
|
||||
U16 Slot; /* 1Ch */
|
||||
U16 EnclosureHandle; /* 1Eh */
|
||||
} MSG_SEP_REPLY, MPI_POINTER PTR_MSG_SEP_REPLY,
|
||||
SEPReply_t, MPI_POINTER pSEPReply_t;
|
||||
|
||||
|
@ -1,12 +1,12 @@
|
||||
/*
|
||||
* Copyright (c) 2000-2003 LSI Logic Corporation.
|
||||
* Copyright (c) 2000-2005 LSI Logic Corporation.
|
||||
*
|
||||
*
|
||||
* Name: mpi_ioc.h
|
||||
* Title: MPI IOC, Port, Event, FW Download, and FW Upload messages
|
||||
* Creation Date: August 11, 2000
|
||||
*
|
||||
* mpi_ioc.h Version: 01.05.xx
|
||||
* mpi_ioc.h Version: 01.05.08
|
||||
*
|
||||
* Version History
|
||||
* ---------------
|
||||
@ -57,6 +57,30 @@
|
||||
* Added AliasIndex to EVENT_DATA_LOGOUT structure.
|
||||
* 04-01-03 01.02.07 Added defines for MPI_FW_HEADER_SIGNATURE_.
|
||||
* 06-26-03 01.02.08 Added new values to the product family defines.
|
||||
* 04-29-04 01.02.09 Added IOCCapabilities field to MSG_IOC_FACTS_REPLY and
|
||||
* added related defines.
|
||||
* 05-11-04 01.03.01 Original release for MPI v1.3.
|
||||
* 08-19-04 01.05.01 Added four new fields to MSG_IOC_INIT.
|
||||
* Added three new fields to MSG_IOC_FACTS_REPLY.
|
||||
* Defined four new bits for the IOCCapabilities field of
|
||||
* the IOCFacts reply.
|
||||
* Added two new PortTypes for the PortFacts reply.
|
||||
* Added six new events along with their EventData
|
||||
* structures.
|
||||
* Added a new MsgFlag to the FwDownload request to
|
||||
* indicate last segment.
|
||||
* Defined a new image type of boot loader.
|
||||
* Added FW family codes for SAS product families.
|
||||
* 10-05-04 01.05.02 Added ReplyFifoHostSignalingAddr field to
|
||||
* MSG_IOC_FACTS_REPLY.
|
||||
* 12-07-04 01.05.03 Added more defines for SAS Discovery Error event.
|
||||
* 12-09-04 01.05.04 Added Unsupported device to SAS Device event.
|
||||
* 01-15-05 01.05.05 Added event data for SAS SES Event.
|
||||
* 02-09-05 01.05.06 Added MPI_FW_UPLOAD_ITYPE_FW_BACKUP define.
|
||||
* 02-22-05 01.05.07 Added Host Page Buffer Persistent flag to IOC Facts
|
||||
* Reply and IOC Init Request.
|
||||
* 03-11-05 01.05.08 Added family code for 1068E family.
|
||||
* Removed IOCFacts Reply EEDP Capability bit.
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
@ -90,20 +114,37 @@ typedef struct _MSG_IOC_INIT
|
||||
U32 HostMfaHighAddr; /* 10h */
|
||||
U32 SenseBufferHighAddr; /* 14h */
|
||||
U32 ReplyFifoHostSignalingAddr; /* 18h */
|
||||
SGE_SIMPLE_UNION HostPageBufferSGE; /* 1Ch */
|
||||
U16 MsgVersion; /* 28h */
|
||||
U16 HeaderVersion; /* 2Ah */
|
||||
} MSG_IOC_INIT, MPI_POINTER PTR_MSG_IOC_INIT,
|
||||
IOCInit_t, MPI_POINTER pIOCInit_t;
|
||||
|
||||
/* WhoInit values */
|
||||
#define MPI_WHOINIT_NO_ONE (0x00)
|
||||
#define MPI_WHOINIT_SYSTEM_BIOS (0x01)
|
||||
#define MPI_WHOINIT_ROM_BIOS (0x02)
|
||||
#define MPI_WHOINIT_PCI_PEER (0x03)
|
||||
#define MPI_WHOINIT_HOST_DRIVER (0x04)
|
||||
#define MPI_WHOINIT_MANUFACTURER (0x05)
|
||||
#define MPI_WHOINIT_NO_ONE (0x00)
|
||||
#define MPI_WHOINIT_SYSTEM_BIOS (0x01)
|
||||
#define MPI_WHOINIT_ROM_BIOS (0x02)
|
||||
#define MPI_WHOINIT_PCI_PEER (0x03)
|
||||
#define MPI_WHOINIT_HOST_DRIVER (0x04)
|
||||
#define MPI_WHOINIT_MANUFACTURER (0x05)
|
||||
|
||||
/* Flags values */
|
||||
#define MPI_IOCINIT_FLAGS_DISCARD_FW_IMAGE (0x01)
|
||||
#define MPI_IOCINIT_FLAGS_REPLY_FIFO_HOST_SIGNAL (0x02)
|
||||
#define MPI_IOCINIT_FLAGS_HOST_PAGE_BUFFER_PERSISTENT (0x04)
|
||||
#define MPI_IOCINIT_FLAGS_REPLY_FIFO_HOST_SIGNAL (0x02)
|
||||
#define MPI_IOCINIT_FLAGS_DISCARD_FW_IMAGE (0x01)
|
||||
|
||||
/* MsgVersion */
|
||||
#define MPI_IOCINIT_MSGVERSION_MAJOR_MASK (0xFF00)
|
||||
#define MPI_IOCINIT_MSGVERSION_MAJOR_SHIFT (8)
|
||||
#define MPI_IOCINIT_MSGVERSION_MINOR_MASK (0x00FF)
|
||||
#define MPI_IOCINIT_MSGVERSION_MINOR_SHIFT (0)
|
||||
|
||||
/* HeaderVersion */
|
||||
#define MPI_IOCINIT_HEADERVERSION_UNIT_MASK (0xFF00)
|
||||
#define MPI_IOCINIT_HEADERVERSION_UNIT_SHIFT (8)
|
||||
#define MPI_IOCINIT_HEADERVERSION_DEV_MASK (0x00FF)
|
||||
#define MPI_IOCINIT_HEADERVERSION_DEV_SHIFT (0)
|
||||
|
||||
|
||||
typedef struct _MSG_IOC_INIT_REPLY
|
||||
{
|
||||
@ -187,32 +228,39 @@ typedef struct _MSG_IOC_FACTS_REPLY
|
||||
MPI_FW_VERSION FWVersion; /* 38h */
|
||||
U16 HighPriorityQueueDepth; /* 3Ch */
|
||||
U16 Reserved2; /* 3Eh */
|
||||
SGE_SIMPLE_UNION HostPageBufferSGE; /* 40h */
|
||||
U32 ReplyFifoHostSignalingAddr; /* 4Ch */
|
||||
} MSG_IOC_FACTS_REPLY, MPI_POINTER PTR_MSG_IOC_FACTS_REPLY,
|
||||
IOCFactsReply_t, MPI_POINTER pIOCFactsReply_t;
|
||||
|
||||
#define MPI_IOCFACTS_MSGVERSION_MAJOR_MASK (0xFF00)
|
||||
#define MPI_IOCFACTS_MSGVERSION_MINOR_MASK (0x00FF)
|
||||
#define MPI_IOCFACTS_MSGVERSION_MAJOR_MASK (0xFF00)
|
||||
#define MPI_IOCFACTS_MSGVERSION_MAJOR_SHIFT (8)
|
||||
#define MPI_IOCFACTS_MSGVERSION_MINOR_MASK (0x00FF)
|
||||
#define MPI_IOCFACTS_MSGVERSION_MINOR_SHIFT (0)
|
||||
|
||||
#define MPI_IOCFACTS_HEADERVERSION_UNIT_MASK (0xFF00)
|
||||
#define MPI_IOCFACTS_HEADERVERSION_DEV_MASK (0x00FF)
|
||||
#define MPI_IOCFACTS_HDRVERSION_UNIT_MASK (0xFF00)
|
||||
#define MPI_IOCFACTS_HDRVERSION_UNIT_SHIFT (8)
|
||||
#define MPI_IOCFACTS_HDRVERSION_DEV_MASK (0x00FF)
|
||||
#define MPI_IOCFACTS_HDRVERSION_DEV_SHIFT (0)
|
||||
|
||||
#define MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL (0x0001)
|
||||
#define MPI_IOCFACTS_EXCEPT_RAID_CONFIG_INVALID (0x0002)
|
||||
#define MPI_IOCFACTS_EXCEPT_FW_CHECKSUM_FAIL (0x0004)
|
||||
#define MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL (0x0008)
|
||||
#define MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL (0x0001)
|
||||
#define MPI_IOCFACTS_EXCEPT_RAID_CONFIG_INVALID (0x0002)
|
||||
#define MPI_IOCFACTS_EXCEPT_FW_CHECKSUM_FAIL (0x0004)
|
||||
#define MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL (0x0008)
|
||||
|
||||
#define MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT (0x01)
|
||||
#define MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT (0x01)
|
||||
#define MPI_IOCFACTS_FLAGS_REPLY_FIFO_HOST_SIGNAL (0x02)
|
||||
#define MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT (0x04)
|
||||
|
||||
#define MPI_IOCFACTS_EVENTSTATE_DISABLED (0x00)
|
||||
#define MPI_IOCFACTS_EVENTSTATE_ENABLED (0x01)
|
||||
#define MPI_IOCFACTS_EVENTSTATE_DISABLED (0x00)
|
||||
#define MPI_IOCFACTS_EVENTSTATE_ENABLED (0x01)
|
||||
|
||||
#define MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q (0x00000001)
|
||||
#define MPI_IOCFACTS_CAPABILITY_REPLY_HOST_SIGNAL (0x00000002)
|
||||
#define MPI_IOCFACTS_CAPABILITY_QUEUE_FULL_HANDLING (0x00000004)
|
||||
#define MPI_IOCFACTS_CAPABILITY_DIAG_TRACE_BUFFER (0x00000008)
|
||||
#define MPI_IOCFACTS_CAPABILITY_SNAPSHOT_BUFFER (0x00000010)
|
||||
#define MPI_IOCFACTS_CAPABILITY_EXTENDED_BUFFER (0x00000020)
|
||||
#define MPI_IOCFACTS_CAPABILITY_EEDP (0x00000040)
|
||||
#define MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q (0x00000001)
|
||||
#define MPI_IOCFACTS_CAPABILITY_REPLY_HOST_SIGNAL (0x00000002)
|
||||
#define MPI_IOCFACTS_CAPABILITY_QUEUE_FULL_HANDLING (0x00000004)
|
||||
#define MPI_IOCFACTS_CAPABILITY_DIAG_TRACE_BUFFER (0x00000008)
|
||||
#define MPI_IOCFACTS_CAPABILITY_SNAPSHOT_BUFFER (0x00000010)
|
||||
#define MPI_IOCFACTS_CAPABILITY_EXTENDED_BUFFER (0x00000020)
|
||||
|
||||
|
||||
|
||||
@ -408,6 +456,8 @@ typedef struct _MSG_EVENT_ACK_REPLY
|
||||
#define MPI_EVENT_SAS_DEVICE_STATUS_CHANGE (0x0000000F)
|
||||
#define MPI_EVENT_SAS_SES (0x00000010)
|
||||
#define MPI_EVENT_PERSISTENT_TABLE_FULL (0x00000011)
|
||||
#define MPI_EVENT_SAS_PHY_LINK_STATUS (0x00000012)
|
||||
#define MPI_EVENT_SAS_DISCOVERY_ERROR (0x00000013)
|
||||
|
||||
/* AckRequired field values */
|
||||
|
||||
@ -467,6 +517,10 @@ typedef struct _EVENT_DATA_SAS_DEVICE_STATUS_CHANGE
|
||||
U8 ASCQ; /* 05h */
|
||||
U16 DevHandle; /* 06h */
|
||||
U32 DeviceInfo; /* 08h */
|
||||
U16 ParentDevHandle; /* 0Ch */
|
||||
U8 PhyNum; /* 0Eh */
|
||||
U8 Reserved1; /* 0Fh */
|
||||
U64 SASAddress; /* 10h */
|
||||
} EVENT_DATA_SAS_DEVICE_STATUS_CHANGE,
|
||||
MPI_POINTER PTR_EVENT_DATA_SAS_DEVICE_STATUS_CHANGE,
|
||||
MpiEventDataSasDeviceStatusChange_t,
|
||||
@ -477,6 +531,8 @@ typedef struct _EVENT_DATA_SAS_DEVICE_STATUS_CHANGE
|
||||
#define MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING (0x04)
|
||||
#define MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA (0x05)
|
||||
#define MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED (0x06)
|
||||
#define MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED (0x07)
|
||||
|
||||
|
||||
/* SCSI Event data for Queue Full event */
|
||||
|
||||
@ -488,6 +544,35 @@ typedef struct _EVENT_DATA_QUEUE_FULL
|
||||
} EVENT_DATA_QUEUE_FULL, MPI_POINTER PTR_EVENT_DATA_QUEUE_FULL,
|
||||
EventDataQueueFull_t, MPI_POINTER pEventDataQueueFull_t;
|
||||
|
||||
/* MPI Integrated RAID Event data */
|
||||
|
||||
typedef struct _EVENT_DATA_RAID
|
||||
{
|
||||
U8 VolumeID; /* 00h */
|
||||
U8 VolumeBus; /* 01h */
|
||||
U8 ReasonCode; /* 02h */
|
||||
U8 PhysDiskNum; /* 03h */
|
||||
U8 ASC; /* 04h */
|
||||
U8 ASCQ; /* 05h */
|
||||
U16 Reserved; /* 06h */
|
||||
U32 SettingsStatus; /* 08h */
|
||||
} EVENT_DATA_RAID, MPI_POINTER PTR_EVENT_DATA_RAID,
|
||||
MpiEventDataRaid_t, MPI_POINTER pMpiEventDataRaid_t;
|
||||
|
||||
/* MPI Integrated RAID Event data ReasonCode values */
|
||||
#define MPI_EVENT_RAID_RC_VOLUME_CREATED (0x00)
|
||||
#define MPI_EVENT_RAID_RC_VOLUME_DELETED (0x01)
|
||||
#define MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED (0x02)
|
||||
#define MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED (0x03)
|
||||
#define MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED (0x04)
|
||||
#define MPI_EVENT_RAID_RC_PHYSDISK_CREATED (0x05)
|
||||
#define MPI_EVENT_RAID_RC_PHYSDISK_DELETED (0x06)
|
||||
#define MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED (0x07)
|
||||
#define MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED (0x08)
|
||||
#define MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED (0x09)
|
||||
#define MPI_EVENT_RAID_RC_SMART_DATA (0x0A)
|
||||
#define MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED (0x0B)
|
||||
|
||||
/* MPI Link Status Change Event data */
|
||||
|
||||
typedef struct _EVENT_DATA_LINK_STATUS
|
||||
@ -535,35 +620,63 @@ typedef struct _EVENT_DATA_LOGOUT
|
||||
|
||||
#define MPI_EVENT_LOGOUT_ALL_ALIASES (0xFF)
|
||||
|
||||
/* SAS SES Event data */
|
||||
|
||||
/* MPI Integrated RAID Event data */
|
||||
|
||||
typedef struct _EVENT_DATA_RAID
|
||||
typedef struct _EVENT_DATA_SAS_SES
|
||||
{
|
||||
U8 VolumeID; /* 00h */
|
||||
U8 VolumeBus; /* 01h */
|
||||
U8 ReasonCode; /* 02h */
|
||||
U8 PhysDiskNum; /* 03h */
|
||||
U8 ASC; /* 04h */
|
||||
U8 ASCQ; /* 05h */
|
||||
U16 Reserved; /* 06h */
|
||||
U32 SettingsStatus; /* 08h */
|
||||
} EVENT_DATA_RAID, MPI_POINTER PTR_EVENT_DATA_RAID,
|
||||
MpiEventDataRaid_t, MPI_POINTER pMpiEventDataRaid_t;
|
||||
U8 PhyNum; /* 00h */
|
||||
U8 Port; /* 01h */
|
||||
U8 PortWidth; /* 02h */
|
||||
U8 Reserved1; /* 04h */
|
||||
} EVENT_DATA_SAS_SES, MPI_POINTER PTR_EVENT_DATA_SAS_SES,
|
||||
MpiEventDataSasSes_t, MPI_POINTER pMpiEventDataSasSes_t;
|
||||
|
||||
/* MPI Integrated RAID Event data ReasonCode values */
|
||||
#define MPI_EVENT_RAID_RC_VOLUME_CREATED (0x00)
|
||||
#define MPI_EVENT_RAID_RC_VOLUME_DELETED (0x01)
|
||||
#define MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED (0x02)
|
||||
#define MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED (0x03)
|
||||
#define MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED (0x04)
|
||||
#define MPI_EVENT_RAID_RC_PHYSDISK_CREATED (0x05)
|
||||
#define MPI_EVENT_RAID_RC_PHYSDISK_DELETED (0x06)
|
||||
#define MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED (0x07)
|
||||
#define MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED (0x08)
|
||||
#define MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED (0x09)
|
||||
#define MPI_EVENT_RAID_RC_SMART_DATA (0x0A)
|
||||
#define MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED (0x0B)
|
||||
/* SAS Phy Link Status Event data */
|
||||
|
||||
typedef struct _EVENT_DATA_SAS_PHY_LINK_STATUS
|
||||
{
|
||||
U8 PhyNum; /* 00h */
|
||||
U8 LinkRates; /* 01h */
|
||||
U16 DevHandle; /* 02h */
|
||||
U64 SASAddress; /* 04h */
|
||||
} EVENT_DATA_SAS_PHY_LINK_STATUS, MPI_POINTER PTR_EVENT_DATA_SAS_PHY_LINK_STATUS,
|
||||
MpiEventDataSasPhyLinkStatus_t, MPI_POINTER pMpiEventDataSasPhyLinkStatus_t;
|
||||
|
||||
/* defines for the LinkRates field of the SAS PHY Link Status event */
|
||||
#define MPI_EVENT_SAS_PLS_LR_CURRENT_MASK (0xF0)
|
||||
#define MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT (4)
|
||||
#define MPI_EVENT_SAS_PLS_LR_PREVIOUS_MASK (0x0F)
|
||||
#define MPI_EVENT_SAS_PLS_LR_PREVIOUS_SHIFT (0)
|
||||
#define MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN (0x00)
|
||||
#define MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED (0x01)
|
||||
#define MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION (0x02)
|
||||
#define MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE (0x03)
|
||||
#define MPI_EVENT_SAS_PLS_LR_RATE_1_5 (0x08)
|
||||
#define MPI_EVENT_SAS_PLS_LR_RATE_3_0 (0x09)
|
||||
|
||||
/* SAS Discovery Errror Event data */
|
||||
|
||||
typedef struct _EVENT_DATA_DISCOVERY_ERROR
|
||||
{
|
||||
U32 DiscoveryStatus; /* 00h */
|
||||
U8 Port; /* 04h */
|
||||
U8 Reserved1; /* 05h */
|
||||
U16 Reserved2; /* 06h */
|
||||
} EVENT_DATA_DISCOVERY_ERROR, MPI_POINTER PTR_EVENT_DATA_DISCOVERY_ERROR,
|
||||
EventDataDiscoveryError_t, MPI_POINTER pEventDataDiscoveryError_t;
|
||||
|
||||
#define MPI_EVENT_DSCVRY_ERR_DS_LOOP_DETECTED (0x00000001)
|
||||
#define MPI_EVENT_DSCVRY_ERR_DS_UNADDRESSABLE_DEVICE (0x00000002)
|
||||
#define MPI_EVENT_DSCVRY_ERR_DS_MULTIPLE_PORTS (0x00000004)
|
||||
#define MPI_EVENT_DSCVRY_ERR_DS_EXPANDER_ERR (0x00000008)
|
||||
#define MPI_EVENT_DSCVRY_ERR_DS_SMP_TIMEOUT (0x00000010)
|
||||
#define MPI_EVENT_DSCVRY_ERR_DS_OUT_ROUTE_ENTRIES (0x00000020)
|
||||
#define MPI_EVENT_DSCVRY_ERR_DS_INDEX_NOT_EXIST (0x00000040)
|
||||
#define MPI_EVENT_DSCVRY_ERR_DS_SMP_FUNCTION_FAILED (0x00000080)
|
||||
#define MPI_EVENT_DSCVRY_ERR_DS_SMP_CRC_ERROR (0x00000100)
|
||||
#define MPI_EVENT_DSCVRY_ERR_DS_MULTPL_SUBTRACTIVE (0x00000200)
|
||||
#define MPI_EVENT_DSCVRY_ERR_DS_TABLE_TO_TABLE (0x00000400)
|
||||
#define MPI_EVENT_DSCVRY_ERR_DS_MULTPL_PATHS (0x00000800)
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
@ -589,11 +702,13 @@ typedef struct _MSG_FW_DOWNLOAD
|
||||
} MSG_FW_DOWNLOAD, MPI_POINTER PTR_MSG_FW_DOWNLOAD,
|
||||
FWDownload_t, MPI_POINTER pFWDownload_t;
|
||||
|
||||
#define MPI_FW_DOWNLOAD_ITYPE_RESERVED (0x00)
|
||||
#define MPI_FW_DOWNLOAD_ITYPE_FW (0x01)
|
||||
#define MPI_FW_DOWNLOAD_ITYPE_BIOS (0x02)
|
||||
#define MPI_FW_DOWNLOAD_ITYPE_NVDATA (0x03)
|
||||
#define MPI_FW_DOWNLOAD_ITYPE_BOOTLOADER (0x04)
|
||||
#define MPI_FW_DOWNLOAD_MSGFLGS_LAST_SEGMENT (0x01)
|
||||
|
||||
#define MPI_FW_DOWNLOAD_ITYPE_RESERVED (0x00)
|
||||
#define MPI_FW_DOWNLOAD_ITYPE_FW (0x01)
|
||||
#define MPI_FW_DOWNLOAD_ITYPE_BIOS (0x02)
|
||||
#define MPI_FW_DOWNLOAD_ITYPE_NVDATA (0x03)
|
||||
#define MPI_FW_DOWNLOAD_ITYPE_BOOTLOADER (0x04)
|
||||
|
||||
|
||||
typedef struct _FWDownloadTCSGE
|
||||
@ -647,6 +762,7 @@ typedef struct _MSG_FW_UPLOAD
|
||||
#define MPI_FW_UPLOAD_ITYPE_BIOS_FLASH (0x02)
|
||||
#define MPI_FW_UPLOAD_ITYPE_NVDATA (0x03)
|
||||
#define MPI_FW_UPLOAD_ITYPE_BOOTLOADER (0x04)
|
||||
#define MPI_FW_UPLOAD_ITYPE_FW_BACKUP (0x05)
|
||||
|
||||
typedef struct _FWUploadTCSGE
|
||||
{
|
||||
@ -723,6 +839,7 @@ typedef struct _MPI_FW_HEADER
|
||||
#define MPI_FW_HEADER_PID_PROD_IM_SCSI (0x0400)
|
||||
#define MPI_FW_HEADER_PID_PROD_IS_SCSI (0x0500)
|
||||
#define MPI_FW_HEADER_PID_PROD_CTX_SCSI (0x0600)
|
||||
#define MPI_FW_HEADER_PID_PROD_IR_SCSI (0x0700)
|
||||
|
||||
#define MPI_FW_HEADER_PID_FAMILY_MASK (0x00FF)
|
||||
/* SCSI */
|
||||
@ -740,13 +857,16 @@ typedef struct _MPI_FW_HEADER
|
||||
#define MPI_FW_HEADER_PID_FAMILY_1020TA0_SCSI (0x000C)
|
||||
/* Fibre Channel */
|
||||
#define MPI_FW_HEADER_PID_FAMILY_909_FC (0x0000)
|
||||
#define MPI_FW_HEADER_PID_FAMILY_919_FC (0x0001)
|
||||
#define MPI_FW_HEADER_PID_FAMILY_919X_FC (0x0002)
|
||||
#define MPI_FW_HEADER_PID_FAMILY_919XL_FC (0x0003)
|
||||
#define MPI_FW_HEADER_PID_FAMILY_949_FC (0x0004)
|
||||
#define MPI_FW_HEADER_PID_FAMILY_919_FC (0x0001) /* 919 and 929 */
|
||||
#define MPI_FW_HEADER_PID_FAMILY_919X_FC (0x0002) /* 919X and 929X */
|
||||
#define MPI_FW_HEADER_PID_FAMILY_919XL_FC (0x0003) /* 919XL and 929XL */
|
||||
#define MPI_FW_HEADER_PID_FAMILY_939X_FC (0x0004) /* 939X and 949X */
|
||||
#define MPI_FW_HEADER_PID_FAMILY_959_FC (0x0005)
|
||||
/* SAS */
|
||||
#define MPI_FW_HEADER_PID_FAMILY_1064_SAS (0x0001)
|
||||
#define MPI_FW_HEADER_PID_FAMILY_1068_SAS (0x0002)
|
||||
#define MPI_FW_HEADER_PID_FAMILY_1078_SAS (0x0003)
|
||||
#define MPI_FW_HEADER_PID_FAMILY_106xE_SAS (0x0004) /* 1068E, 1066E, and 1064E */
|
||||
|
||||
typedef struct _MPI_EXT_IMAGE_HEADER
|
||||
{
|
||||
|
@ -1,12 +1,12 @@
|
||||
/*
|
||||
* Copyright (c) 2000-2003 LSI Logic Corporation.
|
||||
* Copyright (c) 2000-2004 LSI Logic Corporation.
|
||||
*
|
||||
*
|
||||
* Name: mpi_lan.h
|
||||
* Title: MPI LAN messages and structures
|
||||
* Creation Date: June 30, 2000
|
||||
*
|
||||
* mpi_lan.h Version: 01.05.xx
|
||||
* mpi_lan.h Version: 01.05.01
|
||||
*
|
||||
* Version History
|
||||
* ---------------
|
||||
@ -28,6 +28,8 @@
|
||||
* 02-20-01 01.01.02 Started using MPI_POINTER.
|
||||
* 03-27-01 01.01.03 Added structure offset comments.
|
||||
* 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.
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
@ -1,12 +1,12 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2003 LSI Logic Corporation.
|
||||
* Copyright (c) 2001-2005 LSI Logic Corporation.
|
||||
*
|
||||
*
|
||||
* Name: mpi_raid.h
|
||||
* Title: MPI RAID message and structures
|
||||
* Creation Date: February 27, 2001
|
||||
*
|
||||
* mpi_raid.h Version: 01.05.xx
|
||||
* mpi_raid.h Version: 01.05.02
|
||||
*
|
||||
* Version History
|
||||
* ---------------
|
||||
@ -28,6 +28,10 @@
|
||||
* 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
|
||||
* 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
|
||||
#define MPI_RAID_ACTION_REPLACE_PHYSDISK (0x10)
|
||||
#define MPI_RAID_ACTION_ACTIVATE_VOLUME (0x11)
|
||||
#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 */
|
||||
#define MPI_RAID_ACTION_ADATA_DO_NOT_SYNC (0x00000001)
|
||||
@ -99,6 +105,13 @@ typedef struct _MSG_RAID_ACTION
|
||||
/* ActionDataWord defines for use with MPI_RAID_ACTION_ACTIVATE_VOLUME action */
|
||||
#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 */
|
||||
|
||||
|
@ -1,83 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) 2003 LSI Logic Corporation.
|
||||
* Copyright (c) 2004 LSI Logic Corporation.
|
||||
*
|
||||
*
|
||||
* Name: mpi_sas.h
|
||||
* Title: MPI Serial Attached SCSI structures and definitions
|
||||
* Creation Date: April 23, 2003
|
||||
* Creation Date: August 19, 2004
|
||||
*
|
||||
* mpi_sas.h Version: 01.05.xx
|
||||
* mpi_sas.h Version: 01.05.01
|
||||
*
|
||||
* Version History
|
||||
* ---------------
|
||||
*
|
||||
* Date Version Description
|
||||
* -------- -------- ------------------------------------------------------
|
||||
* xx-yy-zz 01.05.01 Original release.
|
||||
* 08-19-04 01.05.01 Original release.
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef MPI_SAS_H
|
||||
#define MPI_SAS_H
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* S e r i a l A t t a c h e d S C S I M e s s a g e s
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/****************************************************************************/
|
||||
/* Serial Management Protocol Passthrough Request */
|
||||
/****************************************************************************/
|
||||
|
||||
typedef struct _MSG_SMP_PASSTHROUGH_REQUEST
|
||||
{
|
||||
U8 PassthroughFlags; /* 00h */
|
||||
U8 PhysicalPort; /* 01h */
|
||||
U8 ChainOffset; /* 02h */
|
||||
U8 Function; /* 03h */
|
||||
U16 RequestDataLength; /* 04h */
|
||||
U8 ConnectionRate; /* 06h */
|
||||
U8 MsgFlags; /* 07h */
|
||||
U32 MsgContext; /* 08h */
|
||||
U32 Reserved1; /* 0Ch */
|
||||
U64 SASAddress; /* 10h */
|
||||
U32 Reserved2; /* 18h */
|
||||
U32 Reserved3; /* 1Ch */
|
||||
SGE_SIMPLE_UNION SGL; /* 20h */
|
||||
} MSG_SMP_PASSTHROUGH_REQUEST, MPI_POINTER PTR_MSG_SMP_PASSTHROUGH_REQUEST,
|
||||
SmpPassthroughRequest_t, MPI_POINTER pSmpPassthroughRequest_t;
|
||||
|
||||
#define MPI_SMP_PT_REQ_PT_FLAGS_IMMEDIATE (0x80)
|
||||
|
||||
#define MPI_SMP_PT_REQ_CONNECT_RATE_NEGOTIATED (0x00)
|
||||
#define MPI_SMP_PT_REQ_CONNECT_RATE_1_5 (0x08)
|
||||
#define MPI_SMP_PT_REQ_CONNECT_RATE_3_0 (0x09)
|
||||
|
||||
|
||||
/* Serial Management Protocol Passthrough Reply */
|
||||
typedef struct _MSG_SMP_PASSTHROUGH_REPLY
|
||||
{
|
||||
U8 PassthroughFlags; /* 00h */
|
||||
U8 PhysicalPort; /* 01h */
|
||||
U8 MsgLength; /* 02h */
|
||||
U8 Function; /* 03h */
|
||||
U16 ResponseDataLength; /* 04h */
|
||||
U8 Reserved1; /* 06h */
|
||||
U8 MsgFlags; /* 07h */
|
||||
U32 MsgContext; /* 08h */
|
||||
U8 Reserved2; /* 0Ch */
|
||||
U8 SASStatus; /* 0Dh */
|
||||
U16 IOCStatus; /* 0Eh */
|
||||
U32 IOCLogInfo; /* 10h */
|
||||
U32 Reserved3; /* 14h */
|
||||
U8 ResponseData[4]; /* 18h */
|
||||
} MSG_SMP_PASSTHROUGH_REPLY, MPI_POINTER PTR_MSG_SMP_PASSTHROUGH_REPLY,
|
||||
SmpPassthroughReply_t, MPI_POINTER pSmpPassthroughReply_t;
|
||||
|
||||
#define MPI_SMP_PT_REPLY_PT_FLAGS_IMMEDIATE (0x80)
|
||||
|
||||
/* values for the SASStatus field */
|
||||
/*
|
||||
* Values for SASStatus.
|
||||
*/
|
||||
#define MPI_SASSTATUS_SUCCESS (0x00)
|
||||
#define MPI_SASSTATUS_UNKNOWN_ERROR (0x01)
|
||||
#define MPI_SASSTATUS_INVALID_FRAME (0x02)
|
||||
@ -124,6 +70,131 @@ typedef struct _MSG_SMP_PASSTHROUGH_REPLY
|
||||
#define MPI_SAS_DEVICE_INFO_FANOUT_EXPANDER (0x00000003)
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* S e r i a l A t t a c h e d S C S I M e s s a g e s
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/****************************************************************************/
|
||||
/* Serial Management Protocol Passthrough Request */
|
||||
/****************************************************************************/
|
||||
|
||||
typedef struct _MSG_SMP_PASSTHROUGH_REQUEST
|
||||
{
|
||||
U8 PassthroughFlags; /* 00h */
|
||||
U8 PhysicalPort; /* 01h */
|
||||
U8 ChainOffset; /* 02h */
|
||||
U8 Function; /* 03h */
|
||||
U16 RequestDataLength; /* 04h */
|
||||
U8 ConnectionRate; /* 06h */
|
||||
U8 MsgFlags; /* 07h */
|
||||
U32 MsgContext; /* 08h */
|
||||
U32 Reserved1; /* 0Ch */
|
||||
U64 SASAddress; /* 10h */
|
||||
U32 Reserved2; /* 18h */
|
||||
U32 Reserved3; /* 1Ch */
|
||||
SGE_SIMPLE_UNION SGL; /* 20h */
|
||||
} MSG_SMP_PASSTHROUGH_REQUEST, MPI_POINTER PTR_MSG_SMP_PASSTHROUGH_REQUEST,
|
||||
SmpPassthroughRequest_t, MPI_POINTER pSmpPassthroughRequest_t;
|
||||
|
||||
/* values for PassthroughFlags field */
|
||||
#define MPI_SMP_PT_REQ_PT_FLAGS_IMMEDIATE (0x80)
|
||||
|
||||
/* values for ConnectionRate field */
|
||||
#define MPI_SMP_PT_REQ_CONNECT_RATE_NEGOTIATED (0x00)
|
||||
#define MPI_SMP_PT_REQ_CONNECT_RATE_1_5 (0x08)
|
||||
#define MPI_SMP_PT_REQ_CONNECT_RATE_3_0 (0x09)
|
||||
|
||||
|
||||
/* Serial Management Protocol Passthrough Reply */
|
||||
typedef struct _MSG_SMP_PASSTHROUGH_REPLY
|
||||
{
|
||||
U8 PassthroughFlags; /* 00h */
|
||||
U8 PhysicalPort; /* 01h */
|
||||
U8 MsgLength; /* 02h */
|
||||
U8 Function; /* 03h */
|
||||
U16 ResponseDataLength; /* 04h */
|
||||
U8 Reserved1; /* 06h */
|
||||
U8 MsgFlags; /* 07h */
|
||||
U32 MsgContext; /* 08h */
|
||||
U8 Reserved2; /* 0Ch */
|
||||
U8 SASStatus; /* 0Dh */
|
||||
U16 IOCStatus; /* 0Eh */
|
||||
U32 IOCLogInfo; /* 10h */
|
||||
U32 Reserved3; /* 14h */
|
||||
U8 ResponseData[4]; /* 18h */
|
||||
} MSG_SMP_PASSTHROUGH_REPLY, MPI_POINTER PTR_MSG_SMP_PASSTHROUGH_REPLY,
|
||||
SmpPassthroughReply_t, MPI_POINTER pSmpPassthroughReply_t;
|
||||
|
||||
#define MPI_SMP_PT_REPLY_PT_FLAGS_IMMEDIATE (0x80)
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/* SATA Passthrough Request */
|
||||
/****************************************************************************/
|
||||
|
||||
typedef struct _MSG_SATA_PASSTHROUGH_REQUEST
|
||||
{
|
||||
U8 TargetID; /* 00h */
|
||||
U8 Bus; /* 01h */
|
||||
U8 ChainOffset; /* 02h */
|
||||
U8 Function; /* 03h */
|
||||
U16 PassthroughFlags; /* 04h */
|
||||
U8 ConnectionRate; /* 06h */
|
||||
U8 MsgFlags; /* 07h */
|
||||
U32 MsgContext; /* 08h */
|
||||
U32 Reserved1; /* 0Ch */
|
||||
U32 Reserved2; /* 10h */
|
||||
U32 Reserved3; /* 14h */
|
||||
U32 DataLength; /* 18h */
|
||||
U8 CommandFIS[20]; /* 1Ch */
|
||||
SGE_SIMPLE_UNION SGL; /* 30h */
|
||||
} MSG_SATA_PASSTHROUGH_REQUEST, MPI_POINTER PTR_MSG_SATA_PASSTHROUGH_REQUEST,
|
||||
SataPassthroughRequest_t, MPI_POINTER pSataPassthroughRequest_t;
|
||||
|
||||
/* values for PassthroughFlags field */
|
||||
#define MPI_SATA_PT_REQ_PT_FLAGS_RESET_DEVICE (0x0200)
|
||||
#define MPI_SATA_PT_REQ_PT_FLAGS_EXECUTE_DIAG (0x0100)
|
||||
#define MPI_SATA_PT_REQ_PT_FLAGS_DMA_QUEUED (0x0080)
|
||||
#define MPI_SATA_PT_REQ_PT_FLAGS_PACKET_COMMAND (0x0040)
|
||||
#define MPI_SATA_PT_REQ_PT_FLAGS_DMA (0x0020)
|
||||
#define MPI_SATA_PT_REQ_PT_FLAGS_PIO (0x0010)
|
||||
#define MPI_SATA_PT_REQ_PT_FLAGS_UNSPECIFIED_VU (0x0004)
|
||||
#define MPI_SATA_PT_REQ_PT_FLAGS_WRITE (0x0002)
|
||||
#define MPI_SATA_PT_REQ_PT_FLAGS_READ (0x0001)
|
||||
|
||||
/* values for ConnectionRate field */
|
||||
#define MPI_SATA_PT_REQ_CONNECT_RATE_NEGOTIATED (0x00)
|
||||
#define MPI_SATA_PT_REQ_CONNECT_RATE_1_5 (0x08)
|
||||
#define MPI_SATA_PT_REQ_CONNECT_RATE_3_0 (0x09)
|
||||
|
||||
|
||||
/* SATA Passthrough Reply */
|
||||
typedef struct _MSG_SATA_PASSTHROUGH_REPLY
|
||||
{
|
||||
U8 TargetID; /* 00h */
|
||||
U8 Bus; /* 01h */
|
||||
U8 MsgLength; /* 02h */
|
||||
U8 Function; /* 03h */
|
||||
U16 PassthroughFlags; /* 04h */
|
||||
U8 Reserved1; /* 06h */
|
||||
U8 MsgFlags; /* 07h */
|
||||
U32 MsgContext; /* 08h */
|
||||
U8 Reserved2; /* 0Ch */
|
||||
U8 SASStatus; /* 0Dh */
|
||||
U16 IOCStatus; /* 0Eh */
|
||||
U32 IOCLogInfo; /* 10h */
|
||||
U8 StatusFIS[20]; /* 14h */
|
||||
U32 StatusControlRegisters; /* 28h */
|
||||
U32 TransferCount; /* 2Ch */
|
||||
} MSG_SATA_PASSTHROUGH_REPLY, MPI_POINTER PTR_MSG_SATA_PASSTHROUGH_REPLY,
|
||||
SataPassthroughReply_t, MPI_POINTER pSataPassthroughReply_t;
|
||||
|
||||
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/* SAS IO Unit Control Request */
|
||||
/****************************************************************************/
|
||||
@ -148,15 +219,13 @@ typedef struct _MSG_SAS_IOUNIT_CONTROL_REQUEST
|
||||
} MSG_SAS_IOUNIT_CONTROL_REQUEST, MPI_POINTER PTR_MSG_SAS_IOUNIT_CONTROL_REQUEST,
|
||||
SasIoUnitControlRequest_t, MPI_POINTER pSasIoUnitControlRequest_t;
|
||||
|
||||
/* values for the ... field */
|
||||
/* values for the Operation field */
|
||||
#define MPI_SAS_OP_CLEAR_NOT_PRESENT (0x01)
|
||||
#define MPI_SAS_OP_CLEAR_ALL (0x02)
|
||||
#define MPI_SAS_OP_MAP (0x03)
|
||||
#define MPI_SAS_OP_MOVE (0x04)
|
||||
#define MPI_SAS_OP_CLEAR (0x05)
|
||||
#define MPI_SAS_OP_CLEAR_ALL_PERSISTENT (0x02)
|
||||
#define MPI_SAS_OP_PHY_LINK_RESET (0x06)
|
||||
#define MPI_SAS_OP_PHY_HARD_RESET (0x07)
|
||||
#define MPI_SAS_OP_PHY_CLEAR_ERROR_LOG (0x08)
|
||||
#define MPI_SAS_OP_MAP_CURRENT (0x09)
|
||||
|
||||
|
||||
/* SAS IO Unit Control Reply */
|
||||
|
@ -1,12 +1,12 @@
|
||||
/*
|
||||
* Copyright (c) 2000-2003 LSI Logic Corporation.
|
||||
* Copyright (c) 2000-2004 LSI Logic Corporation.
|
||||
*
|
||||
*
|
||||
* Name: mpi_targ.h
|
||||
* Title: MPI Target mode messages and structures
|
||||
* Creation Date: June 22, 2000
|
||||
*
|
||||
* mpi_targ.h Version: 01.05.xx
|
||||
* mpi_targ.h Version: 01.05.04
|
||||
*
|
||||
* Version History
|
||||
* ---------------
|
||||
@ -43,6 +43,16 @@
|
||||
* Added PRIORITY_REASON_TARGET_BUSY.
|
||||
* 11-15-02 01.02.08 Added AliasID field to MPI_TARGET_SCSI_SPI_CMD_BUFFER.
|
||||
* 04-01-03 01.02.09 Added OptionalOxid field to MPI_TARGET_FCP_CMD_BUFFER.
|
||||
* 05-11-04 01.03.01 Original release for MPI v1.3.
|
||||
* 08-19-04 01.05.01 Added new request message structures for
|
||||
* MSG_TARGET_CMD_BUF_POST_BASE_REQUEST,
|
||||
* MSG_TARGET_CMD_BUF_POST_LIST_REQUEST, and
|
||||
* MSG_TARGET_ASSIST_EXT_REQUEST.
|
||||
* Added new structures for SAS SSP Command buffer, SSP
|
||||
* Task buffer, and SSP Status IU.
|
||||
* 10-05-04 01.05.02 MSG_TARGET_CMD_BUFFER_POST_BASE_LIST_REPLY added.
|
||||
* 02-22-05 01.05.03 Changed a comment.
|
||||
* 03-11-05 01.05.04 Removed TargetAssistExtended Request.
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
@ -133,18 +143,6 @@ typedef struct _MSG_PRIORITY_CMD_RECEIVED_REPLY
|
||||
} MSG_PRIORITY_CMD_RECEIVED_REPLY, MPI_POINTER PTR_MSG_PRIORITY_CMD_RECEIVED_REPLY,
|
||||
PriorityCommandReceivedReply_t, MPI_POINTER pPriorityCommandReceivedReply_t;
|
||||
|
||||
#define PRIORITY_REASON_NO_DISCONNECT (0x00)
|
||||
#define PRIORITY_REASON_SCSI_TASK_MANAGEMENT (0x01)
|
||||
#define PRIORITY_REASON_CMD_PARITY_ERR (0x02)
|
||||
#define PRIORITY_REASON_MSG_OUT_PARITY_ERR (0x03)
|
||||
#define PRIORITY_REASON_LQ_CRC_ERR (0x04)
|
||||
#define PRIORITY_REASON_CMD_CRC_ERR (0x05)
|
||||
#define PRIORITY_REASON_PROTOCOL_ERR (0x06)
|
||||
#define PRIORITY_REASON_DATA_OUT_PARITY_ERR (0x07)
|
||||
#define PRIORITY_REASON_DATA_OUT_CRC_ERR (0x08)
|
||||
#define PRIORITY_REASON_TARGET_BUSY (0x09)
|
||||
#define PRIORITY_REASON_UNKNOWN (0xFF)
|
||||
|
||||
|
||||
typedef struct _MSG_TARGET_CMD_BUFFER_POST_ERROR_REPLY
|
||||
{
|
||||
@ -164,6 +162,89 @@ typedef struct _MSG_TARGET_CMD_BUFFER_POST_ERROR_REPLY
|
||||
MPI_POINTER PTR_MSG_TARGET_CMD_BUFFER_POST_ERROR_REPLY,
|
||||
TargetCmdBufferPostErrorReply_t, MPI_POINTER pTargetCmdBufferPostErrorReply_t;
|
||||
|
||||
#define PRIORITY_REASON_NO_DISCONNECT (0x00)
|
||||
#define PRIORITY_REASON_SCSI_TASK_MANAGEMENT (0x01)
|
||||
#define PRIORITY_REASON_CMD_PARITY_ERR (0x02)
|
||||
#define PRIORITY_REASON_MSG_OUT_PARITY_ERR (0x03)
|
||||
#define PRIORITY_REASON_LQ_CRC_ERR (0x04)
|
||||
#define PRIORITY_REASON_CMD_CRC_ERR (0x05)
|
||||
#define PRIORITY_REASON_PROTOCOL_ERR (0x06)
|
||||
#define PRIORITY_REASON_DATA_OUT_PARITY_ERR (0x07)
|
||||
#define PRIORITY_REASON_DATA_OUT_CRC_ERR (0x08)
|
||||
#define PRIORITY_REASON_TARGET_BUSY (0x09)
|
||||
#define PRIORITY_REASON_UNKNOWN (0xFF)
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/* Target Command Buffer Post Base Request */
|
||||
/****************************************************************************/
|
||||
|
||||
typedef struct _MSG_TARGET_CMD_BUF_POST_BASE_REQUEST
|
||||
{
|
||||
U8 BufferPostFlags; /* 00h */
|
||||
U8 PortNumber; /* 01h */
|
||||
U8 ChainOffset; /* 02h */
|
||||
U8 Function; /* 03h */
|
||||
U16 TotalCmdBuffers; /* 04h */
|
||||
U8 Reserved; /* 06h */
|
||||
U8 MsgFlags; /* 07h */
|
||||
U32 MsgContext; /* 08h */
|
||||
U32 Reserved1; /* 0Ch */
|
||||
U16 CmdBufferLength; /* 10h */
|
||||
U16 NextCmdBufferOffset; /* 12h */
|
||||
U32 BaseAddressLow; /* 14h */
|
||||
U32 BaseAddressHigh; /* 18h */
|
||||
} MSG_TARGET_CMD_BUF_POST_BASE_REQUEST,
|
||||
MPI_POINTER PTR__MSG_TARGET_CMD_BUF_POST_BASE_REQUEST,
|
||||
TargetCmdBufferPostBaseRequest_t,
|
||||
MPI_POINTER pTargetCmdBufferPostBaseRequest_t;
|
||||
|
||||
#define CMD_BUFFER_POST_BASE_FLAGS_AUTO_POST_ALL (0x01)
|
||||
|
||||
|
||||
typedef struct _MSG_TARGET_CMD_BUFFER_POST_BASE_LIST_REPLY
|
||||
{
|
||||
U16 Reserved; /* 00h */
|
||||
U8 MsgLength; /* 02h */
|
||||
U8 Function; /* 03h */
|
||||
U16 Reserved1; /* 04h */
|
||||
U8 Reserved2; /* 06h */
|
||||
U8 MsgFlags; /* 07h */
|
||||
U32 MsgContext; /* 08h */
|
||||
U16 Reserved3; /* 0Ch */
|
||||
U16 IOCStatus; /* 0Eh */
|
||||
U32 IOCLogInfo; /* 10h */
|
||||
} MSG_TARGET_CMD_BUFFER_POST_BASE_LIST_REPLY,
|
||||
MPI_POINTER PTR_MSG_TARGET_CMD_BUFFER_POST_BASE_LIST_REPLY,
|
||||
TargetCmdBufferPostBaseListReply_t,
|
||||
MPI_POINTER pTargetCmdBufferPostBaseListReply_t;
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/* Target Command Buffer Post List Request */
|
||||
/****************************************************************************/
|
||||
|
||||
typedef struct _MSG_TARGET_CMD_BUF_POST_LIST_REQUEST
|
||||
{
|
||||
U8 Reserved; /* 00h */
|
||||
U8 PortNumber; /* 01h */
|
||||
U8 ChainOffset; /* 02h */
|
||||
U8 Function; /* 03h */
|
||||
U16 CmdBufferCount; /* 04h */
|
||||
U8 Reserved1; /* 06h */
|
||||
U8 MsgFlags; /* 07h */
|
||||
U32 MsgContext; /* 08h */
|
||||
U32 Reserved2; /* 0Ch */
|
||||
U16 IoIndex[2]; /* 10h */
|
||||
} MSG_TARGET_CMD_BUF_POST_LIST_REQUEST,
|
||||
MPI_POINTER PTR_MSG_TARGET_CMD_BUF_POST_LIST_REQUEST,
|
||||
TargetCmdBufferPostListRequest_t,
|
||||
MPI_POINTER pTargetCmdBufferPostListRequest_t;
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/* Command Buffer Formats (with 16 byte CDB) */
|
||||
/****************************************************************************/
|
||||
|
||||
typedef struct _MPI_TARGET_FCP_CMD_BUFFER
|
||||
{
|
||||
@ -201,6 +282,46 @@ typedef struct _MPI_TARGET_SCSI_SPI_CMD_BUFFER
|
||||
MpiTargetScsiSpiCmdBuffer, MPI_POINTER pMpiTargetScsiSpiCmdBuffer;
|
||||
|
||||
|
||||
typedef struct _MPI_TARGET_SSP_CMD_BUFFER
|
||||
{
|
||||
U8 FrameType; /* 00h */
|
||||
U8 Reserved1; /* 01h */
|
||||
U16 Reserved2; /* 02h */
|
||||
U16 InitiatorTag; /* 04h */
|
||||
U16 DevHandle; /* 06h */
|
||||
/* COMMAND information unit starts here */
|
||||
U8 LogicalUnitNumber[8]; /* 08h */
|
||||
U8 Reserved3; /* 10h */
|
||||
U8 TaskAttribute; /* lower 3 bits */ /* 11h */
|
||||
U8 Reserved4; /* 12h */
|
||||
U8 AdditionalCDBLength; /* upper 5 bits */ /* 13h */
|
||||
U8 CDB[16]; /* 14h */
|
||||
/* Additional CDB bytes extend past the CDB field */
|
||||
} MPI_TARGET_SSP_CMD_BUFFER, MPI_POINTER PTR_MPI_TARGET_SSP_CMD_BUFFER,
|
||||
MpiTargetSspCmdBuffer, MPI_POINTER pMpiTargetSspCmdBuffer;
|
||||
|
||||
typedef struct _MPI_TARGET_SSP_TASK_BUFFER
|
||||
{
|
||||
U8 FrameType; /* 00h */
|
||||
U8 Reserved1; /* 01h */
|
||||
U16 Reserved2; /* 02h */
|
||||
U16 InitiatorTag; /* 04h */
|
||||
U16 DevHandle; /* 06h */
|
||||
/* TASK information unit starts here */
|
||||
U8 LogicalUnitNumber[8]; /* 08h */
|
||||
U8 Reserved3; /* 10h */
|
||||
U8 Reserved4; /* 11h */
|
||||
U8 TaskManagementFunction; /* 12h */
|
||||
U8 Reserved5; /* 13h */
|
||||
U16 ManagedTaskTag; /* 14h */
|
||||
U16 Reserved6; /* 16h */
|
||||
U32 Reserved7; /* 18h */
|
||||
U32 Reserved8; /* 1Ch */
|
||||
U32 Reserved9; /* 20h */
|
||||
} MPI_TARGET_SSP_TASK_BUFFER, MPI_POINTER PTR_MPI_TARGET_SSP_TASK_BUFFER,
|
||||
MpiTargetSspTaskBuffer, MPI_POINTER pMpiTargetSspTaskBuffer;
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/* Target Assist Request */
|
||||
/****************************************************************************/
|
||||
@ -308,6 +429,27 @@ typedef struct _MPI_TARGET_SCSI_SPI_STATUS_IU
|
||||
} MPI_TARGET_SCSI_SPI_STATUS_IU, MPI_POINTER PTR_MPI_TARGET_SCSI_SPI_STATUS_IU,
|
||||
TargetScsiSpiStatusIU_t, MPI_POINTER pTargetScsiSpiStatusIU_t;
|
||||
|
||||
/*
|
||||
* NOTE: The SSP status IU is big-endian. When used on a little-endian system,
|
||||
* this structure properly orders the bytes.
|
||||
*/
|
||||
typedef struct _MPI_TARGET_SSP_RSP_IU
|
||||
{
|
||||
U32 Reserved0[6]; /* reserved for SSP header */ /* 00h */
|
||||
/* start of RESPONSE information unit */
|
||||
U32 Reserved1; /* 18h */
|
||||
U32 Reserved2; /* 1Ch */
|
||||
U16 Reserved3; /* 20h */
|
||||
U8 DataPres; /* lower 2 bits */ /* 22h */
|
||||
U8 Status; /* 23h */
|
||||
U32 Reserved4; /* 24h */
|
||||
U32 SenseDataLength; /* 28h */
|
||||
U32 ResponseDataLength; /* 2Ch */
|
||||
U8 ResponseSenseData[4]; /* 30h */
|
||||
} MPI_TARGET_SSP_RSP_IU, MPI_POINTER PTR_MPI_TARGET_SSP_RSP_IU,
|
||||
MpiTargetSspRspIu_t, MPI_POINTER pMpiTargetSspRspIu_t;
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/* Target Mode Abort Request */
|
||||
/****************************************************************************/
|
||||
|
@ -1,12 +1,12 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2003 LSI Logic Corporation.
|
||||
* Copyright (c) 2001-2005 LSI Logic Corporation.
|
||||
*
|
||||
*
|
||||
* Name: mpi_tool.h
|
||||
* Title: MPI Toolbox structures and definitions
|
||||
* Creation Date: July 30, 2001
|
||||
*
|
||||
* mpi_tool.h Version: 01.05.xx
|
||||
* mpi_tool.h Version: 01.05.03
|
||||
*
|
||||
* Version History
|
||||
* ---------------
|
||||
@ -15,6 +15,16 @@
|
||||
* -------- -------- ------------------------------------------------------
|
||||
* 08-08-01 01.02.01 Original release.
|
||||
* 08-29-01 01.02.02 Added DIAG_DATA_UPLOAD_HEADER and related defines.
|
||||
* 01-16-04 01.02.03 Added defines and structures for new tools
|
||||
*. MPI_TOOLBOX_ISTWI_READ_WRITE_TOOL and
|
||||
* MPI_TOOLBOX_FC_MANAGEMENT_TOOL.
|
||||
* 04-29-04 01.02.04 Added message structures for Diagnostic Buffer Post and
|
||||
* Diagnostic Release requests and replies.
|
||||
* 05-11-04 01.03.01 Original release for MPI v1.3.
|
||||
* 08-19-04 01.05.01 Original release for MPI v1.5.
|
||||
* 10-06-04 01.05.02 Added define for MPI_DIAG_BUF_TYPE_COUNT.
|
||||
* 02-09-05 01.05.03 Added frame size option to FC management tool.
|
||||
* Added Beacon tool to the Toolbox.
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
@ -26,6 +36,7 @@
|
||||
#define MPI_TOOLBOX_DIAG_DATA_UPLOAD_TOOL (0x02)
|
||||
#define MPI_TOOLBOX_ISTWI_READ_WRITE_TOOL (0x03)
|
||||
#define MPI_TOOLBOX_FC_MANAGEMENT_TOOL (0x04)
|
||||
#define MPI_TOOLBOX_BEACON_TOOL (0x05)
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
@ -185,11 +196,21 @@ typedef struct _MPI_TB_FC_MANAGE_PID_AI
|
||||
} MPI_TB_FC_MANAGE_PID_AI, MPI_POINTER PTR_MPI_TB_FC_MANAGE_PID_AI,
|
||||
MpiTbFcManagePidAi_t, MPI_POINTER pMpiTbFcManagePidAi_t;
|
||||
|
||||
/* ActionInfo for set max frame size */
|
||||
typedef struct _MPI_TB_FC_MANAGE_FRAME_SIZE_AI
|
||||
{
|
||||
U16 FrameSize; /* 00h */
|
||||
U8 PortNum; /* 02h */
|
||||
U8 Reserved1; /* 03h */
|
||||
} MPI_TB_FC_MANAGE_FRAME_SIZE_AI, MPI_POINTER PTR_MPI_TB_FC_MANAGE_FRAME_SIZE_AI,
|
||||
MpiTbFcManageFrameSizeAi_t, MPI_POINTER pMpiTbFcManageFrameSizeAi_t;
|
||||
|
||||
/* union of ActionInfo */
|
||||
typedef union _MPI_TB_FC_MANAGE_AI_UNION
|
||||
{
|
||||
MPI_TB_FC_MANAGE_BUS_TID_AI BusTid;
|
||||
MPI_TB_FC_MANAGE_PID_AI Port;
|
||||
MPI_TB_FC_MANAGE_FRAME_SIZE_AI FrameSize;
|
||||
} MPI_TB_FC_MANAGE_AI_UNION, MPI_POINTER PTR_MPI_TB_FC_MANAGE_AI_UNION,
|
||||
MpiTbFcManageAiUnion_t, MPI_POINTER pMpiTbFcManageAiUnion_t;
|
||||
|
||||
@ -214,6 +235,32 @@ typedef struct _MSG_TOOLBOX_FC_MANAGE_REQUEST
|
||||
#define MPI_TB_FC_MANAGE_ACTION_DISC_ALL (0x00)
|
||||
#define MPI_TB_FC_MANAGE_ACTION_DISC_PID (0x01)
|
||||
#define MPI_TB_FC_MANAGE_ACTION_DISC_BUS_TID (0x02)
|
||||
#define MPI_TB_FC_MANAGE_ACTION_SET_MAX_FRAME_SIZE (0x03)
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/* Toolbox Beacon Tool request */
|
||||
/****************************************************************************/
|
||||
|
||||
typedef struct _MSG_TOOLBOX_BEACON_REQUEST
|
||||
{
|
||||
U8 Tool; /* 00h */
|
||||
U8 Reserved; /* 01h */
|
||||
U8 ChainOffset; /* 02h */
|
||||
U8 Function; /* 03h */
|
||||
U16 Reserved1; /* 04h */
|
||||
U8 Reserved2; /* 06h */
|
||||
U8 MsgFlags; /* 07h */
|
||||
U32 MsgContext; /* 08h */
|
||||
U8 ConnectNum; /* 0Ch */
|
||||
U8 PortNum; /* 0Dh */
|
||||
U8 Reserved3; /* 0Eh */
|
||||
U8 Flags; /* 0Fh */
|
||||
} MSG_TOOLBOX_BEACON_REQUEST, MPI_POINTER PTR_MSG_TOOLBOX_BEACON_REQUEST,
|
||||
ToolboxBeaconRequest_t, MPI_POINTER pToolboxBeaconRequest_t;
|
||||
|
||||
#define MPI_TOOLBOX_FLAGS_BEACON_MODE_OFF (0x00)
|
||||
#define MPI_TOOLBOX_FLAGS_BEACON_MODE_ON (0x01)
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
@ -233,14 +280,16 @@ typedef struct _MSG_DIAG_BUFFER_POST_REQUEST
|
||||
U32 ExtendedType; /* 0Ch */
|
||||
U32 BufferLength; /* 10h */
|
||||
U32 ProductSpecific[4]; /* 14h */
|
||||
U32 Reserved3; /* 18h */
|
||||
SGE_SIMPLE_UNION SGL; /* 28h */
|
||||
U32 Reserved3; /* 24h */
|
||||
U64 BufferAddress; /* 28h */
|
||||
} MSG_DIAG_BUFFER_POST_REQUEST, MPI_POINTER PTR_MSG_DIAG_BUFFER_POST_REQUEST,
|
||||
DiagBufferPostRequest_t, MPI_POINTER pDiagBufferPostRequest_t;
|
||||
|
||||
#define MPI_DIAG_BUF_TYPE_TRACE (0x00)
|
||||
#define MPI_DIAG_BUF_TYPE_SNAPSHOT (0x01)
|
||||
#define MPI_DIAG_BUF_TYPE_EXTENDED (0x02)
|
||||
/* count of the number of buffer types */
|
||||
#define MPI_DIAG_BUF_TYPE_COUNT (0x03)
|
||||
|
||||
#define MPI_DIAG_EXTENDED_QTAG (0x00000001)
|
||||
|
||||
|
@ -1,12 +1,12 @@
|
||||
/*
|
||||
* Copyright (c) 2000-2003 LSI Logic Corporation.
|
||||
* Copyright (c) 2000-2004 LSI Logic Corporation.
|
||||
*
|
||||
*
|
||||
* Name: mpi_type.h
|
||||
* Title: MPI Basic type definitions
|
||||
* Creation Date: June 6, 2000
|
||||
*
|
||||
* mpi_type.h Version: 01.05.xx
|
||||
* mpi_type.h Version: 01.05.01
|
||||
*
|
||||
* Version History
|
||||
* ---------------
|
||||
@ -18,6 +18,8 @@
|
||||
* 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.
|
||||
* 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;
|
||||
typedef int32_t S32;
|
||||
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
|
||||
{
|
||||
U32 Low;
|
||||
|
@ -1,55 +1,13 @@
|
||||
/*
|
||||
* linux/drivers/message/fusion/mptbase.c
|
||||
* High performance SCSI + LAN / Fibre Channel device drivers.
|
||||
* This is the Fusion MPT base driver which supports multiple
|
||||
* (SCSI + LAN) specialized protocol drivers.
|
||||
* For use with PCI chip/adapter(s):
|
||||
* LSIFC9xx/LSI409xx Fibre Channel
|
||||
* For use with LSI Logic PCI chip/adapter(s)
|
||||
* running LSI Logic Fusion MPT (Message Passing Technology) firmware.
|
||||
*
|
||||
* Credits:
|
||||
* There are lots of people not mentioned below that deserve credit
|
||||
* and thanks but won't get it here - sorry in advance that you
|
||||
* got overlooked.
|
||||
*
|
||||
* This driver would not exist if not for Alan Cox's development
|
||||
* of the linux i2o driver.
|
||||
*
|
||||
* A special thanks to Noah Romer (LSI Logic) for tons of work
|
||||
* and tough debugging on the LAN driver, especially early on;-)
|
||||
* And to Roger Hickerson (LSI Logic) for tirelessly supporting
|
||||
* this driver project.
|
||||
*
|
||||
* A special thanks to Pamela Delaney (LSI Logic) for tons of work
|
||||
* and countless enhancements while adding support for the 1030
|
||||
* chip family. Pam has been instrumental in the development of
|
||||
* of the 2.xx.xx series fusion drivers, and her contributions are
|
||||
* far too numerous to hope to list in one place.
|
||||
*
|
||||
* All manner of help from Stephen Shirron (LSI Logic):
|
||||
* low-level FC analysis, debug + various fixes in FCxx firmware,
|
||||
* initial port to alpha platform, various driver code optimizations,
|
||||
* being a faithful sounding board on all sorts of issues & ideas,
|
||||
* etc.
|
||||
*
|
||||
* 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!
|
||||
*
|
||||
* Special thanks goes to the I2O LAN driver people at the
|
||||
* University of Helsinki, who, unbeknownst to them, provided
|
||||
* the inspiration and initial structure for this driver.
|
||||
*
|
||||
* A really huge debt of gratitude is owed to Eddie C. Dost
|
||||
* for gobs of hard work fixing and optimizing LAN code.
|
||||
* THANK YOU!
|
||||
*
|
||||
* Copyright (c) 1999-2004 LSI Logic Corporation
|
||||
* Originally By: Steven J. Ralston
|
||||
* (mailto:sjralston1@netscape.net)
|
||||
* Copyright (c) 1999-2005 LSI Logic Corporation
|
||||
* (mailto:mpt_linux_developer@lsil.com)
|
||||
*
|
||||
* $Id: mptbase.c,v 1.126 2002/12/16 15:28:45 pdelaney Exp $
|
||||
*/
|
||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
||||
/*
|
||||
@ -101,6 +59,7 @@
|
||||
#include <linux/blkdev.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/interrupt.h> /* needed for in_interrupt() proto */
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <asm/io.h>
|
||||
#ifdef CONFIG_MTRR
|
||||
#include <asm/mtrr.h>
|
||||
@ -218,41 +177,35 @@ static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info);
|
||||
static void mpt_sp_log_info(MPT_ADAPTER *ioc, u32 log_info);
|
||||
|
||||
/* module entry point */
|
||||
static int __devinit mptbase_probe (struct pci_dev *, const struct pci_device_id *);
|
||||
static void __devexit mptbase_remove(struct pci_dev *);
|
||||
static void mptbase_shutdown(struct device * );
|
||||
static int __init fusion_init (void);
|
||||
static void __exit fusion_exit (void);
|
||||
|
||||
/****************************************************************************
|
||||
* Supported hardware
|
||||
*/
|
||||
|
||||
static struct pci_device_id mptbase_pci_table[] = {
|
||||
{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC909,
|
||||
PCI_ANY_ID, PCI_ANY_ID },
|
||||
{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC929,
|
||||
PCI_ANY_ID, PCI_ANY_ID },
|
||||
{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC919,
|
||||
PCI_ANY_ID, PCI_ANY_ID },
|
||||
{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC929X,
|
||||
PCI_ANY_ID, PCI_ANY_ID },
|
||||
{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC919X,
|
||||
PCI_ANY_ID, PCI_ANY_ID },
|
||||
{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_53C1030,
|
||||
PCI_ANY_ID, PCI_ANY_ID },
|
||||
{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_1030_53C1035,
|
||||
PCI_ANY_ID, PCI_ANY_ID },
|
||||
{0} /* Terminating entry */
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, mptbase_pci_table);
|
||||
|
||||
#define CHIPREG_READ32(addr) readl_relaxed(addr)
|
||||
#define CHIPREG_READ32_dmasync(addr) readl(addr)
|
||||
#define CHIPREG_WRITE32(addr,val) writel(val, addr)
|
||||
#define CHIPREG_PIO_WRITE32(addr,val) outl(val, (unsigned long)addr)
|
||||
#define CHIPREG_PIO_READ32(addr) inl((unsigned long)addr)
|
||||
|
||||
static void
|
||||
pci_disable_io_access(struct pci_dev *pdev)
|
||||
{
|
||||
u16 command_reg;
|
||||
|
||||
pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
|
||||
command_reg &= ~1;
|
||||
pci_write_config_word(pdev, PCI_COMMAND, command_reg);
|
||||
}
|
||||
|
||||
static void
|
||||
pci_enable_io_access(struct pci_dev *pdev)
|
||||
{
|
||||
u16 command_reg;
|
||||
|
||||
pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
|
||||
command_reg |= 1;
|
||||
pci_write_config_word(pdev, PCI_COMMAND, command_reg);
|
||||
}
|
||||
|
||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
||||
/*
|
||||
* mpt_interrupt - MPT adapter (IOC) specific interrupt handler.
|
||||
@ -330,8 +283,7 @@ mpt_interrupt(int irq, void *bus_id, struct pt_regs *r)
|
||||
ioc->name, mr, req_idx));
|
||||
DBG_DUMP_REPLY_FRAME(mr)
|
||||
|
||||
/* NEW! 20010301 -sralston
|
||||
* Check/log IOC log info
|
||||
/* Check/log IOC log info
|
||||
*/
|
||||
ioc_stat = le16_to_cpu(mr->u.reply.IOCStatus);
|
||||
if (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
|
||||
@ -357,9 +309,7 @@ mpt_interrupt(int irq, void *bus_id, struct pt_regs *r)
|
||||
mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
|
||||
} else if (type == MPI_CONTEXT_REPLY_TYPE_LAN) {
|
||||
cb_idx = mpt_lan_index;
|
||||
/*
|
||||
* BUG FIX! 20001218 -sralston
|
||||
* Blind set of mf to NULL here was fatal
|
||||
/* Blind set of mf to NULL here was fatal
|
||||
* after lan_reply says "freeme"
|
||||
* Fix sort of combined with an optimization here;
|
||||
* added explicit check for case where lan_reply
|
||||
@ -430,15 +380,8 @@ mpt_interrupt(int irq, void *bus_id, struct pt_regs *r)
|
||||
}
|
||||
|
||||
if (freeme) {
|
||||
unsigned long flags;
|
||||
|
||||
/* Put Request back on FreeQ! */
|
||||
spin_lock_irqsave(&ioc->FreeQlock, flags);
|
||||
list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
|
||||
#ifdef MFCNT
|
||||
ioc->mfcnt--;
|
||||
#endif
|
||||
spin_unlock_irqrestore(&ioc->FreeQlock, flags);
|
||||
mpt_free_msg_frame(ioc, mf);
|
||||
}
|
||||
|
||||
mb();
|
||||
@ -725,11 +668,9 @@ int
|
||||
mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, int cb_idx)
|
||||
{
|
||||
MPT_ADAPTER *ioc;
|
||||
int error=0;
|
||||
|
||||
if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) {
|
||||
error= -EINVAL;
|
||||
return error;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
MptDeviceDriverHandlers[cb_idx] = dd_cbfunc;
|
||||
@ -737,14 +678,12 @@ mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, int cb_idx)
|
||||
/* call per pci device probe entry point */
|
||||
list_for_each_entry(ioc, &ioc_list, list) {
|
||||
if(dd_cbfunc->probe) {
|
||||
error = dd_cbfunc->probe(ioc->pcidev,
|
||||
dd_cbfunc->probe(ioc->pcidev,
|
||||
ioc->pcidev->driver->id_table);
|
||||
if(error != 0)
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
||||
@ -809,8 +748,8 @@ mpt_get_msg_frame(int handle, MPT_ADAPTER *ioc)
|
||||
mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle; /* byte */
|
||||
req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
|
||||
/* u16! */
|
||||
req_idx = cpu_to_le16(req_offset / ioc->req_sz);
|
||||
mf->u.frame.hwhdr.msgctxu.fld.req_idx = req_idx;
|
||||
req_idx = req_offset / ioc->req_sz;
|
||||
mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
|
||||
mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
|
||||
ioc->RequestNB[req_idx] = ioc->NB_for_64_byte_frame; /* Default, will be changed if necessary in SG generation */
|
||||
#ifdef MFCNT
|
||||
@ -856,8 +795,8 @@ mpt_put_msg_frame(int handle, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
|
||||
mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle; /* byte */
|
||||
req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
|
||||
/* u16! */
|
||||
req_idx = cpu_to_le16(req_offset / ioc->req_sz);
|
||||
mf->u.frame.hwhdr.msgctxu.fld.req_idx = req_idx;
|
||||
req_idx = req_offset / ioc->req_sz;
|
||||
mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
|
||||
mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
|
||||
|
||||
#ifdef MPT_DEBUG_MSG_FRAME
|
||||
@ -1058,7 +997,7 @@ mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
|
||||
|
||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
||||
/*
|
||||
* mptbase_probe - Install a PCI intelligent MPT adapter.
|
||||
* mpt_attach - Install a PCI intelligent MPT adapter.
|
||||
* @pdev: Pointer to pci_dev structure
|
||||
*
|
||||
* This routine performs all the steps necessary to bring the IOC of
|
||||
@ -1073,8 +1012,8 @@ mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
|
||||
*
|
||||
* TODO: Add support for polled controllers
|
||||
*/
|
||||
static int __devinit
|
||||
mptbase_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
int
|
||||
mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
{
|
||||
MPT_ADAPTER *ioc;
|
||||
u8 __iomem *mem;
|
||||
@ -1084,7 +1023,6 @@ mptbase_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
u32 psize;
|
||||
int ii;
|
||||
int r = -ENODEV;
|
||||
u64 mask = 0xffffffffffffffffULL;
|
||||
u8 revision;
|
||||
u8 pcixcmd;
|
||||
static int mpt_ids = 0;
|
||||
@ -1097,15 +1035,15 @@ mptbase_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
|
||||
dinitprintk((KERN_WARNING MYNAM ": mpt_adapter_install\n"));
|
||||
|
||||
if (!pci_set_dma_mask(pdev, mask)) {
|
||||
if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
|
||||
dprintk((KERN_INFO MYNAM
|
||||
": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n"));
|
||||
} else if (pci_set_dma_mask(pdev, (u64) 0xffffffff)) {
|
||||
} else if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
|
||||
printk(KERN_WARNING MYNAM ": 32 BIT PCI BUS DMA ADDRESSING NOT SUPPORTED\n");
|
||||
return r;
|
||||
}
|
||||
|
||||
if (!pci_set_consistent_dma_mask(pdev, mask))
|
||||
if (!pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK))
|
||||
dprintk((KERN_INFO MYNAM
|
||||
": Using 64 bit consistent mask\n"));
|
||||
else
|
||||
@ -1243,6 +1181,16 @@ mptbase_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
pcixcmd &= 0x8F;
|
||||
pci_write_config_byte(pdev, 0x6a, pcixcmd);
|
||||
}
|
||||
else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC939X) {
|
||||
ioc->prod_name = "LSIFC939X";
|
||||
ioc->bus_type = FC;
|
||||
ioc->errata_flag_1064 = 1;
|
||||
}
|
||||
else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC949X) {
|
||||
ioc->prod_name = "LSIFC949X";
|
||||
ioc->bus_type = FC;
|
||||
ioc->errata_flag_1064 = 1;
|
||||
}
|
||||
else if (pdev->device == MPI_MANUFACTPAGE_DEVID_53C1030) {
|
||||
ioc->prod_name = "LSI53C1030";
|
||||
ioc->bus_type = SCSI;
|
||||
@ -1261,6 +1209,9 @@ mptbase_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
ioc->bus_type = SCSI;
|
||||
}
|
||||
|
||||
if (ioc->errata_flag_1064)
|
||||
pci_disable_io_access(pdev);
|
||||
|
||||
sprintf(ioc->name, "ioc%d", ioc->id);
|
||||
|
||||
spin_lock_init(&ioc->FreeQlock);
|
||||
@ -1303,8 +1254,7 @@ mptbase_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
#endif
|
||||
}
|
||||
|
||||
/* NEW! 20010220 -sralston
|
||||
* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
|
||||
/* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
|
||||
*/
|
||||
mpt_detect_bound_ports(ioc, pdev);
|
||||
|
||||
@ -1354,13 +1304,13 @@ mptbase_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
|
||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
||||
/*
|
||||
* mptbase_remove - Remove a PCI intelligent MPT adapter.
|
||||
* mpt_detach - Remove a PCI intelligent MPT adapter.
|
||||
* @pdev: Pointer to pci_dev structure
|
||||
*
|
||||
*/
|
||||
|
||||
static void __devexit
|
||||
mptbase_remove(struct pci_dev *pdev)
|
||||
void
|
||||
mpt_detach(struct pci_dev *pdev)
|
||||
{
|
||||
MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
|
||||
char pname[32];
|
||||
@ -1397,43 +1347,21 @@ mptbase_remove(struct pci_dev *pdev)
|
||||
pci_set_drvdata(pdev, NULL);
|
||||
}
|
||||
|
||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
||||
/*
|
||||
* mptbase_shutdown -
|
||||
*
|
||||
*/
|
||||
static void
|
||||
mptbase_shutdown(struct device * dev)
|
||||
{
|
||||
int ii;
|
||||
|
||||
/* call per device driver shutdown entry point */
|
||||
for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
|
||||
if(MptDeviceDriverHandlers[ii] &&
|
||||
MptDeviceDriverHandlers[ii]->shutdown) {
|
||||
MptDeviceDriverHandlers[ii]->shutdown(dev);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* Power Management
|
||||
*/
|
||||
#ifdef CONFIG_PM
|
||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
||||
/*
|
||||
* mptbase_suspend - Fusion MPT base driver suspend routine.
|
||||
* mpt_suspend - Fusion MPT base driver suspend routine.
|
||||
*
|
||||
*
|
||||
*/
|
||||
static int
|
||||
mptbase_suspend(struct pci_dev *pdev, pm_message_t state)
|
||||
int
|
||||
mpt_suspend(struct pci_dev *pdev, pm_message_t state)
|
||||
{
|
||||
u32 device_state;
|
||||
MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
|
||||
int ii;
|
||||
|
||||
switch(state)
|
||||
{
|
||||
@ -1453,14 +1381,6 @@ mptbase_suspend(struct pci_dev *pdev, pm_message_t state)
|
||||
"pci-suspend: pdev=0x%p, slot=%s, Entering operating state [D%d]\n",
|
||||
ioc->name, pdev, pci_name(pdev), device_state);
|
||||
|
||||
/* call per device driver suspend entry point */
|
||||
for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
|
||||
if(MptDeviceDriverHandlers[ii] &&
|
||||
MptDeviceDriverHandlers[ii]->suspend) {
|
||||
MptDeviceDriverHandlers[ii]->suspend(pdev, state);
|
||||
}
|
||||
}
|
||||
|
||||
pci_save_state(pdev);
|
||||
|
||||
/* put ioc into READY_STATE */
|
||||
@ -1484,18 +1404,18 @@ mptbase_suspend(struct pci_dev *pdev, pm_message_t state)
|
||||
|
||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
||||
/*
|
||||
* mptbase_resume - Fusion MPT base driver resume routine.
|
||||
* mpt_resume - Fusion MPT base driver resume routine.
|
||||
*
|
||||
*
|
||||
*/
|
||||
static int
|
||||
mptbase_resume(struct pci_dev *pdev)
|
||||
int
|
||||
mpt_resume(struct pci_dev *pdev)
|
||||
{
|
||||
MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
|
||||
u32 device_state = pdev->current_state;
|
||||
int recovery_state;
|
||||
int ii;
|
||||
|
||||
|
||||
printk(MYIOC_s_INFO_FMT
|
||||
"pci-resume: pdev=0x%p, slot=%s, Previous operating state [D%d]\n",
|
||||
ioc->name, pdev, pci_name(pdev), device_state);
|
||||
@ -1533,14 +1453,6 @@ mptbase_resume(struct pci_dev *pdev)
|
||||
"pci-resume: success\n", ioc->name);
|
||||
}
|
||||
|
||||
/* call per device driver resume entry point */
|
||||
for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
|
||||
if(MptDeviceDriverHandlers[ii] &&
|
||||
MptDeviceDriverHandlers[ii]->resume) {
|
||||
MptDeviceDriverHandlers[ii]->resume(pdev);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@ -1719,8 +1631,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
|
||||
ioc->alt_ioc->active = 1;
|
||||
}
|
||||
|
||||
/* NEW! 20010120 -sralston
|
||||
* Enable MPT base driver management of EventNotification
|
||||
/* Enable MPT base driver management of EventNotification
|
||||
* and EventAck handling.
|
||||
*/
|
||||
if ((ret == 0) && (!ioc->facts.EventState))
|
||||
@ -1729,9 +1640,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
|
||||
if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState)
|
||||
(void) SendEventNotification(ioc->alt_ioc, 1); /* 1=Enable EventNotification */
|
||||
|
||||
/* (Bugzilla:fibrebugs, #513)
|
||||
* Bug fix (part 2)! 20010905 -sralston
|
||||
* Add additional "reason" check before call to GetLanConfigPages
|
||||
/* Add additional "reason" check before call to GetLanConfigPages
|
||||
* (combined with GetIoUnitPage2 call). This prevents a somewhat
|
||||
* recursive scenario; GetLanConfigPages times out, timer expired
|
||||
* routine calls HardResetHandler, which calls into here again,
|
||||
@ -1829,37 +1738,43 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
|
||||
static void
|
||||
mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
|
||||
{
|
||||
unsigned int match_lo, match_hi;
|
||||
struct pci_dev *peer=NULL;
|
||||
unsigned int slot = PCI_SLOT(pdev->devfn);
|
||||
unsigned int func = PCI_FUNC(pdev->devfn);
|
||||
MPT_ADAPTER *ioc_srch;
|
||||
|
||||
match_lo = pdev->devfn-1;
|
||||
match_hi = pdev->devfn+1;
|
||||
dprintk((MYIOC_s_INFO_FMT "PCI bus/devfn=%x/%x, searching for devfn match on %x or %x\n",
|
||||
ioc->name, pdev->bus->number, pdev->devfn, match_lo, match_hi));
|
||||
dprintk((MYIOC_s_INFO_FMT "PCI device %s devfn=%x/%x,"
|
||||
" searching for devfn match on %x or %x\n",
|
||||
ioc->name, pci_name(pdev), pdev->devfn,
|
||||
func-1, func+1));
|
||||
|
||||
peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func-1));
|
||||
if (!peer) {
|
||||
peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func+1));
|
||||
if (!peer)
|
||||
return;
|
||||
}
|
||||
|
||||
list_for_each_entry(ioc_srch, &ioc_list, list) {
|
||||
struct pci_dev *_pcidev = ioc_srch->pcidev;
|
||||
|
||||
if ((_pcidev->device == pdev->device) &&
|
||||
(_pcidev->bus->number == pdev->bus->number) &&
|
||||
(_pcidev->devfn == match_lo || _pcidev->devfn == match_hi) ) {
|
||||
if (_pcidev == peer) {
|
||||
/* Paranoia checks */
|
||||
if (ioc->alt_ioc != NULL) {
|
||||
printk(KERN_WARNING MYNAM ": Oops, already bound (%s <==> %s)!\n",
|
||||
ioc->name, ioc->alt_ioc->name);
|
||||
ioc->name, ioc->alt_ioc->name);
|
||||
break;
|
||||
} else if (ioc_srch->alt_ioc != NULL) {
|
||||
printk(KERN_WARNING MYNAM ": Oops, already bound (%s <==> %s)!\n",
|
||||
ioc_srch->name, ioc_srch->alt_ioc->name);
|
||||
ioc_srch->name, ioc_srch->alt_ioc->name);
|
||||
break;
|
||||
}
|
||||
dprintk((KERN_INFO MYNAM ": FOUND! binding %s <==> %s\n",
|
||||
ioc->name, ioc_srch->name));
|
||||
ioc->name, ioc_srch->name));
|
||||
ioc_srch->alt_ioc = ioc;
|
||||
ioc->alt_ioc = ioc_srch;
|
||||
break;
|
||||
}
|
||||
}
|
||||
pci_dev_put(peer);
|
||||
}
|
||||
|
||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
||||
@ -1922,15 +1837,10 @@ mpt_adapter_disable(MPT_ADAPTER *ioc)
|
||||
ioc->alloc_total -= sz;
|
||||
}
|
||||
|
||||
if (ioc->spi_data.nvram != NULL) {
|
||||
kfree(ioc->spi_data.nvram);
|
||||
ioc->spi_data.nvram = NULL;
|
||||
}
|
||||
|
||||
if (ioc->spi_data.pIocPg3 != NULL) {
|
||||
kfree(ioc->spi_data.pIocPg3);
|
||||
ioc->spi_data.pIocPg3 = NULL;
|
||||
}
|
||||
kfree(ioc->spi_data.nvram);
|
||||
kfree(ioc->spi_data.pIocPg3);
|
||||
ioc->spi_data.nvram = NULL;
|
||||
ioc->spi_data.pIocPg3 = NULL;
|
||||
|
||||
if (ioc->spi_data.pIocPg4 != NULL) {
|
||||
sz = ioc->spi_data.IocPg4Sz;
|
||||
@ -1947,10 +1857,8 @@ mpt_adapter_disable(MPT_ADAPTER *ioc)
|
||||
ioc->ReqToChain = NULL;
|
||||
}
|
||||
|
||||
if (ioc->ChainToChain != NULL) {
|
||||
kfree(ioc->ChainToChain);
|
||||
ioc->ChainToChain = NULL;
|
||||
}
|
||||
kfree(ioc->ChainToChain);
|
||||
ioc->ChainToChain = NULL;
|
||||
}
|
||||
|
||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
||||
@ -2333,7 +2241,7 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
|
||||
return -55;
|
||||
}
|
||||
|
||||
r = sz = le32_to_cpu(facts->BlockSize);
|
||||
r = sz = facts->BlockSize;
|
||||
vv = ((63 / (sz * 4)) + 1) & 0x03;
|
||||
ioc->NB_for_64_byte_frame = vv;
|
||||
while ( sz )
|
||||
@ -2785,7 +2693,7 @@ mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag)
|
||||
/* prevent a second downloadboot and memory free with alt_ioc */
|
||||
if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
|
||||
ioc->alt_ioc->cached_fw = NULL;
|
||||
|
||||
|
||||
CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
|
||||
CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
|
||||
CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
|
||||
@ -2843,6 +2751,9 @@ mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag)
|
||||
/* Write the LoadStartAddress to the DiagRw Address Register
|
||||
* using Programmed IO
|
||||
*/
|
||||
if (ioc->errata_flag_1064)
|
||||
pci_enable_io_access(ioc->pcidev);
|
||||
|
||||
CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->LoadStartAddress);
|
||||
ddlprintk((MYIOC_s_INFO_FMT "LoadStart addr written 0x%x \n",
|
||||
ioc->name, pFwHeader->LoadStartAddress));
|
||||
@ -2889,6 +2800,9 @@ mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag)
|
||||
CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
|
||||
CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
|
||||
|
||||
if (ioc->errata_flag_1064)
|
||||
pci_disable_io_access(ioc->pcidev);
|
||||
|
||||
diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
|
||||
ddlprintk((MYIOC_s_INFO_FMT "downloadboot diag0val=%x, turning off PREVENT_IOC_BOOT, DISABLE_ARM\n",
|
||||
ioc->name, diag0val));
|
||||
@ -4250,7 +4164,7 @@ mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
|
||||
if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) ||
|
||||
(ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE)) {
|
||||
|
||||
if (ioc->spi_data.minSyncFactor < MPT_ULTRA)
|
||||
if (ioc->spi_data.minSyncFactor < MPT_ULTRA)
|
||||
ioc->spi_data.minSyncFactor = MPT_ULTRA;
|
||||
}
|
||||
}
|
||||
@ -4482,10 +4396,8 @@ mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
|
||||
|
||||
/* Free the old page
|
||||
*/
|
||||
if (ioc->spi_data.pIocPg3) {
|
||||
kfree(ioc->spi_data.pIocPg3);
|
||||
ioc->spi_data.pIocPg3 = NULL;
|
||||
}
|
||||
kfree(ioc->spi_data.pIocPg3);
|
||||
ioc->spi_data.pIocPg3 = NULL;
|
||||
|
||||
/* There is at least one physical disk.
|
||||
* Read and save IOC Page 3
|
||||
@ -4753,9 +4665,7 @@ mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
|
||||
u32 flagsLength;
|
||||
int in_isr;
|
||||
|
||||
/* (Bugzilla:fibrebugs, #513)
|
||||
* Bug fix (part 1)! 20010905 -sralston
|
||||
* Prevent calling wait_event() (below), if caller happens
|
||||
/* Prevent calling wait_event() (below), if caller happens
|
||||
* to be in ISR context, because that is fatal!
|
||||
*/
|
||||
in_isr = in_interrupt();
|
||||
@ -4861,9 +4771,7 @@ mpt_toolbox(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
|
||||
u32 flagsLength;
|
||||
int in_isr;
|
||||
|
||||
/* (Bugzilla:fibrebugs, #513)
|
||||
* Bug fix (part 1)! 20010905 -sralston
|
||||
* Prevent calling wait_event() (below), if caller happens
|
||||
/* Prevent calling wait_event() (below), if caller happens
|
||||
* to be in ISR context, because that is fatal!
|
||||
*/
|
||||
in_isr = in_interrupt();
|
||||
@ -5130,20 +5038,26 @@ static int
|
||||
procmpt_version_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
|
||||
{
|
||||
int ii;
|
||||
int scsi, lan, ctl, targ, dmp;
|
||||
int scsi, fc, sas, lan, ctl, targ, dmp;
|
||||
char *drvname;
|
||||
int len;
|
||||
|
||||
len = sprintf(buf, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON);
|
||||
len += sprintf(buf+len, " Fusion MPT base driver\n");
|
||||
|
||||
scsi = lan = ctl = targ = dmp = 0;
|
||||
scsi = fc = sas = lan = ctl = targ = dmp = 0;
|
||||
for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
|
||||
drvname = NULL;
|
||||
if (MptCallbacks[ii]) {
|
||||
switch (MptDriverClass[ii]) {
|
||||
case MPTSCSIH_DRIVER:
|
||||
if (!scsi++) drvname = "SCSI host";
|
||||
case MPTSPI_DRIVER:
|
||||
if (!scsi++) drvname = "SPI host";
|
||||
break;
|
||||
case MPTFC_DRIVER:
|
||||
if (!fc++) drvname = "FC host";
|
||||
break;
|
||||
case MPTSAS_DRIVER:
|
||||
if (!sas++) drvname = "SAS host";
|
||||
break;
|
||||
case MPTLAN_DRIVER:
|
||||
if (!lan++) drvname = "LAN";
|
||||
@ -5832,6 +5746,12 @@ mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
|
||||
}
|
||||
|
||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
||||
EXPORT_SYMBOL(mpt_attach);
|
||||
EXPORT_SYMBOL(mpt_detach);
|
||||
#ifdef CONFIG_PM
|
||||
EXPORT_SYMBOL(mpt_resume);
|
||||
EXPORT_SYMBOL(mpt_suspend);
|
||||
#endif
|
||||
EXPORT_SYMBOL(ioc_list);
|
||||
EXPORT_SYMBOL(mpt_proc_root_dir);
|
||||
EXPORT_SYMBOL(mpt_register);
|
||||
@ -5860,19 +5780,6 @@ EXPORT_SYMBOL(mpt_read_ioc_pg_3);
|
||||
EXPORT_SYMBOL(mpt_alloc_fw_memory);
|
||||
EXPORT_SYMBOL(mpt_free_fw_memory);
|
||||
|
||||
static struct pci_driver mptbase_driver = {
|
||||
.name = "mptbase",
|
||||
.id_table = mptbase_pci_table,
|
||||
.probe = mptbase_probe,
|
||||
.remove = __devexit_p(mptbase_remove),
|
||||
.driver = {
|
||||
.shutdown = mptbase_shutdown,
|
||||
},
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = mptbase_suspend,
|
||||
.resume = mptbase_resume,
|
||||
#endif
|
||||
};
|
||||
|
||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
||||
/*
|
||||
@ -5884,7 +5791,6 @@ static int __init
|
||||
fusion_init(void)
|
||||
{
|
||||
int i;
|
||||
int r;
|
||||
|
||||
show_mptmod_ver(my_NAME, my_VERSION);
|
||||
printk(KERN_INFO COPYRIGHT "\n");
|
||||
@ -5896,8 +5802,7 @@ fusion_init(void)
|
||||
MptResetHandlers[i] = NULL;
|
||||
}
|
||||
|
||||
/* NEW! 20010120 -sralston
|
||||
* Register ourselves (mptbase) in order to facilitate
|
||||
/* Register ourselves (mptbase) in order to facilitate
|
||||
* EventNotification handling.
|
||||
*/
|
||||
mpt_base_index = mpt_register(mpt_base_reply, MPTBASE_DRIVER);
|
||||
@ -5913,11 +5818,7 @@ fusion_init(void)
|
||||
#ifdef CONFIG_PROC_FS
|
||||
(void) procmpt_create();
|
||||
#endif
|
||||
r = pci_register_driver(&mptbase_driver);
|
||||
if(r)
|
||||
return(r);
|
||||
|
||||
return r;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
||||
@ -5933,7 +5834,6 @@ fusion_exit(void)
|
||||
|
||||
dexitprintk((KERN_INFO MYNAM ": fusion_exit() called!\n"));
|
||||
|
||||
pci_unregister_driver(&mptbase_driver);
|
||||
mpt_reset_deregister(mpt_base_index);
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
@ -5941,6 +5841,5 @@ fusion_exit(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
module_init(fusion_init);
|
||||
module_exit(fusion_exit);
|
||||
|
@ -5,15 +5,9 @@
|
||||
* LSIFC9xx/LSI409xx Fibre Channel
|
||||
* running LSI Logic Fusion MPT (Message Passing Technology) firmware.
|
||||
*
|
||||
* Credits:
|
||||
* (see mptbase.c)
|
||||
*
|
||||
* Copyright (c) 1999-2004 LSI Logic Corporation
|
||||
* Originally By: Steven J. Ralston
|
||||
* (mailto:sjralston1@netscape.net)
|
||||
* Copyright (c) 1999-2005 LSI Logic Corporation
|
||||
* (mailto:mpt_linux_developer@lsil.com)
|
||||
*
|
||||
* $Id: mptbase.h,v 1.144 2003/01/28 21:31:56 pdelaney Exp $
|
||||
*/
|
||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
||||
/*
|
||||
@ -71,7 +65,6 @@
|
||||
#include "lsi/mpi_fc.h" /* Fibre Channel (lowlevel) support */
|
||||
#include "lsi/mpi_targ.h" /* SCSI/FCP Target protcol support */
|
||||
#include "lsi/mpi_tool.h" /* Tools support */
|
||||
#include "lsi/fc_log.h"
|
||||
|
||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
||||
|
||||
@ -80,11 +73,11 @@
|
||||
#endif
|
||||
|
||||
#ifndef COPYRIGHT
|
||||
#define COPYRIGHT "Copyright (c) 1999-2004 " MODULEAUTHOR
|
||||
#define COPYRIGHT "Copyright (c) 1999-2005 " MODULEAUTHOR
|
||||
#endif
|
||||
|
||||
#define MPT_LINUX_VERSION_COMMON "3.01.20"
|
||||
#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.01.20"
|
||||
#define MPT_LINUX_VERSION_COMMON "3.03.02"
|
||||
#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.03.02"
|
||||
#define WHAT_MAGIC_STRING "@" "(" "#" ")"
|
||||
|
||||
#define show_mptmod_ver(s,ver) \
|
||||
@ -203,7 +196,9 @@
|
||||
typedef enum {
|
||||
MPTBASE_DRIVER, /* MPT base class */
|
||||
MPTCTL_DRIVER, /* MPT ioctl class */
|
||||
MPTSCSIH_DRIVER, /* MPT SCSI host (initiator) class */
|
||||
MPTSPI_DRIVER, /* MPT SPI host class */
|
||||
MPTFC_DRIVER, /* MPT FC host class */
|
||||
MPTSAS_DRIVER, /* MPT SAS host class */
|
||||
MPTLAN_DRIVER, /* MPT LAN class */
|
||||
MPTSTM_DRIVER, /* MPT SCSI target mode class */
|
||||
MPTUNKNOWN_DRIVER
|
||||
@ -212,11 +207,6 @@ typedef enum {
|
||||
struct mpt_pci_driver{
|
||||
int (*probe) (struct pci_dev *dev, const struct pci_device_id *id);
|
||||
void (*remove) (struct pci_dev *dev);
|
||||
void (*shutdown) (struct device * dev);
|
||||
#ifdef CONFIG_PM
|
||||
int (*resume) (struct pci_dev *dev);
|
||||
int (*suspend) (struct pci_dev *dev, pm_message_t state);
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
@ -483,6 +473,7 @@ typedef struct _ScsiCfgData {
|
||||
u8 forceDv; /* 1 to force DV scheduling */
|
||||
u8 noQas; /* Disable QAS for this adapter */
|
||||
u8 Saf_Te; /* 1 to force all Processors as SAF-TE if Inquiry data length is too short to check for SAF-TE */
|
||||
u8 mpt_dv; /* command line option: enhanced=1, basic=0 */
|
||||
u8 rsvd[1];
|
||||
} ScsiCfgData;
|
||||
|
||||
@ -571,11 +562,21 @@ typedef struct _MPT_ADAPTER
|
||||
FCPortPage0_t fc_port_page0[2];
|
||||
LANPage0_t lan_cnfg_page0;
|
||||
LANPage1_t lan_cnfg_page1;
|
||||
/*
|
||||
* Description: errata_flag_1064
|
||||
* If a PCIX read occurs within 1 or 2 cycles after the chip receives
|
||||
* a split completion for a read data, an internal address pointer incorrectly
|
||||
* increments by 32 bytes
|
||||
*/
|
||||
int errata_flag_1064;
|
||||
u8 FirstWhoInit;
|
||||
u8 upload_fw; /* If set, do a fw upload */
|
||||
u8 reload_fw; /* Force a FW Reload on next reset */
|
||||
u8 NBShiftFactor; /* NB Shift Factor based on Block Size (Facts) */
|
||||
u8 pad1[4];
|
||||
int DoneCtx;
|
||||
int TaskCtx;
|
||||
int InternalCtx;
|
||||
struct list_head list;
|
||||
struct net_device *netdev;
|
||||
} MPT_ADAPTER;
|
||||
@ -773,12 +774,6 @@ typedef struct _mpt_sge {
|
||||
#define DBG_DUMP_TM_REPLY_FRAME(mfp)
|
||||
#endif
|
||||
|
||||
#ifdef MPT_DEBUG_NEH
|
||||
#define nehprintk(x) printk x
|
||||
#else
|
||||
#define nehprintk(x)
|
||||
#endif
|
||||
|
||||
#if defined(MPT_DEBUG_CONFIG) || defined(MPT_DEBUG)
|
||||
#define dcprintk(x) printk x
|
||||
#else
|
||||
@ -898,6 +893,11 @@ typedef struct _MPT_SCSI_HOST {
|
||||
unsigned long soft_resets; /* fw/external bus resets count */
|
||||
unsigned long timeouts; /* cmd timeouts */
|
||||
ushort sel_timeout[MPT_MAX_FC_DEVICES];
|
||||
char *info_kbuf;
|
||||
wait_queue_head_t scandv_waitq;
|
||||
int scandv_wait_done;
|
||||
long last_queue_full;
|
||||
u8 mpt_pq_filter;
|
||||
} MPT_SCSI_HOST;
|
||||
|
||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
||||
@ -931,6 +931,12 @@ typedef struct _x_config_parms {
|
||||
/*
|
||||
* Public entry points...
|
||||
*/
|
||||
extern int mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id);
|
||||
extern void mpt_detach(struct pci_dev *pdev);
|
||||
#ifdef CONFIG_PM
|
||||
extern int mpt_suspend(struct pci_dev *pdev, pm_message_t state);
|
||||
extern int mpt_resume(struct pci_dev *pdev);
|
||||
#endif
|
||||
extern int mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass);
|
||||
extern void mpt_deregister(int cb_idx);
|
||||
extern int mpt_event_register(int cb_idx, MPT_EVHANDLER ev_cbfunc);
|
||||
|
@ -1,40 +1,12 @@
|
||||
/*
|
||||
* linux/drivers/message/fusion/mptctl.c
|
||||
* Fusion MPT misc device (ioctl) driver.
|
||||
* For use with PCI chip/adapter(s):
|
||||
* LSIFC9xx/LSI409xx Fibre Channel
|
||||
* mpt Ioctl driver.
|
||||
* For use with LSI Logic PCI chip/adapters
|
||||
* running LSI Logic Fusion MPT (Message Passing Technology) firmware.
|
||||
*
|
||||
* Credits:
|
||||
* This driver would not exist if not for Alan Cox's development
|
||||
* of the linux i2o driver.
|
||||
*
|
||||
* A special thanks to Pamela Delaney (LSI Logic) for tons of work
|
||||
* and countless enhancements while adding support for the 1030
|
||||
* chip family. Pam has been instrumental in the development of
|
||||
* of the 2.xx.xx series fusion drivers, and her contributions are
|
||||
* far too numerous to hope to list in one place.
|
||||
*
|
||||
* 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!
|
||||
*
|
||||
* A big THANKS to Eddie C. Dost for fixing the ioctl path
|
||||
* and most importantly f/w download on sparc64 platform!
|
||||
* (plus Eddie's other helpful hints and insights)
|
||||
*
|
||||
* Thanks to Arnaldo Carvalho de Melo for finding and patching
|
||||
* a potential memory leak in mptctl_do_fw_download(),
|
||||
* and for some kmalloc insight:-)
|
||||
*
|
||||
* (see also mptbase.c)
|
||||
*
|
||||
* Copyright (c) 1999-2004 LSI Logic Corporation
|
||||
* Originally By: Steven J. Ralston, Noah Romer
|
||||
* (mailto:sjralston1@netscape.net)
|
||||
* Copyright (c) 1999-2005 LSI Logic Corporation
|
||||
* (mailto:mpt_linux_developer@lsil.com)
|
||||
*
|
||||
* $Id: mptctl.c,v 1.63 2002/12/03 21:26:33 pdelaney Exp $
|
||||
*/
|
||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
||||
/*
|
||||
@ -95,8 +67,8 @@
|
||||
#include <scsi/scsi_host.h>
|
||||
#include <scsi/scsi_tcq.h>
|
||||
|
||||
#define COPYRIGHT "Copyright (c) 1999-2004 LSI Logic Corporation"
|
||||
#define MODULEAUTHOR "Steven J. Ralston, Noah Romer, Pamela Delaney"
|
||||
#define COPYRIGHT "Copyright (c) 1999-2005 LSI Logic Corporation"
|
||||
#define MODULEAUTHOR "LSI Logic Corporation"
|
||||
#include "mptbase.h"
|
||||
#include "mptctl.h"
|
||||
|
||||
@ -127,14 +99,14 @@ struct buflist {
|
||||
* arg contents specific to function.
|
||||
*/
|
||||
static int mptctl_fw_download(unsigned long arg);
|
||||
static int mptctl_getiocinfo (unsigned long arg, unsigned int cmd);
|
||||
static int mptctl_gettargetinfo (unsigned long arg);
|
||||
static int mptctl_readtest (unsigned long arg);
|
||||
static int mptctl_mpt_command (unsigned long arg);
|
||||
static int mptctl_eventquery (unsigned long arg);
|
||||
static int mptctl_eventenable (unsigned long arg);
|
||||
static int mptctl_eventreport (unsigned long arg);
|
||||
static int mptctl_replace_fw (unsigned long arg);
|
||||
static int mptctl_getiocinfo(unsigned long arg, unsigned int cmd);
|
||||
static int mptctl_gettargetinfo(unsigned long arg);
|
||||
static int mptctl_readtest(unsigned long arg);
|
||||
static int mptctl_mpt_command(unsigned long arg);
|
||||
static int mptctl_eventquery(unsigned long arg);
|
||||
static int mptctl_eventenable(unsigned long arg);
|
||||
static int mptctl_eventreport(unsigned long arg);
|
||||
static int mptctl_replace_fw(unsigned long arg);
|
||||
|
||||
static int mptctl_do_reset(unsigned long arg);
|
||||
static int mptctl_hp_hostinfo(unsigned long arg, unsigned int cmd);
|
||||
@ -149,11 +121,11 @@ static long compat_mpctl_ioctl(struct file *f, unsigned cmd, unsigned long arg);
|
||||
/*
|
||||
* Private function calls.
|
||||
*/
|
||||
static int mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr);
|
||||
static int mptctl_do_mpt_command(struct mpt_ioctl_command karg, void __user *mfPtr);
|
||||
static int mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen);
|
||||
static MptSge_t *kbuf_alloc_2_sgl( int bytes, u32 dir, int sge_offset, int *frags,
|
||||
static MptSge_t *kbuf_alloc_2_sgl(int bytes, u32 dir, int sge_offset, int *frags,
|
||||
struct buflist **blp, dma_addr_t *sglbuf_dma, MPT_ADAPTER *ioc);
|
||||
static void kfree_sgl( MptSge_t *sgl, dma_addr_t sgl_dma,
|
||||
static void kfree_sgl(MptSge_t *sgl, dma_addr_t sgl_dma,
|
||||
struct buflist *buflist, MPT_ADAPTER *ioc);
|
||||
static void mptctl_timeout_expired (MPT_IOCTL *ioctl);
|
||||
static int mptctl_bus_reset(MPT_IOCTL *ioctl);
|
||||
@ -1119,7 +1091,7 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size)
|
||||
int numDevices = 0;
|
||||
unsigned int max_id;
|
||||
int ii;
|
||||
int port;
|
||||
unsigned int port;
|
||||
int cim_rev;
|
||||
u8 revision;
|
||||
|
||||
@ -1162,9 +1134,7 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* Verify the data transfer size is correct.
|
||||
* Ignore the port setting.
|
||||
*/
|
||||
/* Verify the data transfer size is correct. */
|
||||
if (karg->hdr.maxDataSize != data_size) {
|
||||
printk(KERN_ERR "%s@%d::mptctl_getiocinfo - "
|
||||
"Structure size mismatch. Command not completed.\n",
|
||||
@ -1181,6 +1151,8 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size)
|
||||
else
|
||||
karg->adapterType = MPT_IOCTL_INTERFACE_SCSI;
|
||||
|
||||
if (karg->hdr.port > 1)
|
||||
return -EINVAL;
|
||||
port = karg->hdr.port;
|
||||
|
||||
karg->port = port;
|
||||
|
@ -5,22 +5,9 @@
|
||||
* LSIFC9xx/LSI409xx Fibre Channel
|
||||
* running LSI Logic Fusion MPT (Message Passing Technology) firmware.
|
||||
*
|
||||
* Credits:
|
||||
* 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)
|
||||
* Copyright (c) 1999-2005 LSI Logic Corporation
|
||||
* (mailto:mpt_linux_developer@lsil.com)
|
||||
*
|
||||
* $Id: mptctl.h,v 1.13 2002/12/03 21:26:33 pdelaney Exp $
|
||||
*/
|
||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
||||
/*
|
||||
|
431
drivers/message/fusion/mptfc.c
Normal file
431
drivers/message/fusion/mptfc.c
Normal file
@ -0,0 +1,431 @@
|
||||
/*
|
||||
* linux/drivers/message/fusion/mptfc.c
|
||||
* For use with LSI Logic PCI chip/adapter(s)
|
||||
* running LSI Logic Fusion MPT (Message Passing Technology) firmware.
|
||||
*
|
||||
* Copyright (c) 1999-2005 LSI Logic Corporation
|
||||
* (mailto:mpt_linux_developer@lsil.com)
|
||||
*
|
||||
*/
|
||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
||||
/*
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
NO WARRANTY
|
||||
THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
|
||||
LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
|
||||
solely responsible for determining the appropriateness of using and
|
||||
distributing the Program and assumes all risks associated with its
|
||||
exercise of rights under this Agreement, including but not limited to
|
||||
the risks and costs of program errors, damage to or loss of data,
|
||||
programs or equipment, and unavailability or interruption of operations.
|
||||
|
||||
DISCLAIMER OF LIABILITY
|
||||
NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
|
||||
HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
||||
#include "linux_compat.h" /* linux-2.6 tweaks */
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/kdev_t.h>
|
||||
#include <linux/blkdev.h>
|
||||
#include <linux/delay.h> /* for mdelay */
|
||||
#include <linux/interrupt.h> /* needed for in_interrupt() proto */
|
||||
#include <linux/reboot.h> /* notifier code */
|
||||
#include <linux/sched.h>
|
||||
#include <linux/workqueue.h>
|
||||
|
||||
#include <scsi/scsi.h>
|
||||
#include <scsi/scsi_cmnd.h>
|
||||
#include <scsi/scsi_device.h>
|
||||
#include <scsi/scsi_host.h>
|
||||
#include <scsi/scsi_tcq.h>
|
||||
|
||||
#include "mptbase.h"
|
||||
#include "mptscsih.h"
|
||||
|
||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
||||
#define my_NAME "Fusion MPT FC Host driver"
|
||||
#define my_VERSION MPT_LINUX_VERSION_COMMON
|
||||
#define MYNAM "mptfc"
|
||||
|
||||
MODULE_AUTHOR(MODULEAUTHOR);
|
||||
MODULE_DESCRIPTION(my_NAME);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
/* Command line args */
|
||||
static int mpt_pq_filter = 0;
|
||||
module_param(mpt_pq_filter, int, 0);
|
||||
MODULE_PARM_DESC(mpt_pq_filter, " Enable peripheral qualifier filter: enable=1 (default=0)");
|
||||
|
||||
static int mptfcDoneCtx = -1;
|
||||
static int mptfcTaskCtx = -1;
|
||||
static int mptfcInternalCtx = -1; /* Used only for internal commands */
|
||||
|
||||
static struct device_attribute mptfc_queue_depth_attr = {
|
||||
.attr = {
|
||||
.name = "queue_depth",
|
||||
.mode = S_IWUSR,
|
||||
},
|
||||
.store = mptscsih_store_queue_depth,
|
||||
};
|
||||
|
||||
static struct device_attribute *mptfc_dev_attrs[] = {
|
||||
&mptfc_queue_depth_attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static struct scsi_host_template mptfc_driver_template = {
|
||||
.proc_name = "mptfc",
|
||||
.proc_info = mptscsih_proc_info,
|
||||
.name = "MPT FC Host",
|
||||
.info = mptscsih_info,
|
||||
.queuecommand = mptscsih_qcmd,
|
||||
.slave_alloc = mptscsih_slave_alloc,
|
||||
.slave_configure = mptscsih_slave_configure,
|
||||
.slave_destroy = mptscsih_slave_destroy,
|
||||
.eh_abort_handler = mptscsih_abort,
|
||||
.eh_device_reset_handler = mptscsih_dev_reset,
|
||||
.eh_bus_reset_handler = mptscsih_bus_reset,
|
||||
.eh_host_reset_handler = mptscsih_host_reset,
|
||||
.bios_param = mptscsih_bios_param,
|
||||
.can_queue = MPT_FC_CAN_QUEUE,
|
||||
.this_id = -1,
|
||||
.sg_tablesize = MPT_SCSI_SG_DEPTH,
|
||||
.max_sectors = 8192,
|
||||
.cmd_per_lun = 7,
|
||||
.use_clustering = ENABLE_CLUSTERING,
|
||||
.sdev_attrs = mptfc_dev_attrs,
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Supported hardware
|
||||
*/
|
||||
|
||||
static struct pci_device_id mptfc_pci_table[] = {
|
||||
{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC909,
|
||||
PCI_ANY_ID, PCI_ANY_ID },
|
||||
{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC919,
|
||||
PCI_ANY_ID, PCI_ANY_ID },
|
||||
{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC929,
|
||||
PCI_ANY_ID, PCI_ANY_ID },
|
||||
{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC919X,
|
||||
PCI_ANY_ID, PCI_ANY_ID },
|
||||
{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC929X,
|
||||
PCI_ANY_ID, PCI_ANY_ID },
|
||||
{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC939X,
|
||||
PCI_ANY_ID, PCI_ANY_ID },
|
||||
{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC949X,
|
||||
PCI_ANY_ID, PCI_ANY_ID },
|
||||
{0} /* Terminating entry */
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, mptfc_pci_table);
|
||||
|
||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
||||
/*
|
||||
* mptfc_probe - Installs scsi devices per bus.
|
||||
* @pdev: Pointer to pci_dev structure
|
||||
*
|
||||
* Returns 0 for success, non-zero for failure.
|
||||
*
|
||||
*/
|
||||
static int
|
||||
mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
{
|
||||
struct Scsi_Host *sh;
|
||||
MPT_SCSI_HOST *hd;
|
||||
MPT_ADAPTER *ioc;
|
||||
unsigned long flags;
|
||||
int sz, ii;
|
||||
int numSGE = 0;
|
||||
int scale;
|
||||
int ioc_cap;
|
||||
u8 *mem;
|
||||
int error=0;
|
||||
int r;
|
||||
|
||||
if ((r = mpt_attach(pdev,id)) != 0)
|
||||
return r;
|
||||
|
||||
ioc = pci_get_drvdata(pdev);
|
||||
ioc->DoneCtx = mptfcDoneCtx;
|
||||
ioc->TaskCtx = mptfcTaskCtx;
|
||||
ioc->InternalCtx = mptfcInternalCtx;
|
||||
|
||||
/* Added sanity check on readiness of the MPT adapter.
|
||||
*/
|
||||
if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
|
||||
printk(MYIOC_s_WARN_FMT
|
||||
"Skipping because it's not operational!\n",
|
||||
ioc->name);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (!ioc->active) {
|
||||
printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
|
||||
ioc->name);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* Sanity check - ensure at least 1 port is INITIATOR capable
|
||||
*/
|
||||
ioc_cap = 0;
|
||||
for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
|
||||
if (ioc->pfacts[ii].ProtocolFlags &
|
||||
MPI_PORTFACTS_PROTOCOL_INITIATOR)
|
||||
ioc_cap ++;
|
||||
}
|
||||
|
||||
if (!ioc_cap) {
|
||||
printk(MYIOC_s_WARN_FMT
|
||||
"Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n",
|
||||
ioc->name, ioc);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
sh = scsi_host_alloc(&mptfc_driver_template, sizeof(MPT_SCSI_HOST));
|
||||
|
||||
if (!sh) {
|
||||
printk(MYIOC_s_WARN_FMT
|
||||
"Unable to register controller with SCSI subsystem\n",
|
||||
ioc->name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&ioc->FreeQlock, flags);
|
||||
|
||||
/* Attach the SCSI Host to the IOC structure
|
||||
*/
|
||||
ioc->sh = sh;
|
||||
|
||||
sh->io_port = 0;
|
||||
sh->n_io_port = 0;
|
||||
sh->irq = 0;
|
||||
|
||||
/* set 16 byte cdb's */
|
||||
sh->max_cmd_len = 16;
|
||||
|
||||
sh->max_id = MPT_MAX_FC_DEVICES<256 ? MPT_MAX_FC_DEVICES : 255;
|
||||
|
||||
sh->max_lun = MPT_LAST_LUN + 1;
|
||||
sh->max_channel = 0;
|
||||
sh->this_id = ioc->pfacts[0].PortSCSIID;
|
||||
|
||||
/* Required entry.
|
||||
*/
|
||||
sh->unique_id = ioc->id;
|
||||
|
||||
/* Verify that we won't exceed the maximum
|
||||
* number of chain buffers
|
||||
* We can optimize: ZZ = req_sz/sizeof(SGE)
|
||||
* For 32bit SGE's:
|
||||
* numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
|
||||
* + (req_sz - 64)/sizeof(SGE)
|
||||
* A slightly different algorithm is required for
|
||||
* 64bit SGEs.
|
||||
*/
|
||||
scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
|
||||
if (sizeof(dma_addr_t) == sizeof(u64)) {
|
||||
numSGE = (scale - 1) *
|
||||
(ioc->facts.MaxChainDepth-1) + scale +
|
||||
(ioc->req_sz - 60) / (sizeof(dma_addr_t) +
|
||||
sizeof(u32));
|
||||
} else {
|
||||
numSGE = 1 + (scale - 1) *
|
||||
(ioc->facts.MaxChainDepth-1) + scale +
|
||||
(ioc->req_sz - 64) / (sizeof(dma_addr_t) +
|
||||
sizeof(u32));
|
||||
}
|
||||
|
||||
if (numSGE < sh->sg_tablesize) {
|
||||
/* Reset this value */
|
||||
dprintk((MYIOC_s_INFO_FMT
|
||||
"Resetting sg_tablesize to %d from %d\n",
|
||||
ioc->name, numSGE, sh->sg_tablesize));
|
||||
sh->sg_tablesize = numSGE;
|
||||
}
|
||||
|
||||
/* Set the pci device pointer in Scsi_Host structure.
|
||||
*/
|
||||
scsi_set_device(sh, &ioc->pcidev->dev);
|
||||
|
||||
spin_unlock_irqrestore(&ioc->FreeQlock, flags);
|
||||
|
||||
hd = (MPT_SCSI_HOST *) sh->hostdata;
|
||||
hd->ioc = ioc;
|
||||
|
||||
/* SCSI needs scsi_cmnd lookup table!
|
||||
* (with size equal to req_depth*PtrSz!)
|
||||
*/
|
||||
sz = ioc->req_depth * sizeof(void *);
|
||||
mem = kmalloc(sz, GFP_ATOMIC);
|
||||
if (mem == NULL) {
|
||||
error = -ENOMEM;
|
||||
goto mptfc_probe_failed;
|
||||
}
|
||||
|
||||
memset(mem, 0, sz);
|
||||
hd->ScsiLookup = (struct scsi_cmnd **) mem;
|
||||
|
||||
dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p, sz=%d\n",
|
||||
ioc->name, hd->ScsiLookup, sz));
|
||||
|
||||
/* Allocate memory for the device structures.
|
||||
* A non-Null pointer at an offset
|
||||
* indicates a device exists.
|
||||
* max_id = 1 + maximum id (hosts.h)
|
||||
*/
|
||||
sz = sh->max_id * sizeof(void *);
|
||||
mem = kmalloc(sz, GFP_ATOMIC);
|
||||
if (mem == NULL) {
|
||||
error = -ENOMEM;
|
||||
goto mptfc_probe_failed;
|
||||
}
|
||||
|
||||
memset(mem, 0, sz);
|
||||
hd->Targets = (VirtDevice **) mem;
|
||||
|
||||
dprintk((KERN_INFO
|
||||
" Targets @ %p, sz=%d\n", hd->Targets, sz));
|
||||
|
||||
/* Clear the TM flags
|
||||
*/
|
||||
hd->tmPending = 0;
|
||||
hd->tmState = TM_STATE_NONE;
|
||||
hd->resetPending = 0;
|
||||
hd->abortSCpnt = NULL;
|
||||
|
||||
/* Clear the pointer used to store
|
||||
* single-threaded commands, i.e., those
|
||||
* issued during a bus scan, dv and
|
||||
* configuration pages.
|
||||
*/
|
||||
hd->cmdPtr = NULL;
|
||||
|
||||
/* Initialize this SCSI Hosts' timers
|
||||
* To use, set the timer expires field
|
||||
* and add_timer
|
||||
*/
|
||||
init_timer(&hd->timer);
|
||||
hd->timer.data = (unsigned long) hd;
|
||||
hd->timer.function = mptscsih_timer_expired;
|
||||
|
||||
hd->mpt_pq_filter = mpt_pq_filter;
|
||||
|
||||
ddvprintk((MYIOC_s_INFO_FMT
|
||||
"mpt_pq_filter %x\n",
|
||||
ioc->name,
|
||||
mpt_pq_filter));
|
||||
|
||||
init_waitqueue_head(&hd->scandv_waitq);
|
||||
hd->scandv_wait_done = 0;
|
||||
hd->last_queue_full = 0;
|
||||
|
||||
error = scsi_add_host (sh, &ioc->pcidev->dev);
|
||||
if(error) {
|
||||
dprintk((KERN_ERR MYNAM
|
||||
"scsi_add_host failed\n"));
|
||||
goto mptfc_probe_failed;
|
||||
}
|
||||
|
||||
scsi_scan_host(sh);
|
||||
return 0;
|
||||
|
||||
mptfc_probe_failed:
|
||||
|
||||
mptscsih_remove(pdev);
|
||||
return error;
|
||||
}
|
||||
|
||||
static struct pci_driver mptfc_driver = {
|
||||
.name = "mptfc",
|
||||
.id_table = mptfc_pci_table,
|
||||
.probe = mptfc_probe,
|
||||
.remove = __devexit_p(mptscsih_remove),
|
||||
.driver = {
|
||||
.shutdown = mptscsih_shutdown,
|
||||
},
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = mptscsih_suspend,
|
||||
.resume = mptscsih_resume,
|
||||
#endif
|
||||
};
|
||||
|
||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
||||
/**
|
||||
* mptfc_init - Register MPT adapter(s) as SCSI host(s) with
|
||||
* linux scsi mid-layer.
|
||||
*
|
||||
* Returns 0 for success, non-zero for failure.
|
||||
*/
|
||||
static int __init
|
||||
mptfc_init(void)
|
||||
{
|
||||
|
||||
show_mptmod_ver(my_NAME, my_VERSION);
|
||||
|
||||
mptfcDoneCtx = mpt_register(mptscsih_io_done, MPTFC_DRIVER);
|
||||
mptfcTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTFC_DRIVER);
|
||||
mptfcInternalCtx = mpt_register(mptscsih_scandv_complete, MPTFC_DRIVER);
|
||||
|
||||
if (mpt_event_register(mptfcDoneCtx, mptscsih_event_process) == 0) {
|
||||
devtprintk((KERN_INFO MYNAM
|
||||
": Registered for IOC event notifications\n"));
|
||||
}
|
||||
|
||||
if (mpt_reset_register(mptfcDoneCtx, mptscsih_ioc_reset) == 0) {
|
||||
dprintk((KERN_INFO MYNAM
|
||||
": Registered for IOC reset notifications\n"));
|
||||
}
|
||||
|
||||
return pci_register_driver(&mptfc_driver);
|
||||
}
|
||||
|
||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
||||
/**
|
||||
* mptfc_exit - Unregisters MPT adapter(s)
|
||||
*
|
||||
*/
|
||||
static void __exit
|
||||
mptfc_exit(void)
|
||||
{
|
||||
pci_unregister_driver(&mptfc_driver);
|
||||
|
||||
mpt_reset_deregister(mptfcDoneCtx);
|
||||
dprintk((KERN_INFO MYNAM
|
||||
": Deregistered for IOC reset notifications\n"));
|
||||
|
||||
mpt_event_deregister(mptfcDoneCtx);
|
||||
dprintk((KERN_INFO MYNAM
|
||||
": Deregistered for IOC event notifications\n"));
|
||||
|
||||
mpt_deregister(mptfcInternalCtx);
|
||||
mpt_deregister(mptfcTaskCtx);
|
||||
mpt_deregister(mptfcDoneCtx);
|
||||
}
|
||||
|
||||
module_init(mptfc_init);
|
||||
module_exit(mptfc_exit);
|
@ -1,33 +1,11 @@
|
||||
/*
|
||||
* linux/drivers/message/fusion/mptlan.c
|
||||
* IP Over Fibre Channel device driver.
|
||||
* For use with PCI chip/adapter(s):
|
||||
* LSIFC9xx/LSI409xx Fibre Channel
|
||||
* For use with LSI Logic Fibre Channel PCI chip/adapters
|
||||
* running LSI Logic Fusion MPT (Message Passing Technology) firmware.
|
||||
*
|
||||
* Credits:
|
||||
* This driver would not exist if not for Alan Cox's development
|
||||
* of the linux i2o driver.
|
||||
* Copyright (c) 2000-2005 LSI Logic Corporation
|
||||
*
|
||||
* Special thanks goes to the I2O LAN driver people at the
|
||||
* University of Helsinki, who, unbeknownst to them, provided
|
||||
* the inspiration and initial structure for this 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!
|
||||
*
|
||||
* A really huge debt of gratitude is owed to Eddie C. Dost
|
||||
* for gobs of hard work fixing and optimizing LAN code.
|
||||
* THANK YOU!
|
||||
*
|
||||
* (see also mptbase.c)
|
||||
*
|
||||
* Copyright (c) 2000-2004 LSI Logic Corporation
|
||||
* Originally By: Noah Romer
|
||||
* (mailto:mpt_linux_developer@lsil.com)
|
||||
*
|
||||
* $Id: mptlan.c,v 1.53 2002/10/17 20:15:58 pdelaney Exp $
|
||||
*/
|
||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
||||
/*
|
||||
@ -221,7 +199,7 @@ lan_reply (MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
|
||||
|
||||
// NOTE! (Optimization) First case here is now caught in
|
||||
// mptbase.c::mpt_interrupt() routine and callcack here
|
||||
// is now skipped for this case! 20001218 -sralston
|
||||
// is now skipped for this case!
|
||||
#if 0
|
||||
case LAN_REPLY_FORM_MESSAGE_CONTEXT:
|
||||
// dioprintk((KERN_INFO MYNAM "/lan_reply: "
|
||||
@ -234,7 +212,7 @@ lan_reply (MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
|
||||
// dioprintk((MYNAM "/lan_reply: "
|
||||
// "calling mpt_lan_send_reply (turbo)\n"));
|
||||
|
||||
// Potential BUG here? -sralston
|
||||
// Potential BUG here?
|
||||
// FreeReqFrame = mpt_lan_send_turbo(dev, tmsg);
|
||||
// If/when mpt_lan_send_turbo would return 1 here,
|
||||
// calling routine (mptbase.c|mpt_interrupt)
|
||||
@ -310,8 +288,7 @@ lan_reply (MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
|
||||
|
||||
case MPI_FUNCTION_EVENT_NOTIFICATION:
|
||||
case MPI_FUNCTION_EVENT_ACK:
|
||||
/* UPDATE! 20010120 -sralston
|
||||
* _EVENT_NOTIFICATION should NOT come down this path any more.
|
||||
/* _EVENT_NOTIFICATION should NOT come down this path any more.
|
||||
* Should be routed to mpt_lan_event_process(), but just in case...
|
||||
*/
|
||||
FreeReqFrame = 1;
|
||||
@ -561,8 +538,8 @@ mpt_lan_close(struct net_device *dev)
|
||||
}
|
||||
}
|
||||
|
||||
kfree (priv->RcvCtl);
|
||||
kfree (priv->mpt_rxfidx);
|
||||
kfree(priv->RcvCtl);
|
||||
kfree(priv->mpt_rxfidx);
|
||||
|
||||
for (i = 0; i < priv->tx_max_out; i++) {
|
||||
if (priv->SendCtl[i].skb != NULL) {
|
||||
|
@ -1,3 +1,49 @@
|
||||
/*
|
||||
* linux/drivers/message/fusion/mptlan.h
|
||||
* IP Over Fibre Channel device driver.
|
||||
* For use with LSI Logic Fibre Channel PCI chip/adapters
|
||||
* running LSI Logic Fusion MPT (Message Passing Technology) firmware.
|
||||
*
|
||||
* Copyright (c) 2000-2005 LSI Logic Corporation
|
||||
*
|
||||
*/
|
||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
||||
/*
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
NO WARRANTY
|
||||
THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
|
||||
LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
|
||||
solely responsible for determining the appropriateness of using and
|
||||
distributing the Program and assumes all risks associated with its
|
||||
exercise of rights under this Agreement, including but not limited to
|
||||
the risks and costs of program errors, damage to or loss of data,
|
||||
programs or equipment, and unavailability or interruption of operations.
|
||||
|
||||
DISCLAIMER OF LIABILITY
|
||||
NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
|
||||
HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
||||
|
||||
/* mptlan.h */
|
||||
|
||||
#ifndef LINUX_MPTLAN_H_INCLUDED
|
||||
@ -29,7 +75,7 @@
|
||||
#include <asm/io.h>
|
||||
|
||||
/* Override mptbase.h by pre-defining these! */
|
||||
#define MODULEAUTHOR "Noah Romer, Eddie C. Dost"
|
||||
#define MODULEAUTHOR "LSI Logic Corporation"
|
||||
|
||||
#include "mptbase.h"
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,26 +1,13 @@
|
||||
/*
|
||||
* linux/drivers/message/fusion/mptscsih.h
|
||||
* linux/drivers/message/fusion/mptscsi.h
|
||||
* High performance SCSI / Fibre Channel SCSI Host device driver.
|
||||
* For use with PCI chip/adapter(s):
|
||||
* LSIFC9xx/LSI409xx Fibre Channel
|
||||
* running LSI Logic Fusion MPT (Message Passing Technology) firmware.
|
||||
*
|
||||
* Credits:
|
||||
* 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:netscape.net)
|
||||
* Copyright (c) 1999-2005 LSI Logic Corporation
|
||||
* (mailto:mpt_linux_developer@lsil.com)
|
||||
*
|
||||
* $Id: mptscsih.h,v 1.21 2002/12/03 21:26:35 pdelaney Exp $
|
||||
*/
|
||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
||||
/*
|
||||
@ -91,4 +78,30 @@
|
||||
#define MPTSCSIH_MIN_SYNC 0x08
|
||||
#define MPTSCSIH_SAF_TE 0
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
extern void mptscsih_remove(struct pci_dev *);
|
||||
extern void mptscsih_shutdown(struct device *);
|
||||
#ifdef CONFIG_PM
|
||||
extern int mptscsih_suspend(struct pci_dev *pdev, u32 state);
|
||||
extern int mptscsih_resume(struct pci_dev *pdev);
|
||||
#endif
|
||||
extern int mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, int length, int func);
|
||||
extern const char * mptscsih_info(struct Scsi_Host *SChost);
|
||||
extern int mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *));
|
||||
extern int mptscsih_slave_alloc(struct scsi_device *device);
|
||||
extern void mptscsih_slave_destroy(struct scsi_device *device);
|
||||
extern int mptscsih_slave_configure(struct scsi_device *device);
|
||||
extern int mptscsih_abort(struct scsi_cmnd * SCpnt);
|
||||
extern int mptscsih_dev_reset(struct scsi_cmnd * SCpnt);
|
||||
extern int mptscsih_bus_reset(struct scsi_cmnd * SCpnt);
|
||||
extern int mptscsih_host_reset(struct scsi_cmnd *SCpnt);
|
||||
extern int mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev, sector_t capacity, int geom[]);
|
||||
extern int mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
|
||||
extern int mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
|
||||
extern int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
|
||||
extern int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
|
||||
extern int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
|
||||
extern ssize_t mptscsih_store_queue_depth(struct device *dev, const char *buf, size_t count);
|
||||
extern void mptscsih_timer_expired(unsigned long data);
|
||||
|
486
drivers/message/fusion/mptspi.c
Normal file
486
drivers/message/fusion/mptspi.c
Normal file
@ -0,0 +1,486 @@
|
||||
/*
|
||||
* linux/drivers/message/fusion/mptspi.c
|
||||
* For use with LSI Logic PCI chip/adapter(s)
|
||||
* running LSI Logic Fusion MPT (Message Passing Technology) firmware.
|
||||
*
|
||||
* Copyright (c) 1999-2005 LSI Logic Corporation
|
||||
* (mailto:mpt_linux_developer@lsil.com)
|
||||
*
|
||||
*/
|
||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
||||
/*
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
NO WARRANTY
|
||||
THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
|
||||
LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
|
||||
solely responsible for determining the appropriateness of using and
|
||||
distributing the Program and assumes all risks associated with its
|
||||
exercise of rights under this Agreement, including but not limited to
|
||||
the risks and costs of program errors, damage to or loss of data,
|
||||
programs or equipment, and unavailability or interruption of operations.
|
||||
|
||||
DISCLAIMER OF LIABILITY
|
||||
NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
|
||||
HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
||||
|
||||
#include "linux_compat.h" /* linux-2.6 tweaks */
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/kdev_t.h>
|
||||
#include <linux/blkdev.h>
|
||||
#include <linux/delay.h> /* for mdelay */
|
||||
#include <linux/interrupt.h> /* needed for in_interrupt() proto */
|
||||
#include <linux/reboot.h> /* notifier code */
|
||||
#include <linux/sched.h>
|
||||
#include <linux/workqueue.h>
|
||||
|
||||
#include <scsi/scsi.h>
|
||||
#include <scsi/scsi_cmnd.h>
|
||||
#include <scsi/scsi_device.h>
|
||||
#include <scsi/scsi_host.h>
|
||||
#include <scsi/scsi_tcq.h>
|
||||
|
||||
#include "mptbase.h"
|
||||
#include "mptscsih.h"
|
||||
|
||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
||||
#define my_NAME "Fusion MPT SPI Host driver"
|
||||
#define my_VERSION MPT_LINUX_VERSION_COMMON
|
||||
#define MYNAM "mptspi"
|
||||
|
||||
MODULE_AUTHOR(MODULEAUTHOR);
|
||||
MODULE_DESCRIPTION(my_NAME);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
/* Command line args */
|
||||
#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
|
||||
static int mpt_dv = MPTSCSIH_DOMAIN_VALIDATION;
|
||||
module_param(mpt_dv, int, 0);
|
||||
MODULE_PARM_DESC(mpt_dv, " DV Algorithm: enhanced=1, basic=0 (default=MPTSCSIH_DOMAIN_VALIDATION=1)");
|
||||
|
||||
static int mpt_width = MPTSCSIH_MAX_WIDTH;
|
||||
module_param(mpt_width, int, 0);
|
||||
MODULE_PARM_DESC(mpt_width, " Max Bus Width: wide=1, narrow=0 (default=MPTSCSIH_MAX_WIDTH=1)");
|
||||
|
||||
static ushort mpt_factor = MPTSCSIH_MIN_SYNC;
|
||||
module_param(mpt_factor, ushort, 0);
|
||||
MODULE_PARM_DESC(mpt_factor, " Min Sync Factor (default=MPTSCSIH_MIN_SYNC=0x08)");
|
||||
#endif
|
||||
|
||||
static int mpt_saf_te = MPTSCSIH_SAF_TE;
|
||||
module_param(mpt_saf_te, int, 0);
|
||||
MODULE_PARM_DESC(mpt_saf_te, " Force enabling SEP Processor: enable=1 (default=MPTSCSIH_SAF_TE=0)");
|
||||
|
||||
static int mpt_pq_filter = 0;
|
||||
module_param(mpt_pq_filter, int, 0);
|
||||
MODULE_PARM_DESC(mpt_pq_filter, " Enable peripheral qualifier filter: enable=1 (default=0)");
|
||||
|
||||
static int mptspiDoneCtx = -1;
|
||||
static int mptspiTaskCtx = -1;
|
||||
static int mptspiInternalCtx = -1; /* Used only for internal commands */
|
||||
|
||||
static struct device_attribute mptspi_queue_depth_attr = {
|
||||
.attr = {
|
||||
.name = "queue_depth",
|
||||
.mode = S_IWUSR,
|
||||
},
|
||||
.store = mptscsih_store_queue_depth,
|
||||
};
|
||||
|
||||
static struct device_attribute *mptspi_dev_attrs[] = {
|
||||
&mptspi_queue_depth_attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static struct scsi_host_template mptspi_driver_template = {
|
||||
.proc_name = "mptspi",
|
||||
.proc_info = mptscsih_proc_info,
|
||||
.name = "MPT SPI Host",
|
||||
.info = mptscsih_info,
|
||||
.queuecommand = mptscsih_qcmd,
|
||||
.slave_alloc = mptscsih_slave_alloc,
|
||||
.slave_configure = mptscsih_slave_configure,
|
||||
.slave_destroy = mptscsih_slave_destroy,
|
||||
.eh_abort_handler = mptscsih_abort,
|
||||
.eh_device_reset_handler = mptscsih_dev_reset,
|
||||
.eh_bus_reset_handler = mptscsih_bus_reset,
|
||||
.eh_host_reset_handler = mptscsih_host_reset,
|
||||
.bios_param = mptscsih_bios_param,
|
||||
.can_queue = MPT_SCSI_CAN_QUEUE,
|
||||
.this_id = -1,
|
||||
.sg_tablesize = MPT_SCSI_SG_DEPTH,
|
||||
.max_sectors = 8192,
|
||||
.cmd_per_lun = 7,
|
||||
.use_clustering = ENABLE_CLUSTERING,
|
||||
.sdev_attrs = mptspi_dev_attrs,
|
||||
};
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Supported hardware
|
||||
*/
|
||||
|
||||
static struct pci_device_id mptspi_pci_table[] = {
|
||||
{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_53C1030,
|
||||
PCI_ANY_ID, PCI_ANY_ID },
|
||||
{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_1030_53C1035,
|
||||
PCI_ANY_ID, PCI_ANY_ID },
|
||||
{0} /* Terminating entry */
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, mptspi_pci_table);
|
||||
|
||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
||||
/*
|
||||
* mptspi_probe - Installs scsi devices per bus.
|
||||
* @pdev: Pointer to pci_dev structure
|
||||
*
|
||||
* Returns 0 for success, non-zero for failure.
|
||||
*
|
||||
*/
|
||||
static int
|
||||
mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
{
|
||||
struct Scsi_Host *sh;
|
||||
MPT_SCSI_HOST *hd;
|
||||
MPT_ADAPTER *ioc;
|
||||
unsigned long flags;
|
||||
int sz, ii;
|
||||
int numSGE = 0;
|
||||
int scale;
|
||||
int ioc_cap;
|
||||
u8 *mem;
|
||||
int error=0;
|
||||
int r;
|
||||
|
||||
if ((r = mpt_attach(pdev,id)) != 0)
|
||||
return r;
|
||||
|
||||
ioc = pci_get_drvdata(pdev);
|
||||
ioc->DoneCtx = mptspiDoneCtx;
|
||||
ioc->TaskCtx = mptspiTaskCtx;
|
||||
ioc->InternalCtx = mptspiInternalCtx;
|
||||
|
||||
/* Added sanity check on readiness of the MPT adapter.
|
||||
*/
|
||||
if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
|
||||
printk(MYIOC_s_WARN_FMT
|
||||
"Skipping because it's not operational!\n",
|
||||
ioc->name);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (!ioc->active) {
|
||||
printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
|
||||
ioc->name);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* Sanity check - ensure at least 1 port is INITIATOR capable
|
||||
*/
|
||||
ioc_cap = 0;
|
||||
for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
|
||||
if (ioc->pfacts[ii].ProtocolFlags &
|
||||
MPI_PORTFACTS_PROTOCOL_INITIATOR)
|
||||
ioc_cap ++;
|
||||
}
|
||||
|
||||
if (!ioc_cap) {
|
||||
printk(MYIOC_s_WARN_FMT
|
||||
"Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n",
|
||||
ioc->name, ioc);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
sh = scsi_host_alloc(&mptspi_driver_template, sizeof(MPT_SCSI_HOST));
|
||||
|
||||
if (!sh) {
|
||||
printk(MYIOC_s_WARN_FMT
|
||||
"Unable to register controller with SCSI subsystem\n",
|
||||
ioc->name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&ioc->FreeQlock, flags);
|
||||
|
||||
/* Attach the SCSI Host to the IOC structure
|
||||
*/
|
||||
ioc->sh = sh;
|
||||
|
||||
sh->io_port = 0;
|
||||
sh->n_io_port = 0;
|
||||
sh->irq = 0;
|
||||
|
||||
/* set 16 byte cdb's */
|
||||
sh->max_cmd_len = 16;
|
||||
|
||||
/* Yikes! This is important!
|
||||
* Otherwise, by default, linux
|
||||
* only scans target IDs 0-7!
|
||||
* pfactsN->MaxDevices unreliable
|
||||
* (not supported in early
|
||||
* versions of the FW).
|
||||
* max_id = 1 + actual max id,
|
||||
* max_lun = 1 + actual last lun,
|
||||
* see hosts.h :o(
|
||||
*/
|
||||
sh->max_id = MPT_MAX_SCSI_DEVICES;
|
||||
|
||||
sh->max_lun = MPT_LAST_LUN + 1;
|
||||
sh->max_channel = 0;
|
||||
sh->this_id = ioc->pfacts[0].PortSCSIID;
|
||||
|
||||
/* Required entry.
|
||||
*/
|
||||
sh->unique_id = ioc->id;
|
||||
|
||||
/* Verify that we won't exceed the maximum
|
||||
* number of chain buffers
|
||||
* We can optimize: ZZ = req_sz/sizeof(SGE)
|
||||
* For 32bit SGE's:
|
||||
* numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
|
||||
* + (req_sz - 64)/sizeof(SGE)
|
||||
* A slightly different algorithm is required for
|
||||
* 64bit SGEs.
|
||||
*/
|
||||
scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
|
||||
if (sizeof(dma_addr_t) == sizeof(u64)) {
|
||||
numSGE = (scale - 1) *
|
||||
(ioc->facts.MaxChainDepth-1) + scale +
|
||||
(ioc->req_sz - 60) / (sizeof(dma_addr_t) +
|
||||
sizeof(u32));
|
||||
} else {
|
||||
numSGE = 1 + (scale - 1) *
|
||||
(ioc->facts.MaxChainDepth-1) + scale +
|
||||
(ioc->req_sz - 64) / (sizeof(dma_addr_t) +
|
||||
sizeof(u32));
|
||||
}
|
||||
|
||||
if (numSGE < sh->sg_tablesize) {
|
||||
/* Reset this value */
|
||||
dprintk((MYIOC_s_INFO_FMT
|
||||
"Resetting sg_tablesize to %d from %d\n",
|
||||
ioc->name, numSGE, sh->sg_tablesize));
|
||||
sh->sg_tablesize = numSGE;
|
||||
}
|
||||
|
||||
/* Set the pci device pointer in Scsi_Host structure.
|
||||
*/
|
||||
scsi_set_device(sh, &ioc->pcidev->dev);
|
||||
|
||||
spin_unlock_irqrestore(&ioc->FreeQlock, flags);
|
||||
|
||||
hd = (MPT_SCSI_HOST *) sh->hostdata;
|
||||
hd->ioc = ioc;
|
||||
|
||||
/* SCSI needs scsi_cmnd lookup table!
|
||||
* (with size equal to req_depth*PtrSz!)
|
||||
*/
|
||||
sz = ioc->req_depth * sizeof(void *);
|
||||
mem = kmalloc(sz, GFP_ATOMIC);
|
||||
if (mem == NULL) {
|
||||
error = -ENOMEM;
|
||||
goto mptspi_probe_failed;
|
||||
}
|
||||
|
||||
memset(mem, 0, sz);
|
||||
hd->ScsiLookup = (struct scsi_cmnd **) mem;
|
||||
|
||||
dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p, sz=%d\n",
|
||||
ioc->name, hd->ScsiLookup, sz));
|
||||
|
||||
/* Allocate memory for the device structures.
|
||||
* A non-Null pointer at an offset
|
||||
* indicates a device exists.
|
||||
* max_id = 1 + maximum id (hosts.h)
|
||||
*/
|
||||
sz = sh->max_id * sizeof(void *);
|
||||
mem = kmalloc(sz, GFP_ATOMIC);
|
||||
if (mem == NULL) {
|
||||
error = -ENOMEM;
|
||||
goto mptspi_probe_failed;
|
||||
}
|
||||
|
||||
memset(mem, 0, sz);
|
||||
hd->Targets = (VirtDevice **) mem;
|
||||
|
||||
dprintk((KERN_INFO
|
||||
" Targets @ %p, sz=%d\n", hd->Targets, sz));
|
||||
|
||||
/* Clear the TM flags
|
||||
*/
|
||||
hd->tmPending = 0;
|
||||
hd->tmState = TM_STATE_NONE;
|
||||
hd->resetPending = 0;
|
||||
hd->abortSCpnt = NULL;
|
||||
|
||||
/* Clear the pointer used to store
|
||||
* single-threaded commands, i.e., those
|
||||
* issued during a bus scan, dv and
|
||||
* configuration pages.
|
||||
*/
|
||||
hd->cmdPtr = NULL;
|
||||
|
||||
/* Initialize this SCSI Hosts' timers
|
||||
* To use, set the timer expires field
|
||||
* and add_timer
|
||||
*/
|
||||
init_timer(&hd->timer);
|
||||
hd->timer.data = (unsigned long) hd;
|
||||
hd->timer.function = mptscsih_timer_expired;
|
||||
|
||||
ioc->spi_data.Saf_Te = mpt_saf_te;
|
||||
hd->mpt_pq_filter = mpt_pq_filter;
|
||||
|
||||
#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
|
||||
if (ioc->spi_data.maxBusWidth > mpt_width)
|
||||
ioc->spi_data.maxBusWidth = mpt_width;
|
||||
if (ioc->spi_data.minSyncFactor < mpt_factor)
|
||||
ioc->spi_data.minSyncFactor = mpt_factor;
|
||||
if (ioc->spi_data.minSyncFactor == MPT_ASYNC) {
|
||||
ioc->spi_data.maxSyncOffset = 0;
|
||||
}
|
||||
ioc->spi_data.mpt_dv = mpt_dv;
|
||||
hd->negoNvram = 0;
|
||||
|
||||
ddvprintk((MYIOC_s_INFO_FMT
|
||||
"dv %x width %x factor %x saf_te %x mpt_pq_filter %x\n",
|
||||
ioc->name,
|
||||
mpt_dv,
|
||||
mpt_width,
|
||||
mpt_factor,
|
||||
mpt_saf_te,
|
||||
mpt_pq_filter));
|
||||
#else
|
||||
hd->negoNvram = MPT_SCSICFG_USE_NVRAM;
|
||||
ddvprintk((MYIOC_s_INFO_FMT
|
||||
"saf_te %x mpt_pq_filter %x\n",
|
||||
ioc->name,
|
||||
mpt_saf_te,
|
||||
mpt_pq_filter));
|
||||
#endif
|
||||
|
||||
ioc->spi_data.forceDv = 0;
|
||||
ioc->spi_data.noQas = 0;
|
||||
|
||||
for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++)
|
||||
ioc->spi_data.dvStatus[ii] =
|
||||
MPT_SCSICFG_NEGOTIATE;
|
||||
|
||||
for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++)
|
||||
ioc->spi_data.dvStatus[ii] |=
|
||||
MPT_SCSICFG_DV_NOT_DONE;
|
||||
|
||||
init_waitqueue_head(&hd->scandv_waitq);
|
||||
hd->scandv_wait_done = 0;
|
||||
hd->last_queue_full = 0;
|
||||
|
||||
error = scsi_add_host (sh, &ioc->pcidev->dev);
|
||||
if(error) {
|
||||
dprintk((KERN_ERR MYNAM
|
||||
"scsi_add_host failed\n"));
|
||||
goto mptspi_probe_failed;
|
||||
}
|
||||
|
||||
scsi_scan_host(sh);
|
||||
return 0;
|
||||
|
||||
mptspi_probe_failed:
|
||||
|
||||
mptscsih_remove(pdev);
|
||||
return error;
|
||||
}
|
||||
|
||||
static struct pci_driver mptspi_driver = {
|
||||
.name = "mptspi",
|
||||
.id_table = mptspi_pci_table,
|
||||
.probe = mptspi_probe,
|
||||
.remove = __devexit_p(mptscsih_remove),
|
||||
.driver = {
|
||||
.shutdown = mptscsih_shutdown,
|
||||
},
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = mptscsih_suspend,
|
||||
.resume = mptscsih_resume,
|
||||
#endif
|
||||
};
|
||||
|
||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
||||
/**
|
||||
* mptspi_init - Register MPT adapter(s) as SCSI host(s) with
|
||||
* linux scsi mid-layer.
|
||||
*
|
||||
* Returns 0 for success, non-zero for failure.
|
||||
*/
|
||||
static int __init
|
||||
mptspi_init(void)
|
||||
{
|
||||
|
||||
show_mptmod_ver(my_NAME, my_VERSION);
|
||||
|
||||
mptspiDoneCtx = mpt_register(mptscsih_io_done, MPTSPI_DRIVER);
|
||||
mptspiTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSPI_DRIVER);
|
||||
mptspiInternalCtx = mpt_register(mptscsih_scandv_complete, MPTSPI_DRIVER);
|
||||
|
||||
if (mpt_event_register(mptspiDoneCtx, mptscsih_event_process) == 0) {
|
||||
devtprintk((KERN_INFO MYNAM
|
||||
": Registered for IOC event notifications\n"));
|
||||
}
|
||||
|
||||
if (mpt_reset_register(mptspiDoneCtx, mptscsih_ioc_reset) == 0) {
|
||||
dprintk((KERN_INFO MYNAM
|
||||
": Registered for IOC reset notifications\n"));
|
||||
}
|
||||
|
||||
return pci_register_driver(&mptspi_driver);
|
||||
}
|
||||
|
||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
||||
/**
|
||||
* mptspi_exit - Unregisters MPT adapter(s)
|
||||
*
|
||||
*/
|
||||
static void __exit
|
||||
mptspi_exit(void)
|
||||
{
|
||||
pci_unregister_driver(&mptspi_driver);
|
||||
|
||||
mpt_reset_deregister(mptspiDoneCtx);
|
||||
dprintk((KERN_INFO MYNAM
|
||||
": Deregistered for IOC reset notifications\n"));
|
||||
|
||||
mpt_event_deregister(mptspiDoneCtx);
|
||||
dprintk((KERN_INFO MYNAM
|
||||
": Deregistered for IOC event notifications\n"));
|
||||
|
||||
mpt_deregister(mptspiInternalCtx);
|
||||
mpt_deregister(mptspiTaskCtx);
|
||||
mpt_deregister(mptspiDoneCtx);
|
||||
}
|
||||
|
||||
module_init(mptspi_init);
|
||||
module_exit(mptspi_exit);
|
File diff suppressed because it is too large
Load Diff
@ -137,6 +137,24 @@ config CHR_DEV_SG
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config CHR_DEV_SCH
|
||||
tristate "SCSI media changer support"
|
||||
depends on SCSI
|
||||
---help---
|
||||
This is a driver for SCSI media changers. Most common devices are
|
||||
tape libraries and MOD/CDROM jukeboxes. *Real* jukeboxes, you
|
||||
don't need this for those tiny 6-slot cdrom changers. Media
|
||||
changers are listed as "Type: Medium Changer" in /proc/scsi/scsi.
|
||||
If you have such hardware and want to use it with linux, say Y
|
||||
here. Check <file:Documentation/scsi-changer.txt> for details.
|
||||
|
||||
If you want to compile this as a module ( = code which can be
|
||||
inserted in and removed from the running kernel whenever you want),
|
||||
say M here and read <file:Documentation/modules.txt> and
|
||||
<file:Documentation/scsi.txt>. The module will be called ch.o.
|
||||
If unsure, say N.
|
||||
|
||||
|
||||
comment "Some SCSI devices (e.g. CD jukebox) support multiple LUNs"
|
||||
depends on SCSI
|
||||
|
||||
@ -1192,28 +1210,6 @@ config SCSI_PAS16
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called pas16.
|
||||
|
||||
config SCSI_PCI2000
|
||||
tristate "PCI2000 support"
|
||||
depends on PCI && SCSI && BROKEN
|
||||
help
|
||||
This is support for the PCI2000I EIDE interface card which acts as a
|
||||
SCSI host adapter. Please read the SCSI-HOWTO, available from
|
||||
<http://www.tldp.org/docs.html#howto>.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called pci2000.
|
||||
|
||||
config SCSI_PCI2220I
|
||||
tristate "PCI2220i support"
|
||||
depends on PCI && SCSI && BROKEN
|
||||
help
|
||||
This is support for the PCI2220i EIDE interface card which acts as a
|
||||
SCSI host adapter. Please read the SCSI-HOWTO, available from
|
||||
<http://www.tldp.org/docs.html#howto>.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called pci2220i.
|
||||
|
||||
config SCSI_PSI240I
|
||||
tristate "PSI240i support"
|
||||
depends on ISA && SCSI
|
||||
|
@ -50,8 +50,6 @@ obj-$(CONFIG_MVME16x_SCSI) += mvme16x.o 53c7xx.o
|
||||
obj-$(CONFIG_BVME6000_SCSI) += bvme6000.o 53c7xx.o
|
||||
obj-$(CONFIG_SCSI_SIM710) += 53c700.o sim710.o
|
||||
obj-$(CONFIG_SCSI_ADVANSYS) += advansys.o
|
||||
obj-$(CONFIG_SCSI_PCI2000) += pci2000.o
|
||||
obj-$(CONFIG_SCSI_PCI2220I) += pci2220i.o
|
||||
obj-$(CONFIG_SCSI_PSI240I) += psi240i.o
|
||||
obj-$(CONFIG_SCSI_BUSLOGIC) += BusLogic.o
|
||||
obj-$(CONFIG_SCSI_DPT_I2O) += dpt_i2o.o
|
||||
@ -142,6 +140,7 @@ obj-$(CONFIG_CHR_DEV_OSST) += osst.o
|
||||
obj-$(CONFIG_BLK_DEV_SD) += sd_mod.o
|
||||
obj-$(CONFIG_BLK_DEV_SR) += sr_mod.o
|
||||
obj-$(CONFIG_CHR_DEV_SG) += sg.o
|
||||
obj-$(CONFIG_CHR_DEV_SCH) += ch.o
|
||||
|
||||
scsi_mod-y += scsi.o hosts.o scsi_ioctl.o constants.o \
|
||||
scsicam.o scsi_error.o scsi_lib.o \
|
||||
|
@ -94,7 +94,7 @@ enum {
|
||||
};
|
||||
|
||||
/* The master ring of all esp hosts we are managing in this driver. */
|
||||
struct NCR_ESP *espchain;
|
||||
static struct NCR_ESP *espchain;
|
||||
int nesps = 0, esps_in_use = 0, esps_running = 0;
|
||||
|
||||
irqreturn_t esp_intr(int irq, void *dev_id, struct pt_regs *pregs);
|
||||
|
@ -53,10 +53,6 @@
|
||||
#define INQD_PDT_DMASK 0x1F /* Peripheral Device Type Mask */
|
||||
#define INQD_PDT_QMASK 0xE0 /* Peripheral Device Qualifer Mask */
|
||||
|
||||
#define MAX_FIB_DATA (sizeof(struct hw_fib) - sizeof(FIB_HEADER))
|
||||
|
||||
#define MAX_DRIVER_SG_SEGMENT_COUNT 17
|
||||
|
||||
/*
|
||||
* Sense codes
|
||||
*/
|
||||
@ -158,6 +154,13 @@ MODULE_PARM_DESC(dacmode, "Control whether dma addressing is using 64 bit DAC. 0
|
||||
module_param(commit, int, 0);
|
||||
MODULE_PARM_DESC(commit, "Control whether a COMMIT_CONFIG is issued to the adapter for foreign arrays.\nThis is typically needed in systems that do not have a BIOS. 0=off, 1=on");
|
||||
|
||||
int numacb = -1;
|
||||
module_param(numacb, int, S_IRUGO|S_IWUSR);
|
||||
MODULE_PARM_DESC(numacb, "Request a limit to the number of adapter control blocks (FIB) allocated. Valid\nvalues are 512 and down. Default is to use suggestion from Firmware.");
|
||||
|
||||
int acbsize = -1;
|
||||
module_param(acbsize, int, S_IRUGO|S_IWUSR);
|
||||
MODULE_PARM_DESC(acbsize, "Request a specific adapter control block (FIB) size. Valid values are 512,\n2048, 4096 and 8192. Default is to use suggestion from Firmware.");
|
||||
/**
|
||||
* aac_get_config_status - check the adapter configuration
|
||||
* @common: adapter to query
|
||||
@ -462,7 +465,7 @@ static int probe_container(struct aac_dev *dev, int cid)
|
||||
1, 1,
|
||||
NULL, NULL);
|
||||
if (status < 0) {
|
||||
printk(KERN_WARNING "aacraid: probe_containers query failed.\n");
|
||||
printk(KERN_WARNING "aacraid: probe_container query failed.\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
@ -562,10 +565,10 @@ static void setinqstr(int devtype, void *data, int tindex)
|
||||
inqstrcpy ("V1.0", str->prl);
|
||||
}
|
||||
|
||||
void set_sense(u8 *sense_buf, u8 sense_key, u8 sense_code,
|
||||
u8 a_sense_code, u8 incorrect_length,
|
||||
u8 bit_pointer, u16 field_pointer,
|
||||
u32 residue)
|
||||
static void set_sense(u8 *sense_buf, u8 sense_key, u8 sense_code,
|
||||
u8 a_sense_code, u8 incorrect_length,
|
||||
u8 bit_pointer, u16 field_pointer,
|
||||
u32 residue)
|
||||
{
|
||||
sense_buf[0] = 0xF0; /* Sense data valid, err code 70h (current error) */
|
||||
sense_buf[1] = 0; /* Segment number, always zero */
|
||||
@ -605,35 +608,63 @@ void set_sense(u8 *sense_buf, u8 sense_key, u8 sense_code,
|
||||
int aac_get_adapter_info(struct aac_dev* dev)
|
||||
{
|
||||
struct fib* fibptr;
|
||||
struct aac_adapter_info* info;
|
||||
int rcode;
|
||||
u32 tmp;
|
||||
struct aac_adapter_info * info;
|
||||
|
||||
if (!(fibptr = fib_alloc(dev)))
|
||||
return -ENOMEM;
|
||||
|
||||
fib_init(fibptr);
|
||||
info = (struct aac_adapter_info*) fib_data(fibptr);
|
||||
|
||||
memset(info,0,sizeof(struct aac_adapter_info));
|
||||
info = (struct aac_adapter_info *) fib_data(fibptr);
|
||||
memset(info,0,sizeof(*info));
|
||||
|
||||
rcode = fib_send(RequestAdapterInfo,
|
||||
fibptr,
|
||||
sizeof(struct aac_adapter_info),
|
||||
FsaNormal,
|
||||
1, 1,
|
||||
NULL,
|
||||
NULL);
|
||||
fibptr,
|
||||
sizeof(*info),
|
||||
FsaNormal,
|
||||
1, 1,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
memcpy(&dev->adapter_info, info, sizeof(struct aac_adapter_info));
|
||||
if (rcode < 0) {
|
||||
fib_complete(fibptr);
|
||||
fib_free(fibptr);
|
||||
return rcode;
|
||||
}
|
||||
memcpy(&dev->adapter_info, info, sizeof(*info));
|
||||
|
||||
if (dev->adapter_info.options & AAC_OPT_SUPPLEMENT_ADAPTER_INFO) {
|
||||
struct aac_supplement_adapter_info * info;
|
||||
|
||||
fib_init(fibptr);
|
||||
|
||||
info = (struct aac_supplement_adapter_info *) fib_data(fibptr);
|
||||
|
||||
memset(info,0,sizeof(*info));
|
||||
|
||||
rcode = fib_send(RequestSupplementAdapterInfo,
|
||||
fibptr,
|
||||
sizeof(*info),
|
||||
FsaNormal,
|
||||
1, 1,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
if (rcode >= 0)
|
||||
memcpy(&dev->supplement_adapter_info, info, sizeof(*info));
|
||||
}
|
||||
|
||||
tmp = le32_to_cpu(dev->adapter_info.kernelrev);
|
||||
printk(KERN_INFO "%s%d: kernel %d.%d-%d[%d]\n",
|
||||
printk(KERN_INFO "%s%d: kernel %d.%d-%d[%d] %.*s\n",
|
||||
dev->name,
|
||||
dev->id,
|
||||
tmp>>24,
|
||||
(tmp>>16)&0xff,
|
||||
tmp&0xff,
|
||||
le32_to_cpu(dev->adapter_info.kernelbuild));
|
||||
le32_to_cpu(dev->adapter_info.kernelbuild),
|
||||
(int)sizeof(dev->supplement_adapter_info.BuildDate),
|
||||
dev->supplement_adapter_info.BuildDate);
|
||||
tmp = le32_to_cpu(dev->adapter_info.monitorrev);
|
||||
printk(KERN_INFO "%s%d: monitor %d.%d-%d[%d]\n",
|
||||
dev->name, dev->id,
|
||||
@ -707,6 +738,38 @@ int aac_get_adapter_info(struct aac_dev* dev)
|
||||
rcode = -ENOMEM;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 57 scatter gather elements
|
||||
*/
|
||||
dev->scsi_host_ptr->sg_tablesize = (dev->max_fib_size -
|
||||
sizeof(struct aac_fibhdr) -
|
||||
sizeof(struct aac_write) + sizeof(struct sgmap)) /
|
||||
sizeof(struct sgmap);
|
||||
if (dev->dac_support) {
|
||||
/*
|
||||
* 38 scatter gather elements
|
||||
*/
|
||||
dev->scsi_host_ptr->sg_tablesize =
|
||||
(dev->max_fib_size -
|
||||
sizeof(struct aac_fibhdr) -
|
||||
sizeof(struct aac_write64) +
|
||||
sizeof(struct sgmap64)) /
|
||||
sizeof(struct sgmap64);
|
||||
}
|
||||
dev->scsi_host_ptr->max_sectors = AAC_MAX_32BIT_SGBCOUNT;
|
||||
if(!(dev->adapter_info.options & AAC_OPT_NEW_COMM)) {
|
||||
/*
|
||||
* Worst case size that could cause sg overflow when
|
||||
* we break up SG elements that are larger than 64KB.
|
||||
* Would be nice if we could tell the SCSI layer what
|
||||
* the maximum SG element size can be. Worst case is
|
||||
* (sg_tablesize-1) 4KB elements with one 64KB
|
||||
* element.
|
||||
* 32bit -> 468 or 238KB 64bit -> 424 or 212KB
|
||||
*/
|
||||
dev->scsi_host_ptr->max_sectors =
|
||||
(dev->scsi_host_ptr->sg_tablesize * 8) + 112;
|
||||
}
|
||||
|
||||
fib_complete(fibptr);
|
||||
fib_free(fibptr);
|
||||
@ -747,8 +810,10 @@ static void read_callback(void *context, struct fib * fibptr)
|
||||
if (le32_to_cpu(readreply->status) == ST_OK)
|
||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
|
||||
else {
|
||||
printk(KERN_WARNING "read_callback: read failed, status = %d\n",
|
||||
le32_to_cpu(readreply->status));
|
||||
#ifdef AAC_DETAILED_STATUS_INFO
|
||||
printk(KERN_WARNING "read_callback: io failed, status = %d\n",
|
||||
le32_to_cpu(readreply->status));
|
||||
#endif
|
||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_CHECK_CONDITION;
|
||||
set_sense((u8 *) &dev->fsa_dev[cid].sense_data,
|
||||
HARDWARE_ERROR,
|
||||
@ -813,7 +878,7 @@ static void write_callback(void *context, struct fib * fibptr)
|
||||
aac_io_done(scsicmd);
|
||||
}
|
||||
|
||||
int aac_read(struct scsi_cmnd * scsicmd, int cid)
|
||||
static int aac_read(struct scsi_cmnd * scsicmd, int cid)
|
||||
{
|
||||
u32 lba;
|
||||
u32 count;
|
||||
@ -842,7 +907,8 @@ int aac_read(struct scsi_cmnd * scsicmd, int cid)
|
||||
lba = (scsicmd->cmnd[2] << 24) | (scsicmd->cmnd[3] << 16) | (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5];
|
||||
count = (scsicmd->cmnd[7] << 8) | scsicmd->cmnd[8];
|
||||
}
|
||||
dprintk((KERN_DEBUG "aac_read[cpu %d]: lba = %u, t = %ld.\n", smp_processor_id(), lba, jiffies));
|
||||
dprintk((KERN_DEBUG "aac_read[cpu %d]: lba = %u, t = %ld.\n",
|
||||
smp_processor_id(), (unsigned long long)lba, jiffies));
|
||||
/*
|
||||
* Alocate and initialize a Fib
|
||||
*/
|
||||
@ -852,7 +918,7 @@ int aac_read(struct scsi_cmnd * scsicmd, int cid)
|
||||
|
||||
fib_init(cmd_fibcontext);
|
||||
|
||||
if(dev->dac_support == 1) {
|
||||
if (dev->dac_support == 1) {
|
||||
struct aac_read64 *readcmd;
|
||||
readcmd = (struct aac_read64 *) fib_data(cmd_fibcontext);
|
||||
readcmd->command = cpu_to_le32(VM_CtHostRead64);
|
||||
@ -886,14 +952,11 @@ int aac_read(struct scsi_cmnd * scsicmd, int cid)
|
||||
readcmd->block = cpu_to_le32(lba);
|
||||
readcmd->count = cpu_to_le32(count * 512);
|
||||
|
||||
if (count * 512 > (64 * 1024))
|
||||
BUG();
|
||||
|
||||
aac_build_sg(scsicmd, &readcmd->sg);
|
||||
fibsize = sizeof(struct aac_read) +
|
||||
((le32_to_cpu(readcmd->sg.count) - 1) *
|
||||
sizeof (struct sgentry));
|
||||
BUG_ON (fibsize > (sizeof(struct hw_fib) -
|
||||
BUG_ON (fibsize > (dev->max_fib_size -
|
||||
sizeof(struct aac_fibhdr)));
|
||||
/*
|
||||
* Now send the Fib to the adapter
|
||||
@ -976,7 +1039,7 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid)
|
||||
fibsize = sizeof(struct aac_write64) +
|
||||
((le32_to_cpu(writecmd->sg.count) - 1) *
|
||||
sizeof (struct sgentry64));
|
||||
BUG_ON (fibsize > (sizeof(struct hw_fib) -
|
||||
BUG_ON (fibsize > (dev->max_fib_size -
|
||||
sizeof(struct aac_fibhdr)));
|
||||
/*
|
||||
* Now send the Fib to the adapter
|
||||
@ -998,15 +1061,11 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid)
|
||||
writecmd->sg.count = cpu_to_le32(1);
|
||||
/* ->stable is not used - it did mean which type of write */
|
||||
|
||||
if (count * 512 > (64 * 1024)) {
|
||||
BUG();
|
||||
}
|
||||
|
||||
aac_build_sg(scsicmd, &writecmd->sg);
|
||||
fibsize = sizeof(struct aac_write) +
|
||||
((le32_to_cpu(writecmd->sg.count) - 1) *
|
||||
sizeof (struct sgentry));
|
||||
BUG_ON (fibsize > (sizeof(struct hw_fib) -
|
||||
BUG_ON (fibsize > (dev->max_fib_size -
|
||||
sizeof(struct aac_fibhdr)));
|
||||
/*
|
||||
* Now send the Fib to the adapter
|
||||
@ -1025,7 +1084,6 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid)
|
||||
*/
|
||||
if (status == -EINPROGRESS)
|
||||
{
|
||||
dprintk("write queued.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1111,7 +1169,7 @@ static int aac_synchronize(struct scsi_cmnd *scsicmd, int cid)
|
||||
return SCSI_MLQUEUE_DEVICE_BUSY;
|
||||
|
||||
/*
|
||||
* Alocate and initialize a Fib
|
||||
* Allocate and initialize a Fib
|
||||
*/
|
||||
if (!(cmd_fibcontext =
|
||||
fib_alloc((struct aac_dev *)scsicmd->device->host->hostdata)))
|
||||
@ -1403,7 +1461,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
||||
/*
|
||||
* Unhandled commands
|
||||
*/
|
||||
printk(KERN_WARNING "Unhandled SCSI Command: 0x%x.\n", scsicmd->cmnd[0]);
|
||||
dprintk((KERN_WARNING "Unhandled SCSI Command: 0x%x.\n", scsicmd->cmnd[0]));
|
||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_CHECK_CONDITION;
|
||||
set_sense((u8 *) &dev->fsa_dev[cid].sense_data,
|
||||
ILLEGAL_REQUEST, SENCODE_INVALID_COMMAND,
|
||||
@ -1818,7 +1876,7 @@ static int aac_send_srb_fib(struct scsi_cmnd* scsicmd)
|
||||
fibsize = sizeof (struct aac_srb) - sizeof (struct sgentry) +
|
||||
((le32_to_cpu(srbcmd->sg.count) & 0xff) *
|
||||
sizeof (struct sgentry64));
|
||||
BUG_ON (fibsize > (sizeof(struct hw_fib) -
|
||||
BUG_ON (fibsize > (dev->max_fib_size -
|
||||
sizeof(struct aac_fibhdr)));
|
||||
|
||||
/*
|
||||
@ -1840,7 +1898,7 @@ static int aac_send_srb_fib(struct scsi_cmnd* scsicmd)
|
||||
fibsize = sizeof (struct aac_srb) +
|
||||
(((le32_to_cpu(srbcmd->sg.count) & 0xff) - 1) *
|
||||
sizeof (struct sgentry));
|
||||
BUG_ON (fibsize > (sizeof(struct hw_fib) -
|
||||
BUG_ON (fibsize > (dev->max_fib_size -
|
||||
sizeof(struct aac_fibhdr)));
|
||||
|
||||
/*
|
||||
@ -1893,7 +1951,9 @@ static unsigned long aac_build_sg(struct scsi_cmnd* scsicmd, struct sgmap* psg)
|
||||
}
|
||||
/* hba wants the size to be exact */
|
||||
if(byte_count > scsicmd->request_bufflen){
|
||||
psg->sg[i-1].count -= (byte_count - scsicmd->request_bufflen);
|
||||
u32 temp = le32_to_cpu(psg->sg[i-1].count) -
|
||||
(byte_count - scsicmd->request_bufflen);
|
||||
psg->sg[i-1].count = cpu_to_le32(temp);
|
||||
byte_count = scsicmd->request_bufflen;
|
||||
}
|
||||
/* Check for command underflow */
|
||||
@ -1922,7 +1982,7 @@ static unsigned long aac_build_sg64(struct scsi_cmnd* scsicmd, struct sgmap64* p
|
||||
{
|
||||
struct aac_dev *dev;
|
||||
unsigned long byte_count = 0;
|
||||
u64 le_addr;
|
||||
u64 addr;
|
||||
|
||||
dev = (struct aac_dev *)scsicmd->device->host->hostdata;
|
||||
// Get rid of old data
|
||||
@ -1943,16 +2003,18 @@ static unsigned long aac_build_sg64(struct scsi_cmnd* scsicmd, struct sgmap64* p
|
||||
byte_count = 0;
|
||||
|
||||
for (i = 0; i < sg_count; i++) {
|
||||
le_addr = cpu_to_le64(sg_dma_address(sg));
|
||||
psg->sg[i].addr[1] = (u32)(le_addr>>32);
|
||||
psg->sg[i].addr[0] = (u32)(le_addr & 0xffffffff);
|
||||
addr = sg_dma_address(sg);
|
||||
psg->sg[i].addr[0] = cpu_to_le32(addr & 0xffffffff);
|
||||
psg->sg[i].addr[1] = cpu_to_le32(addr>>32);
|
||||
psg->sg[i].count = cpu_to_le32(sg_dma_len(sg));
|
||||
byte_count += sg_dma_len(sg);
|
||||
sg++;
|
||||
}
|
||||
/* hba wants the size to be exact */
|
||||
if(byte_count > scsicmd->request_bufflen){
|
||||
psg->sg[i-1].count -= (byte_count - scsicmd->request_bufflen);
|
||||
u32 temp = le32_to_cpu(psg->sg[i-1].count) -
|
||||
(byte_count - scsicmd->request_bufflen);
|
||||
psg->sg[i-1].count = cpu_to_le32(temp);
|
||||
byte_count = scsicmd->request_bufflen;
|
||||
}
|
||||
/* Check for command underflow */
|
||||
@ -1962,15 +2024,14 @@ static unsigned long aac_build_sg64(struct scsi_cmnd* scsicmd, struct sgmap64* p
|
||||
}
|
||||
}
|
||||
else if(scsicmd->request_bufflen) {
|
||||
dma_addr_t addr;
|
||||
u64 addr;
|
||||
addr = pci_map_single(dev->pdev,
|
||||
scsicmd->request_buffer,
|
||||
scsicmd->request_bufflen,
|
||||
scsicmd->sc_data_direction);
|
||||
psg->count = cpu_to_le32(1);
|
||||
le_addr = cpu_to_le64(addr);
|
||||
psg->sg[0].addr[1] = (u32)(le_addr>>32);
|
||||
psg->sg[0].addr[0] = (u32)(le_addr & 0xffffffff);
|
||||
psg->sg[0].addr[0] = cpu_to_le32(addr & 0xffffffff);
|
||||
psg->sg[0].addr[1] = cpu_to_le32(addr >> 32);
|
||||
psg->sg[0].count = cpu_to_le32(scsicmd->request_bufflen);
|
||||
scsicmd->SCp.dma_handle = addr;
|
||||
byte_count = scsicmd->request_bufflen;
|
||||
|
@ -8,12 +8,18 @@
|
||||
|
||||
#define MAXIMUM_NUM_CONTAINERS 32
|
||||
|
||||
#define AAC_NUM_FIB (256 + 64)
|
||||
#define AAC_NUM_IO_FIB 100
|
||||
#define AAC_NUM_MGT_FIB 8
|
||||
#define AAC_NUM_IO_FIB (512 - AAC_NUM_MGT_FIB)
|
||||
#define AAC_NUM_FIB (AAC_NUM_IO_FIB + AAC_NUM_MGT_FIB)
|
||||
|
||||
#define AAC_MAX_LUN (8)
|
||||
|
||||
#define AAC_MAX_HOSTPHYSMEMPAGES (0xfffff)
|
||||
/*
|
||||
* max_sectors is an unsigned short, otherwise limit is 0x100000000 / 512
|
||||
* Linux has starvation problems if we permit larger than 4MB I/O ...
|
||||
*/
|
||||
#define AAC_MAX_32BIT_SGBCOUNT ((unsigned short)8192)
|
||||
|
||||
/*
|
||||
* These macros convert from physical channels to virtual channels
|
||||
@ -89,11 +95,21 @@ struct diskparm
|
||||
* on 64 bit systems not all cards support the 64 bit version
|
||||
*/
|
||||
struct sgentry {
|
||||
__le32 addr; /* 32-bit address. */
|
||||
__le32 count; /* Length. */
|
||||
};
|
||||
|
||||
struct user_sgentry {
|
||||
u32 addr; /* 32-bit address. */
|
||||
u32 count; /* Length. */
|
||||
};
|
||||
|
||||
struct sgentry64 {
|
||||
__le32 addr[2]; /* 64-bit addr. 2 pieces for data alignment */
|
||||
__le32 count; /* Length. */
|
||||
};
|
||||
|
||||
struct user_sgentry64 {
|
||||
u32 addr[2]; /* 64-bit addr. 2 pieces for data alignment */
|
||||
u32 count; /* Length. */
|
||||
};
|
||||
@ -106,15 +122,25 @@ struct sgentry64 {
|
||||
*/
|
||||
|
||||
struct sgmap {
|
||||
u32 count;
|
||||
__le32 count;
|
||||
struct sgentry sg[1];
|
||||
};
|
||||
|
||||
struct sgmap64 {
|
||||
struct user_sgmap {
|
||||
u32 count;
|
||||
struct user_sgentry sg[1];
|
||||
};
|
||||
|
||||
struct sgmap64 {
|
||||
__le32 count;
|
||||
struct sgentry64 sg[1];
|
||||
};
|
||||
|
||||
struct user_sgmap64 {
|
||||
u32 count;
|
||||
struct user_sgentry64 sg[1];
|
||||
};
|
||||
|
||||
struct creation_info
|
||||
{
|
||||
u8 buildnum; /* e.g., 588 */
|
||||
@ -123,14 +149,14 @@ struct creation_info
|
||||
* 2 = API
|
||||
*/
|
||||
u8 year; /* e.g., 1997 = 97 */
|
||||
u32 date; /*
|
||||
__le32 date; /*
|
||||
* unsigned Month :4; // 1 - 12
|
||||
* unsigned Day :6; // 1 - 32
|
||||
* unsigned Hour :6; // 0 - 23
|
||||
* unsigned Minute :6; // 0 - 60
|
||||
* unsigned Second :6; // 0 - 60
|
||||
*/
|
||||
u32 serial[2]; /* e.g., 0x1DEADB0BFAFAF001 */
|
||||
__le32 serial[2]; /* e.g., 0x1DEADB0BFAFAF001 */
|
||||
};
|
||||
|
||||
|
||||
@ -175,8 +201,8 @@ struct creation_info
|
||||
*/
|
||||
|
||||
struct aac_entry {
|
||||
u32 size; /* Size in bytes of Fib which this QE points to */
|
||||
u32 addr; /* Receiver address of the FIB */
|
||||
__le32 size; /* Size in bytes of Fib which this QE points to */
|
||||
__le32 addr; /* Receiver address of the FIB */
|
||||
};
|
||||
|
||||
/*
|
||||
@ -185,9 +211,10 @@ struct aac_entry {
|
||||
*/
|
||||
|
||||
struct aac_qhdr {
|
||||
u64 header_addr; /* Address to hand the adapter to access to this queue head */
|
||||
u32 *producer; /* The producer index for this queue (host address) */
|
||||
u32 *consumer; /* The consumer index for this queue (host address) */
|
||||
__le64 header_addr;/* Address to hand the adapter to access
|
||||
to this queue head */
|
||||
__le32 *producer; /* The producer index for this queue (host address) */
|
||||
__le32 *consumer; /* The consumer index for this queue (host address) */
|
||||
};
|
||||
|
||||
/*
|
||||
@ -261,29 +288,30 @@ enum aac_queue_types {
|
||||
*/
|
||||
|
||||
struct aac_fibhdr {
|
||||
u32 XferState; // Current transfer state for this CCB
|
||||
u16 Command; // Routing information for the destination
|
||||
u8 StructType; // Type FIB
|
||||
u8 Flags; // Flags for FIB
|
||||
u16 Size; // Size of this FIB in bytes
|
||||
u16 SenderSize; // Size of the FIB in the sender (for response sizing)
|
||||
u32 SenderFibAddress; // Host defined data in the FIB
|
||||
u32 ReceiverFibAddress; // Logical address of this FIB for the adapter
|
||||
u32 SenderData; // Place holder for the sender to store data
|
||||
__le32 XferState; /* Current transfer state for this CCB */
|
||||
__le16 Command; /* Routing information for the destination */
|
||||
u8 StructType; /* Type FIB */
|
||||
u8 Flags; /* Flags for FIB */
|
||||
__le16 Size; /* Size of this FIB in bytes */
|
||||
__le16 SenderSize; /* Size of the FIB in the sender
|
||||
(for response sizing) */
|
||||
__le32 SenderFibAddress; /* Host defined data in the FIB */
|
||||
__le32 ReceiverFibAddress;/* Logical address of this FIB for
|
||||
the adapter */
|
||||
u32 SenderData; /* Place holder for the sender to store data */
|
||||
union {
|
||||
struct {
|
||||
u32 _ReceiverTimeStart; // Timestamp for receipt of fib
|
||||
u32 _ReceiverTimeDone; // Timestamp for completion of fib
|
||||
__le32 _ReceiverTimeStart; /* Timestamp for
|
||||
receipt of fib */
|
||||
__le32 _ReceiverTimeDone; /* Timestamp for
|
||||
completion of fib */
|
||||
} _s;
|
||||
} _u;
|
||||
};
|
||||
|
||||
#define FIB_DATA_SIZE_IN_BYTES (512 - sizeof(struct aac_fibhdr))
|
||||
|
||||
|
||||
struct hw_fib {
|
||||
struct aac_fibhdr header;
|
||||
u8 data[FIB_DATA_SIZE_IN_BYTES]; // Command specific data
|
||||
u8 data[512-sizeof(struct aac_fibhdr)]; // Command specific data
|
||||
};
|
||||
|
||||
/*
|
||||
@ -345,11 +373,12 @@ struct hw_fib {
|
||||
#define RequestAdapterInfo 703
|
||||
#define IsAdapterPaused 704
|
||||
#define SendHostTime 705
|
||||
#define LastMiscCommand 706
|
||||
#define RequestSupplementAdapterInfo 706
|
||||
#define LastMiscCommand 707
|
||||
|
||||
//
|
||||
// Commands that will target the failover level on the FSA adapter
|
||||
//
|
||||
/*
|
||||
* Commands that will target the failover level on the FSA adapter
|
||||
*/
|
||||
|
||||
enum fib_xfer_state {
|
||||
HostOwned = (1<<0),
|
||||
@ -382,22 +411,32 @@ enum fib_xfer_state {
|
||||
*/
|
||||
|
||||
#define ADAPTER_INIT_STRUCT_REVISION 3
|
||||
#define ADAPTER_INIT_STRUCT_REVISION_4 4 // rocket science
|
||||
|
||||
struct aac_init
|
||||
{
|
||||
u32 InitStructRevision;
|
||||
u32 MiniPortRevision;
|
||||
u32 fsrev;
|
||||
u32 CommHeaderAddress;
|
||||
u32 FastIoCommAreaAddress;
|
||||
u32 AdapterFibsPhysicalAddress;
|
||||
u32 AdapterFibsVirtualAddress;
|
||||
u32 AdapterFibsSize;
|
||||
u32 AdapterFibAlign;
|
||||
u32 printfbuf;
|
||||
u32 printfbufsiz;
|
||||
u32 HostPhysMemPages; // number of 4k pages of host physical memory
|
||||
u32 HostElapsedSeconds; // number of seconds since 1970.
|
||||
__le32 InitStructRevision;
|
||||
__le32 MiniPortRevision;
|
||||
__le32 fsrev;
|
||||
__le32 CommHeaderAddress;
|
||||
__le32 FastIoCommAreaAddress;
|
||||
__le32 AdapterFibsPhysicalAddress;
|
||||
__le32 AdapterFibsVirtualAddress;
|
||||
__le32 AdapterFibsSize;
|
||||
__le32 AdapterFibAlign;
|
||||
__le32 printfbuf;
|
||||
__le32 printfbufsiz;
|
||||
__le32 HostPhysMemPages; /* number of 4k pages of host
|
||||
physical memory */
|
||||
__le32 HostElapsedSeconds; /* number of seconds since 1970. */
|
||||
/*
|
||||
* ADAPTER_INIT_STRUCT_REVISION_4 begins here
|
||||
*/
|
||||
__le32 InitFlags; /* flags for supported features */
|
||||
#define INITFLAGS_NEW_COMM_SUPPORTED 0x00000001
|
||||
__le32 MaxIoCommands; /* max outstanding commands */
|
||||
__le32 MaxIoSize; /* largest I/O command */
|
||||
__le32 MaxFibSize; /* largest FIB to adapter */
|
||||
};
|
||||
|
||||
enum aac_log_level {
|
||||
@ -421,7 +460,7 @@ struct adapter_ops
|
||||
{
|
||||
void (*adapter_interrupt)(struct aac_dev *dev);
|
||||
void (*adapter_notify)(struct aac_dev *dev, u32 event);
|
||||
int (*adapter_sync_cmd)(struct aac_dev *dev, u32 command, u32 p1, u32 *status);
|
||||
int (*adapter_sync_cmd)(struct aac_dev *dev, u32 command, u32 p1, u32 p2, u32 p3, u32 p4, u32 p5, u32 p6, u32 *status, u32 *r1, u32 *r2, u32 *r3, u32 *r4);
|
||||
int (*adapter_check_health)(struct aac_dev *dev);
|
||||
};
|
||||
|
||||
@ -541,6 +580,7 @@ struct sa_drawbridge_CSR {
|
||||
#define Mailbox3 SaDbCSR.MAILBOX3
|
||||
#define Mailbox4 SaDbCSR.MAILBOX4
|
||||
#define Mailbox5 SaDbCSR.MAILBOX5
|
||||
#define Mailbox6 SaDbCSR.MAILBOX6
|
||||
#define Mailbox7 SaDbCSR.MAILBOX7
|
||||
|
||||
#define DoorbellReg_p SaDbCSR.PRISETIRQ
|
||||
@ -763,29 +803,48 @@ struct fib {
|
||||
|
||||
struct aac_adapter_info
|
||||
{
|
||||
u32 platform;
|
||||
u32 cpu;
|
||||
u32 subcpu;
|
||||
u32 clock;
|
||||
u32 execmem;
|
||||
u32 buffermem;
|
||||
u32 totalmem;
|
||||
u32 kernelrev;
|
||||
u32 kernelbuild;
|
||||
u32 monitorrev;
|
||||
u32 monitorbuild;
|
||||
u32 hwrev;
|
||||
u32 hwbuild;
|
||||
u32 biosrev;
|
||||
u32 biosbuild;
|
||||
u32 cluster;
|
||||
u32 clusterchannelmask;
|
||||
u32 serial[2];
|
||||
u32 battery;
|
||||
u32 options;
|
||||
u32 OEM;
|
||||
__le32 platform;
|
||||
__le32 cpu;
|
||||
__le32 subcpu;
|
||||
__le32 clock;
|
||||
__le32 execmem;
|
||||
__le32 buffermem;
|
||||
__le32 totalmem;
|
||||
__le32 kernelrev;
|
||||
__le32 kernelbuild;
|
||||
__le32 monitorrev;
|
||||
__le32 monitorbuild;
|
||||
__le32 hwrev;
|
||||
__le32 hwbuild;
|
||||
__le32 biosrev;
|
||||
__le32 biosbuild;
|
||||
__le32 cluster;
|
||||
__le32 clusterchannelmask;
|
||||
__le32 serial[2];
|
||||
__le32 battery;
|
||||
__le32 options;
|
||||
__le32 OEM;
|
||||
};
|
||||
|
||||
struct aac_supplement_adapter_info
|
||||
{
|
||||
u8 AdapterTypeText[17+1];
|
||||
u8 Pad[2];
|
||||
__le32 FlashMemoryByteSize;
|
||||
__le32 FlashImageId;
|
||||
__le32 MaxNumberPorts;
|
||||
__le32 Version;
|
||||
__le32 FeatureBits;
|
||||
u8 SlotNumber;
|
||||
u8 ReservedPad0[0];
|
||||
u8 BuildDate[12];
|
||||
__le32 CurrentNumberPorts;
|
||||
__le32 ReservedGrowth[24];
|
||||
};
|
||||
#define AAC_FEATURE_FALCON 0x00000010
|
||||
#define AAC_SIS_VERSION_V3 3
|
||||
#define AAC_SIS_SLOT_UNKNOWN 0xFF
|
||||
|
||||
/*
|
||||
* Battery platforms
|
||||
*/
|
||||
@ -830,6 +889,12 @@ struct aac_dev
|
||||
int id;
|
||||
|
||||
u16 irq_mask;
|
||||
/*
|
||||
* negotiated FIB settings
|
||||
*/
|
||||
unsigned max_fib_size;
|
||||
unsigned sg_tablesize;
|
||||
|
||||
/*
|
||||
* Map for 128 fib objects (64k)
|
||||
*/
|
||||
@ -889,12 +954,14 @@ struct aac_dev
|
||||
u32 aif_thread;
|
||||
struct completion aif_completion;
|
||||
struct aac_adapter_info adapter_info;
|
||||
struct aac_supplement_adapter_info supplement_adapter_info;
|
||||
/* These are in adapter info but they are in the io flow so
|
||||
* lets break them out so we don't have to do an AND to check them
|
||||
*/
|
||||
u8 nondasd_support;
|
||||
u8 dac_support;
|
||||
u8 raid_scsi_mode;
|
||||
u8 printf_enabled;
|
||||
};
|
||||
|
||||
#define aac_adapter_interrupt(dev) \
|
||||
@ -903,6 +970,8 @@ struct aac_dev
|
||||
#define aac_adapter_notify(dev, event) \
|
||||
(dev)->a_ops.adapter_notify(dev, event)
|
||||
|
||||
#define aac_adapter_sync_cmd(dev, command, p1, p2, p3, p4, p5, p6, status, r1, r2, r3, r4) \
|
||||
(dev)->a_ops.adapter_sync_cmd(dev, command, p1, p2, p3, p4, p5, p6, status, r1, r2, r3, r4)
|
||||
|
||||
#define aac_adapter_check_health(dev) \
|
||||
(dev)->a_ops.adapter_check_health(dev)
|
||||
@ -1016,82 +1085,101 @@ struct aac_dev
|
||||
|
||||
struct aac_read
|
||||
{
|
||||
u32 command;
|
||||
u32 cid;
|
||||
u32 block;
|
||||
u32 count;
|
||||
__le32 command;
|
||||
__le32 cid;
|
||||
__le32 block;
|
||||
__le32 count;
|
||||
struct sgmap sg; // Must be last in struct because it is variable
|
||||
};
|
||||
|
||||
struct aac_read64
|
||||
{
|
||||
u32 command;
|
||||
u16 cid;
|
||||
u16 sector_count;
|
||||
u32 block;
|
||||
u16 pad;
|
||||
u16 flags;
|
||||
__le32 command;
|
||||
__le16 cid;
|
||||
__le16 sector_count;
|
||||
__le32 block;
|
||||
__le16 pad;
|
||||
__le16 flags;
|
||||
struct sgmap64 sg; // Must be last in struct because it is variable
|
||||
};
|
||||
|
||||
struct aac_read_reply
|
||||
{
|
||||
u32 status;
|
||||
u32 count;
|
||||
__le32 status;
|
||||
__le32 count;
|
||||
};
|
||||
|
||||
struct aac_write
|
||||
{
|
||||
u32 command;
|
||||
u32 cid;
|
||||
u32 block;
|
||||
u32 count;
|
||||
u32 stable; // Not used
|
||||
__le32 command;
|
||||
__le32 cid;
|
||||
__le32 block;
|
||||
__le32 count;
|
||||
__le32 stable; // Not used
|
||||
struct sgmap sg; // Must be last in struct because it is variable
|
||||
};
|
||||
|
||||
struct aac_write64
|
||||
{
|
||||
u32 command;
|
||||
u16 cid;
|
||||
u16 sector_count;
|
||||
u32 block;
|
||||
u16 pad;
|
||||
u16 flags;
|
||||
__le32 command;
|
||||
__le16 cid;
|
||||
__le16 sector_count;
|
||||
__le32 block;
|
||||
__le16 pad;
|
||||
__le16 flags;
|
||||
struct sgmap64 sg; // Must be last in struct because it is variable
|
||||
};
|
||||
struct aac_write_reply
|
||||
{
|
||||
u32 status;
|
||||
u32 count;
|
||||
u32 committed;
|
||||
__le32 status;
|
||||
__le32 count;
|
||||
__le32 committed;
|
||||
};
|
||||
|
||||
#define CT_FLUSH_CACHE 129
|
||||
struct aac_synchronize {
|
||||
u32 command; /* VM_ContainerConfig */
|
||||
u32 type; /* CT_FLUSH_CACHE */
|
||||
u32 cid;
|
||||
u32 parm1;
|
||||
u32 parm2;
|
||||
u32 parm3;
|
||||
u32 parm4;
|
||||
u32 count; /* sizeof(((struct aac_synchronize_reply *)NULL)->data) */
|
||||
__le32 command; /* VM_ContainerConfig */
|
||||
__le32 type; /* CT_FLUSH_CACHE */
|
||||
__le32 cid;
|
||||
__le32 parm1;
|
||||
__le32 parm2;
|
||||
__le32 parm3;
|
||||
__le32 parm4;
|
||||
__le32 count; /* sizeof(((struct aac_synchronize_reply *)NULL)->data) */
|
||||
};
|
||||
|
||||
struct aac_synchronize_reply {
|
||||
u32 dummy0;
|
||||
u32 dummy1;
|
||||
u32 status; /* CT_OK */
|
||||
u32 parm1;
|
||||
u32 parm2;
|
||||
u32 parm3;
|
||||
u32 parm4;
|
||||
u32 parm5;
|
||||
__le32 dummy0;
|
||||
__le32 dummy1;
|
||||
__le32 status; /* CT_OK */
|
||||
__le32 parm1;
|
||||
__le32 parm2;
|
||||
__le32 parm3;
|
||||
__le32 parm4;
|
||||
__le32 parm5;
|
||||
u8 data[16];
|
||||
};
|
||||
|
||||
struct aac_srb
|
||||
{
|
||||
__le32 function;
|
||||
__le32 channel;
|
||||
__le32 id;
|
||||
__le32 lun;
|
||||
__le32 timeout;
|
||||
__le32 flags;
|
||||
__le32 count; // Data xfer size
|
||||
__le32 retry_limit;
|
||||
__le32 cdb_size;
|
||||
u8 cdb[16];
|
||||
struct sgmap sg;
|
||||
};
|
||||
|
||||
/*
|
||||
* This and assocated data structs are used by the
|
||||
* ioctl caller and are in cpu order.
|
||||
*/
|
||||
struct user_aac_srb
|
||||
{
|
||||
u32 function;
|
||||
u32 channel;
|
||||
@ -1103,20 +1191,18 @@ struct aac_srb
|
||||
u32 retry_limit;
|
||||
u32 cdb_size;
|
||||
u8 cdb[16];
|
||||
struct sgmap sg;
|
||||
struct user_sgmap sg;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#define AAC_SENSE_BUFFERSIZE 30
|
||||
|
||||
struct aac_srb_reply
|
||||
{
|
||||
u32 status;
|
||||
u32 srb_status;
|
||||
u32 scsi_status;
|
||||
u32 data_xfer_length;
|
||||
u32 sense_data_size;
|
||||
__le32 status;
|
||||
__le32 srb_status;
|
||||
__le32 scsi_status;
|
||||
__le32 data_xfer_length;
|
||||
__le32 sense_data_size;
|
||||
u8 sense_data[AAC_SENSE_BUFFERSIZE]; // Can this be SCSI_SENSE_BUFFERSIZE
|
||||
};
|
||||
/*
|
||||
@ -1223,14 +1309,14 @@ struct aac_srb_reply
|
||||
*/
|
||||
|
||||
struct aac_fsinfo {
|
||||
u32 fsTotalSize; /* Consumed by fs, incl. metadata */
|
||||
u32 fsBlockSize;
|
||||
u32 fsFragSize;
|
||||
u32 fsMaxExtendSize;
|
||||
u32 fsSpaceUnits;
|
||||
u32 fsMaxNumFiles;
|
||||
u32 fsNumFreeFiles;
|
||||
u32 fsInodeDensity;
|
||||
__le32 fsTotalSize; /* Consumed by fs, incl. metadata */
|
||||
__le32 fsBlockSize;
|
||||
__le32 fsFragSize;
|
||||
__le32 fsMaxExtendSize;
|
||||
__le32 fsSpaceUnits;
|
||||
__le32 fsMaxNumFiles;
|
||||
__le32 fsNumFreeFiles;
|
||||
__le32 fsInodeDensity;
|
||||
}; /* valid iff ObjType == FT_FILESYS && !(ContentState & FSCS_NOTCLEAN) */
|
||||
|
||||
union aac_contentinfo {
|
||||
@ -1243,32 +1329,32 @@ union aac_contentinfo {
|
||||
|
||||
#define CT_GET_CONFIG_STATUS 147
|
||||
struct aac_get_config_status {
|
||||
u32 command; /* VM_ContainerConfig */
|
||||
u32 type; /* CT_GET_CONFIG_STATUS */
|
||||
u32 parm1;
|
||||
u32 parm2;
|
||||
u32 parm3;
|
||||
u32 parm4;
|
||||
u32 parm5;
|
||||
u32 count; /* sizeof(((struct aac_get_config_status_resp *)NULL)->data) */
|
||||
__le32 command; /* VM_ContainerConfig */
|
||||
__le32 type; /* CT_GET_CONFIG_STATUS */
|
||||
__le32 parm1;
|
||||
__le32 parm2;
|
||||
__le32 parm3;
|
||||
__le32 parm4;
|
||||
__le32 parm5;
|
||||
__le32 count; /* sizeof(((struct aac_get_config_status_resp *)NULL)->data) */
|
||||
};
|
||||
|
||||
#define CFACT_CONTINUE 0
|
||||
#define CFACT_PAUSE 1
|
||||
#define CFACT_ABORT 2
|
||||
struct aac_get_config_status_resp {
|
||||
u32 response; /* ST_OK */
|
||||
u32 dummy0;
|
||||
u32 status; /* CT_OK */
|
||||
u32 parm1;
|
||||
u32 parm2;
|
||||
u32 parm3;
|
||||
u32 parm4;
|
||||
u32 parm5;
|
||||
__le32 response; /* ST_OK */
|
||||
__le32 dummy0;
|
||||
__le32 status; /* CT_OK */
|
||||
__le32 parm1;
|
||||
__le32 parm2;
|
||||
__le32 parm3;
|
||||
__le32 parm4;
|
||||
__le32 parm5;
|
||||
struct {
|
||||
u32 action; /* CFACT_CONTINUE, CFACT_PAUSE or CFACT_ABORT */
|
||||
u16 flags;
|
||||
s16 count;
|
||||
__le32 action; /* CFACT_CONTINUE, CFACT_PAUSE or CFACT_ABORT */
|
||||
__le16 flags;
|
||||
__le16 count;
|
||||
} data;
|
||||
};
|
||||
|
||||
@ -1279,26 +1365,26 @@ struct aac_get_config_status_resp {
|
||||
#define CT_COMMIT_CONFIG 152
|
||||
|
||||
struct aac_commit_config {
|
||||
u32 command; /* VM_ContainerConfig */
|
||||
u32 type; /* CT_COMMIT_CONFIG */
|
||||
__le32 command; /* VM_ContainerConfig */
|
||||
__le32 type; /* CT_COMMIT_CONFIG */
|
||||
};
|
||||
|
||||
/*
|
||||
* Query for Container Configuration Count
|
||||
* Query for Container Configuration Status
|
||||
*/
|
||||
|
||||
#define CT_GET_CONTAINER_COUNT 4
|
||||
struct aac_get_container_count {
|
||||
u32 command; /* VM_ContainerConfig */
|
||||
u32 type; /* CT_GET_CONTAINER_COUNT */
|
||||
__le32 command; /* VM_ContainerConfig */
|
||||
__le32 type; /* CT_GET_CONTAINER_COUNT */
|
||||
};
|
||||
|
||||
struct aac_get_container_count_resp {
|
||||
u32 response; /* ST_OK */
|
||||
u32 dummy0;
|
||||
u32 MaxContainers;
|
||||
u32 ContainerSwitchEntries;
|
||||
u32 MaxPartitions;
|
||||
__le32 response; /* ST_OK */
|
||||
__le32 dummy0;
|
||||
__le32 MaxContainers;
|
||||
__le32 ContainerSwitchEntries;
|
||||
__le32 MaxPartitions;
|
||||
};
|
||||
|
||||
|
||||
@ -1308,15 +1394,19 @@ struct aac_get_container_count_resp {
|
||||
*/
|
||||
|
||||
struct aac_mntent {
|
||||
u32 oid;
|
||||
u8 name[16]; // if applicable
|
||||
struct creation_info create_info; // if applicable
|
||||
u32 capacity;
|
||||
u32 vol; // substrate structure
|
||||
u32 obj; // FT_FILESYS, FT_DATABASE, etc.
|
||||
u32 state; // unready for mounting, readonly, etc.
|
||||
union aac_contentinfo fileinfo; // Info specific to content manager (eg, filesystem)
|
||||
u32 altoid; // != oid <==> snapshot or broken mirror exists
|
||||
__le32 oid;
|
||||
u8 name[16]; /* if applicable */
|
||||
struct creation_info create_info; /* if applicable */
|
||||
__le32 capacity;
|
||||
__le32 vol; /* substrate structure */
|
||||
__le32 obj; /* FT_FILESYS,
|
||||
FT_DATABASE, etc. */
|
||||
__le32 state; /* unready for mounting,
|
||||
readonly, etc. */
|
||||
union aac_contentinfo fileinfo; /* Info specific to content
|
||||
manager (eg, filesystem) */
|
||||
__le32 altoid; /* != oid <==> snapshot or
|
||||
broken mirror exists */
|
||||
};
|
||||
|
||||
#define FSCS_NOTCLEAN 0x0001 /* fsck is neccessary before mounting */
|
||||
@ -1324,40 +1414,40 @@ struct aac_mntent {
|
||||
#define FSCS_HIDDEN 0x0004 /* should be ignored - set during a clear */
|
||||
|
||||
struct aac_query_mount {
|
||||
u32 command;
|
||||
u32 type;
|
||||
u32 count;
|
||||
__le32 command;
|
||||
__le32 type;
|
||||
__le32 count;
|
||||
};
|
||||
|
||||
struct aac_mount {
|
||||
u32 status;
|
||||
u32 type; /* should be same as that requested */
|
||||
u32 count;
|
||||
__le32 status;
|
||||
__le32 type; /* should be same as that requested */
|
||||
__le32 count;
|
||||
struct aac_mntent mnt[1];
|
||||
};
|
||||
|
||||
#define CT_READ_NAME 130
|
||||
struct aac_get_name {
|
||||
u32 command; /* VM_ContainerConfig */
|
||||
u32 type; /* CT_READ_NAME */
|
||||
u32 cid;
|
||||
u32 parm1;
|
||||
u32 parm2;
|
||||
u32 parm3;
|
||||
u32 parm4;
|
||||
u32 count; /* sizeof(((struct aac_get_name_resp *)NULL)->data) */
|
||||
__le32 command; /* VM_ContainerConfig */
|
||||
__le32 type; /* CT_READ_NAME */
|
||||
__le32 cid;
|
||||
__le32 parm1;
|
||||
__le32 parm2;
|
||||
__le32 parm3;
|
||||
__le32 parm4;
|
||||
__le32 count; /* sizeof(((struct aac_get_name_resp *)NULL)->data) */
|
||||
};
|
||||
|
||||
#define CT_OK 218
|
||||
struct aac_get_name_resp {
|
||||
u32 dummy0;
|
||||
u32 dummy1;
|
||||
u32 status; /* CT_OK */
|
||||
u32 parm1;
|
||||
u32 parm2;
|
||||
u32 parm3;
|
||||
u32 parm4;
|
||||
u32 parm5;
|
||||
__le32 dummy0;
|
||||
__le32 dummy1;
|
||||
__le32 status; /* CT_OK */
|
||||
__le32 parm1;
|
||||
__le32 parm2;
|
||||
__le32 parm3;
|
||||
__le32 parm4;
|
||||
__le32 parm5;
|
||||
u8 data[16];
|
||||
};
|
||||
|
||||
@ -1366,8 +1456,8 @@ struct aac_get_name_resp {
|
||||
*/
|
||||
|
||||
struct aac_close {
|
||||
u32 command;
|
||||
u32 cid;
|
||||
__le32 command;
|
||||
__le32 cid;
|
||||
};
|
||||
|
||||
struct aac_query_disk
|
||||
@ -1434,6 +1524,7 @@ struct revision
|
||||
#define FSACTL_GET_PCI_INFO CTL_CODE(2119, METHOD_BUFFERED)
|
||||
#define FSACTL_FORCE_DELETE_DISK CTL_CODE(2120, METHOD_NEITHER)
|
||||
#define FSACTL_GET_CONTAINERS 2131
|
||||
#define FSACTL_SEND_LARGE_FIB CTL_CODE(2138, METHOD_BUFFERED)
|
||||
|
||||
|
||||
struct aac_common
|
||||
@ -1573,8 +1664,8 @@ extern struct aac_common aac_config;
|
||||
*/
|
||||
|
||||
struct aac_aifcmd {
|
||||
u32 command; /* Tell host what type of notify this is */
|
||||
u32 seqnum; /* To allow ordering of reports (if necessary) */
|
||||
__le32 command; /* Tell host what type of notify this is */
|
||||
__le32 seqnum; /* To allow ordering of reports (if necessary) */
|
||||
u8 data[1]; /* Undefined length (from kernel viewpoint) */
|
||||
};
|
||||
|
||||
@ -1597,7 +1688,6 @@ int fib_setup(struct aac_dev *dev);
|
||||
void fib_map_free(struct aac_dev *dev);
|
||||
void fib_free(struct fib * context);
|
||||
void fib_init(struct fib * context);
|
||||
void fib_dealloc(struct fib * context);
|
||||
void aac_printf(struct aac_dev *dev, u32 val);
|
||||
int fib_send(u16 command, struct fib * context, unsigned long size, int priority, int wait, int reply, fib_callback callback, void *ctxt);
|
||||
int aac_consumer_get(struct aac_dev * dev, struct aac_queue * q, struct aac_entry **entry);
|
||||
@ -1621,3 +1711,5 @@ int fib_adapter_complete(struct fib * fibptr, unsigned short size);
|
||||
struct aac_driver_ident* aac_get_driver_ident(int devtype);
|
||||
int aac_get_adapter_info(struct aac_dev* dev);
|
||||
int aac_send_shutdown(struct aac_dev *dev);
|
||||
extern int numacb;
|
||||
extern int acbsize;
|
||||
|
@ -51,15 +51,22 @@
|
||||
* This routine sends a fib to the adapter on behalf of a user level
|
||||
* program.
|
||||
*/
|
||||
# define AAC_DEBUG_PREAMBLE KERN_INFO
|
||||
# define AAC_DEBUG_POSTAMBLE
|
||||
|
||||
static int ioctl_send_fib(struct aac_dev * dev, void __user *arg)
|
||||
{
|
||||
struct hw_fib * kfib;
|
||||
struct fib *fibptr;
|
||||
struct hw_fib * hw_fib = (struct hw_fib *)0;
|
||||
dma_addr_t hw_fib_pa = (dma_addr_t)0LL;
|
||||
unsigned size;
|
||||
int retval;
|
||||
|
||||
fibptr = fib_alloc(dev);
|
||||
if(fibptr == NULL)
|
||||
if(fibptr == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
kfib = fibptr->hw_fib;
|
||||
/*
|
||||
@ -74,19 +81,24 @@ static int ioctl_send_fib(struct aac_dev * dev, void __user *arg)
|
||||
* will not overrun the buffer when we copy the memory. Return
|
||||
* an error if we would.
|
||||
*/
|
||||
if (le16_to_cpu(kfib->header.Size) >
|
||||
sizeof(struct hw_fib) - sizeof(struct aac_fibhdr)) {
|
||||
fib_free(fibptr);
|
||||
return -EINVAL;
|
||||
size = le16_to_cpu(kfib->header.Size) + sizeof(struct aac_fibhdr);
|
||||
if (size < le16_to_cpu(kfib->header.SenderSize))
|
||||
size = le16_to_cpu(kfib->header.SenderSize);
|
||||
if (size > dev->max_fib_size) {
|
||||
/* Highjack the hw_fib */
|
||||
hw_fib = fibptr->hw_fib;
|
||||
hw_fib_pa = fibptr->hw_fib_pa;
|
||||
fibptr->hw_fib = kfib = pci_alloc_consistent(dev->pdev, size, &fibptr->hw_fib_pa);
|
||||
memset(((char *)kfib) + dev->max_fib_size, 0, size - dev->max_fib_size);
|
||||
memcpy(kfib, hw_fib, dev->max_fib_size);
|
||||
}
|
||||
|
||||
if (copy_from_user(kfib, arg, le16_to_cpu(kfib->header.Size) +
|
||||
sizeof(struct aac_fibhdr))) {
|
||||
fib_free(fibptr);
|
||||
return -EFAULT;
|
||||
if (copy_from_user(kfib, arg, size)) {
|
||||
retval = -EFAULT;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (kfib->header.Command == cpu_to_le32(TakeABreakPt)) {
|
||||
if (kfib->header.Command == cpu_to_le16(TakeABreakPt)) {
|
||||
aac_adapter_interrupt(dev);
|
||||
/*
|
||||
* Since we didn't really send a fib, zero out the state to allow
|
||||
@ -94,16 +106,15 @@ static int ioctl_send_fib(struct aac_dev * dev, void __user *arg)
|
||||
*/
|
||||
kfib->header.XferState = 0;
|
||||
} else {
|
||||
int retval = fib_send(kfib->header.Command, fibptr,
|
||||
retval = fib_send(le16_to_cpu(kfib->header.Command), fibptr,
|
||||
le16_to_cpu(kfib->header.Size) , FsaNormal,
|
||||
1, 1, NULL, NULL);
|
||||
if (retval) {
|
||||
fib_free(fibptr);
|
||||
return retval;
|
||||
goto cleanup;
|
||||
}
|
||||
if (fib_complete(fibptr) != 0) {
|
||||
fib_free(fibptr);
|
||||
return -EINVAL;
|
||||
retval = -EINVAL;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
/*
|
||||
@ -114,12 +125,17 @@ static int ioctl_send_fib(struct aac_dev * dev, void __user *arg)
|
||||
* was already included by the adapter.)
|
||||
*/
|
||||
|
||||
if (copy_to_user(arg, (void *)kfib, kfib->header.Size)) {
|
||||
fib_free(fibptr);
|
||||
return -EFAULT;
|
||||
retval = 0;
|
||||
if (copy_to_user(arg, (void *)kfib, size))
|
||||
retval = -EFAULT;
|
||||
cleanup:
|
||||
if (hw_fib) {
|
||||
pci_free_consistent(dev->pdev, size, kfib, fibptr->hw_fib_pa);
|
||||
fibptr->hw_fib_pa = hw_fib_pa;
|
||||
fibptr->hw_fib = hw_fib;
|
||||
}
|
||||
fib_free(fibptr);
|
||||
return 0;
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -391,26 +407,28 @@ static int check_revision(struct aac_dev *dev, void __user *arg)
|
||||
struct revision response;
|
||||
|
||||
response.compat = 1;
|
||||
response.version = dev->adapter_info.kernelrev;
|
||||
response.build = dev->adapter_info.kernelbuild;
|
||||
response.version = le32_to_cpu(dev->adapter_info.kernelrev);
|
||||
response.build = le32_to_cpu(dev->adapter_info.kernelbuild);
|
||||
|
||||
if (copy_to_user(arg, &response, sizeof(response)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* aac_send_raw_scb
|
||||
*
|
||||
*/
|
||||
|
||||
int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
|
||||
static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
|
||||
{
|
||||
struct fib* srbfib;
|
||||
int status;
|
||||
struct aac_srb *srbcmd;
|
||||
struct aac_srb __user *user_srb = arg;
|
||||
struct aac_srb *srbcmd = NULL;
|
||||
struct user_aac_srb *user_srbcmd = NULL;
|
||||
struct user_aac_srb __user *user_srb = arg;
|
||||
struct aac_srb_reply __user *user_reply;
|
||||
struct aac_srb_reply* reply;
|
||||
u32 fibsize = 0;
|
||||
@ -426,7 +444,7 @@ int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
|
||||
|
||||
|
||||
if (!capable(CAP_SYS_ADMIN)){
|
||||
printk(KERN_DEBUG"aacraid: No permission to send raw srb\n");
|
||||
dprintk((KERN_DEBUG"aacraid: No permission to send raw srb\n"));
|
||||
return -EPERM;
|
||||
}
|
||||
/*
|
||||
@ -439,37 +457,45 @@ int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
|
||||
|
||||
srbcmd = (struct aac_srb*) fib_data(srbfib);
|
||||
|
||||
memset(sg_list, 0, sizeof(sg_list)); /* cleanup may take issue */
|
||||
if(copy_from_user(&fibsize, &user_srb->count,sizeof(u32))){
|
||||
printk(KERN_DEBUG"aacraid: Could not copy data size from user\n");
|
||||
dprintk((KERN_DEBUG"aacraid: Could not copy data size from user\n"));
|
||||
rcode = -EFAULT;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (fibsize > FIB_DATA_SIZE_IN_BYTES) {
|
||||
if (fibsize > (dev->max_fib_size - sizeof(struct aac_fibhdr))) {
|
||||
rcode = -EINVAL;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if(copy_from_user(srbcmd, user_srb,fibsize)){
|
||||
printk(KERN_DEBUG"aacraid: Could not copy srb from user\n");
|
||||
user_srbcmd = kmalloc(GFP_KERNEL, fibsize);
|
||||
if (!user_srbcmd) {
|
||||
dprintk((KERN_DEBUG"aacraid: Could not make a copy of the srb\n"));
|
||||
rcode = -ENOMEM;
|
||||
goto cleanup;
|
||||
}
|
||||
if(copy_from_user(user_srbcmd, user_srb,fibsize)){
|
||||
dprintk((KERN_DEBUG"aacraid: Could not copy srb from user\n"));
|
||||
rcode = -EFAULT;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
user_reply = arg+fibsize;
|
||||
|
||||
flags = srbcmd->flags;
|
||||
flags = user_srbcmd->flags; /* from user in cpu order */
|
||||
// Fix up srb for endian and force some values
|
||||
|
||||
srbcmd->function = cpu_to_le32(SRBF_ExecuteScsi); // Force this
|
||||
srbcmd->channel = cpu_to_le32(srbcmd->channel);
|
||||
srbcmd->id = cpu_to_le32(srbcmd->id);
|
||||
srbcmd->lun = cpu_to_le32(srbcmd->lun);
|
||||
srbcmd->flags = cpu_to_le32(srbcmd->flags);
|
||||
srbcmd->timeout = cpu_to_le32(srbcmd->timeout);
|
||||
srbcmd->channel = cpu_to_le32(user_srbcmd->channel);
|
||||
srbcmd->id = cpu_to_le32(user_srbcmd->id);
|
||||
srbcmd->lun = cpu_to_le32(user_srbcmd->lun);
|
||||
srbcmd->flags = cpu_to_le32(flags);
|
||||
srbcmd->timeout = cpu_to_le32(user_srbcmd->timeout);
|
||||
srbcmd->retry_limit =cpu_to_le32(0); // Obsolete parameter
|
||||
srbcmd->cdb_size = cpu_to_le32(srbcmd->cdb_size);
|
||||
srbcmd->cdb_size = cpu_to_le32(user_srbcmd->cdb_size);
|
||||
|
||||
switch (srbcmd->flags & (SRB_DataIn | SRB_DataOut)) {
|
||||
switch (flags & (SRB_DataIn | SRB_DataOut)) {
|
||||
case SRB_DataOut:
|
||||
data_dir = DMA_TO_DEVICE;
|
||||
break;
|
||||
@ -482,118 +508,148 @@ int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
|
||||
default:
|
||||
data_dir = DMA_NONE;
|
||||
}
|
||||
if (le32_to_cpu(srbcmd->sg.count) > (sizeof(sg_list)/sizeof(sg_list[0]))) {
|
||||
dprintk((KERN_DEBUG"aacraid: too many sg entries %d\n",
|
||||
le32_to_cpu(srbcmd->sg.count)));
|
||||
rcode = -EINVAL;
|
||||
goto cleanup;
|
||||
}
|
||||
if (dev->dac_support == 1) {
|
||||
struct sgmap64* psg = (struct sgmap64*)&srbcmd->sg;
|
||||
struct user_sgmap64* upsg = (struct user_sgmap64*)&user_srbcmd->sg;
|
||||
struct sgmap64* psg = (struct sgmap64*)&user_srbcmd->sg;
|
||||
struct user_sgmap* usg;
|
||||
byte_count = 0;
|
||||
|
||||
/*
|
||||
* This should also catch if user used the 32 bit sgmap
|
||||
*/
|
||||
actual_fibsize = sizeof(struct aac_srb) -
|
||||
sizeof(struct sgentry) + ((srbcmd->sg.count & 0xff) *
|
||||
sizeof(struct sgentry64));
|
||||
sizeof(struct sgentry) +
|
||||
((upsg->count & 0xff) *
|
||||
sizeof(struct sgentry));
|
||||
if(actual_fibsize != fibsize){ // User made a mistake - should not continue
|
||||
printk(KERN_DEBUG"aacraid: Bad Size specified in Raw SRB command\n");
|
||||
dprintk((KERN_DEBUG"aacraid: Bad Size specified in Raw SRB command\n"));
|
||||
rcode = -EINVAL;
|
||||
goto cleanup;
|
||||
}
|
||||
if ((data_dir == DMA_NONE) && psg->count) {
|
||||
printk(KERN_DEBUG"aacraid: SG with no direction specified in Raw SRB command\n");
|
||||
usg = kmalloc(actual_fibsize - sizeof(struct aac_srb)
|
||||
+ sizeof(struct sgmap), GFP_KERNEL);
|
||||
if (!usg) {
|
||||
dprintk((KERN_DEBUG"aacraid: Allocation error in Raw SRB command\n"));
|
||||
rcode = -ENOMEM;
|
||||
goto cleanup;
|
||||
}
|
||||
memcpy (usg, upsg, actual_fibsize - sizeof(struct aac_srb)
|
||||
+ sizeof(struct sgmap));
|
||||
actual_fibsize = sizeof(struct aac_srb) -
|
||||
sizeof(struct sgentry) + ((usg->count & 0xff) *
|
||||
sizeof(struct sgentry64));
|
||||
if ((data_dir == DMA_NONE) && upsg->count) {
|
||||
kfree (usg);
|
||||
dprintk((KERN_DEBUG"aacraid: SG with no direction specified in Raw SRB command\n"));
|
||||
rcode = -EINVAL;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
for (i = 0; i < psg->count; i++) {
|
||||
dma_addr_t addr;
|
||||
u64 le_addr;
|
||||
for (i = 0; i < usg->count; i++) {
|
||||
u64 addr;
|
||||
void* p;
|
||||
p = kmalloc(psg->sg[i].count,GFP_KERNEL|__GFP_DMA);
|
||||
/* Does this really need to be GFP_DMA? */
|
||||
p = kmalloc(usg->sg[i].count,GFP_KERNEL|__GFP_DMA);
|
||||
if(p == 0) {
|
||||
printk(KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n",
|
||||
psg->sg[i].count,i,psg->count);
|
||||
kfree (usg);
|
||||
dprintk((KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n",
|
||||
usg->sg[i].count,i,usg->count));
|
||||
rcode = -ENOMEM;
|
||||
goto cleanup;
|
||||
}
|
||||
sg_user[i] = (void __user *)psg->sg[i].addr;
|
||||
sg_user[i] = (void __user *)usg->sg[i].addr;
|
||||
sg_list[i] = p; // save so we can clean up later
|
||||
sg_indx = i;
|
||||
|
||||
if( flags & SRB_DataOut ){
|
||||
if(copy_from_user(p,sg_user[i],psg->sg[i].count)){
|
||||
printk(KERN_DEBUG"aacraid: Could not copy sg data from user\n");
|
||||
if(copy_from_user(p,sg_user[i],upsg->sg[i].count)){
|
||||
kfree (usg);
|
||||
dprintk((KERN_DEBUG"aacraid: Could not copy sg data from user\n"));
|
||||
rcode = -EFAULT;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
addr = pci_map_single(dev->pdev, p, psg->sg[i].count, data_dir);
|
||||
addr = pci_map_single(dev->pdev, p, usg->sg[i].count, data_dir);
|
||||
|
||||
le_addr = cpu_to_le64(addr);
|
||||
psg->sg[i].addr[1] = (u32)(le_addr>>32);
|
||||
psg->sg[i].addr[0] = (u32)(le_addr & 0xffffffff);
|
||||
psg->sg[i].count = cpu_to_le32(psg->sg[i].count);
|
||||
byte_count += psg->sg[i].count;
|
||||
psg->sg[i].addr[0] = cpu_to_le32(addr & 0xffffffff);
|
||||
psg->sg[i].addr[1] = cpu_to_le32(addr>>32);
|
||||
psg->sg[i].count = cpu_to_le32(usg->sg[i].count);
|
||||
byte_count += usg->sg[i].count;
|
||||
}
|
||||
kfree (usg);
|
||||
|
||||
srbcmd->count = cpu_to_le32(byte_count);
|
||||
psg->count = cpu_to_le32(sg_indx+1);
|
||||
status = fib_send(ScsiPortCommand64, srbfib, actual_fibsize, FsaNormal, 1, 1,NULL,NULL);
|
||||
} else {
|
||||
struct user_sgmap* upsg = &user_srbcmd->sg;
|
||||
struct sgmap* psg = &srbcmd->sg;
|
||||
byte_count = 0;
|
||||
|
||||
actual_fibsize = sizeof (struct aac_srb) +
|
||||
(((le32_to_cpu(srbcmd->sg.count) & 0xff) - 1) *
|
||||
sizeof (struct sgentry));
|
||||
actual_fibsize = sizeof (struct aac_srb) + (((le32_to_cpu(srbcmd->sg.count) & 0xff) - 1) * sizeof (struct sgentry));
|
||||
if(actual_fibsize != fibsize){ // User made a mistake - should not continue
|
||||
printk(KERN_DEBUG"aacraid: Bad Size specified in Raw SRB command\n");
|
||||
dprintk((KERN_DEBUG"aacraid: Bad Size specified in Raw SRB command\n"));
|
||||
rcode = -EINVAL;
|
||||
goto cleanup;
|
||||
}
|
||||
if ((data_dir == DMA_NONE) && psg->count) {
|
||||
printk(KERN_DEBUG"aacraid: SG with no direction specified in Raw SRB command\n");
|
||||
if ((data_dir == DMA_NONE) && upsg->count) {
|
||||
dprintk((KERN_DEBUG"aacraid: SG with no direction specified in Raw SRB command\n"));
|
||||
rcode = -EINVAL;
|
||||
goto cleanup;
|
||||
}
|
||||
for (i = 0; i < psg->count; i++) {
|
||||
for (i = 0; i < upsg->count; i++) {
|
||||
dma_addr_t addr;
|
||||
void* p;
|
||||
p = kmalloc(psg->sg[i].count,GFP_KERNEL);
|
||||
p = kmalloc(upsg->sg[i].count, GFP_KERNEL);
|
||||
if(p == 0) {
|
||||
printk(KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n",
|
||||
psg->sg[i].count,i,psg->count);
|
||||
dprintk((KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n",
|
||||
upsg->sg[i].count, i, upsg->count));
|
||||
rcode = -ENOMEM;
|
||||
goto cleanup;
|
||||
}
|
||||
sg_user[i] = (void __user *)(psg->sg[i].addr);
|
||||
sg_user[i] = (void __user *)upsg->sg[i].addr;
|
||||
sg_list[i] = p; // save so we can clean up later
|
||||
sg_indx = i;
|
||||
|
||||
if( flags & SRB_DataOut ){
|
||||
if(copy_from_user(p,sg_user[i],psg->sg[i].count)){
|
||||
printk(KERN_DEBUG"aacraid: Could not copy sg data from user\n");
|
||||
if(copy_from_user(p, sg_user[i],
|
||||
upsg->sg[i].count)) {
|
||||
dprintk((KERN_DEBUG"aacraid: Could not copy sg data from user\n"));
|
||||
rcode = -EFAULT;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
addr = pci_map_single(dev->pdev, p, psg->sg[i].count, data_dir);
|
||||
addr = pci_map_single(dev->pdev, p,
|
||||
upsg->sg[i].count, data_dir);
|
||||
|
||||
psg->sg[i].addr = cpu_to_le32(addr);
|
||||
psg->sg[i].count = cpu_to_le32(psg->sg[i].count);
|
||||
byte_count += psg->sg[i].count;
|
||||
psg->sg[i].count = cpu_to_le32(upsg->sg[i].count);
|
||||
byte_count += upsg->sg[i].count;
|
||||
}
|
||||
srbcmd->count = cpu_to_le32(byte_count);
|
||||
psg->count = cpu_to_le32(sg_indx+1);
|
||||
status = fib_send(ScsiPortCommand, srbfib, actual_fibsize, FsaNormal, 1, 1, NULL, NULL);
|
||||
}
|
||||
|
||||
if (status != 0){
|
||||
printk(KERN_DEBUG"aacraid: Could not send raw srb fib to hba\n");
|
||||
dprintk((KERN_DEBUG"aacraid: Could not send raw srb fib to hba\n"));
|
||||
rcode = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if( flags & SRB_DataIn ) {
|
||||
for(i = 0 ; i <= sg_indx; i++){
|
||||
if(copy_to_user(sg_user[i],sg_list[i],le32_to_cpu(srbcmd->sg.sg[i].count))){
|
||||
printk(KERN_DEBUG"aacraid: Could not copy sg data to user\n");
|
||||
byte_count = le32_to_cpu((dev->dac_support == 1)
|
||||
? ((struct sgmap64*)&srbcmd->sg)->sg[i].count
|
||||
: srbcmd->sg.sg[i].count);
|
||||
if(copy_to_user(sg_user[i], sg_list[i], byte_count)){
|
||||
dprintk((KERN_DEBUG"aacraid: Could not copy sg data to user\n"));
|
||||
rcode = -EFAULT;
|
||||
goto cleanup;
|
||||
|
||||
@ -603,12 +659,13 @@ int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
|
||||
|
||||
reply = (struct aac_srb_reply *) fib_data(srbfib);
|
||||
if(copy_to_user(user_reply,reply,sizeof(struct aac_srb_reply))){
|
||||
printk(KERN_DEBUG"aacraid: Could not copy reply to user\n");
|
||||
dprintk((KERN_DEBUG"aacraid: Could not copy reply to user\n"));
|
||||
rcode = -EFAULT;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
kfree(user_srbcmd);
|
||||
for(i=0; i <= sg_indx; i++){
|
||||
kfree(sg_list[i]);
|
||||
}
|
||||
@ -618,14 +675,13 @@ cleanup:
|
||||
return rcode;
|
||||
}
|
||||
|
||||
|
||||
struct aac_pci_info {
|
||||
u32 bus;
|
||||
u32 slot;
|
||||
};
|
||||
|
||||
|
||||
int aac_get_pci_info(struct aac_dev* dev, void __user *arg)
|
||||
static int aac_get_pci_info(struct aac_dev* dev, void __user *arg)
|
||||
{
|
||||
struct aac_pci_info pci_info;
|
||||
|
||||
@ -633,11 +689,11 @@ int aac_get_pci_info(struct aac_dev* dev, void __user *arg)
|
||||
pci_info.slot = PCI_SLOT(dev->pdev->devfn);
|
||||
|
||||
if (copy_to_user(arg, &pci_info, sizeof(struct aac_pci_info))) {
|
||||
printk(KERN_DEBUG "aacraid: Could not copy pci info\n");
|
||||
dprintk((KERN_DEBUG "aacraid: Could not copy pci info\n"));
|
||||
return -EFAULT;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int aac_do_ioctl(struct aac_dev * dev, int cmd, void __user *arg)
|
||||
@ -656,6 +712,7 @@ int aac_do_ioctl(struct aac_dev * dev, int cmd, void __user *arg)
|
||||
case FSACTL_MINIPORT_REV_CHECK:
|
||||
status = check_revision(dev, arg);
|
||||
break;
|
||||
case FSACTL_SEND_LARGE_FIB:
|
||||
case FSACTL_SENDFIB:
|
||||
status = ioctl_send_fib(dev, arg);
|
||||
break;
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include <linux/blkdev.h>
|
||||
#include <linux/completion.h>
|
||||
#include <linux/mm.h>
|
||||
#include <scsi/scsi_host.h>
|
||||
#include <asm/semaphore.h>
|
||||
|
||||
#include "aacraid.h"
|
||||
@ -49,8 +50,8 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co
|
||||
{
|
||||
unsigned char *base;
|
||||
unsigned long size, align;
|
||||
unsigned long fibsize = 4096;
|
||||
unsigned long printfbufsiz = 256;
|
||||
const unsigned long fibsize = 4096;
|
||||
const unsigned long printfbufsiz = 256;
|
||||
struct aac_init *init;
|
||||
dma_addr_t phys;
|
||||
|
||||
@ -74,6 +75,8 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co
|
||||
init = dev->init;
|
||||
|
||||
init->InitStructRevision = cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION);
|
||||
if (dev->max_fib_size != sizeof(struct hw_fib))
|
||||
init->InitStructRevision = cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION_4);
|
||||
init->MiniPortRevision = cpu_to_le32(Sa_MINIPORT_REVISION);
|
||||
init->fsrev = cpu_to_le32(dev->fsrev);
|
||||
|
||||
@ -110,6 +113,10 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co
|
||||
init->HostPhysMemPages = cpu_to_le32(AAC_MAX_HOSTPHYSMEMPAGES);
|
||||
}
|
||||
|
||||
init->InitFlags = 0;
|
||||
init->MaxIoCommands = cpu_to_le32(dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB);
|
||||
init->MaxIoSize = cpu_to_le32(dev->scsi_host_ptr->max_sectors << 9);
|
||||
init->MaxFibSize = cpu_to_le32(dev->max_fib_size);
|
||||
|
||||
/*
|
||||
* Increment the base address by the amount already used
|
||||
@ -152,8 +159,8 @@ static void aac_queue_init(struct aac_dev * dev, struct aac_queue * q, u32 *mem,
|
||||
init_waitqueue_head(&q->qfull);
|
||||
spin_lock_init(&q->lockdata);
|
||||
q->lock = &q->lockdata;
|
||||
q->headers.producer = mem;
|
||||
q->headers.consumer = mem+1;
|
||||
q->headers.producer = (__le32 *)mem;
|
||||
q->headers.consumer = (__le32 *)(mem+1);
|
||||
*(q->headers.producer) = cpu_to_le32(qsize);
|
||||
*(q->headers.consumer) = cpu_to_le32(qsize);
|
||||
q->entries = qsize;
|
||||
@ -173,6 +180,8 @@ int aac_send_shutdown(struct aac_dev * dev)
|
||||
int status;
|
||||
|
||||
fibctx = fib_alloc(dev);
|
||||
if (!fibctx)
|
||||
return -ENOMEM;
|
||||
fib_init(fibctx);
|
||||
|
||||
cmd = (struct aac_close *) fib_data(fibctx);
|
||||
@ -204,7 +213,7 @@ int aac_send_shutdown(struct aac_dev * dev)
|
||||
* 0 - If there were errors initing. This is a fatal error.
|
||||
*/
|
||||
|
||||
int aac_comm_init(struct aac_dev * dev)
|
||||
static int aac_comm_init(struct aac_dev * dev)
|
||||
{
|
||||
unsigned long hdrsize = (sizeof(u32) * NUMBER_OF_COMM_QUEUES) * 2;
|
||||
unsigned long queuesize = sizeof(struct aac_entry) * TOTAL_QUEUE_ENTRIES;
|
||||
@ -293,6 +302,79 @@ int aac_comm_init(struct aac_dev * dev)
|
||||
|
||||
struct aac_dev *aac_init_adapter(struct aac_dev *dev)
|
||||
{
|
||||
u32 status[5];
|
||||
struct Scsi_Host * host = dev->scsi_host_ptr;
|
||||
|
||||
/*
|
||||
* Check the preferred comm settings, defaults from template.
|
||||
*/
|
||||
dev->max_fib_size = sizeof(struct hw_fib);
|
||||
dev->sg_tablesize = host->sg_tablesize = (dev->max_fib_size
|
||||
- sizeof(struct aac_fibhdr)
|
||||
- sizeof(struct aac_write) + sizeof(struct sgmap))
|
||||
/ sizeof(struct sgmap);
|
||||
if ((!aac_adapter_sync_cmd(dev, GET_COMM_PREFERRED_SETTINGS,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
status+0, status+1, status+2, status+3, status+4))
|
||||
&& (status[0] == 0x00000001)) {
|
||||
/*
|
||||
* status[1] >> 16 maximum command size in KB
|
||||
* status[1] & 0xFFFF maximum FIB size
|
||||
* status[2] >> 16 maximum SG elements to driver
|
||||
* status[2] & 0xFFFF maximum SG elements from driver
|
||||
* status[3] & 0xFFFF maximum number FIBs outstanding
|
||||
*/
|
||||
host->max_sectors = (status[1] >> 16) << 1;
|
||||
dev->max_fib_size = status[1] & 0xFFFF;
|
||||
host->sg_tablesize = status[2] >> 16;
|
||||
dev->sg_tablesize = status[2] & 0xFFFF;
|
||||
host->can_queue = (status[3] & 0xFFFF) - AAC_NUM_MGT_FIB;
|
||||
/*
|
||||
* NOTE:
|
||||
* All these overrides are based on a fixed internal
|
||||
* knowledge and understanding of existing adapters,
|
||||
* acbsize should be set with caution.
|
||||
*/
|
||||
if (acbsize == 512) {
|
||||
host->max_sectors = AAC_MAX_32BIT_SGBCOUNT;
|
||||
dev->max_fib_size = 512;
|
||||
dev->sg_tablesize = host->sg_tablesize
|
||||
= (512 - sizeof(struct aac_fibhdr)
|
||||
- sizeof(struct aac_write) + sizeof(struct sgmap))
|
||||
/ sizeof(struct sgmap);
|
||||
host->can_queue = AAC_NUM_IO_FIB;
|
||||
} else if (acbsize == 2048) {
|
||||
host->max_sectors = 512;
|
||||
dev->max_fib_size = 2048;
|
||||
host->sg_tablesize = 65;
|
||||
dev->sg_tablesize = 81;
|
||||
host->can_queue = 512 - AAC_NUM_MGT_FIB;
|
||||
} else if (acbsize == 4096) {
|
||||
host->max_sectors = 1024;
|
||||
dev->max_fib_size = 4096;
|
||||
host->sg_tablesize = 129;
|
||||
dev->sg_tablesize = 166;
|
||||
host->can_queue = 256 - AAC_NUM_MGT_FIB;
|
||||
} else if (acbsize == 8192) {
|
||||
host->max_sectors = 2048;
|
||||
dev->max_fib_size = 8192;
|
||||
host->sg_tablesize = 257;
|
||||
dev->sg_tablesize = 337;
|
||||
host->can_queue = 128 - AAC_NUM_MGT_FIB;
|
||||
} else if (acbsize > 0) {
|
||||
printk("Illegal acbsize=%d ignored\n", acbsize);
|
||||
}
|
||||
}
|
||||
{
|
||||
|
||||
if (numacb > 0) {
|
||||
if (numacb < host->can_queue)
|
||||
host->can_queue = numacb;
|
||||
else
|
||||
printk("numacb=%d ignored\n", numacb);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Ok now init the communication subsystem
|
||||
*/
|
||||
|
@ -25,7 +25,7 @@
|
||||
* commsup.c
|
||||
*
|
||||
* Abstract: Contain all routines that are required for FSA host/adapter
|
||||
* commuication.
|
||||
* communication.
|
||||
*
|
||||
*/
|
||||
|
||||
@ -38,6 +38,7 @@
|
||||
#include <linux/slab.h>
|
||||
#include <linux/completion.h>
|
||||
#include <linux/blkdev.h>
|
||||
#include <scsi/scsi_host.h>
|
||||
#include <asm/semaphore.h>
|
||||
|
||||
#include "aacraid.h"
|
||||
@ -52,7 +53,13 @@
|
||||
|
||||
static int fib_map_alloc(struct aac_dev *dev)
|
||||
{
|
||||
if((dev->hw_fib_va = pci_alloc_consistent(dev->pdev, sizeof(struct hw_fib) * AAC_NUM_FIB, &dev->hw_fib_pa))==NULL)
|
||||
dprintk((KERN_INFO
|
||||
"allocate hardware fibs pci_alloc_consistent(%p, %d * (%d + %d), %p)\n",
|
||||
dev->pdev, dev->max_fib_size, dev->scsi_host_ptr->can_queue,
|
||||
AAC_NUM_MGT_FIB, &dev->hw_fib_pa));
|
||||
if((dev->hw_fib_va = pci_alloc_consistent(dev->pdev, dev->max_fib_size
|
||||
* (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB),
|
||||
&dev->hw_fib_pa))==NULL)
|
||||
return -ENOMEM;
|
||||
return 0;
|
||||
}
|
||||
@ -67,7 +74,7 @@ static int fib_map_alloc(struct aac_dev *dev)
|
||||
|
||||
void fib_map_free(struct aac_dev *dev)
|
||||
{
|
||||
pci_free_consistent(dev->pdev, sizeof(struct hw_fib) * AAC_NUM_FIB, dev->hw_fib_va, dev->hw_fib_pa);
|
||||
pci_free_consistent(dev->pdev, dev->max_fib_size * (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB), dev->hw_fib_va, dev->hw_fib_pa);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -84,17 +91,22 @@ int fib_setup(struct aac_dev * dev)
|
||||
struct hw_fib *hw_fib_va;
|
||||
dma_addr_t hw_fib_pa;
|
||||
int i;
|
||||
|
||||
if(fib_map_alloc(dev)<0)
|
||||
|
||||
while (((i = fib_map_alloc(dev)) == -ENOMEM)
|
||||
&& (dev->scsi_host_ptr->can_queue > (64 - AAC_NUM_MGT_FIB))) {
|
||||
dev->init->MaxIoCommands = cpu_to_le32((dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB) >> 1);
|
||||
dev->scsi_host_ptr->can_queue = le32_to_cpu(dev->init->MaxIoCommands) - AAC_NUM_MGT_FIB;
|
||||
}
|
||||
if (i<0)
|
||||
return -ENOMEM;
|
||||
|
||||
hw_fib_va = dev->hw_fib_va;
|
||||
hw_fib_pa = dev->hw_fib_pa;
|
||||
memset(hw_fib_va, 0, sizeof(struct hw_fib) * AAC_NUM_FIB);
|
||||
memset(hw_fib_va, 0, dev->max_fib_size * (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB));
|
||||
/*
|
||||
* Initialise the fibs
|
||||
*/
|
||||
for (i = 0, fibptr = &dev->fibs[i]; i < AAC_NUM_FIB; i++, fibptr++)
|
||||
for (i = 0, fibptr = &dev->fibs[i]; i < (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB); i++, fibptr++)
|
||||
{
|
||||
fibptr->dev = dev;
|
||||
fibptr->hw_fib = hw_fib_va;
|
||||
@ -102,16 +114,16 @@ int fib_setup(struct aac_dev * dev)
|
||||
fibptr->next = fibptr+1; /* Forward chain the fibs */
|
||||
init_MUTEX_LOCKED(&fibptr->event_wait);
|
||||
spin_lock_init(&fibptr->event_lock);
|
||||
hw_fib_va->header.XferState = 0xffffffff;
|
||||
hw_fib_va->header.SenderSize = cpu_to_le16(sizeof(struct hw_fib));
|
||||
hw_fib_va->header.XferState = cpu_to_le32(0xffffffff);
|
||||
hw_fib_va->header.SenderSize = cpu_to_le16(dev->max_fib_size);
|
||||
fibptr->hw_fib_pa = hw_fib_pa;
|
||||
hw_fib_va = (struct hw_fib *)((unsigned char *)hw_fib_va + sizeof(struct hw_fib));
|
||||
hw_fib_pa = hw_fib_pa + sizeof(struct hw_fib);
|
||||
hw_fib_va = (struct hw_fib *)((unsigned char *)hw_fib_va + dev->max_fib_size);
|
||||
hw_fib_pa = hw_fib_pa + dev->max_fib_size;
|
||||
}
|
||||
/*
|
||||
* Add the fib chain to the free list
|
||||
*/
|
||||
dev->fibs[AAC_NUM_FIB-1].next = NULL;
|
||||
dev->fibs[dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB - 1].next = NULL;
|
||||
/*
|
||||
* Enable this to debug out of queue space
|
||||
*/
|
||||
@ -124,7 +136,7 @@ int fib_setup(struct aac_dev * dev)
|
||||
* @dev: Adapter to allocate the fib for
|
||||
*
|
||||
* Allocate a fib from the adapter fib pool. If the pool is empty we
|
||||
* wait for fibs to become free.
|
||||
* return NULL.
|
||||
*/
|
||||
|
||||
struct fib * fib_alloc(struct aac_dev *dev)
|
||||
@ -133,10 +145,10 @@ struct fib * fib_alloc(struct aac_dev *dev)
|
||||
unsigned long flags;
|
||||
spin_lock_irqsave(&dev->fib_lock, flags);
|
||||
fibptr = dev->free_fib;
|
||||
/* Cannot sleep here or you get hangs. Instead we did the
|
||||
maths at compile time. */
|
||||
if(!fibptr)
|
||||
BUG();
|
||||
if(!fibptr){
|
||||
spin_unlock_irqrestore(&dev->fib_lock, flags);
|
||||
return fibptr;
|
||||
}
|
||||
dev->free_fib = fibptr->next;
|
||||
spin_unlock_irqrestore(&dev->fib_lock, flags);
|
||||
/*
|
||||
@ -196,11 +208,11 @@ void fib_init(struct fib *fibptr)
|
||||
struct hw_fib *hw_fib = fibptr->hw_fib;
|
||||
|
||||
hw_fib->header.StructType = FIB_MAGIC;
|
||||
hw_fib->header.Size = cpu_to_le16(sizeof(struct hw_fib));
|
||||
hw_fib->header.XferState = cpu_to_le32(HostOwned | FibInitialized | FibEmpty | FastResponseCapable);
|
||||
hw_fib->header.Size = cpu_to_le16(fibptr->dev->max_fib_size);
|
||||
hw_fib->header.XferState = cpu_to_le32(HostOwned | FibInitialized | FibEmpty | FastResponseCapable);
|
||||
hw_fib->header.SenderFibAddress = cpu_to_le32(fibptr->hw_fib_pa);
|
||||
hw_fib->header.ReceiverFibAddress = cpu_to_le32(fibptr->hw_fib_pa);
|
||||
hw_fib->header.SenderSize = cpu_to_le16(sizeof(struct hw_fib));
|
||||
hw_fib->header.SenderSize = cpu_to_le16(fibptr->dev->max_fib_size);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -211,7 +223,7 @@ void fib_init(struct fib *fibptr)
|
||||
* caller.
|
||||
*/
|
||||
|
||||
void fib_dealloc(struct fib * fibptr)
|
||||
static void fib_dealloc(struct fib * fibptr)
|
||||
{
|
||||
struct hw_fib *hw_fib = fibptr->hw_fib;
|
||||
if(hw_fib->header.StructType != FIB_MAGIC)
|
||||
@ -279,7 +291,7 @@ static int aac_get_entry (struct aac_dev * dev, u32 qid, struct aac_entry **entr
|
||||
}
|
||||
|
||||
if ((*index + 1) == le32_to_cpu(*(q->headers.consumer))) { /* Queue is full */
|
||||
printk(KERN_WARNING "Queue %d full, %d outstanding.\n",
|
||||
printk(KERN_WARNING "Queue %d full, %u outstanding.\n",
|
||||
qid, q->numpending);
|
||||
return 0;
|
||||
} else {
|
||||
@ -658,9 +670,8 @@ int fib_adapter_complete(struct fib * fibptr, unsigned short size)
|
||||
}
|
||||
if (aac_insert_entry(dev, index, AdapHighRespQueue, (nointr & (int)aac_config.irq_mod)) != 0) {
|
||||
}
|
||||
}
|
||||
else if (hw_fib->header.XferState & NormalPriority)
|
||||
{
|
||||
} else if (hw_fib->header.XferState &
|
||||
cpu_to_le32(NormalPriority)) {
|
||||
u32 index;
|
||||
|
||||
if (size) {
|
||||
@ -744,22 +755,25 @@ int fib_complete(struct fib * fibptr)
|
||||
|
||||
void aac_printf(struct aac_dev *dev, u32 val)
|
||||
{
|
||||
int length = val & 0xffff;
|
||||
int level = (val >> 16) & 0xffff;
|
||||
char *cp = dev->printfbuf;
|
||||
|
||||
/*
|
||||
* The size of the printfbuf is set in port.c
|
||||
* There is no variable or define for it
|
||||
*/
|
||||
if (length > 255)
|
||||
length = 255;
|
||||
if (cp[length] != 0)
|
||||
cp[length] = 0;
|
||||
if (level == LOG_AAC_HIGH_ERROR)
|
||||
printk(KERN_WARNING "aacraid:%s", cp);
|
||||
else
|
||||
printk(KERN_INFO "aacraid:%s", cp);
|
||||
if (dev->printf_enabled)
|
||||
{
|
||||
int length = val & 0xffff;
|
||||
int level = (val >> 16) & 0xffff;
|
||||
|
||||
/*
|
||||
* The size of the printfbuf is set in port.c
|
||||
* There is no variable or define for it
|
||||
*/
|
||||
if (length > 255)
|
||||
length = 255;
|
||||
if (cp[length] != 0)
|
||||
cp[length] = 0;
|
||||
if (level == LOG_AAC_HIGH_ERROR)
|
||||
printk(KERN_WARNING "aacraid:%s", cp);
|
||||
else
|
||||
printk(KERN_INFO "aacraid:%s", cp);
|
||||
}
|
||||
memset(cp, 0, 256);
|
||||
}
|
||||
|
||||
@ -832,8 +846,8 @@ int aac_command_thread(struct aac_dev * dev)
|
||||
aifcmd = (struct aac_aifcmd *) hw_fib->data;
|
||||
if (aifcmd->command == cpu_to_le32(AifCmdDriverNotify)) {
|
||||
/* Handle Driver Notify Events */
|
||||
*(u32 *)hw_fib->data = cpu_to_le32(ST_OK);
|
||||
fib_adapter_complete(fib, sizeof(u32));
|
||||
*(__le32 *)hw_fib->data = cpu_to_le32(ST_OK);
|
||||
fib_adapter_complete(fib, (u16)sizeof(u32));
|
||||
} else {
|
||||
struct list_head *entry;
|
||||
/* The u32 here is important and intended. We are using
|
||||
@ -916,7 +930,7 @@ int aac_command_thread(struct aac_dev * dev)
|
||||
/*
|
||||
* Set the status of this FIB
|
||||
*/
|
||||
*(u32 *)hw_fib->data = cpu_to_le32(ST_OK);
|
||||
*(__le32 *)hw_fib->data = cpu_to_le32(ST_OK);
|
||||
fib_adapter_complete(fib, sizeof(u32));
|
||||
spin_unlock_irqrestore(&dev->fib_lock, flagv);
|
||||
}
|
||||
|
@ -99,7 +99,7 @@ unsigned int aac_response_normal(struct aac_queue * q)
|
||||
/*
|
||||
* Doctor the fib
|
||||
*/
|
||||
*(u32 *)hwfib->data = cpu_to_le32(ST_OK);
|
||||
*(__le32 *)hwfib->data = cpu_to_le32(ST_OK);
|
||||
hwfib->header.XferState |= cpu_to_le32(AdapterProcessed);
|
||||
}
|
||||
|
||||
@ -107,7 +107,7 @@ unsigned int aac_response_normal(struct aac_queue * q)
|
||||
|
||||
if (hwfib->header.Command == cpu_to_le16(NuFileSystem))
|
||||
{
|
||||
u32 *pstatus = (u32 *)hwfib->data;
|
||||
__le32 *pstatus = (__le32 *)hwfib->data;
|
||||
if (*pstatus & cpu_to_le32(0xffff0000))
|
||||
*pstatus = cpu_to_le32(ST_OK);
|
||||
}
|
||||
@ -205,7 +205,7 @@ unsigned int aac_command_normal(struct aac_queue *q)
|
||||
/*
|
||||
* Set the status of this FIB
|
||||
*/
|
||||
*(u32 *)hw_fib->data = cpu_to_le32(ST_OK);
|
||||
*(__le32 *)hw_fib->data = cpu_to_le32(ST_OK);
|
||||
fib_adapter_complete(fib, sizeof(u32));
|
||||
spin_lock_irqsave(q->lock, flags);
|
||||
}
|
||||
|
@ -215,7 +215,7 @@ static int aac_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd
|
||||
* Returns a static string describing the device in question
|
||||
*/
|
||||
|
||||
const char *aac_info(struct Scsi_Host *shost)
|
||||
static const char *aac_info(struct Scsi_Host *shost)
|
||||
{
|
||||
struct aac_dev *dev = (struct aac_dev *)shost->hostdata;
|
||||
return aac_drivers[dev->cardtype].name;
|
||||
@ -288,7 +288,7 @@ static int aac_biosparm(struct scsi_device *sdev, struct block_device *bdev,
|
||||
* translations ( 64/32, 128/32, 255/63 ).
|
||||
*/
|
||||
buf = scsi_bios_ptable(bdev);
|
||||
if(*(unsigned short *)(buf + 0x40) == cpu_to_le16(0xaa55)) {
|
||||
if(*(__le16 *)(buf + 0x40) == cpu_to_le16(0xaa55)) {
|
||||
struct partition *first = (struct partition * )buf;
|
||||
struct partition *entry = first;
|
||||
int saved_cylinders = param->cylinders;
|
||||
@ -347,10 +347,16 @@ static int aac_biosparm(struct scsi_device *sdev, struct block_device *bdev,
|
||||
|
||||
static int aac_slave_configure(struct scsi_device *sdev)
|
||||
{
|
||||
struct Scsi_Host *host = sdev->host;
|
||||
|
||||
if (sdev->tagged_supported)
|
||||
scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, 128);
|
||||
else
|
||||
scsi_adjust_queue_depth(sdev, 0, 1);
|
||||
|
||||
if (host->max_sectors < AAC_MAX_32BIT_SGBCOUNT)
|
||||
blk_queue_max_segment_size(sdev->request_queue, 65536);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -439,11 +445,11 @@ static int aac_eh_reset(struct scsi_cmnd* cmd)
|
||||
static int aac_cfg_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct aac_dev *aac;
|
||||
unsigned minor = iminor(inode);
|
||||
unsigned minor_number = iminor(inode);
|
||||
int err = -ENODEV;
|
||||
|
||||
list_for_each_entry(aac, &aac_devices, entry) {
|
||||
if (aac->id == minor) {
|
||||
if (aac->id == minor_number) {
|
||||
file->private_data = aac;
|
||||
err = 0;
|
||||
break;
|
||||
@ -489,6 +495,7 @@ static long aac_compat_do_ioctl(struct aac_dev *dev, unsigned cmd, unsigned long
|
||||
case FSACTL_DELETE_DISK:
|
||||
case FSACTL_FORCE_DELETE_DISK:
|
||||
case FSACTL_GET_CONTAINERS:
|
||||
case FSACTL_SEND_LARGE_FIB:
|
||||
ret = aac_do_ioctl(dev, cmd, (void __user *)arg);
|
||||
break;
|
||||
|
||||
@ -538,7 +545,7 @@ static struct file_operations aac_cfg_fops = {
|
||||
static struct scsi_host_template aac_driver_template = {
|
||||
.module = THIS_MODULE,
|
||||
.name = "AAC",
|
||||
.proc_name = "aacraid",
|
||||
.proc_name = AAC_DRIVERNAME,
|
||||
.info = aac_info,
|
||||
.ioctl = aac_ioctl,
|
||||
#ifdef CONFIG_COMPAT
|
||||
@ -612,7 +619,7 @@ static int __devinit aac_probe_one(struct pci_dev *pdev,
|
||||
aac->cardtype = index;
|
||||
INIT_LIST_HEAD(&aac->entry);
|
||||
|
||||
aac->fibs = kmalloc(sizeof(struct fib) * AAC_NUM_FIB, GFP_KERNEL);
|
||||
aac->fibs = kmalloc(sizeof(struct fib) * (shost->can_queue + AAC_NUM_MGT_FIB), GFP_KERNEL);
|
||||
if (!aac->fibs)
|
||||
goto out_free_host;
|
||||
spin_lock_init(&aac->fib_lock);
|
||||
@ -632,6 +639,24 @@ static int __devinit aac_probe_one(struct pci_dev *pdev,
|
||||
aac_get_adapter_info(aac);
|
||||
|
||||
/*
|
||||
* Lets override negotiations and drop the maximum SG limit to 34
|
||||
*/
|
||||
if ((aac_drivers[index].quirks & AAC_QUIRK_34SG) &&
|
||||
(aac->scsi_host_ptr->sg_tablesize > 34)) {
|
||||
aac->scsi_host_ptr->sg_tablesize = 34;
|
||||
aac->scsi_host_ptr->max_sectors
|
||||
= (aac->scsi_host_ptr->sg_tablesize * 8) + 112;
|
||||
}
|
||||
|
||||
/*
|
||||
* Firware printf works only with older firmware.
|
||||
*/
|
||||
if (aac_drivers[index].quirks & AAC_QUIRK_34SG)
|
||||
aac->printf_enabled = 1;
|
||||
else
|
||||
aac->printf_enabled = 0;
|
||||
|
||||
/*
|
||||
* max channel will be the physical channels plus 1 virtual channel
|
||||
* all containers are on the virtual channel 0
|
||||
* physical channels are address by their actual physical number+1
|
||||
|
@ -98,7 +98,9 @@ static irqreturn_t aac_rkt_intr(int irq, void *dev_id, struct pt_regs *regs)
|
||||
* for its completion.
|
||||
*/
|
||||
|
||||
static int rkt_sync_cmd(struct aac_dev *dev, u32 command, u32 p1, u32 *status)
|
||||
static int rkt_sync_cmd(struct aac_dev *dev, u32 command,
|
||||
u32 p1, u32 p2, u32 p3, u32 p4, u32 p5, u32 p6,
|
||||
u32 *status, u32 *r1, u32 *r2, u32 *r3, u32 *r4)
|
||||
{
|
||||
unsigned long start;
|
||||
int ok;
|
||||
@ -107,12 +109,12 @@ static int rkt_sync_cmd(struct aac_dev *dev, u32 command, u32 p1, u32 *status)
|
||||
*/
|
||||
rkt_writel(dev, InboundMailbox0, command);
|
||||
/*
|
||||
* Write the parameters into Mailboxes 1 - 4
|
||||
* Write the parameters into Mailboxes 1 - 6
|
||||
*/
|
||||
rkt_writel(dev, InboundMailbox1, p1);
|
||||
rkt_writel(dev, InboundMailbox2, 0);
|
||||
rkt_writel(dev, InboundMailbox3, 0);
|
||||
rkt_writel(dev, InboundMailbox4, 0);
|
||||
rkt_writel(dev, InboundMailbox2, p2);
|
||||
rkt_writel(dev, InboundMailbox3, p3);
|
||||
rkt_writel(dev, InboundMailbox4, p4);
|
||||
/*
|
||||
* Clear the synch command doorbell to start on a clean slate.
|
||||
*/
|
||||
@ -169,6 +171,14 @@ static int rkt_sync_cmd(struct aac_dev *dev, u32 command, u32 p1, u32 *status)
|
||||
*/
|
||||
if (status)
|
||||
*status = rkt_readl(dev, IndexRegs.Mailbox[0]);
|
||||
if (r1)
|
||||
*r1 = rkt_readl(dev, IndexRegs.Mailbox[1]);
|
||||
if (r2)
|
||||
*r2 = rkt_readl(dev, IndexRegs.Mailbox[2]);
|
||||
if (r3)
|
||||
*r3 = rkt_readl(dev, IndexRegs.Mailbox[3]);
|
||||
if (r4)
|
||||
*r4 = rkt_readl(dev, IndexRegs.Mailbox[4]);
|
||||
/*
|
||||
* Clear the synch command doorbell.
|
||||
*/
|
||||
@ -190,8 +200,8 @@ static int rkt_sync_cmd(struct aac_dev *dev, u32 command, u32 p1, u32 *status)
|
||||
|
||||
static void aac_rkt_interrupt_adapter(struct aac_dev *dev)
|
||||
{
|
||||
u32 ret;
|
||||
rkt_sync_cmd(dev, BREAKPOINT_REQUEST, 0, &ret);
|
||||
rkt_sync_cmd(dev, BREAKPOINT_REQUEST, 0, 0, 0, 0, 0, 0,
|
||||
NULL, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -220,7 +230,8 @@ static void aac_rkt_notify_adapter(struct aac_dev *dev, u32 event)
|
||||
rkt_writel(dev, MUnit.IDR,INBOUNDDOORBELL_3);
|
||||
break;
|
||||
case HostShutdown:
|
||||
// rkt_sync_cmd(dev, HOST_CRASHING, 0, 0, 0, 0, &ret);
|
||||
// rkt_sync_cmd(dev, HOST_CRASHING, 0, 0, 0, 0, 0, 0,
|
||||
// NULL, NULL, NULL, NULL, NULL);
|
||||
break;
|
||||
case FastIo:
|
||||
rkt_writel(dev, MUnit.IDR,INBOUNDDOORBELL_6);
|
||||
@ -243,16 +254,10 @@ static void aac_rkt_notify_adapter(struct aac_dev *dev, u32 event)
|
||||
|
||||
static void aac_rkt_start_adapter(struct aac_dev *dev)
|
||||
{
|
||||
u32 status;
|
||||
struct aac_init *init;
|
||||
|
||||
init = dev->init;
|
||||
init->HostElapsedSeconds = cpu_to_le32(get_seconds());
|
||||
/*
|
||||
* Tell the adapter we are back and up and running so it will scan
|
||||
* its command queues and enable our interrupts
|
||||
*/
|
||||
dev->irq_mask = (DoorBellPrintfReady | OUTBOUNDDOORBELL_1 | OUTBOUNDDOORBELL_2 | OUTBOUNDDOORBELL_3 | OUTBOUNDDOORBELL_4);
|
||||
/*
|
||||
* First clear out all interrupts. Then enable the one's that we
|
||||
* can handle.
|
||||
@ -263,7 +268,8 @@ static void aac_rkt_start_adapter(struct aac_dev *dev)
|
||||
rkt_writeb(dev, MUnit.OIMR, dev->OIMR = 0xfb);
|
||||
|
||||
// We can only use a 32 bit address here
|
||||
rkt_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS, (u32)(ulong)dev->init_pa, &status);
|
||||
rkt_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS, (u32)(ulong)dev->init_pa,
|
||||
0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -288,8 +294,8 @@ static int aac_rkt_check_health(struct aac_dev *dev)
|
||||
if (status & KERNEL_PANIC) {
|
||||
char * buffer;
|
||||
struct POSTSTATUS {
|
||||
u32 Post_Command;
|
||||
u32 Post_Address;
|
||||
__le32 Post_Command;
|
||||
__le32 Post_Address;
|
||||
} * post;
|
||||
dma_addr_t paddr, baddr;
|
||||
int ret;
|
||||
@ -310,7 +316,8 @@ static int aac_rkt_check_health(struct aac_dev *dev)
|
||||
post->Post_Command = cpu_to_le32(COMMAND_POST_RESULTS);
|
||||
post->Post_Address = cpu_to_le32(baddr);
|
||||
rkt_writel(dev, MUnit.IMRx[0], paddr);
|
||||
rkt_sync_cmd(dev, COMMAND_POST_RESULTS, baddr, &status);
|
||||
rkt_sync_cmd(dev, COMMAND_POST_RESULTS, baddr, 0, 0, 0, 0, 0,
|
||||
NULL, NULL, NULL, NULL, NULL);
|
||||
pci_free_consistent(dev->pdev, sizeof(struct POSTSTATUS),
|
||||
post, paddr);
|
||||
if ((buffer[0] == '0') && (buffer[1] == 'x')) {
|
||||
|
@ -63,7 +63,7 @@ static irqreturn_t aac_rx_intr(int irq, void *dev_id, struct pt_regs *regs)
|
||||
{
|
||||
bellbits = rx_readl(dev, OutboundDoorbellReg);
|
||||
if (bellbits & DoorBellPrintfReady) {
|
||||
aac_printf(dev, le32_to_cpu(rx_readl (dev, IndexRegs.Mailbox[5])));
|
||||
aac_printf(dev, rx_readl(dev, IndexRegs.Mailbox[5]));
|
||||
rx_writel(dev, MUnit.ODR,DoorBellPrintfReady);
|
||||
rx_writel(dev, InboundDoorbellReg,DoorBellPrintfDone);
|
||||
}
|
||||
@ -98,7 +98,9 @@ static irqreturn_t aac_rx_intr(int irq, void *dev_id, struct pt_regs *regs)
|
||||
* for its completion.
|
||||
*/
|
||||
|
||||
static int rx_sync_cmd(struct aac_dev *dev, u32 command, u32 p1, u32 *status)
|
||||
static int rx_sync_cmd(struct aac_dev *dev, u32 command,
|
||||
u32 p1, u32 p2, u32 p3, u32 p4, u32 p5, u32 p6,
|
||||
u32 *status, u32 * r1, u32 * r2, u32 * r3, u32 * r4)
|
||||
{
|
||||
unsigned long start;
|
||||
int ok;
|
||||
@ -107,12 +109,12 @@ static int rx_sync_cmd(struct aac_dev *dev, u32 command, u32 p1, u32 *status)
|
||||
*/
|
||||
rx_writel(dev, InboundMailbox0, command);
|
||||
/*
|
||||
* Write the parameters into Mailboxes 1 - 4
|
||||
* Write the parameters into Mailboxes 1 - 6
|
||||
*/
|
||||
rx_writel(dev, InboundMailbox1, p1);
|
||||
rx_writel(dev, InboundMailbox2, 0);
|
||||
rx_writel(dev, InboundMailbox3, 0);
|
||||
rx_writel(dev, InboundMailbox4, 0);
|
||||
rx_writel(dev, InboundMailbox2, p2);
|
||||
rx_writel(dev, InboundMailbox3, p3);
|
||||
rx_writel(dev, InboundMailbox4, p4);
|
||||
/*
|
||||
* Clear the synch command doorbell to start on a clean slate.
|
||||
*/
|
||||
@ -120,7 +122,7 @@ static int rx_sync_cmd(struct aac_dev *dev, u32 command, u32 p1, u32 *status)
|
||||
/*
|
||||
* Disable doorbell interrupts
|
||||
*/
|
||||
rx_writeb(dev, MUnit.OIMR, dev->OIMR |= 0x04);
|
||||
rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xff);
|
||||
/*
|
||||
* Force the completion of the mask register write before issuing
|
||||
* the interrupt.
|
||||
@ -169,6 +171,14 @@ static int rx_sync_cmd(struct aac_dev *dev, u32 command, u32 p1, u32 *status)
|
||||
*/
|
||||
if (status)
|
||||
*status = rx_readl(dev, IndexRegs.Mailbox[0]);
|
||||
if (r1)
|
||||
*r1 = rx_readl(dev, IndexRegs.Mailbox[1]);
|
||||
if (r2)
|
||||
*r2 = rx_readl(dev, IndexRegs.Mailbox[2]);
|
||||
if (r3)
|
||||
*r3 = rx_readl(dev, IndexRegs.Mailbox[3]);
|
||||
if (r4)
|
||||
*r4 = rx_readl(dev, IndexRegs.Mailbox[4]);
|
||||
/*
|
||||
* Clear the synch command doorbell.
|
||||
*/
|
||||
@ -190,8 +200,7 @@ static int rx_sync_cmd(struct aac_dev *dev, u32 command, u32 p1, u32 *status)
|
||||
|
||||
static void aac_rx_interrupt_adapter(struct aac_dev *dev)
|
||||
{
|
||||
u32 ret;
|
||||
rx_sync_cmd(dev, BREAKPOINT_REQUEST, 0, &ret);
|
||||
rx_sync_cmd(dev, BREAKPOINT_REQUEST, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -220,7 +229,8 @@ static void aac_rx_notify_adapter(struct aac_dev *dev, u32 event)
|
||||
rx_writel(dev, MUnit.IDR,INBOUNDDOORBELL_3);
|
||||
break;
|
||||
case HostShutdown:
|
||||
// rx_sync_cmd(dev, HOST_CRASHING, 0, 0, 0, 0, &ret);
|
||||
// rx_sync_cmd(dev, HOST_CRASHING, 0, 0, 0, 0, 0, 0,
|
||||
// NULL, NULL, NULL, NULL, NULL);
|
||||
break;
|
||||
case FastIo:
|
||||
rx_writel(dev, MUnit.IDR,INBOUNDDOORBELL_6);
|
||||
@ -243,16 +253,10 @@ static void aac_rx_notify_adapter(struct aac_dev *dev, u32 event)
|
||||
|
||||
static void aac_rx_start_adapter(struct aac_dev *dev)
|
||||
{
|
||||
u32 status;
|
||||
struct aac_init *init;
|
||||
|
||||
init = dev->init;
|
||||
init->HostElapsedSeconds = cpu_to_le32(get_seconds());
|
||||
/*
|
||||
* Tell the adapter we are back and up and running so it will scan
|
||||
* its command queues and enable our interrupts
|
||||
*/
|
||||
dev->irq_mask = (DoorBellPrintfReady | OUTBOUNDDOORBELL_1 | OUTBOUNDDOORBELL_2 | OUTBOUNDDOORBELL_3 | OUTBOUNDDOORBELL_4);
|
||||
/*
|
||||
* First clear out all interrupts. Then enable the one's that we
|
||||
* can handle.
|
||||
@ -263,7 +267,8 @@ static void aac_rx_start_adapter(struct aac_dev *dev)
|
||||
rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xfb);
|
||||
|
||||
// We can only use a 32 bit address here
|
||||
rx_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS, (u32)(ulong)dev->init_pa, &status);
|
||||
rx_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS, (u32)(ulong)dev->init_pa,
|
||||
0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -288,8 +293,8 @@ static int aac_rx_check_health(struct aac_dev *dev)
|
||||
if (status & KERNEL_PANIC) {
|
||||
char * buffer;
|
||||
struct POSTSTATUS {
|
||||
u32 Post_Command;
|
||||
u32 Post_Address;
|
||||
__le32 Post_Command;
|
||||
__le32 Post_Address;
|
||||
} * post;
|
||||
dma_addr_t paddr, baddr;
|
||||
int ret;
|
||||
@ -310,7 +315,8 @@ static int aac_rx_check_health(struct aac_dev *dev)
|
||||
post->Post_Command = cpu_to_le32(COMMAND_POST_RESULTS);
|
||||
post->Post_Address = cpu_to_le32(baddr);
|
||||
rx_writel(dev, MUnit.IMRx[0], paddr);
|
||||
rx_sync_cmd(dev, COMMAND_POST_RESULTS, baddr, &status);
|
||||
rx_sync_cmd(dev, COMMAND_POST_RESULTS, baddr, 0, 0, 0, 0, 0,
|
||||
NULL, NULL, NULL, NULL, NULL);
|
||||
pci_free_consistent(dev->pdev, sizeof(struct POSTSTATUS),
|
||||
post, paddr);
|
||||
if ((buffer[0] == '0') && (buffer[1] == 'x')) {
|
||||
|
@ -89,7 +89,7 @@ static irqreturn_t aac_sa_intr(int irq, void *dev_id, struct pt_regs *regs)
|
||||
* Notify the adapter of an event
|
||||
*/
|
||||
|
||||
void aac_sa_notify_adapter(struct aac_dev *dev, u32 event)
|
||||
static void aac_sa_notify_adapter(struct aac_dev *dev, u32 event)
|
||||
{
|
||||
switch (event) {
|
||||
|
||||
@ -106,7 +106,10 @@ void aac_sa_notify_adapter(struct aac_dev *dev, u32 event)
|
||||
sa_writew(dev, DoorbellReg_s,DOORBELL_3);
|
||||
break;
|
||||
case HostShutdown:
|
||||
//sa_sync_cmd(dev, HOST_CRASHING, 0, &ret);
|
||||
/*
|
||||
sa_sync_cmd(dev, HOST_CRASHING, 0, 0, 0, 0, 0, 0,
|
||||
NULL, NULL, NULL, NULL, NULL);
|
||||
*/
|
||||
break;
|
||||
case FastIo:
|
||||
sa_writew(dev, DoorbellReg_s,DOORBELL_6);
|
||||
@ -132,7 +135,9 @@ void aac_sa_notify_adapter(struct aac_dev *dev, u32 event)
|
||||
* for its completion.
|
||||
*/
|
||||
|
||||
static int sa_sync_cmd(struct aac_dev *dev, u32 command, u32 p1, u32 *ret)
|
||||
static int sa_sync_cmd(struct aac_dev *dev, u32 command,
|
||||
u32 p1, u32 p2, u32 p3, u32 p4, u32 p5, u32 p6,
|
||||
u32 *ret, u32 *r1, u32 *r2, u32 *r3, u32 *r4)
|
||||
{
|
||||
unsigned long start;
|
||||
int ok;
|
||||
@ -144,9 +149,10 @@ static int sa_sync_cmd(struct aac_dev *dev, u32 command, u32 p1, u32 *ret)
|
||||
* Write the parameters into Mailboxes 1 - 4
|
||||
*/
|
||||
sa_writel(dev, Mailbox1, p1);
|
||||
sa_writel(dev, Mailbox2, 0);
|
||||
sa_writel(dev, Mailbox3, 0);
|
||||
sa_writel(dev, Mailbox4, 0);
|
||||
sa_writel(dev, Mailbox2, p2);
|
||||
sa_writel(dev, Mailbox3, p3);
|
||||
sa_writel(dev, Mailbox4, p4);
|
||||
|
||||
/*
|
||||
* Clear the synch command doorbell to start on a clean slate.
|
||||
*/
|
||||
@ -188,6 +194,14 @@ static int sa_sync_cmd(struct aac_dev *dev, u32 command, u32 p1, u32 *ret)
|
||||
*/
|
||||
if (ret)
|
||||
*ret = sa_readl(dev, Mailbox0);
|
||||
if (r1)
|
||||
*r1 = sa_readl(dev, Mailbox1);
|
||||
if (r2)
|
||||
*r2 = sa_readl(dev, Mailbox2);
|
||||
if (r3)
|
||||
*r3 = sa_readl(dev, Mailbox3);
|
||||
if (r4)
|
||||
*r4 = sa_readl(dev, Mailbox4);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -201,7 +215,8 @@ static int sa_sync_cmd(struct aac_dev *dev, u32 command, u32 p1, u32 *ret)
|
||||
static void aac_sa_interrupt_adapter (struct aac_dev *dev)
|
||||
{
|
||||
u32 ret;
|
||||
sa_sync_cmd(dev, BREAKPOINT_REQUEST, 0, &ret);
|
||||
sa_sync_cmd(dev, BREAKPOINT_REQUEST, 0, 0, 0, 0, 0, 0,
|
||||
&ret, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -230,10 +245,12 @@ static void aac_sa_start_adapter(struct aac_dev *dev)
|
||||
* First clear out all interrupts. Then enable the one's that
|
||||
* we can handle.
|
||||
*/
|
||||
sa_writew(dev, SaDbCSR.PRISETIRQMASK, cpu_to_le16(0xffff));
|
||||
sa_writew(dev, SaDbCSR.PRISETIRQMASK, 0xffff);
|
||||
sa_writew(dev, SaDbCSR.PRICLEARIRQMASK, (PrintfReady | DOORBELL_1 | DOORBELL_2 | DOORBELL_3 | DOORBELL_4));
|
||||
/* We can only use a 32 bit address here */
|
||||
sa_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS, (u32)(ulong)dev->init_pa, &ret);
|
||||
sa_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS,
|
||||
(u32)(ulong)dev->init_pa, 0, 0, 0, 0, 0,
|
||||
&ret, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3146,8 +3146,8 @@ static const char *atp870u_info(struct Scsi_Host *notused)
|
||||
}
|
||||
|
||||
#define BLS buffer + len + size
|
||||
int atp870u_proc_info(struct Scsi_Host *HBAptr, char *buffer,
|
||||
char **start, off_t offset, int length, int inout)
|
||||
static int atp870u_proc_info(struct Scsi_Host *HBAptr, char *buffer,
|
||||
char **start, off_t offset, int length, int inout)
|
||||
{
|
||||
static u8 buff[512];
|
||||
int size = 0;
|
||||
|
1026
drivers/scsi/ch.c
Normal file
1026
drivers/scsi/ch.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -113,7 +113,6 @@ static struct i2o_sys_tbl *sys_tbl = NULL;
|
||||
static int sys_tbl_ind = 0;
|
||||
static int sys_tbl_len = 0;
|
||||
|
||||
static adpt_hba* hbas[DPTI_MAX_HBA];
|
||||
static adpt_hba* hba_chain = NULL;
|
||||
static int hba_count = 0;
|
||||
|
||||
@ -691,7 +690,7 @@ static int adpt_device_reset(struct scsi_cmnd* cmd)
|
||||
u32 msg[4];
|
||||
u32 rcode;
|
||||
int old_state;
|
||||
struct adpt_device* d = (void*) cmd->device->hostdata;
|
||||
struct adpt_device* d = cmd->device->hostdata;
|
||||
|
||||
pHba = (void*) cmd->device->host->hostdata[0];
|
||||
printk(KERN_INFO"%s: Trying to reset device\n",pHba->name);
|
||||
@ -707,7 +706,7 @@ static int adpt_device_reset(struct scsi_cmnd* cmd)
|
||||
|
||||
old_state = d->state;
|
||||
d->state |= DPTI_DEV_RESET;
|
||||
if( (rcode = adpt_i2o_post_wait(pHba, (void*)msg,sizeof(msg), FOREVER)) ){
|
||||
if( (rcode = adpt_i2o_post_wait(pHba, msg,sizeof(msg), FOREVER)) ){
|
||||
d->state = old_state;
|
||||
if(rcode == -EOPNOTSUPP ){
|
||||
printk(KERN_INFO"%s: Device reset not supported\n",pHba->name);
|
||||
@ -737,7 +736,7 @@ static int adpt_bus_reset(struct scsi_cmnd* cmd)
|
||||
msg[1] = (I2O_HBA_BUS_RESET<<24|HOST_TID<<12|pHba->channel[cmd->device->channel].tid);
|
||||
msg[2] = 0;
|
||||
msg[3] = 0;
|
||||
if(adpt_i2o_post_wait(pHba, (void*)msg,sizeof(msg), FOREVER) ){
|
||||
if(adpt_i2o_post_wait(pHba, msg,sizeof(msg), FOREVER) ){
|
||||
printk(KERN_WARNING"%s: Bus reset failed.\n",pHba->name);
|
||||
return FAILED;
|
||||
} else {
|
||||
@ -875,7 +874,6 @@ static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev
|
||||
void __iomem *msg_addr_virt = NULL;
|
||||
|
||||
int raptorFlag = FALSE;
|
||||
int i;
|
||||
|
||||
if(pci_enable_device(pDev)) {
|
||||
return -EINVAL;
|
||||
@ -935,12 +933,6 @@ static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev
|
||||
memset(pHba, 0, sizeof(adpt_hba));
|
||||
|
||||
down(&adpt_configuration_lock);
|
||||
for(i=0;i<DPTI_MAX_HBA;i++) {
|
||||
if(hbas[i]==NULL) {
|
||||
hbas[i]=pHba;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(hba_chain != NULL){
|
||||
for(p = hba_chain; p->next; p = p->next);
|
||||
@ -950,7 +942,7 @@ static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev
|
||||
}
|
||||
pHba->next = NULL;
|
||||
pHba->unit = hba_count;
|
||||
sprintf(pHba->name, "dpti%d", i);
|
||||
sprintf(pHba->name, "dpti%d", hba_count);
|
||||
hba_count++;
|
||||
|
||||
up(&adpt_configuration_lock);
|
||||
@ -1015,11 +1007,6 @@ static void adpt_i2o_delete_hba(adpt_hba* pHba)
|
||||
if(pHba->host){
|
||||
free_irq(pHba->host->irq, pHba);
|
||||
}
|
||||
for(i=0;i<DPTI_MAX_HBA;i++) {
|
||||
if(hbas[i]==pHba) {
|
||||
hbas[i] = NULL;
|
||||
}
|
||||
}
|
||||
p2 = NULL;
|
||||
for( p1 = hba_chain; p1; p2 = p1,p1=p1->next){
|
||||
if(p1 == pHba) {
|
||||
@ -1076,12 +1063,7 @@ static void adpt_i2o_delete_hba(adpt_hba* pHba)
|
||||
|
||||
static int adpt_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
printk("Loading Adaptec I2O RAID: Version " DPT_I2O_VERSION "\n");
|
||||
for (i = 0; i < DPTI_MAX_HBA; i++) {
|
||||
hbas[i] = NULL;
|
||||
}
|
||||
#ifdef REBOOT_NOTIFIER
|
||||
register_reboot_notifier(&adpt_reboot_notifier);
|
||||
#endif
|
||||
@ -1454,7 +1436,7 @@ static int adpt_i2o_parse_lct(adpt_hba* pHba)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
d->controller = (void*)pHba;
|
||||
d->controller = pHba;
|
||||
d->next = NULL;
|
||||
|
||||
memcpy(&d->lct_data, &lct->lct_entry[i], sizeof(i2o_lct_entry));
|
||||
@ -2000,7 +1982,7 @@ static irqreturn_t adpt_isr(int irq, void *dev_id, struct pt_regs *regs)
|
||||
struct scsi_cmnd* cmd;
|
||||
adpt_hba* pHba = dev_id;
|
||||
u32 m;
|
||||
ulong reply;
|
||||
void __iomem *reply;
|
||||
u32 status=0;
|
||||
u32 context;
|
||||
ulong flags = 0;
|
||||
@ -2025,11 +2007,11 @@ static irqreturn_t adpt_isr(int irq, void *dev_id, struct pt_regs *regs)
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
reply = (ulong)bus_to_virt(m);
|
||||
reply = bus_to_virt(m);
|
||||
|
||||
if (readl(reply) & MSG_FAIL) {
|
||||
u32 old_m = readl(reply+28);
|
||||
ulong msg;
|
||||
void __iomem *msg;
|
||||
u32 old_context;
|
||||
PDEBUG("%s: Failed message\n",pHba->name);
|
||||
if(old_m >= 0x100000){
|
||||
@ -2038,16 +2020,16 @@ static irqreturn_t adpt_isr(int irq, void *dev_id, struct pt_regs *regs)
|
||||
continue;
|
||||
}
|
||||
// Transaction context is 0 in failed reply frame
|
||||
msg = (ulong)(pHba->msg_addr_virt + old_m);
|
||||
msg = pHba->msg_addr_virt + old_m;
|
||||
old_context = readl(msg+12);
|
||||
writel(old_context, reply+12);
|
||||
adpt_send_nop(pHba, old_m);
|
||||
}
|
||||
context = readl(reply+8);
|
||||
if(context & 0x40000000){ // IOCTL
|
||||
ulong p = (ulong)(readl(reply+12));
|
||||
if( p != 0) {
|
||||
memcpy((void*)p, (void*)reply, REPLY_FRAME_SIZE * 4);
|
||||
void *p = (void *)readl(reply+12);
|
||||
if( p != NULL) {
|
||||
memcpy_fromio(p, reply, REPLY_FRAME_SIZE * 4);
|
||||
}
|
||||
// All IOCTLs will also be post wait
|
||||
}
|
||||
@ -2231,7 +2213,7 @@ static s32 adpt_scsi_register(adpt_hba* pHba,struct scsi_host_template * sht)
|
||||
}
|
||||
|
||||
|
||||
static s32 adpt_i2o_to_scsi(ulong reply, struct scsi_cmnd* cmd)
|
||||
static s32 adpt_i2o_to_scsi(void __iomem *reply, struct scsi_cmnd* cmd)
|
||||
{
|
||||
adpt_hba* pHba;
|
||||
u32 hba_status;
|
||||
@ -2323,7 +2305,7 @@ static s32 adpt_i2o_to_scsi(ulong reply, struct scsi_cmnd* cmd)
|
||||
u32 len = sizeof(cmd->sense_buffer);
|
||||
len = (len > 40) ? 40 : len;
|
||||
// Copy over the sense data
|
||||
memcpy(cmd->sense_buffer, (void*)(reply+28) , len);
|
||||
memcpy_fromio(cmd->sense_buffer, (reply+28) , len);
|
||||
if(cmd->sense_buffer[0] == 0x70 /* class 7 */ &&
|
||||
cmd->sense_buffer[2] == DATA_PROTECT ){
|
||||
/* This is to handle an array failed */
|
||||
@ -2438,7 +2420,7 @@ static s32 adpt_i2o_reparse_lct(adpt_hba* pHba)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
d->controller = (void*)pHba;
|
||||
d->controller = pHba;
|
||||
d->next = NULL;
|
||||
|
||||
memcpy(&d->lct_data, &lct->lct_entry[i], sizeof(i2o_lct_entry));
|
||||
@ -2985,8 +2967,8 @@ static int adpt_i2o_build_sys_table(void)
|
||||
sys_tbl->iops[count].frame_size = pHba->status_block->inbound_frame_size;
|
||||
sys_tbl->iops[count].last_changed = sys_tbl_ind - 1; // ??
|
||||
sys_tbl->iops[count].iop_capabilities = pHba->status_block->iop_capabilities;
|
||||
sys_tbl->iops[count].inbound_low = (u32)virt_to_bus((void*)pHba->post_port);
|
||||
sys_tbl->iops[count].inbound_high = (u32)((u64)virt_to_bus((void*)pHba->post_port)>>32);
|
||||
sys_tbl->iops[count].inbound_low = (u32)virt_to_bus(pHba->post_port);
|
||||
sys_tbl->iops[count].inbound_high = (u32)((u64)virt_to_bus(pHba->post_port)>>32);
|
||||
|
||||
count++;
|
||||
}
|
||||
|
@ -296,7 +296,7 @@ static s32 adpt_i2o_status_get(adpt_hba* pHba);
|
||||
static s32 adpt_i2o_init_outbound_q(adpt_hba* pHba);
|
||||
static s32 adpt_i2o_hrt_get(adpt_hba* pHba);
|
||||
static s32 adpt_scsi_to_i2o(adpt_hba* pHba, struct scsi_cmnd* cmd, struct adpt_device* dptdevice);
|
||||
static s32 adpt_i2o_to_scsi(ulong reply, struct scsi_cmnd* cmd);
|
||||
static s32 adpt_i2o_to_scsi(void __iomem *reply, struct scsi_cmnd* cmd);
|
||||
static s32 adpt_scsi_register(adpt_hba* pHba,struct scsi_host_template * sht);
|
||||
static s32 adpt_hba_reset(adpt_hba* pHba);
|
||||
static s32 adpt_i2o_reset_hba(adpt_hba* pHba);
|
||||
|
@ -1053,7 +1053,7 @@ static void ipr_log_array_error(struct ipr_ioa_cfg *ioa_cfg,
|
||||
array_entry->dev_res_addr.lun);
|
||||
}
|
||||
|
||||
if (array_entry->dev_res_addr.bus >= IPR_MAX_NUM_BUSES) {
|
||||
if (array_entry->expected_dev_res_addr.bus >= IPR_MAX_NUM_BUSES) {
|
||||
ipr_err("Expected Location: unknown\n");
|
||||
} else {
|
||||
ipr_err("Expected Location: %d:%d:%d:%d\n",
|
||||
@ -5886,6 +5886,7 @@ static void __ipr_remove(struct pci_dev *pdev)
|
||||
|
||||
spin_unlock_irqrestore(ioa_cfg->host->host_lock, host_lock_flags);
|
||||
wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload);
|
||||
flush_scheduled_work();
|
||||
spin_lock_irqsave(ioa_cfg->host->host_lock, host_lock_flags);
|
||||
|
||||
spin_lock(&ipr_driver_lock);
|
||||
@ -5916,8 +5917,6 @@ static void ipr_remove(struct pci_dev *pdev)
|
||||
|
||||
ENTER;
|
||||
|
||||
ioa_cfg->allow_cmds = 0;
|
||||
flush_scheduled_work();
|
||||
ipr_remove_trace_file(&ioa_cfg->host->shost_classdev.kobj,
|
||||
&ipr_trace_attr);
|
||||
ipr_remove_dump_file(&ioa_cfg->host->shost_classdev.kobj,
|
||||
|
@ -36,8 +36,8 @@
|
||||
/*
|
||||
* Literals
|
||||
*/
|
||||
#define IPR_DRIVER_VERSION "2.0.13"
|
||||
#define IPR_DRIVER_DATE "(February 21, 2005)"
|
||||
#define IPR_DRIVER_VERSION "2.0.14"
|
||||
#define IPR_DRIVER_DATE "(May 2, 2005)"
|
||||
|
||||
/*
|
||||
* IPR_DBG_TRACE: Setting this to 1 will turn on some general function tracing
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include <linux/list.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <asm/semaphore.h>
|
||||
#include <scsi/scsi.h>
|
||||
#include <scsi/scsi_cmnd.h>
|
||||
|
@ -10,7 +10,7 @@
|
||||
* 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FILE : megaraid_mbox.c
|
||||
* Version : v2.20.4.5 (Feb 03 2005)
|
||||
* Version : v2.20.4.6 (Mar 07 2005)
|
||||
*
|
||||
* Authors:
|
||||
* Atul Mukker <Atul.Mukker@lsil.com>
|
||||
@ -202,7 +202,7 @@ MODULE_PARM_DESC(debug_level, "Debug level for driver (default=0)");
|
||||
* ### global data ###
|
||||
*/
|
||||
static uint8_t megaraid_mbox_version[8] =
|
||||
{ 0x02, 0x20, 0x04, 0x05, 2, 3, 20, 5 };
|
||||
{ 0x02, 0x20, 0x04, 0x06, 3, 7, 20, 5 };
|
||||
|
||||
|
||||
/*
|
||||
@ -229,9 +229,9 @@ static struct pci_device_id pci_id_table_g[] = {
|
||||
},
|
||||
{
|
||||
PCI_VENDOR_ID_LSI_LOGIC,
|
||||
PCI_DEVICE_ID_PERC4_QC,
|
||||
PCI_VENDOR_ID_DELL,
|
||||
PCI_SUBSYS_ID_PERC4_QC,
|
||||
PCI_DEVICE_ID_VERDE,
|
||||
PCI_ANY_ID,
|
||||
PCI_ANY_ID,
|
||||
},
|
||||
{
|
||||
PCI_VENDOR_ID_DELL,
|
||||
@ -271,15 +271,9 @@ static struct pci_device_id pci_id_table_g[] = {
|
||||
},
|
||||
{
|
||||
PCI_VENDOR_ID_LSI_LOGIC,
|
||||
PCI_DEVICE_ID_PERC4E_DC_320_2E,
|
||||
PCI_VENDOR_ID_DELL,
|
||||
PCI_SUBSYS_ID_PERC4E_DC_320_2E,
|
||||
},
|
||||
{
|
||||
PCI_VENDOR_ID_LSI_LOGIC,
|
||||
PCI_DEVICE_ID_PERC4E_SC_320_1E,
|
||||
PCI_VENDOR_ID_DELL,
|
||||
PCI_SUBSYS_ID_PERC4E_SC_320_1E,
|
||||
PCI_DEVICE_ID_DOBSON,
|
||||
PCI_ANY_ID,
|
||||
PCI_ANY_ID,
|
||||
},
|
||||
{
|
||||
PCI_VENDOR_ID_AMI,
|
||||
@ -329,36 +323,6 @@ static struct pci_device_id pci_id_table_g[] = {
|
||||
PCI_VENDOR_ID_LSI_LOGIC,
|
||||
PCI_SUBSYS_ID_MEGARAID_SCSI_320_2,
|
||||
},
|
||||
{
|
||||
PCI_VENDOR_ID_LSI_LOGIC,
|
||||
PCI_DEVICE_ID_MEGARAID_SCSI_320_0x,
|
||||
PCI_VENDOR_ID_LSI_LOGIC,
|
||||
PCI_SUBSYS_ID_MEGARAID_SCSI_320_0x,
|
||||
},
|
||||
{
|
||||
PCI_VENDOR_ID_LSI_LOGIC,
|
||||
PCI_DEVICE_ID_MEGARAID_SCSI_320_2x,
|
||||
PCI_VENDOR_ID_LSI_LOGIC,
|
||||
PCI_SUBSYS_ID_MEGARAID_SCSI_320_2x,
|
||||
},
|
||||
{
|
||||
PCI_VENDOR_ID_LSI_LOGIC,
|
||||
PCI_DEVICE_ID_MEGARAID_SCSI_320_4x,
|
||||
PCI_VENDOR_ID_LSI_LOGIC,
|
||||
PCI_SUBSYS_ID_MEGARAID_SCSI_320_4x,
|
||||
},
|
||||
{
|
||||
PCI_VENDOR_ID_LSI_LOGIC,
|
||||
PCI_DEVICE_ID_MEGARAID_SCSI_320_1E,
|
||||
PCI_VENDOR_ID_LSI_LOGIC,
|
||||
PCI_SUBSYS_ID_MEGARAID_SCSI_320_1E,
|
||||
},
|
||||
{
|
||||
PCI_VENDOR_ID_LSI_LOGIC,
|
||||
PCI_DEVICE_ID_MEGARAID_SCSI_320_2E,
|
||||
PCI_VENDOR_ID_LSI_LOGIC,
|
||||
PCI_SUBSYS_ID_MEGARAID_SCSI_320_2E,
|
||||
},
|
||||
{
|
||||
PCI_VENDOR_ID_LSI_LOGIC,
|
||||
PCI_DEVICE_ID_MEGARAID_I4_133_RAID,
|
||||
@ -379,21 +343,9 @@ static struct pci_device_id pci_id_table_g[] = {
|
||||
},
|
||||
{
|
||||
PCI_VENDOR_ID_LSI_LOGIC,
|
||||
PCI_DEVICE_ID_MEGARAID_SATA_300_4x,
|
||||
PCI_VENDOR_ID_LSI_LOGIC,
|
||||
PCI_SUBSYS_ID_MEGARAID_SATA_300_4x,
|
||||
},
|
||||
{
|
||||
PCI_VENDOR_ID_LSI_LOGIC,
|
||||
PCI_DEVICE_ID_MEGARAID_SATA_300_8x,
|
||||
PCI_VENDOR_ID_LSI_LOGIC,
|
||||
PCI_SUBSYS_ID_MEGARAID_SATA_300_8x,
|
||||
},
|
||||
{
|
||||
PCI_VENDOR_ID_LSI_LOGIC,
|
||||
PCI_DEVICE_ID_INTEL_RAID_SRCU42X,
|
||||
PCI_VENDOR_ID_INTEL,
|
||||
PCI_SUBSYS_ID_INTEL_RAID_SRCU42X,
|
||||
PCI_DEVICE_ID_LINDSAY,
|
||||
PCI_ANY_ID,
|
||||
PCI_ANY_ID,
|
||||
},
|
||||
{
|
||||
PCI_VENDOR_ID_LSI_LOGIC,
|
||||
@ -401,60 +353,12 @@ static struct pci_device_id pci_id_table_g[] = {
|
||||
PCI_VENDOR_ID_INTEL,
|
||||
PCI_SUBSYS_ID_INTEL_RAID_SRCS16,
|
||||
},
|
||||
{
|
||||
PCI_VENDOR_ID_LSI_LOGIC,
|
||||
PCI_DEVICE_ID_INTEL_RAID_SRCU42E,
|
||||
PCI_VENDOR_ID_INTEL,
|
||||
PCI_SUBSYS_ID_INTEL_RAID_SRCU42E,
|
||||
},
|
||||
{
|
||||
PCI_VENDOR_ID_LSI_LOGIC,
|
||||
PCI_DEVICE_ID_INTEL_RAID_SRCZCRX,
|
||||
PCI_VENDOR_ID_INTEL,
|
||||
PCI_SUBSYS_ID_INTEL_RAID_SRCZCRX,
|
||||
},
|
||||
{
|
||||
PCI_VENDOR_ID_LSI_LOGIC,
|
||||
PCI_DEVICE_ID_INTEL_RAID_SRCS28X,
|
||||
PCI_VENDOR_ID_INTEL,
|
||||
PCI_SUBSYS_ID_INTEL_RAID_SRCS28X,
|
||||
},
|
||||
{
|
||||
PCI_VENDOR_ID_LSI_LOGIC,
|
||||
PCI_DEVICE_ID_INTEL_RAID_SROMBU42E_ALIEF,
|
||||
PCI_VENDOR_ID_INTEL,
|
||||
PCI_SUBSYS_ID_INTEL_RAID_SROMBU42E_ALIEF,
|
||||
},
|
||||
{
|
||||
PCI_VENDOR_ID_LSI_LOGIC,
|
||||
PCI_DEVICE_ID_INTEL_RAID_SROMBU42E_HARWICH,
|
||||
PCI_VENDOR_ID_INTEL,
|
||||
PCI_SUBSYS_ID_INTEL_RAID_SROMBU42E_HARWICH,
|
||||
},
|
||||
{
|
||||
PCI_VENDOR_ID_LSI_LOGIC,
|
||||
PCI_DEVICE_ID_INTEL_RAID_SRCU41L_LAKE_SHETEK,
|
||||
PCI_VENDOR_ID_INTEL,
|
||||
PCI_SUBSYS_ID_INTEL_RAID_SRCU41L_LAKE_SHETEK,
|
||||
},
|
||||
{
|
||||
PCI_VENDOR_ID_LSI_LOGIC,
|
||||
PCI_DEVICE_ID_FSC_MEGARAID_PCI_EXPRESS_ROMB,
|
||||
PCI_SUBSYS_ID_FSC,
|
||||
PCI_SUBSYS_ID_FSC_MEGARAID_PCI_EXPRESS_ROMB,
|
||||
},
|
||||
{
|
||||
PCI_VENDOR_ID_LSI_LOGIC,
|
||||
PCI_DEVICE_ID_MEGARAID_ACER_ROMB_2E,
|
||||
PCI_VENDOR_ID_AI,
|
||||
PCI_SUBSYS_ID_MEGARAID_ACER_ROMB_2E,
|
||||
},
|
||||
{
|
||||
PCI_VENDOR_ID_LSI_LOGIC,
|
||||
PCI_DEVICE_ID_MEGARAID_NEC_ROMB_2E,
|
||||
PCI_VENDOR_ID_NEC,
|
||||
PCI_SUBSYS_ID_MEGARAID_NEC_ROMB_2E,
|
||||
},
|
||||
{0} /* Terminating entry */
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, pci_id_table_g);
|
||||
@ -539,7 +443,8 @@ megaraid_init(void)
|
||||
|
||||
|
||||
// register as a PCI hot-plug driver module
|
||||
if ((rval = pci_module_init(&megaraid_pci_driver_g))) {
|
||||
rval = pci_register_driver(&megaraid_pci_driver_g);
|
||||
if (rval < 0) {
|
||||
con_log(CL_ANN, (KERN_WARNING
|
||||
"megaraid: could not register hotplug support.\n"));
|
||||
}
|
||||
@ -619,7 +524,7 @@ megaraid_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
|
||||
// Setup the default DMA mask. This would be changed later on
|
||||
// depending on hardware capabilities
|
||||
if (pci_set_dma_mask(adapter->pdev, 0xFFFFFFFF) != 0) {
|
||||
if (pci_set_dma_mask(adapter->pdev, DMA_32BIT_MASK) != 0) {
|
||||
|
||||
con_log(CL_ANN, (KERN_WARNING
|
||||
"megaraid: pci_set_dma_mask failed:%d\n", __LINE__));
|
||||
@ -1031,7 +936,7 @@ megaraid_init_mbox(adapter_t *adapter)
|
||||
|
||||
// Set the DMA mask to 64-bit. All supported controllers as capable of
|
||||
// DMA in this range
|
||||
if (pci_set_dma_mask(adapter->pdev, 0xFFFFFFFFFFFFFFFFULL) != 0) {
|
||||
if (pci_set_dma_mask(adapter->pdev, DMA_64BIT_MASK) != 0) {
|
||||
|
||||
con_log(CL_ANN, (KERN_WARNING
|
||||
"megaraid: could not set DMA mask for 64-bit.\n"));
|
||||
|
@ -21,8 +21,8 @@
|
||||
#include "megaraid_ioctl.h"
|
||||
|
||||
|
||||
#define MEGARAID_VERSION "2.20.4.5"
|
||||
#define MEGARAID_EXT_VERSION "(Release Date: Thu Feb 03 12:27:22 EST 2005)"
|
||||
#define MEGARAID_VERSION "2.20.4.6"
|
||||
#define MEGARAID_EXT_VERSION "(Release Date: Mon Mar 07 12:27:22 EST 2005)"
|
||||
|
||||
|
||||
/*
|
||||
@ -37,8 +37,7 @@
|
||||
#define PCI_DEVICE_ID_PERC4_DC 0x1960
|
||||
#define PCI_SUBSYS_ID_PERC4_DC 0x0518
|
||||
|
||||
#define PCI_DEVICE_ID_PERC4_QC 0x0407
|
||||
#define PCI_SUBSYS_ID_PERC4_QC 0x0531
|
||||
#define PCI_DEVICE_ID_VERDE 0x0407
|
||||
|
||||
#define PCI_DEVICE_ID_PERC4_DI_EVERGLADES 0x000F
|
||||
#define PCI_SUBSYS_ID_PERC4_DI_EVERGLADES 0x014A
|
||||
@ -58,11 +57,7 @@
|
||||
#define PCI_DEVICE_ID_PERC4E_DI_GUADALUPE 0x0013
|
||||
#define PCI_SUBSYS_ID_PERC4E_DI_GUADALUPE 0x0170
|
||||
|
||||
#define PCI_DEVICE_ID_PERC4E_DC_320_2E 0x0408
|
||||
#define PCI_SUBSYS_ID_PERC4E_DC_320_2E 0x0002
|
||||
|
||||
#define PCI_DEVICE_ID_PERC4E_SC_320_1E 0x0408
|
||||
#define PCI_SUBSYS_ID_PERC4E_SC_320_1E 0x0001
|
||||
#define PCI_DEVICE_ID_DOBSON 0x0408
|
||||
|
||||
#define PCI_DEVICE_ID_MEGARAID_SCSI_320_0 0x1960
|
||||
#define PCI_SUBSYS_ID_MEGARAID_SCSI_320_0 0xA520
|
||||
@ -73,21 +68,6 @@
|
||||
#define PCI_DEVICE_ID_MEGARAID_SCSI_320_2 0x1960
|
||||
#define PCI_SUBSYS_ID_MEGARAID_SCSI_320_2 0x0518
|
||||
|
||||
#define PCI_DEVICE_ID_MEGARAID_SCSI_320_0x 0x0407
|
||||
#define PCI_SUBSYS_ID_MEGARAID_SCSI_320_0x 0x0530
|
||||
|
||||
#define PCI_DEVICE_ID_MEGARAID_SCSI_320_2x 0x0407
|
||||
#define PCI_SUBSYS_ID_MEGARAID_SCSI_320_2x 0x0532
|
||||
|
||||
#define PCI_DEVICE_ID_MEGARAID_SCSI_320_4x 0x0407
|
||||
#define PCI_SUBSYS_ID_MEGARAID_SCSI_320_4x 0x0531
|
||||
|
||||
#define PCI_DEVICE_ID_MEGARAID_SCSI_320_1E 0x0408
|
||||
#define PCI_SUBSYS_ID_MEGARAID_SCSI_320_1E 0x0001
|
||||
|
||||
#define PCI_DEVICE_ID_MEGARAID_SCSI_320_2E 0x0408
|
||||
#define PCI_SUBSYS_ID_MEGARAID_SCSI_320_2E 0x0002
|
||||
|
||||
#define PCI_DEVICE_ID_MEGARAID_I4_133_RAID 0x1960
|
||||
#define PCI_SUBSYS_ID_MEGARAID_I4_133_RAID 0x0522
|
||||
|
||||
@ -97,52 +77,18 @@
|
||||
#define PCI_DEVICE_ID_MEGARAID_SATA_150_6 0x1960
|
||||
#define PCI_SUBSYS_ID_MEGARAID_SATA_150_6 0x0523
|
||||
|
||||
#define PCI_DEVICE_ID_MEGARAID_SATA_300_4x 0x0409
|
||||
#define PCI_SUBSYS_ID_MEGARAID_SATA_300_4x 0x3004
|
||||
|
||||
#define PCI_DEVICE_ID_MEGARAID_SATA_300_8x 0x0409
|
||||
#define PCI_SUBSYS_ID_MEGARAID_SATA_300_8x 0x3008
|
||||
|
||||
#define PCI_DEVICE_ID_INTEL_RAID_SRCU42X 0x0407
|
||||
#define PCI_SUBSYS_ID_INTEL_RAID_SRCU42X 0x0532
|
||||
#define PCI_DEVICE_ID_LINDSAY 0x0409
|
||||
|
||||
#define PCI_DEVICE_ID_INTEL_RAID_SRCS16 0x1960
|
||||
#define PCI_SUBSYS_ID_INTEL_RAID_SRCS16 0x0523
|
||||
|
||||
#define PCI_DEVICE_ID_INTEL_RAID_SRCU42E 0x0408
|
||||
#define PCI_SUBSYS_ID_INTEL_RAID_SRCU42E 0x0002
|
||||
|
||||
#define PCI_DEVICE_ID_INTEL_RAID_SRCZCRX 0x0407
|
||||
#define PCI_SUBSYS_ID_INTEL_RAID_SRCZCRX 0x0530
|
||||
|
||||
#define PCI_DEVICE_ID_INTEL_RAID_SRCS28X 0x0409
|
||||
#define PCI_SUBSYS_ID_INTEL_RAID_SRCS28X 0x3008
|
||||
|
||||
#define PCI_DEVICE_ID_INTEL_RAID_SROMBU42E_ALIEF 0x0408
|
||||
#define PCI_SUBSYS_ID_INTEL_RAID_SROMBU42E_ALIEF 0x3431
|
||||
|
||||
#define PCI_DEVICE_ID_INTEL_RAID_SROMBU42E_HARWICH 0x0408
|
||||
#define PCI_SUBSYS_ID_INTEL_RAID_SROMBU42E_HARWICH 0x3499
|
||||
|
||||
#define PCI_DEVICE_ID_INTEL_RAID_SRCU41L_LAKE_SHETEK 0x1960
|
||||
#define PCI_SUBSYS_ID_INTEL_RAID_SRCU41L_LAKE_SHETEK 0x0520
|
||||
|
||||
#define PCI_DEVICE_ID_FSC_MEGARAID_PCI_EXPRESS_ROMB 0x0408
|
||||
#define PCI_SUBSYS_ID_FSC_MEGARAID_PCI_EXPRESS_ROMB 0x1065
|
||||
|
||||
#define PCI_DEVICE_ID_MEGARAID_ACER_ROMB_2E 0x0408
|
||||
#define PCI_SUBSYS_ID_MEGARAID_ACER_ROMB_2E 0x004D
|
||||
|
||||
#define PCI_SUBSYS_ID_PERC3_QC 0x0471
|
||||
#define PCI_SUBSYS_ID_PERC3_DC 0x0493
|
||||
#define PCI_SUBSYS_ID_PERC3_SC 0x0475
|
||||
|
||||
#define PCI_DEVICE_ID_MEGARAID_NEC_ROMB_2E 0x0408
|
||||
#define PCI_SUBSYS_ID_MEGARAID_NEC_ROMB_2E 0x8287
|
||||
|
||||
#ifndef PCI_SUBSYS_ID_FSC
|
||||
#define PCI_SUBSYS_ID_FSC 0x1734
|
||||
#endif
|
||||
|
||||
#define MBOX_MAX_SCSI_CMDS 128 // number of cmds reserved for kernel
|
||||
#define MBOX_MAX_USER_CMDS 32 // number of cmds for applications
|
||||
|
@ -10,13 +10,12 @@
|
||||
* 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FILE : megaraid_mm.c
|
||||
* Version : v2.20.2.5 (Jan 21 2005)
|
||||
* Version : v2.20.2.6 (Mar 7 2005)
|
||||
*
|
||||
* Common management module
|
||||
*/
|
||||
|
||||
#include "megaraid_mm.h"
|
||||
#include <linux/smp_lock.h>
|
||||
|
||||
|
||||
// Entry points for char node driver
|
||||
@ -61,7 +60,7 @@ EXPORT_SYMBOL(mraid_mm_unregister_adp);
|
||||
EXPORT_SYMBOL(mraid_mm_adapter_app_handle);
|
||||
|
||||
static int majorno;
|
||||
static uint32_t drvr_ver = 0x02200201;
|
||||
static uint32_t drvr_ver = 0x02200206;
|
||||
|
||||
static int adapters_count_g;
|
||||
static struct list_head adapters_list_g;
|
||||
@ -1231,9 +1230,9 @@ mraid_mm_compat_ioctl(struct file *filep, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
int err;
|
||||
lock_kernel();
|
||||
|
||||
err = mraid_mm_ioctl(NULL, filep, cmd, arg);
|
||||
unlock_kernel();
|
||||
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
|
@ -29,9 +29,9 @@
|
||||
#include "megaraid_ioctl.h"
|
||||
|
||||
|
||||
#define LSI_COMMON_MOD_VERSION "2.20.2.5"
|
||||
#define LSI_COMMON_MOD_VERSION "2.20.2.6"
|
||||
#define LSI_COMMON_MOD_EXT_VERSION \
|
||||
"(Release Date: Fri Jan 21 00:01:03 EST 2005)"
|
||||
"(Release Date: Mon Mar 7 00:01:03 EST 2005)"
|
||||
|
||||
|
||||
#define LSI_DBGLVL dbglevel
|
||||
|
@ -1,836 +0,0 @@
|
||||
/****************************************************************************
|
||||
* Perceptive Solutions, Inc. PCI-2000 device driver for Linux.
|
||||
*
|
||||
* pci2000.c - Linux Host Driver for PCI-2000 IntelliCache SCSI Adapters
|
||||
*
|
||||
* Copyright (c) 1997-1999 Perceptive Solutions, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that redistributions of source
|
||||
* code retain the above copyright notice and this comment without
|
||||
* modification.
|
||||
*
|
||||
* Technical updates and product information at:
|
||||
* http://www.psidisk.com
|
||||
*
|
||||
* Please send questions, comments, bug reports to:
|
||||
* tech@psidisk.com Technical Support
|
||||
*
|
||||
*
|
||||
* Revisions 1.10 Jan-21-1999
|
||||
* - Fixed sign on message to reflect proper controller name.
|
||||
* - Added support for RAID status monitoring and control.
|
||||
*
|
||||
* Revisions 1.11 Mar-22-1999
|
||||
* - Fixed control timeout to not lock up the entire system if
|
||||
* controller goes offline completely.
|
||||
*
|
||||
* Revisions 1.12 Mar-26-1999
|
||||
* - Fixed spinlock and PCI configuration.
|
||||
*
|
||||
* Revisions 1.20 Mar-27-2000
|
||||
* - Added support for dynamic DMA
|
||||
*
|
||||
****************************************************************************/
|
||||
#define PCI2000_VERSION "1.20"
|
||||
|
||||
#include <linux/blkdev.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/stat.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
#include <asm/dma.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
#include "scsi.h"
|
||||
#include <scsi/scsi_host.h>
|
||||
#include "pci2000.h"
|
||||
#include "psi_roy.h"
|
||||
|
||||
|
||||
//#define DEBUG 1
|
||||
|
||||
#ifdef DEBUG
|
||||
#define DEB(x) x
|
||||
#define STOP_HERE {int st;for(st=0;st<100;st++){st=1;}}
|
||||
#else
|
||||
#define DEB(x)
|
||||
#define STOP_HERE
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned int address;
|
||||
unsigned int length;
|
||||
} SCATGATH, *PSCATGATH;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Scsi_Cmnd *SCpnt;
|
||||
PSCATGATH scatGath;
|
||||
dma_addr_t scatGathDma;
|
||||
UCHAR *cdb;
|
||||
dma_addr_t cdbDma;
|
||||
UCHAR tag;
|
||||
} DEV2000, *PDEV2000;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ULONG basePort;
|
||||
ULONG mb0;
|
||||
ULONG mb1;
|
||||
ULONG mb2;
|
||||
ULONG mb3;
|
||||
ULONG mb4;
|
||||
ULONG cmd;
|
||||
ULONG tag;
|
||||
ULONG irqOwned;
|
||||
struct pci_dev *pdev;
|
||||
DEV2000 dev[MAX_BUS][MAX_UNITS];
|
||||
} ADAPTER2000, *PADAPTER2000;
|
||||
|
||||
#define HOSTDATA(host) ((PADAPTER2000)&host->hostdata)
|
||||
#define consistentLen (MAX_BUS * MAX_UNITS * (16 * sizeof (SCATGATH) + MAX_COMMAND_SIZE))
|
||||
|
||||
|
||||
static struct Scsi_Host *PsiHost[MAXADAPTER] = {NULL,}; // One for each adapter
|
||||
static int NumAdapters = 0;
|
||||
/****************************************************************
|
||||
* Name: WaitReady :LOCAL
|
||||
*
|
||||
* Description: Wait for controller ready.
|
||||
*
|
||||
* Parameters: padapter - Pointer adapter data structure.
|
||||
*
|
||||
* Returns: TRUE on not ready.
|
||||
*
|
||||
****************************************************************/
|
||||
static int WaitReady (PADAPTER2000 padapter)
|
||||
{
|
||||
ULONG z;
|
||||
|
||||
for ( z = 0; z < (TIMEOUT_COMMAND * 4); z++ )
|
||||
{
|
||||
if ( !inb_p (padapter->cmd) )
|
||||
return FALSE;
|
||||
udelay (250);
|
||||
};
|
||||
return TRUE;
|
||||
}
|
||||
/****************************************************************
|
||||
* Name: WaitReadyLong :LOCAL
|
||||
*
|
||||
* Description: Wait for controller ready.
|
||||
*
|
||||
* Parameters: padapter - Pointer adapter data structure.
|
||||
*
|
||||
* Returns: TRUE on not ready.
|
||||
*
|
||||
****************************************************************/
|
||||
static int WaitReadyLong (PADAPTER2000 padapter)
|
||||
{
|
||||
ULONG z;
|
||||
|
||||
for ( z = 0; z < (5000 * 4); z++ )
|
||||
{
|
||||
if ( !inb_p (padapter->cmd) )
|
||||
return FALSE;
|
||||
udelay (250);
|
||||
};
|
||||
return TRUE;
|
||||
}
|
||||
/****************************************************************
|
||||
* Name: OpDone :LOCAL
|
||||
*
|
||||
* Description: Clean up operation and issue done to caller.
|
||||
*
|
||||
* Parameters: SCpnt - Pointer to SCSI command structure.
|
||||
* status - Caller status.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
****************************************************************/
|
||||
static void OpDone (Scsi_Cmnd *SCpnt, ULONG status)
|
||||
{
|
||||
SCpnt->result = status;
|
||||
SCpnt->scsi_done (SCpnt);
|
||||
}
|
||||
/****************************************************************
|
||||
* Name: Command :LOCAL
|
||||
*
|
||||
* Description: Issue queued command to the PCI-2000.
|
||||
*
|
||||
* Parameters: padapter - Pointer to adapter information structure.
|
||||
* cmd - PCI-2000 command byte.
|
||||
*
|
||||
* Returns: Non-zero command tag if operation is accepted.
|
||||
*
|
||||
****************************************************************/
|
||||
static UCHAR Command (PADAPTER2000 padapter, UCHAR cmd)
|
||||
{
|
||||
outb_p (cmd, padapter->cmd);
|
||||
if ( WaitReady (padapter) )
|
||||
return 0;
|
||||
|
||||
if ( inw_p (padapter->mb0) )
|
||||
return 0;
|
||||
|
||||
return inb_p (padapter->mb1);
|
||||
}
|
||||
/****************************************************************
|
||||
* Name: BuildSgList :LOCAL
|
||||
*
|
||||
* Description: Build the scatter gather list for controller.
|
||||
*
|
||||
* Parameters: SCpnt - Pointer to SCSI command structure.
|
||||
* padapter - Pointer to adapter information structure.
|
||||
* pdev - Pointer to adapter device structure.
|
||||
*
|
||||
* Returns: Non-zero in not scatter gather.
|
||||
*
|
||||
****************************************************************/
|
||||
static int BuildSgList (Scsi_Cmnd *SCpnt, PADAPTER2000 padapter, PDEV2000 pdev)
|
||||
{
|
||||
int z;
|
||||
int zc;
|
||||
struct scatterlist *sg;
|
||||
|
||||
if ( SCpnt->use_sg )
|
||||
{
|
||||
sg = (struct scatterlist *)SCpnt->request_buffer;
|
||||
zc = pci_map_sg (padapter->pdev, sg, SCpnt->use_sg, SCpnt->sc_data_direction);
|
||||
for ( z = 0; z < zc; z++ )
|
||||
{
|
||||
pdev->scatGath[z].address = cpu_to_le32 (sg_dma_address (sg));
|
||||
pdev->scatGath[z].length = cpu_to_le32 (sg_dma_len (sg++));
|
||||
}
|
||||
outl (pdev->scatGathDma, padapter->mb2);
|
||||
outl ((zc << 24) | SCpnt->request_bufflen, padapter->mb3);
|
||||
return FALSE;
|
||||
}
|
||||
if ( !SCpnt->request_bufflen)
|
||||
{
|
||||
outl (0, padapter->mb2);
|
||||
outl (0, padapter->mb3);
|
||||
return TRUE;
|
||||
}
|
||||
SCpnt->SCp.have_data_in = pci_map_single (padapter->pdev,
|
||||
SCpnt->request_buffer, SCpnt->request_bufflen,
|
||||
SCpnt->sc_data_direction);
|
||||
outl (SCpnt->SCp.have_data_in, padapter->mb2);
|
||||
outl (SCpnt->request_bufflen, padapter->mb3);
|
||||
return TRUE;
|
||||
}
|
||||
/*********************************************************************
|
||||
* Name: PsiRaidCmd
|
||||
*
|
||||
* Description: Execute a simple command.
|
||||
*
|
||||
* Parameters: padapter - Pointer to adapter control structure.
|
||||
* cmd - Roy command byte.
|
||||
*
|
||||
* Returns: Return error status.
|
||||
*
|
||||
********************************************************************/
|
||||
static int PsiRaidCmd (PADAPTER2000 padapter, char cmd)
|
||||
{
|
||||
if ( WaitReady (padapter) ) // test for command register ready
|
||||
return DID_TIME_OUT;
|
||||
outb_p (cmd, padapter->cmd); // issue command
|
||||
if ( WaitReadyLong (padapter) ) // wait for adapter ready
|
||||
return DID_TIME_OUT;
|
||||
return DID_OK;
|
||||
}
|
||||
/****************************************************************
|
||||
* Name: Irq_Handler :LOCAL
|
||||
*
|
||||
* Description: Interrupt handler.
|
||||
*
|
||||
* Parameters: irq - Hardware IRQ number.
|
||||
* dev_id -
|
||||
* regs -
|
||||
*
|
||||
* Returns: TRUE if drive is not ready in time.
|
||||
*
|
||||
****************************************************************/
|
||||
static irqreturn_t Irq_Handler (int irq, void *dev_id, struct pt_regs *regs)
|
||||
{
|
||||
struct Scsi_Host *shost = NULL; // Pointer to host data block
|
||||
PADAPTER2000 padapter; // Pointer to adapter control structure
|
||||
PDEV2000 pdev;
|
||||
Scsi_Cmnd *SCpnt;
|
||||
UCHAR tag = 0;
|
||||
UCHAR tag0;
|
||||
ULONG error;
|
||||
int pun;
|
||||
int bus;
|
||||
int z;
|
||||
unsigned long flags;
|
||||
int handled = 0;
|
||||
|
||||
DEB(printk ("\npci2000 received interrupt "));
|
||||
for ( z = 0; z < NumAdapters; z++ ) // scan for interrupt to process
|
||||
{
|
||||
if ( PsiHost[z]->irq == (UCHAR)(irq & 0xFF) )
|
||||
{
|
||||
tag = inb_p (HOSTDATA(PsiHost[z])->tag);
|
||||
if ( tag )
|
||||
{
|
||||
shost = PsiHost[z];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( !shost )
|
||||
{
|
||||
DEB (printk ("\npci2000: not my interrupt"));
|
||||
goto out;
|
||||
}
|
||||
|
||||
handled = 1;
|
||||
spin_lock_irqsave(shost->host_lock, flags);
|
||||
padapter = HOSTDATA(shost);
|
||||
|
||||
tag0 = tag & 0x7F; // mask off the error bit
|
||||
for ( bus = 0; bus < MAX_BUS; bus++ ) // scan the busses
|
||||
{
|
||||
for ( pun = 0; pun < MAX_UNITS; pun++ ) // scan the targets
|
||||
{
|
||||
pdev = &padapter->dev[bus][pun];
|
||||
if ( !pdev->tag )
|
||||
continue;
|
||||
if ( pdev->tag == tag0 ) // is this it?
|
||||
{
|
||||
pdev->tag = 0;
|
||||
SCpnt = pdev->SCpnt;
|
||||
goto unmapProceed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
outb_p (0xFF, padapter->tag); // clear the op interrupt
|
||||
outb_p (CMD_DONE, padapter->cmd); // complete the op
|
||||
goto irq_return; // done, but, with what?
|
||||
|
||||
unmapProceed:;
|
||||
if ( !bus )
|
||||
{
|
||||
switch ( SCpnt->cmnd[0] )
|
||||
{
|
||||
case SCSIOP_TEST_UNIT_READY:
|
||||
pci_unmap_single (padapter->pdev, SCpnt->SCp.have_data_in, sizeof (SCpnt->sense_buffer), PCI_DMA_FROMDEVICE);
|
||||
goto irqProceed;
|
||||
case SCSIOP_READ_CAPACITY:
|
||||
pci_unmap_single (padapter->pdev, SCpnt->SCp.have_data_in, 8, PCI_DMA_FROMDEVICE);
|
||||
goto irqProceed;
|
||||
case SCSIOP_VERIFY:
|
||||
case SCSIOP_START_STOP_UNIT:
|
||||
case SCSIOP_MEDIUM_REMOVAL:
|
||||
goto irqProceed;
|
||||
}
|
||||
}
|
||||
if ( SCpnt->SCp.have_data_in )
|
||||
pci_unmap_single (padapter->pdev, SCpnt->SCp.have_data_in, SCpnt->request_bufflen, SCpnt->sc_data_direction);
|
||||
else
|
||||
{
|
||||
if ( SCpnt->use_sg )
|
||||
pci_unmap_sg (padapter->pdev, (struct scatterlist *)SCpnt->request_buffer, SCpnt->use_sg, SCpnt->sc_data_direction);
|
||||
}
|
||||
|
||||
irqProceed:;
|
||||
if ( tag & ERR08_TAGGED ) // is there an error here?
|
||||
{
|
||||
if ( WaitReady (padapter) )
|
||||
{
|
||||
OpDone (SCpnt, DID_TIME_OUT << 16);
|
||||
goto irq_return;
|
||||
}
|
||||
|
||||
outb_p (tag0, padapter->mb0); // get real error code
|
||||
outb_p (CMD_ERROR, padapter->cmd);
|
||||
if ( WaitReady (padapter) ) // wait for controller to suck up the op
|
||||
{
|
||||
OpDone (SCpnt, DID_TIME_OUT << 16);
|
||||
goto irq_return;
|
||||
}
|
||||
|
||||
error = inl (padapter->mb0); // get error data
|
||||
outb_p (0xFF, padapter->tag); // clear the op interrupt
|
||||
outb_p (CMD_DONE, padapter->cmd); // complete the op
|
||||
|
||||
DEB (printk ("status: %lX ", error));
|
||||
if ( error == 0x00020002 ) // is this error a check condition?
|
||||
{
|
||||
if ( bus ) // are we doint SCSI commands?
|
||||
{
|
||||
OpDone (SCpnt, (DID_OK << 16) | 2);
|
||||
goto irq_return;
|
||||
}
|
||||
if ( *SCpnt->cmnd == SCSIOP_TEST_UNIT_READY )
|
||||
OpDone (SCpnt, (DRIVER_SENSE << 24) | (DID_OK << 16) | 2); // test caller we have sense data too
|
||||
else
|
||||
OpDone (SCpnt, DID_ERROR << 16);
|
||||
goto irq_return;
|
||||
}
|
||||
OpDone (SCpnt, DID_ERROR << 16);
|
||||
goto irq_return;
|
||||
}
|
||||
|
||||
outb_p (0xFF, padapter->tag); // clear the op interrupt
|
||||
outb_p (CMD_DONE, padapter->cmd); // complete the op
|
||||
OpDone (SCpnt, DID_OK << 16);
|
||||
|
||||
irq_return:
|
||||
spin_unlock_irqrestore(shost->host_lock, flags);
|
||||
out:
|
||||
return IRQ_RETVAL(handled);
|
||||
}
|
||||
/****************************************************************
|
||||
* Name: Pci2000_QueueCommand
|
||||
*
|
||||
* Description: Process a queued command from the SCSI manager.
|
||||
*
|
||||
* Parameters: SCpnt - Pointer to SCSI command structure.
|
||||
* done - Pointer to done function to call.
|
||||
*
|
||||
* Returns: Status code.
|
||||
*
|
||||
****************************************************************/
|
||||
int Pci2000_QueueCommand (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
|
||||
{
|
||||
UCHAR *cdb = (UCHAR *)SCpnt->cmnd; // Pointer to SCSI CDB
|
||||
PADAPTER2000 padapter = HOSTDATA(SCpnt->device->host); // Pointer to adapter control structure
|
||||
int rc = -1; // command return code
|
||||
UCHAR bus = SCpnt->device->channel;
|
||||
UCHAR pun = SCpnt->device->id;
|
||||
UCHAR lun = SCpnt->device->lun;
|
||||
UCHAR cmd;
|
||||
PDEV2000 pdev = &padapter->dev[bus][pun];
|
||||
|
||||
if ( !done )
|
||||
{
|
||||
printk("pci2000_queuecommand: %02X: done can't be NULL\n", *cdb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
SCpnt->scsi_done = done;
|
||||
SCpnt->SCp.have_data_in = 0;
|
||||
pdev->SCpnt = SCpnt; // Save this command data
|
||||
|
||||
if ( WaitReady (padapter) )
|
||||
{
|
||||
rc = DID_ERROR;
|
||||
goto finished;
|
||||
}
|
||||
|
||||
outw_p (pun | (lun << 8), padapter->mb0);
|
||||
|
||||
if ( bus )
|
||||
{
|
||||
DEB (if(*cdb) printk ("\nCDB: %X- %X %X %X %X %X %X %X %X %X %X ", SCpnt->cmd_len, cdb[0], cdb[1], cdb[2], cdb[3], cdb[4], cdb[5], cdb[6], cdb[7], cdb[8], cdb[9]));
|
||||
DEB (if(*cdb) printk ("\ntimeout_per_command: %d, timeout_total: %d, timeout: %d", SCpnt->timeout_per_command,
|
||||
SCpnt->timeout_total, SCpnt->timeout));
|
||||
outl (SCpnt->timeout_per_command, padapter->mb1);
|
||||
outb_p (CMD_SCSI_TIMEOUT, padapter->cmd);
|
||||
if ( WaitReady (padapter) )
|
||||
{
|
||||
rc = DID_ERROR;
|
||||
goto finished;
|
||||
}
|
||||
|
||||
outw_p (pun | (lun << 8), padapter->mb0);
|
||||
outw_p (SCpnt->cmd_len << 8, padapter->mb0 + 2);
|
||||
memcpy (pdev->cdb, cdb, MAX_COMMAND_SIZE);
|
||||
|
||||
outl (pdev->cdbDma, padapter->mb1);
|
||||
if ( BuildSgList (SCpnt, padapter, pdev) )
|
||||
cmd = CMD_SCSI_THRU;
|
||||
else
|
||||
cmd = CMD_SCSI_THRU_SG;
|
||||
if ( (pdev->tag = Command (padapter, cmd)) == 0 )
|
||||
rc = DID_TIME_OUT;
|
||||
goto finished;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( lun )
|
||||
{
|
||||
rc = DID_BAD_TARGET;
|
||||
goto finished;
|
||||
}
|
||||
}
|
||||
|
||||
switch ( *cdb )
|
||||
{
|
||||
case SCSIOP_INQUIRY: // inquiry CDB
|
||||
if ( cdb[2] == SC_MY_RAID )
|
||||
{
|
||||
switch ( cdb[3] )
|
||||
{
|
||||
case MY_SCSI_REBUILD:
|
||||
OpDone (SCpnt, PsiRaidCmd (padapter, CMD_RAID_REBUILD) << 16);
|
||||
return 0;
|
||||
case MY_SCSI_ALARMMUTE:
|
||||
OpDone (SCpnt, PsiRaidCmd (padapter, CMD_RAID_MUTE) << 16);
|
||||
return 0;
|
||||
case MY_SCSI_DEMOFAIL:
|
||||
OpDone (SCpnt, PsiRaidCmd (padapter, CMD_RAID_FAIL) << 16);
|
||||
return 0;
|
||||
default:
|
||||
if ( SCpnt->use_sg )
|
||||
{
|
||||
rc = DID_ERROR;
|
||||
goto finished;
|
||||
}
|
||||
else
|
||||
{
|
||||
SCpnt->SCp.have_data_in = pci_map_single (padapter->pdev, SCpnt->request_buffer, SCpnt->request_bufflen,
|
||||
SCpnt->sc_data_direction);
|
||||
outl (SCpnt->SCp.have_data_in, padapter->mb2);
|
||||
}
|
||||
outl (cdb[5], padapter->mb0);
|
||||
outl (cdb[3], padapter->mb3);
|
||||
cmd = CMD_DASD_RAID_RQ;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if ( SCpnt->use_sg )
|
||||
{
|
||||
SCpnt->SCp.have_data_in = pci_map_single (padapter->pdev,
|
||||
((struct scatterlist *)SCpnt->request_buffer)->address,
|
||||
SCpnt->request_bufflen,
|
||||
SCpnt->sc_data_direction);
|
||||
}
|
||||
else
|
||||
{
|
||||
SCpnt->SCp.have_data_in = pci_map_single (padapter->pdev, SCpnt->request_buffer,
|
||||
SCpnt->request_bufflen,
|
||||
SCpnt->sc_data_direction);
|
||||
}
|
||||
outl (SCpnt->SCp.have_data_in, padapter->mb2);
|
||||
outl (SCpnt->request_bufflen, padapter->mb3);
|
||||
cmd = CMD_DASD_SCSI_INQ;
|
||||
break;
|
||||
|
||||
case SCSIOP_TEST_UNIT_READY: // test unit ready CDB
|
||||
SCpnt->SCp.have_data_in = pci_map_single (padapter->pdev, SCpnt->sense_buffer, sizeof (SCpnt->sense_buffer), PCI_DMA_FROMDEVICE);
|
||||
outl (SCpnt->SCp.have_data_in, padapter->mb2);
|
||||
outl (sizeof (SCpnt->sense_buffer), padapter->mb3);
|
||||
cmd = CMD_TEST_READY;
|
||||
break;
|
||||
|
||||
case SCSIOP_READ_CAPACITY: // read capacity CDB
|
||||
if ( SCpnt->use_sg )
|
||||
{
|
||||
SCpnt->SCp.have_data_in = pci_map_single (padapter->pdev, ((struct scatterlist *)(SCpnt->request_buffer))->address,
|
||||
8, PCI_DMA_FROMDEVICE);
|
||||
}
|
||||
else
|
||||
SCpnt->SCp.have_data_in = pci_map_single (padapter->pdev, SCpnt->request_buffer, 8, PCI_DMA_FROMDEVICE);
|
||||
outl (SCpnt->SCp.have_data_in, padapter->mb2);
|
||||
outl (8, padapter->mb3);
|
||||
cmd = CMD_DASD_CAP;
|
||||
break;
|
||||
case SCSIOP_VERIFY: // verify CDB
|
||||
outw_p ((USHORT)cdb[8] | ((USHORT)cdb[7] << 8), padapter->mb0 + 2);
|
||||
outl (XSCSI2LONG (&cdb[2]), padapter->mb1);
|
||||
cmd = CMD_READ_SG;
|
||||
break;
|
||||
case SCSIOP_READ: // read10 CDB
|
||||
outw_p ((USHORT)cdb[8] | ((USHORT)cdb[7] << 8), padapter->mb0 + 2);
|
||||
outl (XSCSI2LONG (&cdb[2]), padapter->mb1);
|
||||
if ( BuildSgList (SCpnt, padapter, pdev) )
|
||||
cmd = CMD_READ;
|
||||
else
|
||||
cmd = CMD_READ_SG;
|
||||
break;
|
||||
case SCSIOP_READ6: // read6 CDB
|
||||
outw_p (cdb[4], padapter->mb0 + 2);
|
||||
outl ((SCSI2LONG (&cdb[1])) & 0x001FFFFF, padapter->mb1);
|
||||
if ( BuildSgList (SCpnt, padapter, pdev) )
|
||||
cmd = CMD_READ;
|
||||
else
|
||||
cmd = CMD_READ_SG;
|
||||
break;
|
||||
case SCSIOP_WRITE: // write10 CDB
|
||||
outw_p ((USHORT)cdb[8] | ((USHORT)cdb[7] << 8), padapter->mb0 + 2);
|
||||
outl (XSCSI2LONG (&cdb[2]), padapter->mb1);
|
||||
if ( BuildSgList (SCpnt, padapter, pdev) )
|
||||
cmd = CMD_WRITE;
|
||||
else
|
||||
cmd = CMD_WRITE_SG;
|
||||
break;
|
||||
case SCSIOP_WRITE6: // write6 CDB
|
||||
outw_p (cdb[4], padapter->mb0 + 2);
|
||||
outl ((SCSI2LONG (&cdb[1])) & 0x001FFFFF, padapter->mb1);
|
||||
if ( BuildSgList (SCpnt, padapter, pdev) )
|
||||
cmd = CMD_WRITE;
|
||||
else
|
||||
cmd = CMD_WRITE_SG;
|
||||
break;
|
||||
case SCSIOP_START_STOP_UNIT:
|
||||
cmd = CMD_EJECT_MEDIA;
|
||||
break;
|
||||
case SCSIOP_MEDIUM_REMOVAL:
|
||||
switch ( cdb[4] )
|
||||
{
|
||||
case 0:
|
||||
cmd = CMD_UNLOCK_DOOR;
|
||||
break;
|
||||
case 1:
|
||||
cmd = CMD_LOCK_DOOR;
|
||||
break;
|
||||
default:
|
||||
cmd = 0;
|
||||
break;
|
||||
}
|
||||
if ( cmd )
|
||||
break;
|
||||
default:
|
||||
DEB (printk ("pci2000_queuecommand: Unsupported command %02X\n", *cdb));
|
||||
OpDone (SCpnt, DID_ERROR << 16);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( (pdev->tag = Command (padapter, cmd)) == 0 )
|
||||
rc = DID_TIME_OUT;
|
||||
finished:;
|
||||
if ( rc != -1 )
|
||||
OpDone (SCpnt, rc << 16);
|
||||
return 0;
|
||||
}
|
||||
/****************************************************************
|
||||
* Name: Pci2000_Detect
|
||||
*
|
||||
* Description: Detect and initialize our boards.
|
||||
*
|
||||
* Parameters: tpnt - Pointer to SCSI host template structure.
|
||||
*
|
||||
* Returns: Number of adapters installed.
|
||||
*
|
||||
****************************************************************/
|
||||
int Pci2000_Detect (Scsi_Host_Template *tpnt)
|
||||
{
|
||||
int found = 0;
|
||||
int installed = 0;
|
||||
struct Scsi_Host *pshost;
|
||||
PADAPTER2000 padapter;
|
||||
int z, zz;
|
||||
int setirq;
|
||||
struct pci_dev *pdev = NULL;
|
||||
UCHAR *consistent;
|
||||
dma_addr_t consistentDma;
|
||||
|
||||
while ( (pdev = pci_find_device (VENDOR_PSI, DEVICE_ROY_1, pdev)) != NULL )
|
||||
{
|
||||
if (pci_enable_device(pdev))
|
||||
continue;
|
||||
pshost = scsi_register (tpnt, sizeof(ADAPTER2000));
|
||||
if(pshost == NULL)
|
||||
continue;
|
||||
padapter = HOSTDATA(pshost);
|
||||
|
||||
padapter->basePort = pci_resource_start (pdev, 1);
|
||||
DEB (printk ("\nBase Regs = %#04X", padapter->basePort)); // get the base I/O port address
|
||||
padapter->mb0 = padapter->basePort + RTR_MAILBOX; // get the 32 bit mail boxes
|
||||
padapter->mb1 = padapter->basePort + RTR_MAILBOX + 4;
|
||||
padapter->mb2 = padapter->basePort + RTR_MAILBOX + 8;
|
||||
padapter->mb3 = padapter->basePort + RTR_MAILBOX + 12;
|
||||
padapter->mb4 = padapter->basePort + RTR_MAILBOX + 16;
|
||||
padapter->cmd = padapter->basePort + RTR_LOCAL_DOORBELL; // command register
|
||||
padapter->tag = padapter->basePort + RTR_PCI_DOORBELL; // tag/response register
|
||||
padapter->pdev = pdev;
|
||||
|
||||
if ( WaitReady (padapter) )
|
||||
goto unregister;
|
||||
outb_p (0x84, padapter->mb0);
|
||||
outb_p (CMD_SPECIFY, padapter->cmd);
|
||||
if ( WaitReady (padapter) )
|
||||
goto unregister;
|
||||
|
||||
consistent = pci_alloc_consistent (pdev, consistentLen, &consistentDma);
|
||||
if ( !consistent )
|
||||
{
|
||||
printk ("Unable to allocate DMA memory for PCI-2000 controller.\n");
|
||||
goto unregister;
|
||||
}
|
||||
|
||||
scsi_set_device(pshost, &pdev->dev);
|
||||
pshost->irq = pdev->irq;
|
||||
setirq = 1;
|
||||
padapter->irqOwned = 0;
|
||||
for ( z = 0; z < installed; z++ ) // scan for shared interrupts
|
||||
{
|
||||
if ( PsiHost[z]->irq == pshost->irq ) // if shared then, don't posses
|
||||
setirq = 0;
|
||||
}
|
||||
if ( setirq ) // if not shared, posses
|
||||
{
|
||||
if ( request_irq (pshost->irq, Irq_Handler, SA_SHIRQ, "pci2000", padapter) < 0 )
|
||||
{
|
||||
if ( request_irq (pshost->irq, Irq_Handler, SA_INTERRUPT | SA_SHIRQ, "pci2000", padapter) < 0 )
|
||||
{
|
||||
printk ("Unable to allocate IRQ for PCI-2000 controller.\n");
|
||||
pci_free_consistent (pdev, consistentLen, consistent, consistentDma);
|
||||
goto unregister;
|
||||
}
|
||||
}
|
||||
padapter->irqOwned = pshost->irq; // set IRQ as owned
|
||||
}
|
||||
PsiHost[installed] = pshost; // save SCSI_HOST pointer
|
||||
|
||||
pshost->io_port = padapter->basePort;
|
||||
pshost->n_io_port = 0xFF;
|
||||
pshost->unique_id = padapter->basePort;
|
||||
pshost->max_id = 16;
|
||||
pshost->max_channel = 1;
|
||||
|
||||
for ( zz = 0; zz < MAX_BUS; zz++ )
|
||||
for ( z = 0; z < MAX_UNITS; z++ )
|
||||
{
|
||||
padapter->dev[zz][z].tag = 0;
|
||||
padapter->dev[zz][z].scatGath = (PSCATGATH)consistent;
|
||||
padapter->dev[zz][z].scatGathDma = consistentDma;
|
||||
consistent += 16 * sizeof (SCATGATH);
|
||||
consistentDma += 16 * sizeof (SCATGATH);
|
||||
padapter->dev[zz][z].cdb = (UCHAR *)consistent;
|
||||
padapter->dev[zz][z].cdbDma = consistentDma;
|
||||
consistent += MAX_COMMAND_SIZE;
|
||||
consistentDma += MAX_COMMAND_SIZE;
|
||||
}
|
||||
|
||||
printk("\nPSI-2000 Intelligent Storage SCSI CONTROLLER: at I/O = %lX IRQ = %d\n", padapter->basePort, pshost->irq);
|
||||
printk("Version %s, Compiled %s %s\n\n", PCI2000_VERSION, __DATE__, __TIME__);
|
||||
found++;
|
||||
if ( ++installed < MAXADAPTER )
|
||||
continue;
|
||||
break;
|
||||
unregister:;
|
||||
scsi_unregister (pshost);
|
||||
found++;
|
||||
}
|
||||
NumAdapters = installed;
|
||||
return installed;
|
||||
}
|
||||
/****************************************************************
|
||||
* Name: Pci2000_Abort
|
||||
*
|
||||
* Description: Process the Abort command from the SCSI manager.
|
||||
*
|
||||
* Parameters: SCpnt - Pointer to SCSI command structure.
|
||||
*
|
||||
* Returns: Allways snooze.
|
||||
*
|
||||
****************************************************************/
|
||||
int Pci2000_Abort (Scsi_Cmnd *SCpnt)
|
||||
{
|
||||
DEB (printk ("pci2000_abort\n"));
|
||||
return SCSI_ABORT_SNOOZE;
|
||||
}
|
||||
/****************************************************************
|
||||
* Name: Pci2000_Reset
|
||||
*
|
||||
* Description: Process the Reset command from the SCSI manager.
|
||||
*
|
||||
* Parameters: SCpnt - Pointer to SCSI command structure.
|
||||
* flags - Flags about the reset command
|
||||
*
|
||||
* Returns: No active command at this time, so this means
|
||||
* that each time we got some kind of response the
|
||||
* last time through. Tell the mid-level code to
|
||||
* request sense information in order to decide what
|
||||
* to do next.
|
||||
*
|
||||
****************************************************************/
|
||||
int Pci2000_Reset (Scsi_Cmnd *SCpnt, unsigned int reset_flags)
|
||||
{
|
||||
return SCSI_RESET_PUNT;
|
||||
}
|
||||
/****************************************************************
|
||||
* Name: Pci2000_Release
|
||||
*
|
||||
* Description: Release resources allocated for a single each adapter.
|
||||
*
|
||||
* Parameters: pshost - Pointer to SCSI command structure.
|
||||
*
|
||||
* Returns: zero.
|
||||
*
|
||||
****************************************************************/
|
||||
int Pci2000_Release (struct Scsi_Host *pshost)
|
||||
{
|
||||
PADAPTER2000 padapter = HOSTDATA (pshost);
|
||||
|
||||
if ( padapter->irqOwned )
|
||||
free_irq (pshost->irq, padapter);
|
||||
pci_free_consistent (padapter->pdev, consistentLen, padapter->dev[0][0].scatGath, padapter->dev[0][0].scatGathDma);
|
||||
release_region (pshost->io_port, pshost->n_io_port);
|
||||
scsi_unregister(pshost);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
* Name: Pci2000_BiosParam
|
||||
*
|
||||
* Description: Process the biosparam request from the SCSI manager to
|
||||
* return C/H/S data.
|
||||
*
|
||||
* Parameters: disk - Pointer to SCSI disk structure.
|
||||
* dev - Major/minor number from kernel.
|
||||
* geom - Pointer to integer array to place geometry data.
|
||||
*
|
||||
* Returns: zero.
|
||||
*
|
||||
****************************************************************/
|
||||
int Pci2000_BiosParam (struct scsi_device *sdev, struct block_device *dev,
|
||||
sector_t capacity, int geom[])
|
||||
{
|
||||
PADAPTER2000 padapter;
|
||||
|
||||
padapter = HOSTDATA(sdev->host);
|
||||
|
||||
if ( WaitReady (padapter) )
|
||||
return 0;
|
||||
outb_p (sdev->id, padapter->mb0);
|
||||
outb_p (CMD_GET_PARMS, padapter->cmd);
|
||||
if ( WaitReady (padapter) )
|
||||
return 0;
|
||||
|
||||
geom[0] = inb_p (padapter->mb2 + 3);
|
||||
geom[1] = inb_p (padapter->mb2 + 2);
|
||||
geom[2] = inw_p (padapter->mb2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
MODULE_LICENSE("Dual BSD/GPL");
|
||||
|
||||
static Scsi_Host_Template driver_template = {
|
||||
.proc_name = "pci2000",
|
||||
.name = "PCI-2000 SCSI Intelligent Disk Controller",
|
||||
.detect = Pci2000_Detect,
|
||||
.release = Pci2000_Release,
|
||||
.queuecommand = Pci2000_QueueCommand,
|
||||
.abort = Pci2000_Abort,
|
||||
.reset = Pci2000_Reset,
|
||||
.bios_param = Pci2000_BiosParam,
|
||||
.can_queue = 16,
|
||||
.this_id = -1,
|
||||
.sg_tablesize = 16,
|
||||
.cmd_per_lun = 1,
|
||||
.use_clustering = DISABLE_CLUSTERING,
|
||||
};
|
||||
#include "scsi_module.c"
|
File diff suppressed because it is too large
Load Diff
@ -1,39 +0,0 @@
|
||||
/****************************************************************************
|
||||
* Perceptive Solutions, Inc. PCI-2220I device driver for Linux.
|
||||
*
|
||||
* pci2220i.h - Linux Host Driver for PCI-2220i EIDE Adapters
|
||||
*
|
||||
* Copyright (c) 1997-1999 Perceptive Solutions, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that redistributions of source
|
||||
* code retain the above copyright notice and this comment without
|
||||
* modification.
|
||||
*
|
||||
* Technical updates and product information at:
|
||||
* http://www.psidisk.com
|
||||
*
|
||||
* Please send questions, comments, bug reports to:
|
||||
* tech@psidisk.com Technical Support
|
||||
*
|
||||
****************************************************************************/
|
||||
#ifndef _PCI2220I_H
|
||||
#define _PCI2220I_H
|
||||
|
||||
#ifndef LINUX_VERSION_CODE
|
||||
#include <linux/version.h>
|
||||
#endif
|
||||
#define LINUXVERSION(v,p,s) (((v)<<16) + ((p)<<8) + (s))
|
||||
|
||||
// function prototypes
|
||||
int Pci2220i_Detect (Scsi_Host_Template *tpnt);
|
||||
int Pci2220i_Command (Scsi_Cmnd *SCpnt);
|
||||
int Pci2220i_QueueCommand (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *));
|
||||
int Pci2220i_Abort (Scsi_Cmnd *SCpnt);
|
||||
int Pci2220i_Reset (Scsi_Cmnd *SCpnt, unsigned int flags);
|
||||
int Pci2220i_Release (struct Scsi_Host *pshost);
|
||||
int Pci2220i_BiosParam (struct scsi_device *sdev,
|
||||
struct block_device *dev,
|
||||
sector_t capacity, int geom[]);
|
||||
#endif
|
@ -1,564 +0,0 @@
|
||||
/****************************************************************************
|
||||
* Perceptive Solutions, Inc. PCI-2220I device driver for Linux.
|
||||
*
|
||||
* psi_dalei.h - Linux Host Driver for PCI-2220i EIDE Adapters
|
||||
*
|
||||
* Copyright (c) 1997-1999 Perceptive Solutions, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that redistributions of source
|
||||
* code retain the above copyright notice and this comment without
|
||||
* modification.
|
||||
*
|
||||
* Technical updates and product information at:
|
||||
* http://www.psidisk.com
|
||||
*
|
||||
* Please send questions, comments, bug reports to:
|
||||
* tech@psidisk.com Technical Support
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/************************************************/
|
||||
/* Some defines that we like */
|
||||
/************************************************/
|
||||
#define CHAR char
|
||||
#define UCHAR unsigned char
|
||||
#define SHORT short
|
||||
#define USHORT unsigned short
|
||||
#define BOOL unsigned short
|
||||
#define LONG long
|
||||
#define ULONG unsigned long
|
||||
#define VOID void
|
||||
|
||||
/************************************************/
|
||||
/* Dale PCI setup */
|
||||
/************************************************/
|
||||
#define VENDOR_PSI 0x1256
|
||||
#define DEVICE_DALE_1 0x4401 /* 'D1' */
|
||||
#define DEVICE_BIGD_1 0x4201 /* 'B1' */
|
||||
#define DEVICE_BIGD_2 0x4202 /* 'B2' */
|
||||
|
||||
/************************************************/
|
||||
/* Misc konstants */
|
||||
/************************************************/
|
||||
#define DALE_MAXDRIVES 4
|
||||
#define BIGD_MAXDRIVES 8
|
||||
#define SECTORSXFER 8
|
||||
#define ATAPI_TRANSFER 8192
|
||||
#define BYTES_PER_SECTOR 512
|
||||
#define DEFAULT_TIMING_MODE 5
|
||||
|
||||
/************************************************/
|
||||
/* EEPROM locations */
|
||||
/************************************************/
|
||||
#define DALE_FLASH_PAGE_SIZE 128 // number of bytes per page
|
||||
#define DALE_FLASH_SIZE 65536L
|
||||
|
||||
#define DALE_FLASH_BIOS 0x00080000L // BIOS base address
|
||||
#define DALE_FLASH_SETUP 0x00088000L // SETUP PROGRAM base address offset from BIOS
|
||||
#define DALE_FLASH_RAID 0x00088400L // RAID signature storage
|
||||
#define DALE_FLASH_FACTORY 0x00089000L // FACTORY data base address offset from BIOS
|
||||
|
||||
#define DALE_FLASH_BIOS_SIZE 32768U // size of FLASH BIOS REGION
|
||||
|
||||
/************************************************/
|
||||
/* DALE Register address offsets */
|
||||
/************************************************/
|
||||
#define REG_DATA 0x80
|
||||
#define REG_ERROR 0x84
|
||||
#define REG_SECTOR_COUNT 0x88
|
||||
#define REG_LBA_0 0x8C
|
||||
#define REG_LBA_8 0x90
|
||||
#define REG_LBA_16 0x94
|
||||
#define REG_LBA_24 0x98
|
||||
#define REG_STAT_CMD 0x9C
|
||||
#define REG_STAT_SEL 0xA0
|
||||
#define REG_FAIL 0xB0
|
||||
#define REG_ALT_STAT 0xB8
|
||||
#define REG_DRIVE_ADRS 0xBC
|
||||
|
||||
#define DALE_DATA_SLOW 0x00040000L
|
||||
#define DALE_DATA_MODE2 0x00040000L
|
||||
#define DALE_DATA_MODE3 0x00050000L
|
||||
#define DALE_DATA_MODE4 0x00060000L
|
||||
#define DALE_DATA_MODE5 0x00070000L
|
||||
|
||||
#define BIGD_DATA_SLOW 0x00000000L
|
||||
#define BIGD_DATA_MODE0 0x00000000L
|
||||
#define BIGD_DATA_MODE2 0x00000000L
|
||||
#define BIGD_DATA_MODE3 0x00000008L
|
||||
#define BIGD_DATA_MODE4 0x00000010L
|
||||
#define BIGD_DATA_MODE5 0x00000020L
|
||||
|
||||
#define RTR_LOCAL_RANGE 0x000
|
||||
#define RTR_LOCAL_REMAP 0x004
|
||||
#define RTR_EXP_RANGE 0x010
|
||||
#define RTR_EXP_REMAP 0x014
|
||||
#define RTR_REGIONS 0x018
|
||||
#define RTR_DM_MASK 0x01C
|
||||
#define RTR_DM_LOCAL_BASE 0x020
|
||||
#define RTR_DM_IO_BASE 0x024
|
||||
#define RTR_DM_PCI_REMAP 0x028
|
||||
#define RTR_DM_IO_CONFIG 0x02C
|
||||
#define RTR_MAILBOX 0x040
|
||||
#define RTR_LOCAL_DOORBELL 0x060
|
||||
#define RTR_PCI_DOORBELL 0x064
|
||||
#define RTR_INT_CONTROL_STATUS 0x068
|
||||
#define RTR_EEPROM_CONTROL_STATUS 0x06C
|
||||
|
||||
#define RTR_DMA0_MODE 0x0080
|
||||
#define RTR_DMA0_PCI_ADDR 0x0084
|
||||
#define RTR_DMA0_LOCAL_ADDR 0x0088
|
||||
#define RTR_DMA0_COUNT 0x008C
|
||||
#define RTR_DMA0_DESC_PTR 0x0090
|
||||
#define RTR_DMA1_MODE 0x0094
|
||||
#define RTR_DMA1_PCI_ADDR 0x0098
|
||||
#define RTR_DMA1_LOCAL_ADDR 0x009C
|
||||
#define RTR_DMA1_COUNT 0x00A0
|
||||
#define RTR_DMA1_DESC_PTR 0x00A4
|
||||
#define RTR_DMA_COMMAND_STATUS 0x00A8
|
||||
#define RTR_DMA_ARB0 0x00AC
|
||||
#define RTR_DMA_ARB1 0x00B0
|
||||
|
||||
#define RTL_DMA0_MODE 0x00
|
||||
#define RTL_DMA0_PCI_ADDR 0x04
|
||||
#define RTL_DMA0_LOCAL_ADDR 0x08
|
||||
#define RTL_DMA0_COUNT 0x0C
|
||||
#define RTL_DMA0_DESC_PTR 0x10
|
||||
#define RTL_DMA1_MODE 0x14
|
||||
#define RTL_DMA1_PCI_ADDR 0x18
|
||||
#define RTL_DMA1_LOCAL_ADDR 0x1C
|
||||
#define RTL_DMA1_COUNT 0x20
|
||||
#define RTL_DMA1_DESC_PTR 0x24
|
||||
#define RTL_DMA_COMMAND_STATUS 0x28
|
||||
#define RTL_DMA_ARB0 0x2C
|
||||
#define RTL_DMA_ARB1 0x30
|
||||
|
||||
/************************************************/
|
||||
/* Dale Scratchpad locations */
|
||||
/************************************************/
|
||||
#define DALE_CHANNEL_DEVICE_0 0 // device channel locations
|
||||
#define DALE_CHANNEL_DEVICE_1 1
|
||||
#define DALE_CHANNEL_DEVICE_2 2
|
||||
#define DALE_CHANNEL_DEVICE_3 3
|
||||
|
||||
#define DALE_SCRATCH_DEVICE_0 4 // device type codes
|
||||
#define DALE_SCRATCH_DEVICE_1 5
|
||||
#define DALE_SCRATCH_DEVICE_2 6
|
||||
#define DALE_SCRATCH_DEVICE_3 7
|
||||
|
||||
#define DALE_RAID_0_STATUS 8
|
||||
#define DALE_RAID_1_STATUS 9
|
||||
|
||||
#define DALE_TIMING_MODE 12 // bus master timing mode (2, 3, 4, 5)
|
||||
#define DALE_NUM_DRIVES 13 // number of addressable drives on this board
|
||||
#define DALE_RAID_ON 14 // RAID status On
|
||||
#define DALE_LAST_ERROR 15 // Last error code from BIOS
|
||||
|
||||
/************************************************/
|
||||
/* BigD Scratchpad locations */
|
||||
/************************************************/
|
||||
#define BIGD_DEVICE_0 0 // device channel locations
|
||||
#define BIGD_DEVICE_1 1
|
||||
#define BIGD_DEVICE_2 2
|
||||
#define BIGD_DEVICE_3 3
|
||||
|
||||
#define BIGD_DEVICE_4 4 // device type codes
|
||||
#define BIGD_DEVICE_5 5
|
||||
#define BIGD_DEVICE_6 6
|
||||
#define BIGD_DEVICE_7 7
|
||||
|
||||
#define BIGD_ALARM_IMAGE 11 // ~image of alarm fail register
|
||||
#define BIGD_TIMING_MODE 12 // bus master timing mode (2, 3, 4, 5)
|
||||
#define BIGD_NUM_DRIVES 13 // number of addressable drives on this board
|
||||
#define BIGD_RAID_ON 14 // RAID status is on for the whole board
|
||||
#define BIGD_LAST_ERROR 15 // Last error code from BIOS
|
||||
|
||||
#define BIGD_RAID_0_STATUS 16
|
||||
#define BIGD_RAID_1_STATUS 17
|
||||
#define BIGD_RAID_2_STATUS 18
|
||||
#define BIGD_RAID_3_STATUS 19
|
||||
#define BIGD_RAID_4_STATUS 20
|
||||
#define BIGD_RAID_5_STATUS 21
|
||||
#define BIGD_RAID_6_STATUS 22
|
||||
#define BIGD_RAID_7_STATUS 23
|
||||
|
||||
/************************************************/
|
||||
/* Dale cable select bits */
|
||||
/************************************************/
|
||||
#define SEL_NONE 0x00
|
||||
#define SEL_1 0x01
|
||||
#define SEL_2 0x02
|
||||
#define SEL_3 0x04
|
||||
#define SEL_4 0x08
|
||||
#define SEL_NEW_SPEED_1 0x20
|
||||
#define SEL_COPY 0x40
|
||||
#define SEL_IRQ_OFF 0x80
|
||||
|
||||
/************************************************/
|
||||
/* Device/Geometry controls */
|
||||
/************************************************/
|
||||
#define GEOMETRY_NONE 0x0 // No device
|
||||
#define GEOMETRY_SET 0x1 // Geometry set
|
||||
#define GEOMETRY_LBA 0x2 // Geometry set in default LBA mode
|
||||
#define GEOMETRY_PHOENIX 0x3 // Geometry set in Pheonix BIOS compatibility mode
|
||||
|
||||
#define DEVICE_NONE 0x0 // No device present
|
||||
#define DEVICE_INACTIVE 0x1 // device present but not registered active
|
||||
#define DEVICE_ATAPI 0x2 // ATAPI device (CD_ROM, Tape, Etc...)
|
||||
#define DEVICE_DASD_NONLBA 0x3 // Non LBA incompatible device
|
||||
#define DEVICE_DASD_LBA 0x4 // LBA compatible device
|
||||
|
||||
/************************************************/
|
||||
/* BigD fail register bits */
|
||||
/************************************************/
|
||||
#define FAIL_NONE 0x00
|
||||
#define FAIL_0 0x01
|
||||
#define FAIL_1 0x02
|
||||
#define FAIL_2 0x04
|
||||
#define FAIL_MULTIPLE 0x08
|
||||
#define FAIL_GOOD 0x20
|
||||
#define FAIL_AUDIBLE 0x40
|
||||
#define FAIL_ANY 0x80
|
||||
|
||||
/************************************************/
|
||||
/* Setup Structure Definitions */
|
||||
/************************************************/
|
||||
typedef struct // device setup parameters
|
||||
{
|
||||
UCHAR geometryControl; // geometry control flags
|
||||
UCHAR device; // device code
|
||||
USHORT sectors; // number of sectors per track
|
||||
USHORT heads; // number of heads
|
||||
USHORT cylinders; // number of cylinders for this device
|
||||
ULONG blocks; // number of blocks on device
|
||||
ULONG realCapacity; // number of real blocks on this device for drive changed testing
|
||||
} SETUP_DEVICE, *PSETUP_DEVICE;
|
||||
|
||||
typedef struct // master setup structure
|
||||
{
|
||||
USHORT startupDelay;
|
||||
BOOL promptBIOS;
|
||||
BOOL fastFormat;
|
||||
BOOL shareInterrupt;
|
||||
BOOL rebootRebuild;
|
||||
USHORT timingMode;
|
||||
USHORT spare5;
|
||||
USHORT spare6;
|
||||
SETUP_DEVICE setupDevice[BIGD_MAXDRIVES];
|
||||
} SETUP, *PSETUP;
|
||||
|
||||
/************************************************/
|
||||
/* RAID Structure Definitions */
|
||||
/************************************************/
|
||||
typedef struct
|
||||
{
|
||||
UCHAR signature; // 0x55 our mirror signature
|
||||
UCHAR status; // current status bits
|
||||
UCHAR pairIdentifier; // unique identifier for pair
|
||||
ULONG reconstructPoint; // recontruction point for hot reconstruct
|
||||
} DISK_MIRROR;
|
||||
|
||||
typedef struct DEVICE_RAID1
|
||||
{
|
||||
long TotalSectors;
|
||||
DISK_MIRROR DiskRaid1;
|
||||
} DEVICE_RAID1, *PDEVICE_RAID1;
|
||||
|
||||
#define DISK_MIRROR_POSITION 0x01A8
|
||||
#define SIGNATURE 0x55
|
||||
|
||||
#define MASK_SERIAL_NUMBER 0x0FFE // mask for serial number matching
|
||||
#define MASK_SERIAL_UNIT 0x0001 // mask for unit portion of serial number
|
||||
|
||||
// Status bits
|
||||
#define UCBF_MIRRORED 0x0010 // drive has a pair
|
||||
#define UCBF_MATCHED 0x0020 // drive pair is matched
|
||||
#define UCBF_SURVIVOR 0x0040 // this unit is a survivor of a pair
|
||||
#define UCBF_REBUILD 0x0080 // rebuild in progress on this device
|
||||
|
||||
// SCSI controls for RAID
|
||||
#define SC_MY_RAID 0xBF // our special CDB command byte for Win95... interface
|
||||
#define MY_SCSI_QUERY1 0x32 // byte 1 subcommand to query driver for RAID 1 informatation
|
||||
#define MY_SCSI_REBUILD 0x40 // byte 1 subcommand to reconstruct a mirrored pair
|
||||
#define MY_SCSI_DEMOFAIL 0x54 // byte 1 subcommand for RAID failure demonstration
|
||||
#define MY_SCSI_ALARMMUTE 0x60 // byte 1 subcommand to mute any alarm currently on
|
||||
|
||||
/************************************************/
|
||||
/* Timeout konstants */
|
||||
/************************************************/
|
||||
#define TIMEOUT_READY 100 // 100 mSec
|
||||
#define TIMEOUT_DRQ 300 // 300 mSec
|
||||
#define TIMEOUT_DATA (3 * HZ) // 3 seconds
|
||||
|
||||
/************************************************/
|
||||
/* Misc. macros */
|
||||
/************************************************/
|
||||
#define ANY2SCSI(up, p) \
|
||||
((UCHAR *)up)[0] = (((ULONG)(p)) >> 8); \
|
||||
((UCHAR *)up)[1] = ((ULONG)(p));
|
||||
|
||||
#define SCSI2LONG(up) \
|
||||
( (((long)*(((UCHAR *)up))) << 16) \
|
||||
+ (((long)(((UCHAR *)up)[1])) << 8) \
|
||||
+ ((long)(((UCHAR *)up)[2])) )
|
||||
|
||||
#define XANY2SCSI(up, p) \
|
||||
((UCHAR *)up)[0] = ((long)(p)) >> 24; \
|
||||
((UCHAR *)up)[1] = ((long)(p)) >> 16; \
|
||||
((UCHAR *)up)[2] = ((long)(p)) >> 8; \
|
||||
((UCHAR *)up)[3] = ((long)(p));
|
||||
|
||||
#define XSCSI2LONG(up) \
|
||||
( (((long)(((UCHAR *)up)[0])) << 24) \
|
||||
+ (((long)(((UCHAR *)up)[1])) << 16) \
|
||||
+ (((long)(((UCHAR *)up)[2])) << 8) \
|
||||
+ ((long)(((UCHAR *)up)[3])) )
|
||||
|
||||
#define SelectSpigot(padapter,spigot) outb_p (spigot, padapter->regStatSel)
|
||||
#define WriteCommand(padapter,cmd) outb_p (cmd, padapter->regStatCmd)
|
||||
#define AtapiDevice(padapter,b) outb_p (b, padapter->regLba24);
|
||||
#define AtapiCountLo(padapter,b) outb_p (b, padapter->regLba8)
|
||||
#define AtapiCountHi(padapter,b) outb_p (b, padapter->regLba16)
|
||||
|
||||
/************************************************/
|
||||
/* SCSI CDB operation codes */
|
||||
/************************************************/
|
||||
#define SCSIOP_TEST_UNIT_READY 0x00
|
||||
#define SCSIOP_REZERO_UNIT 0x01
|
||||
#define SCSIOP_REWIND 0x01
|
||||
#define SCSIOP_REQUEST_BLOCK_ADDR 0x02
|
||||
#define SCSIOP_REQUEST_SENSE 0x03
|
||||
#define SCSIOP_FORMAT_UNIT 0x04
|
||||
#define SCSIOP_READ_BLOCK_LIMITS 0x05
|
||||
#define SCSIOP_REASSIGN_BLOCKS 0x07
|
||||
#define SCSIOP_READ6 0x08
|
||||
#define SCSIOP_RECEIVE 0x08
|
||||
#define SCSIOP_WRITE6 0x0A
|
||||
#define SCSIOP_PRINT 0x0A
|
||||
#define SCSIOP_SEND 0x0A
|
||||
#define SCSIOP_SEEK6 0x0B
|
||||
#define SCSIOP_TRACK_SELECT 0x0B
|
||||
#define SCSIOP_SLEW_PRINT 0x0B
|
||||
#define SCSIOP_SEEK_BLOCK 0x0C
|
||||
#define SCSIOP_PARTITION 0x0D
|
||||
#define SCSIOP_READ_REVERSE 0x0F
|
||||
#define SCSIOP_WRITE_FILEMARKS 0x10
|
||||
#define SCSIOP_FLUSH_BUFFER 0x10
|
||||
#define SCSIOP_SPACE 0x11
|
||||
#define SCSIOP_INQUIRY 0x12
|
||||
#define SCSIOP_VERIFY6 0x13
|
||||
#define SCSIOP_RECOVER_BUF_DATA 0x14
|
||||
#define SCSIOP_MODE_SELECT 0x15
|
||||
#define SCSIOP_RESERVE_UNIT 0x16
|
||||
#define SCSIOP_RELEASE_UNIT 0x17
|
||||
#define SCSIOP_COPY 0x18
|
||||
#define SCSIOP_ERASE 0x19
|
||||
#define SCSIOP_MODE_SENSE 0x1A
|
||||
#define SCSIOP_START_STOP_UNIT 0x1B
|
||||
#define SCSIOP_STOP_PRINT 0x1B
|
||||
#define SCSIOP_LOAD_UNLOAD 0x1B
|
||||
#define SCSIOP_RECEIVE_DIAGNOSTIC 0x1C
|
||||
#define SCSIOP_SEND_DIAGNOSTIC 0x1D
|
||||
#define SCSIOP_MEDIUM_REMOVAL 0x1E
|
||||
#define SCSIOP_READ_CAPACITY 0x25
|
||||
#define SCSIOP_READ 0x28
|
||||
#define SCSIOP_WRITE 0x2A
|
||||
#define SCSIOP_SEEK 0x2B
|
||||
#define SCSIOP_LOCATE 0x2B
|
||||
#define SCSIOP_WRITE_VERIFY 0x2E
|
||||
#define SCSIOP_VERIFY 0x2F
|
||||
#define SCSIOP_SEARCH_DATA_HIGH 0x30
|
||||
#define SCSIOP_SEARCH_DATA_EQUAL 0x31
|
||||
#define SCSIOP_SEARCH_DATA_LOW 0x32
|
||||
#define SCSIOP_SET_LIMITS 0x33
|
||||
#define SCSIOP_READ_POSITION 0x34
|
||||
#define SCSIOP_SYNCHRONIZE_CACHE 0x35
|
||||
#define SCSIOP_COMPARE 0x39
|
||||
#define SCSIOP_COPY_COMPARE 0x3A
|
||||
#define SCSIOP_WRITE_DATA_BUFF 0x3B
|
||||
#define SCSIOP_READ_DATA_BUFF 0x3C
|
||||
#define SCSIOP_CHANGE_DEFINITION 0x40
|
||||
#define SCSIOP_READ_SUB_CHANNEL 0x42
|
||||
#define SCSIOP_READ_TOC 0x43
|
||||
#define SCSIOP_READ_HEADER 0x44
|
||||
#define SCSIOP_PLAY_AUDIO 0x45
|
||||
#define SCSIOP_PLAY_AUDIO_MSF 0x47
|
||||
#define SCSIOP_PLAY_TRACK_INDEX 0x48
|
||||
#define SCSIOP_PLAY_TRACK_RELATIVE 0x49
|
||||
#define SCSIOP_PAUSE_RESUME 0x4B
|
||||
#define SCSIOP_LOG_SELECT 0x4C
|
||||
#define SCSIOP_LOG_SENSE 0x4D
|
||||
#define SCSIOP_MODE_SELECT10 0x55
|
||||
#define SCSIOP_MODE_SENSE10 0x5A
|
||||
#define SCSIOP_LOAD_UNLOAD_SLOT 0xA6
|
||||
#define SCSIOP_MECHANISM_STATUS 0xBD
|
||||
#define SCSIOP_READ_CD 0xBE
|
||||
|
||||
// IDE command definitions
|
||||
#define IDE_COMMAND_ATAPI_RESET 0x08
|
||||
#define IDE_COMMAND_READ 0x20
|
||||
#define IDE_COMMAND_WRITE 0x30
|
||||
#define IDE_COMMAND_RECALIBRATE 0x10
|
||||
#define IDE_COMMAND_SEEK 0x70
|
||||
#define IDE_COMMAND_SET_PARAMETERS 0x91
|
||||
#define IDE_COMMAND_VERIFY 0x40
|
||||
#define IDE_COMMAND_ATAPI_PACKET 0xA0
|
||||
#define IDE_COMMAND_ATAPI_IDENTIFY 0xA1
|
||||
#define IDE_CMD_READ_MULTIPLE 0xC4
|
||||
#define IDE_CMD_WRITE_MULTIPLE 0xC5
|
||||
#define IDE_CMD_SET_MULTIPLE 0xC6
|
||||
#define IDE_COMMAND_IDENTIFY 0xEC
|
||||
|
||||
// IDE status definitions
|
||||
#define IDE_STATUS_ERROR 0x01
|
||||
#define IDE_STATUS_INDEX 0x02
|
||||
#define IDE_STATUS_CORRECTED_ERROR 0x04
|
||||
#define IDE_STATUS_DRQ 0x08
|
||||
#define IDE_STATUS_DSC 0x10
|
||||
#define IDE_STATUS_WRITE_FAULT 0x20
|
||||
#define IDE_STATUS_DRDY 0x40
|
||||
#define IDE_STATUS_BUSY 0x80
|
||||
|
||||
typedef struct _ATAPI_STATUS
|
||||
{
|
||||
CHAR check :1;
|
||||
CHAR reserved1 :1;
|
||||
CHAR corr :1;
|
||||
CHAR drq :1;
|
||||
CHAR dsc :1;
|
||||
CHAR reserved2 :1;
|
||||
CHAR drdy :1;
|
||||
CHAR bsy :1;
|
||||
} ATAPI_STATUS;
|
||||
|
||||
typedef struct _ATAPI_REASON
|
||||
{
|
||||
CHAR cod :1;
|
||||
CHAR io :1;
|
||||
CHAR reserved1 :6;
|
||||
} ATAPI_REASON;
|
||||
|
||||
typedef struct _ATAPI_ERROR
|
||||
{
|
||||
CHAR ili :1;
|
||||
CHAR eom :1;
|
||||
CHAR abort :1;
|
||||
CHAR mcr :1;
|
||||
CHAR senseKey :4;
|
||||
} ATAPI_ERROR;
|
||||
|
||||
// IDE error definitions
|
||||
#define IDE_ERROR_AMNF 0x01
|
||||
#define IDE_ERROR_TKONF 0x02
|
||||
#define IDE_ERROR_ABRT 0x04
|
||||
#define IDE_ERROR_MCR 0x08
|
||||
#define IDE_ERROR_IDFN 0x10
|
||||
#define IDE_ERROR_MC 0x20
|
||||
#define IDE_ERROR_UNC 0x40
|
||||
#define IDE_ERROR_BBK 0x80
|
||||
|
||||
// SCSI read capacity structure
|
||||
typedef struct _READ_CAPACITY_DATA
|
||||
{
|
||||
ULONG blks; /* total blocks (converted to little endian) */
|
||||
ULONG blksiz; /* size of each (converted to little endian) */
|
||||
} READ_CAPACITY_DATA, *PREAD_CAPACITY_DATA;
|
||||
|
||||
// SCSI inquiry data
|
||||
typedef struct _INQUIRYDATA
|
||||
{
|
||||
UCHAR DeviceType :5;
|
||||
UCHAR DeviceTypeQualifier :3;
|
||||
UCHAR DeviceTypeModifier :7;
|
||||
UCHAR RemovableMedia :1;
|
||||
UCHAR Versions;
|
||||
UCHAR ResponseDataFormat;
|
||||
UCHAR AdditionalLength;
|
||||
UCHAR Reserved[2];
|
||||
UCHAR SoftReset :1;
|
||||
UCHAR CommandQueue :1;
|
||||
UCHAR Reserved2 :1;
|
||||
UCHAR LinkedCommands :1;
|
||||
UCHAR Synchronous :1;
|
||||
UCHAR Wide16Bit :1;
|
||||
UCHAR Wide32Bit :1;
|
||||
UCHAR RelativeAddressing :1;
|
||||
UCHAR VendorId[8];
|
||||
UCHAR ProductId[16];
|
||||
UCHAR ProductRevisionLevel[4];
|
||||
UCHAR VendorSpecific[20];
|
||||
UCHAR Reserved3[40];
|
||||
} INQUIRYDATA, *PINQUIRYDATA;
|
||||
|
||||
// IDE IDENTIFY data
|
||||
#pragma pack (1)
|
||||
typedef struct _IDENTIFY_DATA
|
||||
{
|
||||
USHORT GeneralConfiguration; // 0
|
||||
USHORT NumberOfCylinders; // 1
|
||||
USHORT Reserved1; // 2
|
||||
USHORT NumberOfHeads; // 3
|
||||
USHORT UnformattedBytesPerTrack; // 4
|
||||
USHORT UnformattedBytesPerSector; // 5
|
||||
USHORT SectorsPerTrack; // 6
|
||||
USHORT NumBytesISG; // 7 Byte Len - inter-sector gap
|
||||
USHORT NumBytesSync; // 8 - sync field
|
||||
USHORT NumWordsVUS; // 9 Len - Vendor Unique Info
|
||||
USHORT SerialNumber[10]; // 10
|
||||
USHORT BufferType; // 20
|
||||
USHORT BufferSectorSize; // 21
|
||||
USHORT NumberOfEccBytes; // 22
|
||||
USHORT FirmwareRevision[4]; // 23
|
||||
USHORT ModelNumber[20]; // 27
|
||||
USHORT NumSectorsPerInt :8; // 47 Multiple Mode - Sec/Blk
|
||||
USHORT Reserved2 :8; // 47
|
||||
USHORT DoubleWordMode; // 48 flag for double word mode capable
|
||||
USHORT VendorUnique1 :8; // 49
|
||||
USHORT SupportDMA :1; // 49 DMA supported
|
||||
USHORT SupportLBA :1; // 49 LBA supported
|
||||
USHORT SupportIORDYDisable :1; // 49 IORDY can be disabled
|
||||
USHORT SupportIORDY :1; // 49 IORDY supported
|
||||
USHORT ReservedPsuedoDMA :1; // 49 reserved for pseudo DMA mode support
|
||||
USHORT Reserved3 :3; // 49
|
||||
USHORT Reserved4; // 50
|
||||
USHORT Reserved5 :8; // 51 Transfer Cycle Timing - PIO
|
||||
USHORT PIOCycleTime :8; // 51 Transfer Cycle Timing - PIO
|
||||
USHORT Reserved6 :8; // 52 - DMA
|
||||
USHORT DMACycleTime :8; // 52 - DMA
|
||||
USHORT Valid_54_58 :1; // 53 words 54 - 58 are valid
|
||||
USHORT Valid_64_70 :1; // 53 words 64 - 70 are valid
|
||||
USHORT Reserved7 :14; // 53
|
||||
USHORT LogNumCyl; // 54 Current Translation - Num Cyl
|
||||
USHORT LogNumHeads; // 55 Num Heads
|
||||
USHORT LogSectorsPerTrack; // 56 Sec/Trk
|
||||
ULONG LogTotalSectors; // 57 Total Sec
|
||||
USHORT CurrentNumSecPerInt :8; // 59 current setting for number of sectors per interrupt
|
||||
USHORT ValidNumSecPerInt :1; // 59 Current setting is valid for number of sectors per interrupt
|
||||
USHORT Reserved8 :7; // 59
|
||||
ULONG LBATotalSectors; // 60 LBA Mode - Sectors
|
||||
USHORT DMASWordFlags; // 62
|
||||
USHORT DMAMWordFlags; // 63
|
||||
USHORT AdvancedPIOSupport :8; // 64 Flow control PIO transfer modes supported
|
||||
USHORT Reserved9 :8; // 64
|
||||
USHORT MinMultiDMACycle; // 65 minimum multiword DMA transfer cycle time per word
|
||||
USHORT RecomendDMACycle; // 66 Manufacturer's recommende multiword DMA transfer cycle time
|
||||
USHORT MinPIOCycleWithoutFlow; // 67 Minimum PIO transfer cycle time without flow control
|
||||
USHORT MinPIOCylceWithFlow; // 68 Minimum PIO transfer cycle time with IORDY flow control
|
||||
USHORT ReservedSpace[256-69]; // 69
|
||||
} IDENTIFY_DATA, *PIDENTIFY_DATA;
|
||||
|
||||
// ATAPI configuration bits
|
||||
typedef struct _ATAPI_GENERAL_0
|
||||
{
|
||||
USHORT CmdPacketSize :2; // Command packet size
|
||||
USHORT Reserved1 :3;
|
||||
USHORT CmdDrqType :2;
|
||||
USHORT Removable :1;
|
||||
USHORT DeviceType :5;
|
||||
USHORT Reserved2 :1;
|
||||
USHORT ProtocolType :2;
|
||||
} ATAPI_GENERAL_0;
|
||||
|
||||
#pragma pack ()
|
@ -1,331 +0,0 @@
|
||||
/****************************************************************************
|
||||
* Perceptive Solutions, Inc. PCI-2000 device driver for Linux.
|
||||
*
|
||||
* psi_roy.h - Linux Host Driver for PCI-2000 IntelliCache SCSI Adapters
|
||||
*
|
||||
* Copyright (c) 1997-1999 Perceptive Solutions, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that redistributions of source
|
||||
* code retain the above copyright notice and this comment without
|
||||
* modification.
|
||||
*
|
||||
* Technical updates and product information at:
|
||||
* http://www.psidisk.com
|
||||
*
|
||||
* Please send questions, comments, bug reports to:
|
||||
* tech@psidisk.com Technical Support
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef ROY_HOST
|
||||
#define ROY_HOST
|
||||
|
||||
/************************************************/
|
||||
/* PCI setup */
|
||||
/************************************************/
|
||||
#define VENDOR_PSI 0x1256
|
||||
#define DEVICE_ROY_1 0x5201 /* 'R1' */
|
||||
|
||||
/************************************************/
|
||||
/* controller constants */
|
||||
/************************************************/
|
||||
#define MAXADAPTER 4 // Increase this and the sizes of the arrays below, if you need more.
|
||||
#define MAX_BUS 2
|
||||
#define MAX_UNITS 16
|
||||
#define TIMEOUT_COMMAND 400 // number of milliSecondos for command busy timeout
|
||||
|
||||
/************************************************/
|
||||
/* I/O address offsets */
|
||||
/************************************************/
|
||||
#define RTR_MAILBOX 0x040
|
||||
#define RTR_LOCAL_DOORBELL 0x060
|
||||
#define RTR_PCI_DOORBELL 0x064
|
||||
|
||||
/************************************************/
|
||||
/* */
|
||||
/* Host command codes */
|
||||
/* */
|
||||
/************************************************/
|
||||
#define CMD_READ_CHS 0x01 /* read sectors as specified (CHS mode) */
|
||||
#define CMD_READ 0x02 /* read sectors as specified (RBA mode) */
|
||||
#define CMD_READ_SG 0x03 /* read sectors using scatter/gather list */
|
||||
#define CMD_WRITE_CHS 0x04 /* write sectors as specified (CHS mode) */
|
||||
#define CMD_WRITE 0x05 /* write sectors as specified (RBA mode) */
|
||||
#define CMD_WRITE_SG 0x06 /* write sectors using scatter/gather list (LBA mode) */
|
||||
#define CMD_READ_CHS_SG 0x07 /* read sectors using scatter/gather list (CHS mode) */
|
||||
#define CMD_WRITE_CHS_SG 0x08 /* write sectors using scatter/gather list (CHS mode) */
|
||||
#define CMD_VERIFY_CHS 0x09 /* verify data on sectors as specified (CHS mode) */
|
||||
#define CMD_VERIFY 0x0A /* verify data on sectors as specified (RBA mode) */
|
||||
#define CMD_DASD_CDB 0x0B /* process CDB for a DASD device */
|
||||
#define CMD_DASD_CDB_SG 0x0C /* process CDB for a DASD device with scatter/gather */
|
||||
|
||||
#define CMD_READ_ABS 0x10 /* read absolute disk */
|
||||
#define CMD_WRITE_ABS 0x11 /* write absolute disk */
|
||||
#define CMD_VERIFY_ABS 0x12 /* verify absolute disk */
|
||||
#define CMD_TEST_READY 0x13 /* test unit ready and return status code */
|
||||
#define CMD_LOCK_DOOR 0x14 /* lock device door */
|
||||
#define CMD_UNLOCK_DOOR 0x15 /* unlock device door */
|
||||
#define CMD_EJECT_MEDIA 0x16 /* eject the media */
|
||||
#define CMD_UPDATE_CAP 0x17 /* update capacity information */
|
||||
#define CMD_TEST_PRIV 0x18 /* test and setup private format media */
|
||||
|
||||
|
||||
#define CMD_SCSI_THRU 0x30 /* SCSI pass through CDB */
|
||||
#define CMD_SCSI_THRU_SG 0x31 /* SCSI pass through CDB with scatter/gather */
|
||||
#define CMD_SCSI_REQ_SENSE 0x32 /* SCSI pass through request sense after check condition */
|
||||
|
||||
#define CMD_DASD_RAID_RQ 0x35 /* request DASD RAID drive data */
|
||||
#define CMD_DASD_RAID_RQ0 0x31 /* byte 1 subcommand to query for RAID 0 informatation */
|
||||
#define CMD_DASD_RAID_RQ1 0x32 /* byte 1 subcommand to query for RAID 1 informatation */
|
||||
#define CMD_DASD_RAID_RQ5 0x33 /* byte 1 subcommand to query for RAID 5 informatation */
|
||||
|
||||
#define CMD_DASD_SCSI_INQ 0x36 /* do DASD inquire and return in SCSI format */
|
||||
#define CMD_DASD_CAP 0x37 /* read DASD capacity */
|
||||
#define CMD_DASD_INQ 0x38 /* do DASD inquire for type data and return SCSI/EIDE inquiry */
|
||||
#define CMD_SCSI_INQ 0x39 /* do SCSI inquire */
|
||||
#define CMD_READ_SETUP 0x3A /* Get setup structures from controller */
|
||||
#define CMD_WRITE_SETUP 0x3B /* Put setup structures in controller and burn in flash */
|
||||
#define CMD_READ_CONFIG 0x3C /* Get the entire configuration and setup structures */
|
||||
#define CMD_WRITE_CONFIG 0x3D /* Put the entire configuration and setup structures in flash */
|
||||
|
||||
#define CMD_TEXT_DEVICE 0x3E /* obtain device text */
|
||||
#define CMD_TEXT_SIGNON 0x3F /* get sign on banner */
|
||||
|
||||
#define CMD_QUEUE 0x40 /* any command below this generates a queue tag interrupt to host*/
|
||||
|
||||
#define CMD_PREFETCH 0x40 /* prefetch sectors as specified */
|
||||
#define CMD_TEST_WRITE 0x41 /* Test a device for write protect */
|
||||
#define CMD_LAST_STATUS 0x42 /* get last command status and error data*/
|
||||
#define CMD_ABORT 0x43 /* abort command as specified */
|
||||
#define CMD_ERROR 0x44 /* fetch error code from a tagged op */
|
||||
#define CMD_DONE 0x45 /* done with operation */
|
||||
#define CMD_DIAGNOSTICS 0x46 /* execute controller diagnostics and wait for results */
|
||||
#define CMD_FEATURE_MODE 0x47 /* feature mode control word */
|
||||
#define CMD_DASD_INQUIRE 0x48 /* inquire as to DASD SCSI device (32 possible) */
|
||||
#define CMD_FEATURE_QUERY 0x49 /* query the feature control word */
|
||||
#define CMD_DASD_EJECT 0x4A /* Eject removable media for DASD type */
|
||||
#define CMD_DASD_LOCK 0x4B /* Lock removable media for DASD type */
|
||||
#define CMD_DASD_TYPE 0x4C /* obtain DASD device type */
|
||||
#define CMD_NUM_DEV 0x4D /* obtain the number of devices connected to the controller */
|
||||
#define CMD_GET_PARMS 0x4E /* obtain device parameters */
|
||||
#define CMD_SPECIFY 0x4F /* specify operating system for scatter/gather operations */
|
||||
|
||||
#define CMD_RAID_GET_DEV 0x50 /* read RAID device geometry */
|
||||
#define CMD_RAID_READ 0x51 /* read RAID 1 parameter block */
|
||||
#define CMD_RAID_WRITE 0x52 /* write RAID 1 parameter block */
|
||||
#define CMD_RAID_LITEUP 0x53 /* Light up the drive light for identification */
|
||||
#define CMD_RAID_REBUILD 0x54 /* issue a RAID 1 pair rebuild */
|
||||
#define CMD_RAID_MUTE 0x55 /* mute RAID failure alarm */
|
||||
#define CMD_RAID_FAIL 0x56 /* induce a RAID failure */
|
||||
#define CMD_RAID_STATUS 0x57 /* get status of RAID pair */
|
||||
#define CMD_RAID_STOP 0x58 /* stop any reconstruct in progress */
|
||||
#define CMD_RAID_START 0x59 /* start reconstruct */
|
||||
#define CMD_RAID0_READ 0x5A /* read RAID 0 parameter block */
|
||||
#define CMD_RAID0_WRITE 0x5B /* write RAID 0 parameter block */
|
||||
#define CMD_RAID5_READ 0x5C /* read RAID 5 parameter block */
|
||||
#define CMD_RAID5_WRITE 0x5D /* write RAID 5 parameter block */
|
||||
|
||||
#define CMD_ERASE_TABLES 0x5F /* erase partition table and RAID signatutures */
|
||||
|
||||
#define CMD_SCSI_GET 0x60 /* get SCSI pass through devices */
|
||||
#define CMD_SCSI_TIMEOUT 0x61 /* set SCSI pass through timeout */
|
||||
#define CMD_SCSI_ERROR 0x62 /* get SCSI pass through request sense length and residual data count */
|
||||
#define CMD_GET_SPARMS 0x63 /* get SCSI bus and user parms */
|
||||
#define CMD_SCSI_ABORT 0x64 /* abort by setting time-out to zero */
|
||||
|
||||
#define CMD_CHIRP_CHIRP 0x77 /* make a chirp chirp sound */
|
||||
#define CMD_GET_LAST_DONE 0x78 /* get tag of last done in progress */
|
||||
#define CMD_GET_FEATURES 0x79 /* get feature code and ESN */
|
||||
#define CMD_CLEAR_CACHE 0x7A /* Clear cache on specified device */
|
||||
#define CMD_BIOS_TEST 0x7B /* Test whether or not to load BIOS */
|
||||
#define CMD_WAIT_FLUSH 0x7C /* wait for cache flushed and invalidate read cache */
|
||||
#define CMD_RESET_BUS 0x7D /* reset the SCSI bus */
|
||||
#define CMD_STARTUP_QRY 0x7E /* startup in progress query */
|
||||
#define CMD_RESET 0x7F /* reset the controller */
|
||||
|
||||
#define CMD_RESTART_RESET 0x80 /* reload and restart the controller at any reset issued */
|
||||
#define CMD_SOFT_RESET 0x81 /* do a soft reset NOW! */
|
||||
|
||||
/************************************************/
|
||||
/* */
|
||||
/* Host return errors */
|
||||
/* */
|
||||
/************************************************/
|
||||
#define ERR08_TAGGED 0x80 /* doorbell error ored with tag */
|
||||
|
||||
#define ERR16_NONE 0x0000 /* no errors */
|
||||
#define ERR16_SC_COND_MET 0x0004 /* SCSI status - Condition Met */
|
||||
#define ERR16_CMD 0x0101 /* command error */
|
||||
#define ERR16_SC_CHECK_COND 0x0002 /* SCSI status - Check Condition */
|
||||
#define ERR16_CMD_NOT 0x0201 /* command not supported */
|
||||
#define ERR16_NO_DEVICE 0x0301 /* invalid device selection */
|
||||
#define ERR16_SECTOR 0x0202 /* bad sector */
|
||||
#define ERR16_PROTECT 0x0303 /* write protected */
|
||||
#define ERR16_NOSECTOR 0x0404 /* sector not found */
|
||||
#define ERR16_MEDIA 0x0C0C /* invalid media */
|
||||
#define ERR16_CONTROL 0x2020 /* controller error */
|
||||
#define ERR16_CONTROL_DMA 0x2120 /* controller DMA engine error */
|
||||
#define ERR16_NO_ALARM 0x2220 /* alarm is not active */
|
||||
#define ERR16_OP_BUSY 0x2320 /* operation busy */
|
||||
#define ERR16_SEEK 0x4040 /* seek failure */
|
||||
#define ERR16_DEVICE_FAIL 0x4140 /* device has failed */
|
||||
#define ERR16_TIMEOUT 0x8080 /* timeout error */
|
||||
#define ERR16_DEV_NOT_READY 0xAAAA /* drive not ready */
|
||||
#define ERR16_UNDEFINED 0xBBBB /* undefined error */
|
||||
#define ERR16_WRITE_FAULT 0xCCCC /* write fault */
|
||||
#define ERR16_INVALID_DEV 0x4001 /* invalid device access */
|
||||
#define ERR16_DEVICE_BUSY 0x4002 /* device is busy */
|
||||
#define ERR16_MEMORY 0x4003 /* device pass thru requires too much memory */
|
||||
#define ERR16_NO_FEATURE 0x40FA /* feature no implemented */
|
||||
#define ERR16_NOTAG 0x40FD /* no tag space available */
|
||||
#define ERR16_NOT_READY 0x40FE /* controller not ready error */
|
||||
#define ERR16_SETUP_FLASH 0x5050 /* error when writing setup to flash memory */
|
||||
#define ERR16_SETUP_SIZE 0x5051 /* setup block size error */
|
||||
#define ERR16_SENSE 0xFFFF /* sense opereration failed */
|
||||
#define ERR16_SC_BUSY 0x0008 /* SCSI status - Busy */
|
||||
#define ERR16_SC_RES_CONFL 0x0018 /* SCSI status - Reservation Conflict */
|
||||
#define ERR16_SC_CMD_TERM 0x0022 /* SCSI status - Command Terminated */
|
||||
#define ERR16_SC_OTHER 0x00FF /* SCSI status - not recognized (any value masked) */
|
||||
#define ERR16_MEDIA_CHANGED 0x8001 /* devices media has been changed */
|
||||
|
||||
#define ERR32_NONE 0x00000000 /* no errors */
|
||||
#define ERR32_SC_COND_MET 0x00000004 /* SCSI status - Condition Met */
|
||||
#define ERR32_CMD 0x00010101 /* command error */
|
||||
#define ERR32_SC_CHECK_COND 0x00020002 /* SCSI status - Check Condition */
|
||||
#define ERR32_CMD_NOT 0x00030201 /* command not supported */
|
||||
#define ERR32_NO_DEVICE 0x00040301 /* invalid device selection */
|
||||
#define ERR32_SECTOR 0x00050202 /* bad sector */
|
||||
#define ERR32_PROTECT 0x00060303 /* write protected */
|
||||
#define ERR32_NOSECTOR 0x00070404 /* sector not found */
|
||||
#define ERR32_MEDIA 0x00080C0C /* invalid media */
|
||||
#define ERR32_CONTROL 0x00092020 /* controller error */
|
||||
#define ERR32_CONTROL_DMA 0x000A2120 /* Controller DMA error */
|
||||
#define ERR32_NO_ALARM 0x000B2220 /* alarm is not active */
|
||||
#define ERR32_OP_BUSY 0x000C2320 /* operation busy */
|
||||
#define ERR32_SEEK 0x000D4040 /* seek failure */
|
||||
#define ERR32_DEVICE_FAIL 0x000E4140 /* device has failed */
|
||||
#define ERR32_TIMEOUT 0x000F8080 /* timeout error */
|
||||
#define ERR32_DEV_NOT_READY 0x0010AAAA /* drive not ready */
|
||||
#define ERR32_UNDEFINED 0x0011BBBB /* undefined error */
|
||||
#define ERR32_WRITE_FAULT 0x0012CCCC /* write fault */
|
||||
#define ERR32_INVALID_DEV 0x00134001 /* invalid device access */
|
||||
#define ERR32_DEVICE_BUSY 0x00144002 /* device is busy */
|
||||
#define ERR32_MEMORY 0x00154003 /* device pass thru requires too much memory */
|
||||
#define ERR32_NO_FEATURE 0x001640FA /* feature no implemented */
|
||||
#define ERR32_NOTAG 0x001740FD /* no tag space available */
|
||||
#define ERR32_NOT_READY 0x001840FE /* controller not ready error */
|
||||
#define ERR32_SETUP_FLASH 0x00195050 /* error when writing setup to flash memory */
|
||||
#define ERR32_SETUP_SIZE 0x001A5051 /* setup block size error */
|
||||
#define ERR32_SENSE 0x001BFFFF /* sense opereration failed */
|
||||
#define ERR32_SC_BUSY 0x001C0008 /* SCSI status - Busy */
|
||||
#define ERR32_SC_RES_CONFL 0x001D0018 /* SCSI status - Reservation Conflict */
|
||||
#define ERR32_SC_CMD_TERM 0x001E0022 /* SCSI status - Command Terminated */
|
||||
#define ERR32_SC_OTHER 0x001F00FF /* SCSI status - not recognized (any value masked) */
|
||||
#define ERR32_MEDIA_CHANGED 0x00208001 /* devices media has been changed */
|
||||
|
||||
/************************************************/
|
||||
/* */
|
||||
/* Host Operating System specification codes */
|
||||
/* */
|
||||
/************************************************/
|
||||
#define SPEC_INTERRUPT 0x80 /* specification requires host interrupt */
|
||||
#define SPEC_BACKWARD_SG 0x40 /* specification requires scatter/gather items reversed */
|
||||
#define SPEC_DOS_BLOCK 0x01 /* DOS DASD blocking on pass through */
|
||||
#define SPEC_OS2_V3 0x02 /* OS/2 Warp */
|
||||
#define SPCE_SCO_3242 0x04 /* SCO 3.4.2.2 */
|
||||
#define SPEC_QNX_4X 0x05 /* QNX 4.XX */
|
||||
#define SPEC_NOVELL_NWPA 0x08 /* Novell NWPA scatter/gather support */
|
||||
|
||||
/************************************************/
|
||||
/* */
|
||||
/* Inquire structures */
|
||||
/* */
|
||||
/************************************************/
|
||||
typedef struct _CNT_SCSI_INQ
|
||||
{
|
||||
UCHAR devt; /* 00: device type */
|
||||
UCHAR devtm; /* 01: device type modifier */
|
||||
UCHAR svers; /* 02: SCSI version */
|
||||
UCHAR rfmt; /* 03: response data format */
|
||||
UCHAR adlen; /* 04: additional length of data */
|
||||
UCHAR res1; /* 05: */
|
||||
UCHAR res2; /* 06: */
|
||||
UCHAR fncs; /* 07: functional capabilities */
|
||||
UCHAR vid[8]; /* 08: vendor ID */
|
||||
UCHAR pid[16]; /* 10: product ID */
|
||||
UCHAR rev[4]; /* 20: product revision */
|
||||
} CNT_SCSI_INQ;
|
||||
|
||||
typedef struct _CNT_IDE_INQ
|
||||
{
|
||||
USHORT GeneralConfiguration; /* 00 */
|
||||
USHORT NumberOfCylinders; /* 02 */
|
||||
USHORT Reserved1; /* 04 */
|
||||
USHORT NumberOfHeads; /* 06 */
|
||||
USHORT UnformattedBytesPerTrack; /* 08 */
|
||||
USHORT UnformattedBytesPerSector; /* 0A */
|
||||
USHORT SectorsPerTrack; /* 0C */
|
||||
USHORT VendorUnique1[3]; /* 0E */
|
||||
USHORT SerialNumber[10]; /* 14 */
|
||||
USHORT BufferType; /* 28 */
|
||||
USHORT BufferSectorSize; /* 2A */
|
||||
USHORT NumberOfEccBytes; /* 2C */
|
||||
USHORT FirmwareRevision[4]; /* 2E */
|
||||
USHORT ModelNumber[20]; /* 36 */
|
||||
UCHAR MaximumBlockTransfer; /* 5E */
|
||||
UCHAR VendorUnique2; /* 5F */
|
||||
USHORT DoubleWordIo; /* 60 */
|
||||
USHORT Capabilities; /* 62 */
|
||||
USHORT Reserved2; /* 64 */
|
||||
UCHAR VendorUnique3; /* 66 */
|
||||
UCHAR PioCycleTimingMode; /* 67 */
|
||||
UCHAR VendorUnique4; /* 68 */
|
||||
UCHAR DmaCycleTimingMode; /* 69 */
|
||||
USHORT TranslationFieldsValid; /* 6A */
|
||||
USHORT NumberOfCurrentCylinders; /* 6C */
|
||||
USHORT NumberOfCurrentHeads; /* 6E */
|
||||
USHORT CurrentSectorsPerTrack; /* 70 */
|
||||
ULONG CurrentSectorCapacity; /* 72 */
|
||||
} CNT_IDE_INQ;
|
||||
|
||||
typedef struct _DASD_INQUIRE
|
||||
{
|
||||
ULONG type; /* 0 = SCSI, 1 = IDE */
|
||||
union
|
||||
{
|
||||
CNT_SCSI_INQ scsi; /* SCSI inquire data */
|
||||
CNT_IDE_INQ ide; /* IDE inquire data */
|
||||
} inq;
|
||||
} DASD_INQUIRE;
|
||||
|
||||
/************************************************/
|
||||
/* */
|
||||
/* Device Codes */
|
||||
/* */
|
||||
/************************************************/
|
||||
#define DEVC_DASD 0x00 /* Direct-access Storage Device */
|
||||
#define DEVC_SEQACESS 0x01 /* Sequential-access device */
|
||||
#define DEVC_PRINTER 0x02 /* Printer device */
|
||||
#define DEVC_PROCESSOR 0x03 /* Processor device */
|
||||
#define DEVC_WRITEONCE 0x04 /* Write-once device */
|
||||
#define DEVC_CDROM 0x05 /* CD-ROM device */
|
||||
#define DEVC_SCANNER 0x06 /* Scanner device */
|
||||
#define DEVC_OPTICAL 0x07 /* Optical memory device */
|
||||
#define DEVC_MEDCHGR 0x08 /* Medium changer device */
|
||||
#define DEVC_DASD_REMOVABLE 0x80 /* Direct-access storage device, Removable */
|
||||
#define DEVC_NONE 0xFF /* no device */
|
||||
|
||||
// SCSI controls for RAID
|
||||
#define SC_MY_RAID 0xBF // our special CDB command byte for Win95... interface
|
||||
#define MY_SCSI_QUERY0 0x31 // byte 1 subcommand to query driver for RAID 0 informatation
|
||||
#define MY_SCSI_QUERY1 0x32 // byte 1 subcommand to query driver for RAID 1 informatation
|
||||
#define MY_SCSI_QUERY5 0x33 // byte 1 subcommand to query driver for RAID 5 informatation
|
||||
#define MY_SCSI_REBUILD 0x40 // byte 1 subcommand to reconstruct a mirrored pair
|
||||
#define MY_SCSI_DEMOFAIL 0x54 // byte 1 subcommand for RAID failure demonstration
|
||||
#define MY_SCSI_ALARMMUTE 0x60 // byte 1 subcommand to mute any alarm currently on
|
||||
|
||||
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -4038,11 +4038,10 @@ qla1280_status_entry(struct scsi_qla_host *ha, struct response *pkt,
|
||||
scsi_status, handle);
|
||||
}
|
||||
|
||||
/* Target busy */
|
||||
if (scsi_status & SS_BUSY_CONDITION &&
|
||||
scsi_status != SS_RESERVE_CONFLICT) {
|
||||
CMD_RESULT(cmd) =
|
||||
DID_BUS_BUSY << 16 | (scsi_status & 0xff);
|
||||
/* Target busy or queue full */
|
||||
if ((scsi_status & 0xFF) == SAM_STAT_TASK_SET_FULL ||
|
||||
(scsi_status & 0xFF) == SAM_STAT_BUSY) {
|
||||
CMD_RESULT(cmd) = scsi_status & 0xff;
|
||||
} else {
|
||||
|
||||
/* Save ISP completion status */
|
||||
|
@ -1063,8 +1063,7 @@ qla2x00_print_scsi_cmd(struct scsi_cmnd * cmd)
|
||||
return;
|
||||
|
||||
printk(" sp flags=0x%x\n", sp->flags);
|
||||
printk(" r_start=0x%lx, u_start=0x%lx, f_start=0x%lx, state=%d\n",
|
||||
sp->r_start, sp->u_start, sp->f_start, sp->state);
|
||||
printk(" state=%d\n", sp->state);
|
||||
}
|
||||
|
||||
#if defined(QL_DEBUG_ROUTINES)
|
||||
|
@ -252,31 +252,12 @@ typedef struct srb {
|
||||
/* Request state */
|
||||
uint16_t state;
|
||||
|
||||
/* Timing counts. */
|
||||
unsigned long e_start; /* Start of extend timeout */
|
||||
unsigned long r_start; /* Start of request */
|
||||
unsigned long u_start; /* When sent to RISC */
|
||||
unsigned long f_start; /* When placed in FO queue*/
|
||||
|
||||
/* Single transfer DMA context */
|
||||
dma_addr_t dma_handle;
|
||||
|
||||
uint32_t request_sense_length;
|
||||
uint8_t *request_sense_ptr;
|
||||
|
||||
int ext_history;
|
||||
|
||||
/* Suspend delay */
|
||||
int delay;
|
||||
|
||||
/* Raw completion info for use by failover ? */
|
||||
uint8_t fo_retry_cnt; /* Retry count this request */
|
||||
uint8_t err_id; /* error id */
|
||||
#define SRB_ERR_PORT 1 /* Request failed -- "port down" */
|
||||
#define SRB_ERR_LOOP 2 /* Request failed -- "loop down" */
|
||||
#define SRB_ERR_DEVICE 3 /* Request failed -- "device error" */
|
||||
#define SRB_ERR_OTHER 4
|
||||
|
||||
/* SRB magic number */
|
||||
uint16_t magic;
|
||||
#define SRB_MAGIC 0x10CB
|
||||
@ -2082,23 +2063,8 @@ typedef struct scsi_qla_host {
|
||||
uint32_t current_outstanding_cmd;
|
||||
srb_t *status_srb; /* Status continuation entry. */
|
||||
|
||||
unsigned long last_irq_cpu; /* cpu where we got our last irq */
|
||||
|
||||
uint16_t revision;
|
||||
uint8_t ports;
|
||||
u_long actthreads;
|
||||
u_long ipreq_cnt;
|
||||
u_long qthreads;
|
||||
|
||||
uint32_t total_isr_cnt; /* Interrupt count */
|
||||
uint32_t total_isp_aborts; /* controller err cnt */
|
||||
uint32_t total_lip_cnt; /* LIP cnt */
|
||||
uint32_t total_dev_errs; /* device error cnt */
|
||||
uint32_t total_ios; /* IO cnt */
|
||||
uint64_t total_bytes; /* xfr byte cnt */
|
||||
uint32_t total_mbx_timeout; /* mailbox timeout cnt */
|
||||
uint32_t total_loop_resync; /* loop resyn cnt */
|
||||
uint32_t dropped_frame_error_cnt;
|
||||
|
||||
/* ISP configuration data. */
|
||||
uint16_t loop_id; /* Host adapter loop id */
|
||||
@ -2124,8 +2090,6 @@ typedef struct scsi_qla_host {
|
||||
#define P2P_LOOP 3
|
||||
|
||||
uint8_t marker_needed;
|
||||
uint8_t sns_retry_cnt;
|
||||
uint8_t mem_err;
|
||||
|
||||
uint8_t interrupts_on;
|
||||
|
||||
@ -2138,16 +2102,11 @@ typedef struct scsi_qla_host {
|
||||
uint16_t nvram_base;
|
||||
|
||||
uint16_t loop_reset_delay;
|
||||
uint16_t minimum_timeout;
|
||||
uint8_t retry_count;
|
||||
uint8_t login_timeout;
|
||||
uint16_t r_a_tov;
|
||||
int port_down_retry_count;
|
||||
uint8_t loop_down_timeout;
|
||||
uint8_t mbx_count;
|
||||
uint16_t max_probe_luns;
|
||||
uint16_t max_luns;
|
||||
uint16_t max_targets;
|
||||
uint16_t last_loop_id;
|
||||
|
||||
uint32_t login_retry_count;
|
||||
@ -2181,7 +2140,6 @@ typedef struct scsi_qla_host {
|
||||
uint8_t dpc_active; /* DPC routine is active */
|
||||
|
||||
/* Timeout timers. */
|
||||
uint8_t queue_restart_timer;
|
||||
uint8_t loop_down_abort_time; /* port down timer */
|
||||
atomic_t loop_down_timer; /* loop down timer */
|
||||
uint8_t link_down_timeout; /* link down timeout */
|
||||
@ -2230,18 +2188,6 @@ typedef struct scsi_qla_host {
|
||||
|
||||
mbx_cmd_t mc;
|
||||
|
||||
uint8_t *cmdline;
|
||||
|
||||
uint32_t failover_type;
|
||||
uint32_t failback_delay;
|
||||
unsigned long cfg_flags;
|
||||
#define CFG_ACTIVE 0 /* CFG during a failover, event update, or ioctl */
|
||||
#define CFG_FAILOVER 1 /* CFG during path change */
|
||||
|
||||
uint32_t binding_type;
|
||||
#define BIND_BY_PORT_NAME 0
|
||||
#define BIND_BY_PORT_ID 1
|
||||
|
||||
/* Basic firmware related information. */
|
||||
struct qla_board_info *brd_info;
|
||||
uint16_t fw_major_version;
|
||||
@ -2274,12 +2220,6 @@ typedef struct scsi_qla_host {
|
||||
uint8_t nvram_version;
|
||||
uint32_t isp_abort_cnt;
|
||||
|
||||
/* Adapter I/O statistics for failover */
|
||||
uint64_t IosRequested;
|
||||
uint64_t BytesRequested;
|
||||
uint64_t IosExecuted;
|
||||
uint64_t BytesExecuted;
|
||||
|
||||
/* Needed for BEACON */
|
||||
uint16_t beacon_blink_led;
|
||||
uint16_t beacon_green_on;
|
||||
|
@ -53,27 +53,13 @@ extern void qla2x00_reg_remote_port(scsi_qla_host_t *, fc_port_t *);
|
||||
*/
|
||||
extern char qla2x00_version_str[];
|
||||
|
||||
extern int num_hosts;
|
||||
extern int apiHBAInstance;
|
||||
|
||||
extern struct _qla2x00stats qla2x00_stats;
|
||||
extern int ql2xretrycount;
|
||||
extern int ql2xlogintimeout;
|
||||
extern int qlport_down_retry;
|
||||
extern int ql2xmaxqdepth;
|
||||
extern int displayConfig;
|
||||
extern int ql2xplogiabsentdevice;
|
||||
extern int ql2xenablezio;
|
||||
extern int ql2xintrdelaytimer;
|
||||
extern int ql2xloginretrycount;
|
||||
|
||||
extern int ConfigRequired;
|
||||
|
||||
extern int Bind;
|
||||
extern int ql2xsuspendcount;
|
||||
#if defined(MODULE)
|
||||
extern char *ql2xopts;
|
||||
#endif
|
||||
extern void qla2x00_sp_compl(scsi_qla_host_t *, srb_t *);
|
||||
|
||||
extern char *qla2x00_get_fw_version_str(struct scsi_qla_host *, char *);
|
||||
|
@ -85,9 +85,7 @@ qla2x00_initialize_adapter(scsi_qla_host_t *ha)
|
||||
atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME);
|
||||
atomic_set(&ha->loop_state, LOOP_DOWN);
|
||||
ha->device_flags = 0;
|
||||
ha->sns_retry_cnt = 0;
|
||||
ha->dpc_flags = 0;
|
||||
ha->failback_delay = 0;
|
||||
ha->flags.management_server_logged_in = 0;
|
||||
ha->marker_needed = 0;
|
||||
ha->mbx_flags = 0;
|
||||
@ -171,8 +169,6 @@ check_fw_ready_again:
|
||||
|
||||
if (wait_time == 0)
|
||||
rval = QLA_FUNCTION_FAILED;
|
||||
if (ha->mem_err)
|
||||
restart_risc = 1;
|
||||
} else if (ha->device_flags & DFLG_NO_CABLE)
|
||||
/* If no cable, then all is good. */
|
||||
rval = QLA_SUCCESS;
|
||||
@ -1410,13 +1406,8 @@ qla2x00_nvram_config(scsi_qla_host_t *ha)
|
||||
/* Set minimum RATOV to 200 tenths of a second. */
|
||||
ha->r_a_tov = 200;
|
||||
|
||||
ha->minimum_timeout =
|
||||
(ha->login_timeout * ha->retry_count) + nv->port_down_retry_count;
|
||||
ha->loop_reset_delay = nv->reset_delay;
|
||||
|
||||
/* Will get the value from NVRAM. */
|
||||
ha->loop_down_timeout = LOOP_DOWN_TIMEOUT;
|
||||
|
||||
/* Link Down Timeout = 0:
|
||||
*
|
||||
* When Port Down timer expires we will start returning
|
||||
@ -1429,18 +1420,13 @@ qla2x00_nvram_config(scsi_qla_host_t *ha)
|
||||
*/
|
||||
if (nv->link_down_timeout == 0) {
|
||||
ha->loop_down_abort_time =
|
||||
(LOOP_DOWN_TIME - ha->loop_down_timeout);
|
||||
(LOOP_DOWN_TIME - LOOP_DOWN_TIMEOUT);
|
||||
} else {
|
||||
ha->link_down_timeout = nv->link_down_timeout;
|
||||
ha->loop_down_abort_time =
|
||||
(LOOP_DOWN_TIME - ha->link_down_timeout);
|
||||
}
|
||||
|
||||
ha->max_luns = MAX_LUNS;
|
||||
ha->max_probe_luns = le16_to_cpu(nv->max_luns_per_target);
|
||||
if (ha->max_probe_luns == 0)
|
||||
ha->max_probe_luns = MIN_LUNS;
|
||||
|
||||
/*
|
||||
* Need enough time to try and get the port back.
|
||||
*/
|
||||
@ -1457,16 +1443,6 @@ qla2x00_nvram_config(scsi_qla_host_t *ha)
|
||||
if (ql2xloginretrycount)
|
||||
ha->login_retry_count = ql2xloginretrycount;
|
||||
|
||||
ha->binding_type = Bind;
|
||||
if (ha->binding_type != BIND_BY_PORT_NAME &&
|
||||
ha->binding_type != BIND_BY_PORT_ID) {
|
||||
qla_printk(KERN_WARNING, ha,
|
||||
"Invalid binding type specified (%d), "
|
||||
"defaulting to BIND_BY_PORT_NAME!!!\n", ha->binding_type);
|
||||
|
||||
ha->binding_type = BIND_BY_PORT_NAME;
|
||||
}
|
||||
|
||||
icb->lun_enables = __constant_cpu_to_le16(0);
|
||||
icb->command_resource_count = 0;
|
||||
icb->immediate_notify_resource_count = 0;
|
||||
@ -1578,7 +1554,6 @@ qla2x00_configure_loop(scsi_qla_host_t *ha)
|
||||
*/
|
||||
clear_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags);
|
||||
clear_bit(RSCN_UPDATE, &ha->dpc_flags);
|
||||
ha->mem_err = 0 ;
|
||||
|
||||
/* Determine what we need to do */
|
||||
if (ha->current_topology == ISP_CFG_FL &&
|
||||
@ -2707,7 +2682,6 @@ qla2x00_loop_resync(scsi_qla_host_t *ha)
|
||||
rval = QLA_SUCCESS;
|
||||
|
||||
atomic_set(&ha->loop_state, LOOP_UPDATE);
|
||||
qla2x00_stats.loop_resync++;
|
||||
clear_bit(ISP_ABORT_RETRY, &ha->dpc_flags);
|
||||
if (ha->flags.online) {
|
||||
if (!(rval = qla2x00_fw_ready(ha))) {
|
||||
@ -2786,9 +2760,6 @@ qla2x00_abort_isp(scsi_qla_host_t *ha)
|
||||
if (ha->flags.online) {
|
||||
ha->flags.online = 0;
|
||||
clear_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
|
||||
qla2x00_stats.ispAbort++;
|
||||
ha->total_isp_aborts++; /* used by ioctl */
|
||||
ha->sns_retry_cnt = 0;
|
||||
|
||||
qla_printk(KERN_INFO, ha,
|
||||
"Performing ISP error recovery - ha= %p.\n", ha);
|
||||
@ -2810,8 +2781,6 @@ qla2x00_abort_isp(scsi_qla_host_t *ha)
|
||||
sp = ha->outstanding_cmds[cnt];
|
||||
if (sp) {
|
||||
ha->outstanding_cmds[cnt] = NULL;
|
||||
if (ha->actthreads)
|
||||
ha->actthreads--;
|
||||
sp->flags = 0;
|
||||
sp->cmd->result = DID_RESET << 16;
|
||||
sp->cmd->host_scribble = (unsigned char *)NULL;
|
||||
|
@ -433,11 +433,8 @@ qla2x00_start_scsi(srb_t *sp)
|
||||
} else
|
||||
ha->request_ring_ptr++;
|
||||
|
||||
ha->actthreads++;
|
||||
ha->total_ios++;
|
||||
sp->flags |= SRB_DMA_VALID;
|
||||
sp->state = SRB_ACTIVE_STATE;
|
||||
sp->u_start = jiffies;
|
||||
|
||||
/* Set chip new ring index. */
|
||||
WRT_REG_WORD(ISP_REQ_Q_IN(ha, reg), ha->req_ring_index);
|
||||
|
@ -91,9 +91,6 @@ qla2100_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
|
||||
}
|
||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||
|
||||
ha->last_irq_cpu = _smp_processor_id();
|
||||
ha->total_isr_cnt++;
|
||||
|
||||
if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
|
||||
(status & MBX_INTERRUPT) && ha->flags.mbox_int) {
|
||||
spin_lock_irqsave(&ha->mbx_reg_lock, flags);
|
||||
@ -200,9 +197,6 @@ qla2300_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
|
||||
}
|
||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||
|
||||
ha->last_irq_cpu = _smp_processor_id();
|
||||
ha->total_isr_cnt++;
|
||||
|
||||
if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
|
||||
(status & MBX_INTERRUPT) && ha->flags.mbox_int) {
|
||||
spin_lock_irqsave(&ha->mbx_reg_lock, flags);
|
||||
@ -417,7 +411,6 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint32_t mbx)
|
||||
/* Update AEN queue. */
|
||||
qla2x00_enqueue_aen(ha, MBA_LIP_OCCURRED, NULL);
|
||||
|
||||
ha->total_lip_cnt++;
|
||||
break;
|
||||
|
||||
case MBA_LOOP_UP: /* Loop Up Event */
|
||||
@ -485,7 +478,6 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint32_t mbx)
|
||||
/* Update AEN queue. */
|
||||
qla2x00_enqueue_aen(ha, MBA_LIP_RESET, NULL);
|
||||
|
||||
ha->total_lip_cnt++;
|
||||
break;
|
||||
|
||||
case MBA_POINT_TO_POINT: /* Point-to-Point */
|
||||
@ -695,14 +687,11 @@ qla2x00_process_completed_request(struct scsi_qla_host *ha, uint32_t index)
|
||||
/* Free outstanding command slot. */
|
||||
ha->outstanding_cmds[index] = NULL;
|
||||
|
||||
if (ha->actthreads)
|
||||
ha->actthreads--;
|
||||
CMD_COMPL_STATUS(sp->cmd) = 0L;
|
||||
CMD_SCSI_STATUS(sp->cmd) = 0L;
|
||||
|
||||
/* Save ISP completion status */
|
||||
sp->cmd->result = DID_OK << 16;
|
||||
sp->fo_retry_cnt = 0;
|
||||
qla2x00_sp_compl(ha, sp);
|
||||
} else {
|
||||
DEBUG2(printk("scsi(%ld): Invalid ISP SCSI completion handle\n",
|
||||
@ -865,9 +854,6 @@ qla2x00_status_entry(scsi_qla_host_t *ha, sts_entry_t *pkt)
|
||||
return;
|
||||
}
|
||||
|
||||
if (ha->actthreads)
|
||||
ha->actthreads--;
|
||||
|
||||
comp_status = le16_to_cpu(pkt->comp_status);
|
||||
/* Mask of reserved bits 12-15, before we examine the scsi status */
|
||||
scsi_status = le16_to_cpu(pkt->scsi_status) & SS_MASK;
|
||||
@ -1026,7 +1012,6 @@ qla2x00_status_entry(scsi_qla_host_t *ha, sts_entry_t *pkt)
|
||||
cp->request_bufflen));
|
||||
|
||||
cp->result = DID_BUS_BUSY << 16;
|
||||
ha->dropped_frame_error_cnt++;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1233,8 +1218,7 @@ qla2x00_error_entry(scsi_qla_host_t *ha, sts_entry_t *pkt)
|
||||
if (sp) {
|
||||
/* Free outstanding command slot. */
|
||||
ha->outstanding_cmds[pkt->handle] = NULL;
|
||||
if (ha->actthreads)
|
||||
ha->actthreads--;
|
||||
|
||||
/* Bad payload or header */
|
||||
if (pkt->entry_status &
|
||||
(RF_INV_E_ORDER | RF_INV_E_COUNT |
|
||||
|
@ -219,10 +219,8 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp)
|
||||
ha->flags.mbox_int = 0;
|
||||
clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
|
||||
|
||||
if (ha->mailbox_out[0] != MBS_COMMAND_COMPLETE) {
|
||||
qla2x00_stats.mboxerr++;
|
||||
if (ha->mailbox_out[0] != MBS_COMMAND_COMPLETE)
|
||||
rval = QLA_FUNCTION_FAILED;
|
||||
}
|
||||
|
||||
/* Load return mailbox registers. */
|
||||
iptr2 = mcp->mb;
|
||||
@ -249,8 +247,6 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp)
|
||||
qla2x00_dump_regs(ha);
|
||||
#endif
|
||||
|
||||
qla2x00_stats.mboxtout++;
|
||||
ha->total_mbx_timeout++;
|
||||
rval = QLA_FUNCTION_TIMEOUT;
|
||||
}
|
||||
|
||||
|
@ -36,27 +36,12 @@ char qla2x00_version_str[40];
|
||||
/*
|
||||
* SRB allocation cache
|
||||
*/
|
||||
char srb_cachep_name[16];
|
||||
kmem_cache_t *srb_cachep;
|
||||
|
||||
/*
|
||||
* Stats for all adpaters.
|
||||
*/
|
||||
struct _qla2x00stats qla2x00_stats;
|
||||
static kmem_cache_t *srb_cachep;
|
||||
|
||||
/*
|
||||
* Ioctl related information.
|
||||
*/
|
||||
int num_hosts;
|
||||
int apiHBAInstance;
|
||||
|
||||
/*
|
||||
* Module parameter information and variables
|
||||
*/
|
||||
int ql2xmaxqdepth;
|
||||
module_param(ql2xmaxqdepth, int, S_IRUGO|S_IWUSR);
|
||||
MODULE_PARM_DESC(ql2xmaxqdepth,
|
||||
"Maximum queue depth to report for target devices.");
|
||||
static int num_hosts;
|
||||
|
||||
int ql2xlogintimeout = 20;
|
||||
module_param(ql2xlogintimeout, int, S_IRUGO|S_IRUSR);
|
||||
@ -69,12 +54,6 @@ MODULE_PARM_DESC(qlport_down_retry,
|
||||
"Maximum number of command retries to a port that returns"
|
||||
"a PORT-DOWN status.");
|
||||
|
||||
int ql2xretrycount = 20;
|
||||
module_param(ql2xretrycount, int, S_IRUGO|S_IWUSR);
|
||||
MODULE_PARM_DESC(ql2xretrycount,
|
||||
"Maximum number of mid-layer retries allowed for a command. "
|
||||
"Default value is 20, ");
|
||||
|
||||
int ql2xplogiabsentdevice;
|
||||
module_param(ql2xplogiabsentdevice, int, S_IRUGO|S_IWUSR);
|
||||
MODULE_PARM_DESC(ql2xplogiabsentdevice,
|
||||
@ -95,25 +74,6 @@ MODULE_PARM_DESC(ql2xintrdelaytimer,
|
||||
"ZIO: Waiting time for Firmware before it generates an "
|
||||
"interrupt to the host to notify completion of request.");
|
||||
|
||||
int ConfigRequired;
|
||||
module_param(ConfigRequired, int, S_IRUGO|S_IRUSR);
|
||||
MODULE_PARM_DESC(ConfigRequired,
|
||||
"If 1, then only configured devices passed in through the"
|
||||
"ql2xopts parameter will be presented to the OS");
|
||||
|
||||
int Bind = BIND_BY_PORT_NAME;
|
||||
module_param(Bind, int, S_IRUGO|S_IRUSR);
|
||||
MODULE_PARM_DESC(Bind,
|
||||
"Target persistent binding method: "
|
||||
"0 by Portname (default); 1 by PortID; 2 by Nodename. ");
|
||||
|
||||
int ql2xsuspendcount = SUSPEND_COUNT;
|
||||
module_param(ql2xsuspendcount, int, S_IRUGO|S_IWUSR);
|
||||
MODULE_PARM_DESC(ql2xsuspendcount,
|
||||
"Number of 6-second suspend iterations to perform while a "
|
||||
"target returns a <NOT READY> status. Default is 10 "
|
||||
"iterations.");
|
||||
|
||||
int ql2xloginretrycount = 0;
|
||||
module_param(ql2xloginretrycount, int, S_IRUGO|S_IRUSR);
|
||||
MODULE_PARM_DESC(ql2xloginretrycount,
|
||||
@ -330,7 +290,6 @@ qla2x00_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
|
||||
sp->fcport = fcport;
|
||||
sp->cmd = cmd;
|
||||
sp->flags = 0;
|
||||
sp->err_id = 0;
|
||||
|
||||
CMD_SP(cmd) = (void *)sp;
|
||||
cmd->scsi_done = done;
|
||||
@ -474,7 +433,6 @@ qla2x00_wait_for_loop_ready(scsi_qla_host_t *ha)
|
||||
|
||||
while ((!atomic_read(&ha->loop_down_timer) &&
|
||||
atomic_read(&ha->loop_state) == LOOP_DOWN) ||
|
||||
test_bit(CFG_ACTIVE, &ha->cfg_flags) ||
|
||||
atomic_read(&ha->loop_state) != LOOP_READY) {
|
||||
msleep(1000);
|
||||
if (time_after_eq(jiffies, loop_timeout)) {
|
||||
@ -1194,34 +1152,24 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info)
|
||||
|
||||
spin_lock_init(&ha->hardware_lock);
|
||||
|
||||
/* 4.23 Initialize /proc/scsi/qla2x00 counters */
|
||||
ha->actthreads = 0;
|
||||
ha->qthreads = 0;
|
||||
ha->total_isr_cnt = 0;
|
||||
ha->total_isp_aborts = 0;
|
||||
ha->total_lip_cnt = 0;
|
||||
ha->total_dev_errs = 0;
|
||||
ha->total_ios = 0;
|
||||
ha->total_bytes = 0;
|
||||
|
||||
ha->prev_topology = 0;
|
||||
ha->ports = MAX_BUSES;
|
||||
|
||||
if (IS_QLA2100(ha)) {
|
||||
ha->max_targets = MAX_TARGETS_2100;
|
||||
host->max_id = MAX_TARGETS_2100;
|
||||
ha->mbx_count = MAILBOX_REGISTER_COUNT_2100;
|
||||
ha->request_q_length = REQUEST_ENTRY_CNT_2100;
|
||||
ha->response_q_length = RESPONSE_ENTRY_CNT_2100;
|
||||
ha->last_loop_id = SNS_LAST_LOOP_ID_2100;
|
||||
host->sg_tablesize = 32;
|
||||
} else if (IS_QLA2200(ha)) {
|
||||
ha->max_targets = MAX_TARGETS_2200;
|
||||
host->max_id = MAX_TARGETS_2200;
|
||||
ha->mbx_count = MAILBOX_REGISTER_COUNT;
|
||||
ha->request_q_length = REQUEST_ENTRY_CNT_2200;
|
||||
ha->response_q_length = RESPONSE_ENTRY_CNT_2100;
|
||||
ha->last_loop_id = SNS_LAST_LOOP_ID_2100;
|
||||
} else /*if (IS_QLA2300(ha))*/ {
|
||||
ha->max_targets = MAX_TARGETS_2200;
|
||||
host->max_id = MAX_TARGETS_2200;
|
||||
ha->mbx_count = MAILBOX_REGISTER_COUNT;
|
||||
ha->request_q_length = REQUEST_ENTRY_CNT_2200;
|
||||
ha->response_q_length = RESPONSE_ENTRY_CNT_2300;
|
||||
@ -1265,8 +1213,7 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info)
|
||||
host->unique_id = ha->instance;
|
||||
host->max_cmd_len = MAX_CMDSZ;
|
||||
host->max_channel = ha->ports - 1;
|
||||
host->max_id = ha->max_targets;
|
||||
host->max_lun = ha->max_luns;
|
||||
host->max_lun = MAX_LUNS;
|
||||
host->transportt = qla2xxx_transport_template;
|
||||
if (scsi_add_host(host, &pdev->dev))
|
||||
goto probe_alloc_failed;
|
||||
@ -2336,8 +2283,7 @@ static int __init
|
||||
qla2x00_module_init(void)
|
||||
{
|
||||
/* Allocate cache for SRBs. */
|
||||
sprintf(srb_cachep_name, "qla2xxx_srbs");
|
||||
srb_cachep = kmem_cache_create(srb_cachep_name, sizeof(srb_t), 0,
|
||||
srb_cachep = kmem_cache_create("qla2xxx_srbs", sizeof(srb_t), 0,
|
||||
SLAB_HWCACHE_ALIGN, NULL, NULL);
|
||||
if (srb_cachep == NULL) {
|
||||
printk(KERN_ERR
|
||||
@ -2365,16 +2311,7 @@ qla2x00_module_init(void)
|
||||
static void __exit
|
||||
qla2x00_module_exit(void)
|
||||
{
|
||||
/* Free SRBs cache. */
|
||||
if (srb_cachep != NULL) {
|
||||
if (kmem_cache_destroy(srb_cachep) != 0) {
|
||||
printk(KERN_ERR
|
||||
"qla2xxx: Unable to free SRB cache...Memory pools "
|
||||
"still active?\n");
|
||||
}
|
||||
srb_cachep = NULL;
|
||||
}
|
||||
|
||||
kmem_cache_destroy(srb_cachep);
|
||||
fc_release_transport(qla2xxx_transport_template);
|
||||
}
|
||||
|
||||
|
@ -638,10 +638,12 @@ int scsi_dispatch_cmd(struct scsi_cmnd *cmd)
|
||||
}
|
||||
spin_unlock_irqrestore(host->host_lock, flags);
|
||||
if (rtn) {
|
||||
atomic_inc(&cmd->device->iodone_cnt);
|
||||
scsi_queue_insert(cmd,
|
||||
(rtn == SCSI_MLQUEUE_DEVICE_BUSY) ?
|
||||
rtn : SCSI_MLQUEUE_HOST_BUSY);
|
||||
if (scsi_delete_timer(cmd)) {
|
||||
atomic_inc(&cmd->device->iodone_cnt);
|
||||
scsi_queue_insert(cmd,
|
||||
(rtn == SCSI_MLQUEUE_DEVICE_BUSY) ?
|
||||
rtn : SCSI_MLQUEUE_HOST_BUSY);
|
||||
}
|
||||
SCSI_LOG_MLQUEUE(3,
|
||||
printk("queuecommand : request rejected\n"));
|
||||
}
|
||||
|
@ -434,8 +434,7 @@ static void scsi_eh_times_out(struct scsi_cmnd *scmd)
|
||||
SCSI_LOG_ERROR_RECOVERY(3, printk("%s: scmd:%p\n", __FUNCTION__,
|
||||
scmd));
|
||||
|
||||
if (scmd->device->host->eh_action)
|
||||
up(scmd->device->host->eh_action);
|
||||
up(scmd->device->host->eh_action);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -457,8 +456,7 @@ static void scsi_eh_done(struct scsi_cmnd *scmd)
|
||||
SCSI_LOG_ERROR_RECOVERY(3, printk("%s scmd: %p result: %x\n",
|
||||
__FUNCTION__, scmd, scmd->result));
|
||||
|
||||
if (scmd->device->host->eh_action)
|
||||
up(scmd->device->host->eh_action);
|
||||
up(scmd->device->host->eh_action);
|
||||
}
|
||||
}
|
||||
|
||||
@ -770,6 +768,7 @@ static int scsi_eh_tur(struct scsi_cmnd *scmd)
|
||||
{
|
||||
static unsigned char tur_command[6] = {TEST_UNIT_READY, 0, 0, 0, 0, 0};
|
||||
int retry_cnt = 1, rtn;
|
||||
int saved_result;
|
||||
|
||||
retry_tur:
|
||||
memcpy(scmd->cmnd, tur_command, sizeof(tur_command));
|
||||
@ -780,6 +779,7 @@ retry_tur:
|
||||
*/
|
||||
memset(scmd->sense_buffer, 0, sizeof(scmd->sense_buffer));
|
||||
|
||||
saved_result = scmd->result;
|
||||
scmd->request_buffer = NULL;
|
||||
scmd->request_bufflen = 0;
|
||||
scmd->use_sg = 0;
|
||||
@ -794,6 +794,7 @@ retry_tur:
|
||||
* the original request, so let's restore the original data. (db)
|
||||
*/
|
||||
scsi_setup_cmd_retry(scmd);
|
||||
scmd->result = saved_result;
|
||||
|
||||
/*
|
||||
* hey, we are done. let's look to see what happened.
|
||||
@ -896,6 +897,7 @@ static int scsi_eh_try_stu(struct scsi_cmnd *scmd)
|
||||
{
|
||||
static unsigned char stu_command[6] = {START_STOP, 0, 0, 0, 1, 0};
|
||||
int rtn;
|
||||
int saved_result;
|
||||
|
||||
if (!scmd->device->allow_restart)
|
||||
return 1;
|
||||
@ -908,6 +910,7 @@ static int scsi_eh_try_stu(struct scsi_cmnd *scmd)
|
||||
*/
|
||||
memset(scmd->sense_buffer, 0, sizeof(scmd->sense_buffer));
|
||||
|
||||
saved_result = scmd->result;
|
||||
scmd->request_buffer = NULL;
|
||||
scmd->request_bufflen = 0;
|
||||
scmd->use_sg = 0;
|
||||
@ -922,6 +925,7 @@ static int scsi_eh_try_stu(struct scsi_cmnd *scmd)
|
||||
* the original request, so let's restore the original data. (db)
|
||||
*/
|
||||
scsi_setup_cmd_retry(scmd);
|
||||
scmd->result = saved_result;
|
||||
|
||||
/*
|
||||
* hey, we are done. let's look to see what happened.
|
||||
@ -1561,6 +1565,11 @@ static void scsi_eh_flush_done_q(struct list_head *done_q)
|
||||
scmd));
|
||||
scsi_queue_insert(scmd, SCSI_MLQUEUE_EH_RETRY);
|
||||
} else {
|
||||
/*
|
||||
* If just we got sense for the device (called
|
||||
* scsi_eh_get_sense), scmd->result is already
|
||||
* set, do not set DRIVER_TIMEOUT.
|
||||
*/
|
||||
if (!scmd->result)
|
||||
scmd->result |= (DRIVER_TIMEOUT << 24);
|
||||
SCSI_LOG_ERROR_RECOVERY(3, printk("%s: flush finish"
|
||||
@ -1870,7 +1879,6 @@ scsi_reset_provider(struct scsi_device *dev, int flag)
|
||||
rtn = FAILED;
|
||||
}
|
||||
|
||||
scsi_delete_timer(scmd);
|
||||
scsi_next_command(scmd);
|
||||
return rtn;
|
||||
}
|
||||
|
@ -92,10 +92,12 @@ int scsi_insert_special_req(struct scsi_request *sreq, int at_head)
|
||||
*/
|
||||
sreq->sr_request->flags &= ~REQ_DONTPREP;
|
||||
blk_insert_request(sreq->sr_device->request_queue, sreq->sr_request,
|
||||
at_head, sreq, 0);
|
||||
at_head, sreq);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void scsi_run_queue(struct request_queue *q);
|
||||
|
||||
/*
|
||||
* Function: scsi_queue_insert()
|
||||
*
|
||||
@ -119,18 +121,14 @@ int scsi_queue_insert(struct scsi_cmnd *cmd, int reason)
|
||||
{
|
||||
struct Scsi_Host *host = cmd->device->host;
|
||||
struct scsi_device *device = cmd->device;
|
||||
struct request_queue *q = device->request_queue;
|
||||
unsigned long flags;
|
||||
|
||||
SCSI_LOG_MLQUEUE(1,
|
||||
printk("Inserting command %p into mlqueue\n", cmd));
|
||||
|
||||
/*
|
||||
* We are inserting the command into the ml queue. First, we
|
||||
* cancel the timer, so it doesn't time out.
|
||||
*/
|
||||
scsi_delete_timer(cmd);
|
||||
|
||||
/*
|
||||
* Next, set the appropriate busy bit for the device/host.
|
||||
* Set the appropriate busy bit for the device/host.
|
||||
*
|
||||
* If the host/device isn't busy, assume that something actually
|
||||
* completed, and that we should be able to queue a command now.
|
||||
@ -160,17 +158,22 @@ int scsi_queue_insert(struct scsi_cmnd *cmd, int reason)
|
||||
scsi_device_unbusy(device);
|
||||
|
||||
/*
|
||||
* Insert this command at the head of the queue for it's device.
|
||||
* It will go before all other commands that are already in the queue.
|
||||
* Requeue this command. It will go before all other commands
|
||||
* that are already in the queue.
|
||||
*
|
||||
* NOTE: there is magic here about the way the queue is plugged if
|
||||
* we have no outstanding commands.
|
||||
*
|
||||
* Although this *doesn't* plug the queue, it does call the request
|
||||
* Although we *don't* plug the queue, we call the request
|
||||
* function. The SCSI request function detects the blocked condition
|
||||
* and plugs the queue appropriately.
|
||||
*/
|
||||
blk_insert_request(device->request_queue, cmd->request, 1, cmd, 1);
|
||||
*/
|
||||
spin_lock_irqsave(q->queue_lock, flags);
|
||||
blk_requeue_request(q, cmd->request);
|
||||
spin_unlock_irqrestore(q->queue_lock, flags);
|
||||
|
||||
scsi_run_queue(q);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -485,8 +488,13 @@ static void scsi_run_queue(struct request_queue *q)
|
||||
*/
|
||||
static void scsi_requeue_command(struct request_queue *q, struct scsi_cmnd *cmd)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
cmd->request->flags &= ~REQ_DONTPREP;
|
||||
blk_insert_request(q, cmd->request, 1, cmd, 1);
|
||||
|
||||
spin_lock_irqsave(q->queue_lock, flags);
|
||||
blk_requeue_request(q, cmd->request);
|
||||
spin_unlock_irqrestore(q->queue_lock, flags);
|
||||
|
||||
scsi_run_queue(q);
|
||||
}
|
||||
@ -941,10 +949,8 @@ static int scsi_init_io(struct scsi_cmnd *cmd)
|
||||
* if sg table allocation fails, requeue request later.
|
||||
*/
|
||||
sgpnt = scsi_alloc_sgtable(cmd, GFP_ATOMIC);
|
||||
if (unlikely(!sgpnt)) {
|
||||
req->flags |= REQ_SPECIAL;
|
||||
if (unlikely(!sgpnt))
|
||||
return BLKPREP_DEFER;
|
||||
}
|
||||
|
||||
cmd->request_buffer = (char *) sgpnt;
|
||||
cmd->request_bufflen = req->nr_sectors << 9;
|
||||
|
@ -293,6 +293,10 @@ static void scsi_target_dev_release(struct device *dev)
|
||||
{
|
||||
struct device *parent = dev->parent;
|
||||
struct scsi_target *starget = to_scsi_target(dev);
|
||||
struct Scsi_Host *shost = dev_to_shost(parent);
|
||||
|
||||
if (shost->hostt->target_destroy)
|
||||
shost->hostt->target_destroy(starget);
|
||||
kfree(starget);
|
||||
put_device(parent);
|
||||
}
|
||||
@ -360,9 +364,23 @@ static struct scsi_target *scsi_alloc_target(struct device *parent,
|
||||
list_add_tail(&starget->siblings, &shost->__targets);
|
||||
spin_unlock_irqrestore(shost->host_lock, flags);
|
||||
/* allocate and add */
|
||||
transport_setup_device(&starget->dev);
|
||||
device_add(&starget->dev);
|
||||
transport_add_device(&starget->dev);
|
||||
transport_setup_device(dev);
|
||||
device_add(dev);
|
||||
transport_add_device(dev);
|
||||
if (shost->hostt->target_alloc) {
|
||||
int error = shost->hostt->target_alloc(starget);
|
||||
|
||||
if(error) {
|
||||
dev_printk(KERN_ERR, dev, "target allocation failed, error %d\n", error);
|
||||
/* don't want scsi_target_reap to do the final
|
||||
* put because it will be under the host lock */
|
||||
get_device(dev);
|
||||
scsi_target_reap(starget);
|
||||
put_device(dev);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return starget;
|
||||
|
||||
found:
|
||||
@ -625,6 +643,7 @@ static int scsi_add_lun(struct scsi_device *sdev, char *inq_result, int *bflags)
|
||||
case TYPE_MEDIUM_CHANGER:
|
||||
case TYPE_ENCLOSURE:
|
||||
case TYPE_COMM:
|
||||
case TYPE_RBC:
|
||||
sdev->writeable = 1;
|
||||
break;
|
||||
case TYPE_WORM:
|
||||
|
@ -1368,17 +1368,26 @@ sd_read_write_protect_flag(struct scsi_disk *sdkp, char *diskname,
|
||||
*/
|
||||
static void
|
||||
sd_read_cache_type(struct scsi_disk *sdkp, char *diskname,
|
||||
struct scsi_request *SRpnt, unsigned char *buffer) {
|
||||
struct scsi_request *SRpnt, unsigned char *buffer)
|
||||
{
|
||||
int len = 0, res;
|
||||
|
||||
const int dbd = 0; /* DBD */
|
||||
const int modepage = 0x08; /* current values, cache page */
|
||||
int dbd;
|
||||
int modepage;
|
||||
struct scsi_mode_data data;
|
||||
struct scsi_sense_hdr sshdr;
|
||||
|
||||
if (sdkp->device->skip_ms_page_8)
|
||||
goto defaults;
|
||||
|
||||
if (sdkp->device->type == TYPE_RBC) {
|
||||
modepage = 6;
|
||||
dbd = 8;
|
||||
} else {
|
||||
modepage = 8;
|
||||
dbd = 0;
|
||||
}
|
||||
|
||||
/* cautiously ask */
|
||||
res = sd_do_mode_sense(SRpnt, dbd, modepage, buffer, 4, &data);
|
||||
|
||||
@ -1409,11 +1418,20 @@ sd_read_cache_type(struct scsi_disk *sdkp, char *diskname,
|
||||
"write back, no read (daft)"
|
||||
};
|
||||
int ct = 0;
|
||||
int offset = data.header_length +
|
||||
data.block_descriptor_length + 2;
|
||||
int offset = data.header_length + data.block_descriptor_length;
|
||||
|
||||
sdkp->WCE = ((buffer[offset] & 0x04) != 0);
|
||||
sdkp->RCD = ((buffer[offset] & 0x01) != 0);
|
||||
if ((buffer[offset] & 0x3f) != modepage) {
|
||||
printk(KERN_ERR "%s: got wrong page\n", diskname);
|
||||
goto defaults;
|
||||
}
|
||||
|
||||
if (modepage == 8) {
|
||||
sdkp->WCE = ((buffer[offset + 2] & 0x04) != 0);
|
||||
sdkp->RCD = ((buffer[offset + 2] & 0x01) != 0);
|
||||
} else {
|
||||
sdkp->WCE = ((buffer[offset + 2] & 0x01) == 0);
|
||||
sdkp->RCD = 0;
|
||||
}
|
||||
|
||||
ct = sdkp->RCD + 2*sdkp->WCE;
|
||||
|
||||
@ -1533,7 +1551,7 @@ static int sd_probe(struct device *dev)
|
||||
int error;
|
||||
|
||||
error = -ENODEV;
|
||||
if ((sdp->type != TYPE_DISK) && (sdp->type != TYPE_MOD))
|
||||
if (sdp->type != TYPE_DISK && sdp->type != TYPE_MOD && sdp->type != TYPE_RBC)
|
||||
goto out;
|
||||
|
||||
SCSI_LOG_HLQUEUE(3, printk("sd_attach: scsi device: <%d,%d,%d,%d>\n",
|
||||
@ -1570,7 +1588,7 @@ static int sd_probe(struct device *dev)
|
||||
sdkp->openers = 0;
|
||||
|
||||
if (!sdp->timeout) {
|
||||
if (sdp->type == TYPE_DISK)
|
||||
if (sdp->type != TYPE_MOD)
|
||||
sdp->timeout = SD_TIMEOUT;
|
||||
else
|
||||
sdp->timeout = SD_MOD_TIMEOUT;
|
||||
|
@ -17,7 +17,7 @@
|
||||
Last modified: 18-JAN-1998 Richard Gooch <rgooch@atnf.csiro.au> Devfs support
|
||||
*/
|
||||
|
||||
static char *verstr = "20050312";
|
||||
static char *verstr = "20050501";
|
||||
|
||||
#include <linux/module.h>
|
||||
|
||||
@ -29,6 +29,7 @@ static char *verstr = "20050312";
|
||||
#include <linux/string.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/mtio.h>
|
||||
#include <linux/cdrom.h>
|
||||
#include <linux/ioctl.h>
|
||||
#include <linux/fcntl.h>
|
||||
#include <linux/spinlock.h>
|
||||
@ -50,6 +51,7 @@ static char *verstr = "20050312";
|
||||
#include <scsi/scsi_host.h>
|
||||
#include <scsi/scsi_ioctl.h>
|
||||
#include <scsi/scsi_request.h>
|
||||
#include <scsi/sg.h>
|
||||
|
||||
|
||||
/* The driver prints some debugging information on the console if DEBUG
|
||||
@ -3463,7 +3465,10 @@ static int st_ioctl(struct inode *inode, struct file *file,
|
||||
case SCSI_IOCTL_GET_BUS_NUMBER:
|
||||
break;
|
||||
default:
|
||||
if (!capable(CAP_SYS_ADMIN))
|
||||
if ((cmd_in == SG_IO ||
|
||||
cmd_in == SCSI_IOCTL_SEND_COMMAND ||
|
||||
cmd_in == CDROM_SEND_PACKET) &&
|
||||
!capable(CAP_SYS_RAWIO))
|
||||
i = -EPERM;
|
||||
else
|
||||
i = scsi_cmd_ioctl(file, STp->disk, cmd_in, p);
|
||||
@ -3471,10 +3476,12 @@ static int st_ioctl(struct inode *inode, struct file *file,
|
||||
return i;
|
||||
break;
|
||||
}
|
||||
if (!capable(CAP_SYS_ADMIN) &&
|
||||
(cmd_in == SCSI_IOCTL_START_UNIT || cmd_in == SCSI_IOCTL_STOP_UNIT))
|
||||
return -EPERM;
|
||||
return scsi_ioctl(STp->device, cmd_in, p);
|
||||
retval = scsi_ioctl(STp->device, cmd_in, p);
|
||||
if (!retval && cmd_in == SCSI_IOCTL_STOP_UNIT) { /* unload */
|
||||
STp->rew_at_close = 0;
|
||||
STp->ready = ST_NO_TAPE;
|
||||
}
|
||||
return retval;
|
||||
|
||||
out:
|
||||
up(&STp->lock);
|
||||
|
@ -23,8 +23,6 @@
|
||||
#include <asm/dvma.h>
|
||||
#include <asm/irq.h>
|
||||
|
||||
extern struct NCR_ESP *espchain;
|
||||
|
||||
static void dma_barrier(struct NCR_ESP *esp);
|
||||
static int dma_bytes_sent(struct NCR_ESP *esp, int fifo_count);
|
||||
static int dma_can_transfer(struct NCR_ESP *esp, Scsi_Cmnd *sp);
|
||||
|
@ -40,7 +40,7 @@
|
||||
#ifndef SYM_DEFS_H
|
||||
#define SYM_DEFS_H
|
||||
|
||||
#define SYM_VERSION "2.2.0"
|
||||
#define SYM_VERSION "2.2.1"
|
||||
#define SYM_DRIVER_NAME "sym-" SYM_VERSION
|
||||
|
||||
/*
|
||||
|
@ -155,10 +155,11 @@ pci_get_base_address(struct pci_dev *pdev, int index, unsigned long *basep)
|
||||
base = tmp;
|
||||
if ((tmp & 0x7) == PCI_BASE_ADDRESS_MEM_TYPE_64) {
|
||||
pci_read_config_dword(pdev, PCI_BAR_OFFSET(index++), &tmp);
|
||||
if (tmp > 0)
|
||||
if (tmp > 0) {
|
||||
dev_err(&pdev->dev,
|
||||
"BAR %d is 64-bit, disabling\n", index - 1);
|
||||
base = 0;
|
||||
base = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ((base & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) {
|
||||
@ -389,13 +390,20 @@ static int sym_scatter_no_sglist(struct sym_hcb *np, struct sym_ccb *cp, struct
|
||||
{
|
||||
struct sym_tblmove *data = &cp->phys.data[SYM_CONF_MAX_SG-1];
|
||||
int segment;
|
||||
unsigned int len = cmd->request_bufflen;
|
||||
|
||||
cp->data_len = cmd->request_bufflen;
|
||||
|
||||
if (cmd->request_bufflen) {
|
||||
if (len) {
|
||||
dma_addr_t baddr = map_scsi_single_data(np, cmd);
|
||||
if (baddr) {
|
||||
sym_build_sge(np, data, baddr, cmd->request_bufflen);
|
||||
if (len & 1) {
|
||||
struct sym_tcb *tp = &np->target[cp->target];
|
||||
if (tp->head.wval & EWS) {
|
||||
len++;
|
||||
cp->odd_byte_adjustment++;
|
||||
}
|
||||
}
|
||||
cp->data_len = len;
|
||||
sym_build_sge(np, data, baddr, len);
|
||||
segment = 1;
|
||||
} else {
|
||||
segment = -2;
|
||||
@ -418,6 +426,7 @@ static int sym_scatter(struct sym_hcb *np, struct sym_ccb *cp, struct scsi_cmnd
|
||||
segment = sym_scatter_no_sglist(np, cp, cmd);
|
||||
else if ((use_sg = map_scsi_sg_data(np, cmd)) > 0) {
|
||||
struct scatterlist *scatter = (struct scatterlist *)cmd->buffer;
|
||||
struct sym_tcb *tp = &np->target[cp->target];
|
||||
struct sym_tblmove *data;
|
||||
|
||||
if (use_sg > SYM_CONF_MAX_SG) {
|
||||
@ -431,6 +440,11 @@ static int sym_scatter(struct sym_hcb *np, struct sym_ccb *cp, struct scsi_cmnd
|
||||
dma_addr_t baddr = sg_dma_address(&scatter[segment]);
|
||||
unsigned int len = sg_dma_len(&scatter[segment]);
|
||||
|
||||
if ((len & 1) && (tp->head.wval & EWS)) {
|
||||
len++;
|
||||
cp->odd_byte_adjustment++;
|
||||
}
|
||||
|
||||
sym_build_sge(np, &data[segment], baddr, len);
|
||||
cp->data_len += len;
|
||||
}
|
||||
@ -456,10 +470,8 @@ static int sym_queue_command(struct sym_hcb *np, struct scsi_cmnd *cmd)
|
||||
* Minimal checkings, so that we will not
|
||||
* go outside our tables.
|
||||
*/
|
||||
if (sdev->id == np->myaddr ||
|
||||
sdev->id >= SYM_CONF_MAX_TARGET ||
|
||||
sdev->lun >= SYM_CONF_MAX_LUN) {
|
||||
sym_xpt_done2(np, cmd, CAM_DEV_NOT_THERE);
|
||||
if (sdev->id == np->myaddr) {
|
||||
sym_xpt_done2(np, cmd, DID_NO_CONNECT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -468,28 +480,6 @@ static int sym_queue_command(struct sym_hcb *np, struct scsi_cmnd *cmd)
|
||||
*/
|
||||
tp = &np->target[sdev->id];
|
||||
|
||||
/*
|
||||
* Complete the 1st INQUIRY command with error
|
||||
* condition if the device is flagged NOSCAN
|
||||
* at BOOT in the NVRAM. This may speed up
|
||||
* the boot and maintain coherency with BIOS
|
||||
* device numbering. Clearing the flag allows
|
||||
* user to rescan skipped devices later.
|
||||
* We also return error for devices not flagged
|
||||
* for SCAN LUNS in the NVRAM since some mono-lun
|
||||
* devices behave badly when asked for some non
|
||||
* zero LUN. Btw, this is an absolute hack.:-)
|
||||
*/
|
||||
if (cmd->cmnd[0] == 0x12 || cmd->cmnd[0] == 0x0) {
|
||||
if ((tp->usrflags & SYM_SCAN_BOOT_DISABLED) ||
|
||||
((tp->usrflags & SYM_SCAN_LUNS_DISABLED) &&
|
||||
sdev->lun != 0)) {
|
||||
tp->usrflags &= ~SYM_SCAN_BOOT_DISABLED;
|
||||
sym_xpt_done2(np, cmd, CAM_DEV_NOT_THERE);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Select tagged/untagged.
|
||||
*/
|
||||
@ -511,23 +501,10 @@ static int sym_queue_command(struct sym_hcb *np, struct scsi_cmnd *cmd)
|
||||
*/
|
||||
static inline int sym_setup_cdb(struct sym_hcb *np, struct scsi_cmnd *cmd, struct sym_ccb *cp)
|
||||
{
|
||||
u32 cmd_ba;
|
||||
int cmd_len;
|
||||
|
||||
/*
|
||||
* CDB is 16 bytes max.
|
||||
*/
|
||||
if (cmd->cmd_len > sizeof(cp->cdb_buf)) {
|
||||
sym_set_cam_status(cp->cmd, CAM_REQ_INVALID);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(cp->cdb_buf, cmd->cmnd, cmd->cmd_len);
|
||||
cmd_ba = CCB_BA (cp, cdb_buf[0]);
|
||||
cmd_len = cmd->cmd_len;
|
||||
|
||||
cp->phys.cmd.addr = cpu_to_scr(cmd_ba);
|
||||
cp->phys.cmd.size = cpu_to_scr(cmd_len);
|
||||
cp->phys.cmd.addr = CCB_BA(cp, cdb_buf[0]);
|
||||
cp->phys.cmd.size = cpu_to_scr(cmd->cmd_len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -554,10 +531,7 @@ int sym_setup_data_and_start(struct sym_hcb *np, struct scsi_cmnd *cmd, struct s
|
||||
if (dir != DMA_NONE) {
|
||||
cp->segments = sym_scatter(np, cp, cmd);
|
||||
if (cp->segments < 0) {
|
||||
if (cp->segments == -2)
|
||||
sym_set_cam_status(cmd, CAM_RESRC_UNAVAIL);
|
||||
else
|
||||
sym_set_cam_status(cmd, CAM_REQ_TOO_BIG);
|
||||
sym_set_cam_status(cmd, DID_ERROR);
|
||||
goto out_abort;
|
||||
}
|
||||
} else {
|
||||
@ -855,7 +829,7 @@ prepare:
|
||||
ep->to_do = to_do;
|
||||
/* Complete the command with locks held as required by the driver */
|
||||
if (to_do == SYM_EH_DO_COMPLETE)
|
||||
sym_xpt_done2(np, cmd, CAM_REQ_ABORTED);
|
||||
sym_xpt_done2(np, cmd, DID_ABORT);
|
||||
|
||||
/* Wait for completion with locks released, as required by kernel */
|
||||
if (to_do == SYM_EH_DO_WAIT) {
|
||||
@ -921,7 +895,7 @@ static void sym_tune_dev_queuing(struct sym_tcb *tp, int lun, u_short reqtags)
|
||||
lp->s.reqtags = reqtags;
|
||||
|
||||
if (reqtags != oldtags) {
|
||||
dev_info(&tp->sdev->sdev_target->dev,
|
||||
dev_info(&tp->starget->dev,
|
||||
"tagged command queuing %s, command queue depth %d.\n",
|
||||
lp->s.reqtags ? "enabled" : "disabled",
|
||||
lp->started_limit);
|
||||
@ -981,24 +955,36 @@ static int device_queue_depth(struct sym_hcb *np, int target, int lun)
|
||||
return DEF_DEPTH;
|
||||
}
|
||||
|
||||
static int sym53c8xx_slave_alloc(struct scsi_device *device)
|
||||
static int sym53c8xx_slave_alloc(struct scsi_device *sdev)
|
||||
{
|
||||
struct sym_hcb *np = sym_get_hcb(device->host);
|
||||
struct sym_tcb *tp = &np->target[device->id];
|
||||
if (!tp->sdev)
|
||||
tp->sdev = device;
|
||||
struct sym_hcb *np;
|
||||
struct sym_tcb *tp;
|
||||
|
||||
if (sdev->id >= SYM_CONF_MAX_TARGET || sdev->lun >= SYM_CONF_MAX_LUN)
|
||||
return -ENXIO;
|
||||
|
||||
np = sym_get_hcb(sdev->host);
|
||||
tp = &np->target[sdev->id];
|
||||
|
||||
/*
|
||||
* Fail the device init if the device is flagged NOSCAN at BOOT in
|
||||
* the NVRAM. This may speed up boot and maintain coherency with
|
||||
* BIOS device numbering. Clearing the flag allows the user to
|
||||
* rescan skipped devices later. We also return an error for
|
||||
* devices not flagged for SCAN LUNS in the NVRAM since some single
|
||||
* lun devices behave badly when asked for a non zero LUN.
|
||||
*/
|
||||
|
||||
if ((tp->usrflags & SYM_SCAN_BOOT_DISABLED) ||
|
||||
((tp->usrflags & SYM_SCAN_LUNS_DISABLED) && sdev->lun != 0)) {
|
||||
tp->usrflags &= ~SYM_SCAN_BOOT_DISABLED;
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
tp->starget = sdev->sdev_target;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sym53c8xx_slave_destroy(struct scsi_device *device)
|
||||
{
|
||||
struct sym_hcb *np = sym_get_hcb(device->host);
|
||||
struct sym_tcb *tp = &np->target[device->id];
|
||||
if (tp->sdev == device)
|
||||
tp->sdev = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Linux entry point for device queue sizing.
|
||||
*/
|
||||
@ -1897,6 +1883,7 @@ static int sym_detach(struct sym_hcb *np, struct pci_dev *pdev)
|
||||
*/
|
||||
printk("%s: resetting chip\n", sym_name(np));
|
||||
OUTB(np, nc_istat, SRST);
|
||||
INB(np, nc_mbox1);
|
||||
udelay(10);
|
||||
OUTB(np, nc_istat, 0);
|
||||
|
||||
@ -1915,7 +1902,6 @@ static struct scsi_host_template sym2_template = {
|
||||
.queuecommand = sym53c8xx_queue_command,
|
||||
.slave_alloc = sym53c8xx_slave_alloc,
|
||||
.slave_configure = sym53c8xx_slave_configure,
|
||||
.slave_destroy = sym53c8xx_slave_destroy,
|
||||
.eh_abort_handler = sym53c8xx_eh_abort_handler,
|
||||
.eh_device_reset_handler = sym53c8xx_eh_device_reset_handler,
|
||||
.eh_bus_reset_handler = sym53c8xx_eh_bus_reset_handler,
|
||||
|
@ -141,33 +141,6 @@
|
||||
#define cpu_to_scr(dw) cpu_to_le32(dw)
|
||||
#define scr_to_cpu(dw) le32_to_cpu(dw)
|
||||
|
||||
/*
|
||||
* Remap some status field values.
|
||||
*/
|
||||
#define CAM_REQ_CMP DID_OK
|
||||
#define CAM_SEL_TIMEOUT DID_NO_CONNECT
|
||||
#define CAM_CMD_TIMEOUT DID_TIME_OUT
|
||||
#define CAM_REQ_ABORTED DID_ABORT
|
||||
#define CAM_UNCOR_PARITY DID_PARITY
|
||||
#define CAM_SCSI_BUS_RESET DID_RESET
|
||||
#define CAM_REQUEUE_REQ DID_SOFT_ERROR
|
||||
#define CAM_UNEXP_BUSFREE DID_ERROR
|
||||
#define CAM_SCSI_BUSY DID_BUS_BUSY
|
||||
|
||||
#define CAM_DEV_NOT_THERE DID_NO_CONNECT
|
||||
#define CAM_REQ_INVALID DID_ERROR
|
||||
#define CAM_REQ_TOO_BIG DID_ERROR
|
||||
|
||||
#define CAM_RESRC_UNAVAIL DID_ERROR
|
||||
|
||||
/*
|
||||
* Remap data direction values.
|
||||
*/
|
||||
#define CAM_DIR_NONE DMA_NONE
|
||||
#define CAM_DIR_IN DMA_FROM_DEVICE
|
||||
#define CAM_DIR_OUT DMA_TO_DEVICE
|
||||
#define CAM_DIR_UNKNOWN DMA_BIDIRECTIONAL
|
||||
|
||||
/*
|
||||
* These ones are used as return code from
|
||||
* error recovery handlers under Linux.
|
||||
|
@ -97,7 +97,7 @@ static void sym_print_msg(struct sym_ccb *cp, char *label, u_char *msg)
|
||||
static void sym_print_nego_msg(struct sym_hcb *np, int target, char *label, u_char *msg)
|
||||
{
|
||||
struct sym_tcb *tp = &np->target[target];
|
||||
dev_info(&tp->sdev->sdev_target->dev, "%s: ", label);
|
||||
dev_info(&tp->starget->dev, "%s: ", label);
|
||||
|
||||
sym_show_msg(msg);
|
||||
printf(".\n");
|
||||
@ -149,8 +149,10 @@ static char *sym_scsi_bus_mode(int mode)
|
||||
static void sym_chip_reset (struct sym_hcb *np)
|
||||
{
|
||||
OUTB(np, nc_istat, SRST);
|
||||
INB(np, nc_mbox1);
|
||||
udelay(10);
|
||||
OUTB(np, nc_istat, 0);
|
||||
INB(np, nc_mbox1);
|
||||
udelay(2000); /* For BUS MODE to settle */
|
||||
}
|
||||
|
||||
@ -216,6 +218,7 @@ int sym_reset_scsi_bus(struct sym_hcb *np, int enab_int)
|
||||
OUTB(np, nc_stest3, TE);
|
||||
OUTB(np, nc_dcntl, (np->rv_dcntl & IRQM));
|
||||
OUTB(np, nc_scntl1, CRST);
|
||||
INB(np, nc_mbox1);
|
||||
udelay(200);
|
||||
|
||||
if (!SYM_SETUP_SCSI_BUS_CHECK)
|
||||
@ -280,8 +283,10 @@ static void sym_selectclock(struct sym_hcb *np, u_char scntl3)
|
||||
if (!i)
|
||||
printf("%s: the chip cannot lock the frequency\n",
|
||||
sym_name(np));
|
||||
} else
|
||||
udelay((50+10));
|
||||
} else {
|
||||
INB(np, nc_mbox1);
|
||||
udelay(50+10);
|
||||
}
|
||||
OUTB(np, nc_stest3, HSC); /* Halt the scsi clock */
|
||||
OUTB(np, nc_scntl3, scntl3);
|
||||
OUTB(np, nc_stest1, (DBLEN|DBLSEL));/* Select clock multiplier */
|
||||
@ -1445,7 +1450,7 @@ static void sym_check_goals(struct sym_hcb *np, struct scsi_target *starget,
|
||||
static int sym_prepare_nego(struct sym_hcb *np, struct sym_ccb *cp, u_char *msgptr)
|
||||
{
|
||||
struct sym_tcb *tp = &np->target[cp->target];
|
||||
struct scsi_target *starget = tp->sdev->sdev_target;
|
||||
struct scsi_target *starget = tp->starget;
|
||||
struct sym_trans *goal = &tp->tgoal;
|
||||
int msglen = 0;
|
||||
int nego;
|
||||
@ -1690,7 +1695,7 @@ static void sym_flush_comp_queue(struct sym_hcb *np, int cam_status)
|
||||
if (cam_status)
|
||||
sym_set_cam_status(cmd, cam_status);
|
||||
#ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
|
||||
if (sym_get_cam_status(cmd) == CAM_REQUEUE_REQ) {
|
||||
if (sym_get_cam_status(cmd) == DID_SOFT_ERROR) {
|
||||
struct sym_tcb *tp = &np->target[cp->target];
|
||||
struct sym_lcb *lp = sym_lp(tp, cp->lun);
|
||||
if (lp) {
|
||||
@ -1791,12 +1796,13 @@ void sym_start_up (struct sym_hcb *np, int reason)
|
||||
/*
|
||||
* Wakeup all pending jobs.
|
||||
*/
|
||||
sym_flush_busy_queue(np, CAM_SCSI_BUS_RESET);
|
||||
sym_flush_busy_queue(np, DID_RESET);
|
||||
|
||||
/*
|
||||
* Init chip.
|
||||
*/
|
||||
OUTB(np, nc_istat, 0x00); /* Remove Reset, abort */
|
||||
INB(np, nc_mbox1);
|
||||
udelay(2000); /* The 895 needs time for the bus mode to settle */
|
||||
|
||||
OUTB(np, nc_scntl0, np->rv_scntl0 | 0xc0);
|
||||
@ -1905,6 +1911,7 @@ void sym_start_up (struct sym_hcb *np, int reason)
|
||||
if (np->features & (FE_ULTRA2|FE_ULTRA3)) {
|
||||
OUTONW(np, nc_sien, SBMC);
|
||||
if (reason == 0) {
|
||||
INB(np, nc_mbox1);
|
||||
mdelay(100);
|
||||
INW(np, nc_sist);
|
||||
}
|
||||
@ -2074,7 +2081,7 @@ static void sym_settrans(struct sym_hcb *np, int target, u_char opts, u_char ofs
|
||||
static void sym_setwide(struct sym_hcb *np, int target, u_char wide)
|
||||
{
|
||||
struct sym_tcb *tp = &np->target[target];
|
||||
struct scsi_target *starget = tp->sdev->sdev_target;
|
||||
struct scsi_target *starget = tp->starget;
|
||||
|
||||
if (spi_width(starget) == wide)
|
||||
return;
|
||||
@ -2102,7 +2109,7 @@ sym_setsync(struct sym_hcb *np, int target,
|
||||
u_char ofs, u_char per, u_char div, u_char fak)
|
||||
{
|
||||
struct sym_tcb *tp = &np->target[target];
|
||||
struct scsi_target *starget = tp->sdev->sdev_target;
|
||||
struct scsi_target *starget = tp->starget;
|
||||
u_char wide = (tp->head.wval & EWS) ? BUS_16_BIT : BUS_8_BIT;
|
||||
|
||||
sym_settrans(np, target, 0, ofs, per, wide, div, fak);
|
||||
@ -2129,7 +2136,7 @@ sym_setpprot(struct sym_hcb *np, int target, u_char opts, u_char ofs,
|
||||
u_char per, u_char wide, u_char div, u_char fak)
|
||||
{
|
||||
struct sym_tcb *tp = &np->target[target];
|
||||
struct scsi_target *starget = tp->sdev->sdev_target;
|
||||
struct scsi_target *starget = tp->starget;
|
||||
|
||||
sym_settrans(np, target, opts, ofs, per, wide, div, fak);
|
||||
|
||||
@ -2944,7 +2951,7 @@ unknown_int:
|
||||
* Dequeue from the START queue all CCBs that match
|
||||
* a given target/lun/task condition (-1 means all),
|
||||
* and move them from the BUSY queue to the COMP queue
|
||||
* with CAM_REQUEUE_REQ status condition.
|
||||
* with DID_SOFT_ERROR status condition.
|
||||
* This function is used during error handling/recovery.
|
||||
* It is called with SCRIPTS not running.
|
||||
*/
|
||||
@ -2974,7 +2981,7 @@ sym_dequeue_from_squeue(struct sym_hcb *np, int i, int target, int lun, int task
|
||||
if ((target == -1 || cp->target == target) &&
|
||||
(lun == -1 || cp->lun == lun) &&
|
||||
(task == -1 || cp->tag == task)) {
|
||||
sym_set_cam_status(cp->cmd, CAM_REQUEUE_REQ);
|
||||
sym_set_cam_status(cp->cmd, DID_SOFT_ERROR);
|
||||
sym_remque(&cp->link_ccbq);
|
||||
sym_insque_tail(&cp->link_ccbq, &np->comp_ccbq);
|
||||
}
|
||||
@ -3093,13 +3100,13 @@ static void sym_sir_bad_scsi_status(struct sym_hcb *np, int num, struct sym_ccb
|
||||
/*
|
||||
* Message table indirect structure.
|
||||
*/
|
||||
cp->phys.smsg.addr = cpu_to_scr(CCB_BA(cp, scsi_smsg2));
|
||||
cp->phys.smsg.addr = CCB_BA(cp, scsi_smsg2);
|
||||
cp->phys.smsg.size = cpu_to_scr(msglen);
|
||||
|
||||
/*
|
||||
* sense command
|
||||
*/
|
||||
cp->phys.cmd.addr = cpu_to_scr(CCB_BA(cp, sensecmd));
|
||||
cp->phys.cmd.addr = CCB_BA(cp, sensecmd);
|
||||
cp->phys.cmd.size = cpu_to_scr(6);
|
||||
|
||||
/*
|
||||
@ -3116,7 +3123,7 @@ static void sym_sir_bad_scsi_status(struct sym_hcb *np, int num, struct sym_ccb
|
||||
* sense data
|
||||
*/
|
||||
memset(cp->sns_bbuf, 0, SYM_SNS_BBUF_LEN);
|
||||
cp->phys.sense.addr = cpu_to_scr(CCB_BA(cp, sns_bbuf));
|
||||
cp->phys.sense.addr = CCB_BA(cp, sns_bbuf);
|
||||
cp->phys.sense.size = cpu_to_scr(SYM_SNS_BBUF_LEN);
|
||||
|
||||
/*
|
||||
@ -3198,7 +3205,7 @@ int sym_clear_tasks(struct sym_hcb *np, int cam_status, int target, int lun, int
|
||||
sym_insque_tail(&cp->link_ccbq, &np->comp_ccbq);
|
||||
|
||||
/* Preserve the software timeout condition */
|
||||
if (sym_get_cam_status(cmd) != CAM_CMD_TIMEOUT)
|
||||
if (sym_get_cam_status(cmd) != DID_TIME_OUT)
|
||||
sym_set_cam_status(cmd, cam_status);
|
||||
++i;
|
||||
#if 0
|
||||
@ -3366,7 +3373,7 @@ static void sym_sir_task_recovery(struct sym_hcb *np, int num)
|
||||
* Make sure at least our IO to abort has been dequeued.
|
||||
*/
|
||||
#ifndef SYM_OPT_HANDLE_DEVICE_QUEUEING
|
||||
assert(i && sym_get_cam_status(cp->cmd) == CAM_REQUEUE_REQ);
|
||||
assert(i && sym_get_cam_status(cp->cmd) == DID_SOFT_ERROR);
|
||||
#else
|
||||
sym_remque(&cp->link_ccbq);
|
||||
sym_insque_tail(&cp->link_ccbq, &np->comp_ccbq);
|
||||
@ -3375,9 +3382,9 @@ static void sym_sir_task_recovery(struct sym_hcb *np, int num)
|
||||
* Keep track in cam status of the reason of the abort.
|
||||
*/
|
||||
if (cp->to_abort == 2)
|
||||
sym_set_cam_status(cp->cmd, CAM_CMD_TIMEOUT);
|
||||
sym_set_cam_status(cp->cmd, DID_TIME_OUT);
|
||||
else
|
||||
sym_set_cam_status(cp->cmd, CAM_REQ_ABORTED);
|
||||
sym_set_cam_status(cp->cmd, DID_ABORT);
|
||||
|
||||
/*
|
||||
* Complete with error everything that we have dequeued.
|
||||
@ -3491,7 +3498,7 @@ static void sym_sir_task_recovery(struct sym_hcb *np, int num)
|
||||
* conditions not due to timeout.
|
||||
*/
|
||||
if (cp->to_abort == 2)
|
||||
sym_set_cam_status(cp->cmd, CAM_CMD_TIMEOUT);
|
||||
sym_set_cam_status(cp->cmd, DID_TIME_OUT);
|
||||
cp->to_abort = 0; /* We donnot expect to fail here */
|
||||
break;
|
||||
|
||||
@ -3502,7 +3509,7 @@ static void sym_sir_task_recovery(struct sym_hcb *np, int num)
|
||||
case SIR_ABORT_SENT:
|
||||
target = INB(np, nc_sdid) & 0xf;
|
||||
tp = &np->target[target];
|
||||
starget = tp->sdev->sdev_target;
|
||||
starget = tp->starget;
|
||||
|
||||
/*
|
||||
** If we didn't abort anything, leave here.
|
||||
@ -3551,7 +3558,7 @@ static void sym_sir_task_recovery(struct sym_hcb *np, int num)
|
||||
*/
|
||||
i = (INL(np, nc_scratcha) - np->squeue_ba) / 4;
|
||||
sym_dequeue_from_squeue(np, i, target, lun, -1);
|
||||
sym_clear_tasks(np, CAM_REQ_ABORTED, target, lun, task);
|
||||
sym_clear_tasks(np, DID_ABORT, target, lun, task);
|
||||
sym_flush_comp_queue(np, 0);
|
||||
|
||||
/*
|
||||
@ -3566,7 +3573,7 @@ static void sym_sir_task_recovery(struct sym_hcb *np, int num)
|
||||
* Print to the log the message we intend to send.
|
||||
*/
|
||||
if (num == SIR_TARGET_SELECTED) {
|
||||
dev_info(&tp->sdev->sdev_target->dev, "control msgout:");
|
||||
dev_info(&tp->starget->dev, "control msgout:");
|
||||
sym_printl_hex(np->abrt_msg, np->abrt_tbl.size);
|
||||
np->abrt_tbl.size = cpu_to_scr(np->abrt_tbl.size);
|
||||
}
|
||||
@ -3877,6 +3884,8 @@ int sym_compute_residual(struct sym_hcb *np, struct sym_ccb *cp)
|
||||
resid += (tmp & 0xffffff);
|
||||
}
|
||||
|
||||
resid -= cp->odd_byte_adjustment;
|
||||
|
||||
/*
|
||||
* Hopefully, the result is not too wrong.
|
||||
*/
|
||||
@ -4758,10 +4767,8 @@ struct sym_ccb *sym_get_ccb (struct sym_hcb *np, struct scsi_cmnd *cmd, u_char t
|
||||
}
|
||||
|
||||
#endif
|
||||
/*
|
||||
* Remember all informations needed to free this CCB.
|
||||
*/
|
||||
cp->to_abort = 0;
|
||||
cp->odd_byte_adjustment = 0;
|
||||
cp->tag = tag;
|
||||
cp->order = tag_order;
|
||||
cp->target = tn;
|
||||
@ -5104,7 +5111,7 @@ static void sym_alloc_lcb_tags (struct sym_hcb *np, u_char tn, u_char ln)
|
||||
lp->itlq_tbl = sym_calloc_dma(SYM_CONF_MAX_TASK*4, "ITLQ_TBL");
|
||||
if (!lp->itlq_tbl)
|
||||
goto fail;
|
||||
lp->cb_tags = kcalloc(SYM_CONF_MAX_TASK, 1, GFP_KERNEL);
|
||||
lp->cb_tags = kcalloc(SYM_CONF_MAX_TASK, 1, GFP_ATOMIC);
|
||||
if (!lp->cb_tags) {
|
||||
sym_mfree_dma(lp->itlq_tbl, SYM_CONF_MAX_TASK*4, "ITLQ_TBL");
|
||||
lp->itlq_tbl = NULL;
|
||||
@ -5243,7 +5250,7 @@ int sym_queue_scsiio(struct sym_hcb *np, struct scsi_cmnd *cmd, struct sym_ccb *
|
||||
/*
|
||||
* message
|
||||
*/
|
||||
cp->phys.smsg.addr = cpu_to_scr(CCB_BA(cp, scsi_smsg));
|
||||
cp->phys.smsg.addr = CCB_BA(cp, scsi_smsg);
|
||||
cp->phys.smsg.size = cpu_to_scr(msglen);
|
||||
|
||||
/*
|
||||
@ -5343,7 +5350,7 @@ int sym_abort_scsiio(struct sym_hcb *np, struct scsi_cmnd *cmd, int timed_out)
|
||||
}
|
||||
|
||||
/*
|
||||
* Complete execution of a SCSI command with extented
|
||||
* Complete execution of a SCSI command with extended
|
||||
* error, SCSI status error, or having been auto-sensed.
|
||||
*
|
||||
* The SCRIPTS processor is not running there, so we
|
||||
@ -5441,7 +5448,7 @@ if (resid)
|
||||
/*
|
||||
* Let's requeue it to device.
|
||||
*/
|
||||
sym_set_cam_status(cmd, CAM_REQUEUE_REQ);
|
||||
sym_set_cam_status(cmd, DID_SOFT_ERROR);
|
||||
goto finish;
|
||||
}
|
||||
weirdness:
|
||||
|
@ -444,7 +444,7 @@ struct sym_tcb {
|
||||
*/
|
||||
u_char usrflags;
|
||||
u_short usrtags;
|
||||
struct scsi_device *sdev;
|
||||
struct scsi_target *starget;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -754,10 +754,8 @@ struct sym_ccb {
|
||||
int segments; /* Number of SG segments */
|
||||
|
||||
u8 order; /* Tag type (if tagged command) */
|
||||
unsigned char odd_byte_adjustment; /* odd-sized req on wide bus */
|
||||
|
||||
/*
|
||||
* Miscellaneous status'.
|
||||
*/
|
||||
u_char nego_status; /* Negotiation status */
|
||||
u_char xerr_status; /* Extended error flags */
|
||||
u32 extra_bytes; /* Extraneous bytes transferred */
|
||||
@ -809,7 +807,7 @@ struct sym_ccb {
|
||||
#endif
|
||||
};
|
||||
|
||||
#define CCB_BA(cp,lbl) (cp->ccb_ba + offsetof(struct sym_ccb, lbl))
|
||||
#define CCB_BA(cp,lbl) cpu_to_scr(cp->ccb_ba + offsetof(struct sym_ccb, lbl))
|
||||
|
||||
#ifdef SYM_OPT_HANDLE_DIR_UNKNOWN
|
||||
#define sym_goalp(cp) ((cp->host_flags & HF_DATA_IN) ? cp->goalp : cp->wgoalp)
|
||||
@ -1138,33 +1136,33 @@ static inline void sym_setup_data_pointers(struct sym_hcb *np,
|
||||
* No segments means no data.
|
||||
*/
|
||||
if (!cp->segments)
|
||||
dir = CAM_DIR_NONE;
|
||||
dir = DMA_NONE;
|
||||
|
||||
/*
|
||||
* Set the data pointer.
|
||||
*/
|
||||
switch(dir) {
|
||||
#ifdef SYM_OPT_HANDLE_DIR_UNKNOWN
|
||||
case CAM_DIR_UNKNOWN:
|
||||
case DMA_BIDIRECTIONAL:
|
||||
#endif
|
||||
case CAM_DIR_OUT:
|
||||
case DMA_TO_DEVICE:
|
||||
goalp = SCRIPTA_BA(np, data_out2) + 8;
|
||||
lastp = goalp - 8 - (cp->segments * (2*4));
|
||||
#ifdef SYM_OPT_HANDLE_DIR_UNKNOWN
|
||||
cp->wgoalp = cpu_to_scr(goalp);
|
||||
if (dir != CAM_DIR_UNKNOWN)
|
||||
if (dir != DMA_BIDIRECTIONAL)
|
||||
break;
|
||||
cp->phys.head.wlastp = cpu_to_scr(lastp);
|
||||
/* fall through */
|
||||
#else
|
||||
break;
|
||||
#endif
|
||||
case CAM_DIR_IN:
|
||||
case DMA_FROM_DEVICE:
|
||||
cp->host_flags |= HF_DATA_IN;
|
||||
goalp = SCRIPTA_BA(np, data_in2) + 8;
|
||||
lastp = goalp - 8 - (cp->segments * (2*4));
|
||||
break;
|
||||
case CAM_DIR_NONE:
|
||||
case DMA_NONE:
|
||||
default:
|
||||
#ifdef SYM_OPT_HANDLE_DIR_UNKNOWN
|
||||
cp->host_flags |= HF_DATA_IN;
|
||||
@ -1185,7 +1183,7 @@ static inline void sym_setup_data_pointers(struct sym_hcb *np,
|
||||
/*
|
||||
* If direction is unknown, start at data_io.
|
||||
*/
|
||||
if (dir == CAM_DIR_UNKNOWN)
|
||||
if (dir == DMA_BIDIRECTIONAL)
|
||||
cp->phys.head.savep = cpu_to_scr(SCRIPTB_BA(np, data_io));
|
||||
#endif
|
||||
}
|
||||
|
@ -270,6 +270,7 @@ static void S24C16_set_bit(struct sym_device *np, u_char write_bit, u_char *gpre
|
||||
|
||||
}
|
||||
OUTB(np, nc_gpreg, *gpreg);
|
||||
INB(np, nc_mbox1);
|
||||
udelay(5);
|
||||
}
|
||||
|
||||
@ -547,6 +548,7 @@ static int sym_read_Symbios_nvram(struct sym_device *np, Symbios_nvram *nvram)
|
||||
static void T93C46_Clk(struct sym_device *np, u_char *gpreg)
|
||||
{
|
||||
OUTB(np, nc_gpreg, *gpreg | 0x04);
|
||||
INB(np, nc_mbox1);
|
||||
udelay(2);
|
||||
OUTB(np, nc_gpreg, *gpreg);
|
||||
}
|
||||
@ -574,6 +576,7 @@ static void T93C46_Write_Bit(struct sym_device *np, u_char write_bit, u_char *gp
|
||||
*gpreg |= 0x10;
|
||||
|
||||
OUTB(np, nc_gpreg, *gpreg);
|
||||
INB(np, nc_mbox1);
|
||||
udelay(2);
|
||||
|
||||
T93C46_Clk(np, gpreg);
|
||||
@ -586,6 +589,7 @@ static void T93C46_Stop(struct sym_device *np, u_char *gpreg)
|
||||
{
|
||||
*gpreg &= 0xef;
|
||||
OUTB(np, nc_gpreg, *gpreg);
|
||||
INB(np, nc_mbox1);
|
||||
udelay(2);
|
||||
|
||||
T93C46_Clk(np, gpreg);
|
||||
@ -733,7 +737,8 @@ static int sym_read_parisc_pdc(struct sym_device *np, struct pdc_initiator *pdc)
|
||||
return SYM_PARISC_PDC;
|
||||
}
|
||||
#else
|
||||
static int sym_read_parisc_pdc(struct sym_device *np, struct pdc_initiator *x)
|
||||
static inline int sym_read_parisc_pdc(struct sym_device *np,
|
||||
struct pdc_initiator *x)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -544,7 +544,7 @@ extern void blk_end_sync_rq(struct request *rq);
|
||||
extern void blk_attempt_remerge(request_queue_t *, struct request *);
|
||||
extern void __blk_attempt_remerge(request_queue_t *, struct request *);
|
||||
extern struct request *blk_get_request(request_queue_t *, int, int);
|
||||
extern void blk_insert_request(request_queue_t *, struct request *, int, void *, int);
|
||||
extern void blk_insert_request(request_queue_t *, struct request *, int, void *);
|
||||
extern void blk_requeue_request(request_queue_t *, struct request *);
|
||||
extern void blk_plug_device(request_queue_t *);
|
||||
extern int blk_remove_plug(request_queue_t *);
|
||||
|
168
include/linux/chio.h
Normal file
168
include/linux/chio.h
Normal file
@ -0,0 +1,168 @@
|
||||
/*
|
||||
* ioctl interface for the scsi media changer driver
|
||||
*/
|
||||
|
||||
/* changer element types */
|
||||
#define CHET_MT 0 /* media transport element (robot) */
|
||||
#define CHET_ST 1 /* storage element (media slots) */
|
||||
#define CHET_IE 2 /* import/export element */
|
||||
#define CHET_DT 3 /* data transfer element (tape/cdrom/whatever) */
|
||||
#define CHET_V1 4 /* vendor specific #1 */
|
||||
#define CHET_V2 5 /* vendor specific #2 */
|
||||
#define CHET_V3 6 /* vendor specific #3 */
|
||||
#define CHET_V4 7 /* vendor specific #4 */
|
||||
|
||||
|
||||
/*
|
||||
* CHIOGPARAMS
|
||||
* query changer properties
|
||||
*
|
||||
* CHIOVGPARAMS
|
||||
* query vendor-specific element types
|
||||
*
|
||||
* accessing elements works by specifing type and unit of the element.
|
||||
* for eample, storage elements are addressed with type = CHET_ST and
|
||||
* unit = 0 .. cp_nslots-1
|
||||
*
|
||||
*/
|
||||
struct changer_params {
|
||||
int cp_curpicker; /* current transport element */
|
||||
int cp_npickers; /* number of transport elements (CHET_MT) */
|
||||
int cp_nslots; /* number of storage elements (CHET_ST) */
|
||||
int cp_nportals; /* number of import/export elements (CHET_IE) */
|
||||
int cp_ndrives; /* number of data transfer elements (CHET_DT) */
|
||||
};
|
||||
struct changer_vendor_params {
|
||||
int cvp_n1; /* number of vendor specific elems (CHET_V1) */
|
||||
char cvp_label1[16];
|
||||
int cvp_n2; /* number of vendor specific elems (CHET_V2) */
|
||||
char cvp_label2[16];
|
||||
int cvp_n3; /* number of vendor specific elems (CHET_V3) */
|
||||
char cvp_label3[16];
|
||||
int cvp_n4; /* number of vendor specific elems (CHET_V4) */
|
||||
char cvp_label4[16];
|
||||
int reserved[8];
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* CHIOMOVE
|
||||
* move a medium from one element to another
|
||||
*/
|
||||
struct changer_move {
|
||||
int cm_fromtype; /* type/unit of source element */
|
||||
int cm_fromunit;
|
||||
int cm_totype; /* type/unit of destination element */
|
||||
int cm_tounit;
|
||||
int cm_flags;
|
||||
};
|
||||
#define CM_INVERT 1 /* flag: rotate media (for double-sided like MOD) */
|
||||
|
||||
|
||||
/*
|
||||
* CHIOEXCHANGE
|
||||
* move one medium from element #1 to element #2,
|
||||
* and another one from element #2 to element #3.
|
||||
* element #1 and #3 are allowed to be identical.
|
||||
*/
|
||||
struct changer_exchange {
|
||||
int ce_srctype; /* type/unit of element #1 */
|
||||
int ce_srcunit;
|
||||
int ce_fdsttype; /* type/unit of element #2 */
|
||||
int ce_fdstunit;
|
||||
int ce_sdsttype; /* type/unit of element #3 */
|
||||
int ce_sdstunit;
|
||||
int ce_flags;
|
||||
};
|
||||
#define CE_INVERT1 1
|
||||
#define CE_INVERT2 2
|
||||
|
||||
|
||||
/*
|
||||
* CHIOPOSITION
|
||||
* move the transport element (robot arm) to a specific element.
|
||||
*/
|
||||
struct changer_position {
|
||||
int cp_type;
|
||||
int cp_unit;
|
||||
int cp_flags;
|
||||
};
|
||||
#define CP_INVERT 1
|
||||
|
||||
|
||||
/*
|
||||
* CHIOGSTATUS
|
||||
* get element status for all elements of a specific type
|
||||
*/
|
||||
struct changer_element_status {
|
||||
int ces_type;
|
||||
unsigned char *ces_data;
|
||||
};
|
||||
#define CESTATUS_FULL 0x01 /* full */
|
||||
#define CESTATUS_IMPEXP 0x02 /* media was imported (inserted by sysop) */
|
||||
#define CESTATUS_EXCEPT 0x04 /* error condition */
|
||||
#define CESTATUS_ACCESS 0x08 /* access allowed */
|
||||
#define CESTATUS_EXENAB 0x10 /* element can export media */
|
||||
#define CESTATUS_INENAB 0x20 /* element can import media */
|
||||
|
||||
|
||||
/*
|
||||
* CHIOGELEM
|
||||
* get more detailed status informtion for a single element
|
||||
*/
|
||||
struct changer_get_element {
|
||||
int cge_type; /* type/unit */
|
||||
int cge_unit;
|
||||
int cge_status; /* status */
|
||||
int cge_errno; /* errno */
|
||||
int cge_srctype; /* source element of the last move/exchange */
|
||||
int cge_srcunit;
|
||||
int cge_id; /* scsi id (for data transfer elements) */
|
||||
int cge_lun; /* scsi lun (for data transfer elements) */
|
||||
char cge_pvoltag[36]; /* primary volume tag */
|
||||
char cge_avoltag[36]; /* alternate volume tag */
|
||||
int cge_flags;
|
||||
};
|
||||
/* flags */
|
||||
#define CGE_ERRNO 0x01 /* errno available */
|
||||
#define CGE_INVERT 0x02 /* media inverted */
|
||||
#define CGE_SRC 0x04 /* media src available */
|
||||
#define CGE_IDLUN 0x08 /* ID+LUN available */
|
||||
#define CGE_PVOLTAG 0x10 /* primary volume tag available */
|
||||
#define CGE_AVOLTAG 0x20 /* alternate volume tag available */
|
||||
|
||||
|
||||
/*
|
||||
* CHIOSVOLTAG
|
||||
* set volume tag
|
||||
*/
|
||||
struct changer_set_voltag {
|
||||
int csv_type; /* type/unit */
|
||||
int csv_unit;
|
||||
char csv_voltag[36]; /* volume tag */
|
||||
int csv_flags;
|
||||
};
|
||||
#define CSV_PVOLTAG 0x01 /* primary volume tag */
|
||||
#define CSV_AVOLTAG 0x02 /* alternate volume tag */
|
||||
#define CSV_CLEARTAG 0x04 /* clear volume tag */
|
||||
|
||||
/* ioctls */
|
||||
#define CHIOMOVE _IOW('c', 1,struct changer_move)
|
||||
#define CHIOEXCHANGE _IOW('c', 2,struct changer_exchange)
|
||||
#define CHIOPOSITION _IOW('c', 3,struct changer_position)
|
||||
#define CHIOGPICKER _IOR('c', 4,int) /* not impl. */
|
||||
#define CHIOSPICKER _IOW('c', 5,int) /* not impl. */
|
||||
#define CHIOGPARAMS _IOR('c', 6,struct changer_params)
|
||||
#define CHIOGSTATUS _IOW('c', 8,struct changer_element_status)
|
||||
#define CHIOGELEM _IOW('c',16,struct changer_get_element)
|
||||
#define CHIOINITELEM _IO('c',17)
|
||||
#define CHIOSVOLTAG _IOW('c',18,struct changer_set_voltag)
|
||||
#define CHIOGVPARAMS _IOR('c',19,struct changer_vendor_params)
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* c-basic-offset: 8
|
||||
* End:
|
||||
*/
|
@ -100,6 +100,7 @@
|
||||
#define I2O_MAJOR 80 /* 80->87 */
|
||||
|
||||
#define SHMIQ_MAJOR 85 /* Linux/mips, SGI /dev/shmiq */
|
||||
#define SCSI_CHANGER_MAJOR 86
|
||||
|
||||
#define IDE6_MAJOR 88
|
||||
#define IDE7_MAJOR 89
|
||||
|
@ -41,6 +41,7 @@ extern const char *const scsi_device_types[MAX_SCSI_DEVICE_CODE];
|
||||
#define FORMAT_UNIT 0x04
|
||||
#define READ_BLOCK_LIMITS 0x05
|
||||
#define REASSIGN_BLOCKS 0x07
|
||||
#define INITIALIZE_ELEMENT_STATUS 0x07
|
||||
#define READ_6 0x08
|
||||
#define WRITE_6 0x0a
|
||||
#define SEEK_6 0x0b
|
||||
@ -65,6 +66,7 @@ extern const char *const scsi_device_types[MAX_SCSI_DEVICE_CODE];
|
||||
#define READ_10 0x28
|
||||
#define WRITE_10 0x2a
|
||||
#define SEEK_10 0x2b
|
||||
#define POSITION_TO_ELEMENT 0x2b
|
||||
#define WRITE_VERIFY 0x2e
|
||||
#define VERIFY 0x2f
|
||||
#define SEARCH_HIGH 0x30
|
||||
@ -97,6 +99,7 @@ extern const char *const scsi_device_types[MAX_SCSI_DEVICE_CODE];
|
||||
#define PERSISTENT_RESERVE_OUT 0x5f
|
||||
#define REPORT_LUNS 0xa0
|
||||
#define MOVE_MEDIUM 0xa5
|
||||
#define EXCHANGE_MEDIUM 0xa6
|
||||
#define READ_12 0xa8
|
||||
#define WRITE_12 0xaa
|
||||
#define WRITE_VERIFY_12 0xae
|
||||
@ -210,6 +213,7 @@ static inline int scsi_status_is_good(int status)
|
||||
#define TYPE_COMM 0x09 /* Communications device */
|
||||
#define TYPE_ENCLOSURE 0x0d /* Enclosure Services Device */
|
||||
#define TYPE_RAID 0x0c
|
||||
#define TYPE_RBC 0x0e
|
||||
#define TYPE_NO_LUN 0x7f
|
||||
|
||||
/*
|
||||
|
@ -154,7 +154,9 @@ struct scsi_target {
|
||||
unsigned int id; /* target id ... replace
|
||||
* scsi_device.id eventually */
|
||||
unsigned long create:1; /* signal that it needs to be added */
|
||||
unsigned long starget_data[0];
|
||||
void *hostdata; /* available to low-level driver */
|
||||
unsigned long starget_data[0]; /* for the transport */
|
||||
/* starget_data must be the last element!!!! */
|
||||
} __attribute__((aligned(sizeof(unsigned long))));
|
||||
|
||||
#define to_scsi_target(d) container_of(d, struct scsi_target, dev)
|
||||
|
@ -10,6 +10,7 @@ struct block_device;
|
||||
struct module;
|
||||
struct scsi_cmnd;
|
||||
struct scsi_device;
|
||||
struct scsi_target;
|
||||
struct Scsi_Host;
|
||||
struct scsi_host_cmd_pool;
|
||||
struct scsi_transport_template;
|
||||
@ -227,6 +228,30 @@ struct scsi_host_template {
|
||||
*/
|
||||
void (* slave_destroy)(struct scsi_device *);
|
||||
|
||||
/*
|
||||
* Before the mid layer attempts to scan for a new device attached
|
||||
* to a target where no target currently exists, it will call this
|
||||
* entry in your driver. Should your driver need to allocate any
|
||||
* structs or perform any other init items in order to send commands
|
||||
* to a currently unused target, then this is where you can perform
|
||||
* those allocations.
|
||||
*
|
||||
* Return values: 0 on success, non-0 on failure
|
||||
*
|
||||
* Status: OPTIONAL
|
||||
*/
|
||||
int (* target_alloc)(struct scsi_target *);
|
||||
|
||||
/*
|
||||
* Immediately prior to deallocating the target structure, and
|
||||
* after all activity to attached scsi devices has ceased, the
|
||||
* midlayer calls this point so that the driver may deallocate
|
||||
* and terminate any references to the target.
|
||||
*
|
||||
* Status: OPTIONAL
|
||||
*/
|
||||
void (* target_destroy)(struct scsi_target *);
|
||||
|
||||
/*
|
||||
* fill in this function to allow the queue depth of this host
|
||||
* to be changeable (on a per device basis). returns either
|
||||
|
@ -21,6 +21,7 @@
|
||||
#define SCSI_TRANSPORT_H
|
||||
|
||||
#include <linux/transport_class.h>
|
||||
#include <scsi/scsi_host.h>
|
||||
|
||||
struct scsi_transport_template {
|
||||
/* the attribute containers */
|
||||
@ -32,8 +33,11 @@ struct scsi_transport_template {
|
||||
* space of this size will be left at the end of the
|
||||
* scsi_* structure */
|
||||
int device_size;
|
||||
int device_private_offset;
|
||||
int target_size;
|
||||
int target_private_offset;
|
||||
int host_size;
|
||||
/* no private offset for the host; there's an alternative mechanism */
|
||||
|
||||
/*
|
||||
* True if the transport wants to use a host-based work-queue
|
||||
@ -45,4 +49,38 @@ struct scsi_transport_template {
|
||||
dev_to_shost((tc)->dev)
|
||||
|
||||
|
||||
/* Private area maintenance. The driver requested allocations come
|
||||
* directly after the transport class allocations (if any). The idea
|
||||
* is that you *must* call these only once. The code assumes that the
|
||||
* initial values are the ones the transport specific code requires */
|
||||
static inline void
|
||||
scsi_transport_reserve_target(struct scsi_transport_template * t, int space)
|
||||
{
|
||||
BUG_ON(t->target_private_offset != 0);
|
||||
t->target_private_offset = ALIGN(t->target_size, sizeof(void *));
|
||||
t->target_size = t->target_private_offset + space;
|
||||
}
|
||||
static inline void
|
||||
scsi_transport_reserve_device(struct scsi_transport_template * t, int space)
|
||||
{
|
||||
BUG_ON(t->device_private_offset != 0);
|
||||
t->device_private_offset = ALIGN(t->device_size, sizeof(void *));
|
||||
t->device_size = t->device_private_offset + space;
|
||||
}
|
||||
static inline void *
|
||||
scsi_transport_target_data(struct scsi_target *starget)
|
||||
{
|
||||
struct Scsi_Host *shost = dev_to_shost(&starget->dev);
|
||||
return (u8 *)starget->starget_data
|
||||
+ shost->transportt->target_private_offset;
|
||||
|
||||
}
|
||||
static inline void *
|
||||
scsi_transport_device_data(struct scsi_device *sdev)
|
||||
{
|
||||
struct Scsi_Host *shost = sdev->host;
|
||||
return (u8 *)sdev->sdev_data
|
||||
+ shost->transportt->device_private_offset;
|
||||
}
|
||||
|
||||
#endif /* SCSI_TRANSPORT_H */
|
||||
|
Loading…
Reference in New Issue
Block a user