merge by hand (fix up qla_os.c merge error)

This commit is contained in:
James Bottomley 2005-06-17 18:42:23 -05:00
commit 3237ee78fc
188 changed files with 13451 additions and 19229 deletions

View File

@ -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

View File

@ -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>

View File

@ -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)

View 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>

View File

@ -936,8 +936,7 @@ Details:
*
* Returns SUCCESS if command aborted else FAILED
*
* Locks: struct Scsi_Host::host_lock held (with irqsave) on entry
* and assumed to be held on return.
* Locks: None held
*
* Calling context: kernel thread
*
@ -955,8 +954,7 @@ Details:
*
* Returns SUCCESS if command aborted else FAILED
*
* Locks: struct Scsi_Host::host_lock held (with irqsave) on entry
* and assumed to be held on return.
* Locks: None held
*
* Calling context: kernel thread
*
@ -974,8 +972,7 @@ Details:
*
* Returns SUCCESS if command aborted else FAILED
*
* Locks: struct Scsi_Host::host_lock held (with irqsave) on entry
* and assumed to be held on return.
* Locks: None held
*
* Calling context: kernel thread
*
@ -993,8 +990,7 @@ Details:
*
* Returns SUCCESS if command aborted else FAILED
*
* Locks: struct Scsi_Host::host_lock held (with irqsave) on entry
* and assumed to be held on return.
* Locks: None held
*
* Calling context: kernel thread
*

View File

@ -41,6 +41,7 @@
#include <asm/uaccess.h>
#include <asm/io.h>
#include <linux/dma-mapping.h>
#include <linux/blkdev.h>
#include <linux/genhd.h>
#include <linux/completion.h>
@ -126,8 +127,6 @@ static struct board_type products[] = {
#define MAX_CTLR_ORIG 8
#define CCISS_DMA_MASK 0xFFFFFFFF /* 32 bit DMA */
static ctlr_info_t *hba[MAX_CTLR];
static void do_cciss_request(request_queue_t *q);
@ -2393,11 +2392,6 @@ static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
printk(KERN_ERR "cciss: Unable to Enable PCI device\n");
return( -1);
}
if (pci_set_dma_mask(pdev, CCISS_DMA_MASK ) != 0)
{
printk(KERN_ERR "cciss: Unable to set DMA mask\n");
return(-1);
}
subsystem_vendor_id = pdev->subsystem_vendor;
subsystem_device_id = pdev->subsystem_device;
@ -2747,9 +2741,9 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
hba[i]->pdev = pdev;
/* configure PCI DMA stuff */
if (!pci_set_dma_mask(pdev, 0xffffffffffffffffULL))
if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK))
printk("cciss: using DAC cycles\n");
else if (!pci_set_dma_mask(pdev, 0xffffffff))
else if (!pci_set_dma_mask(pdev, DMA_32BIT_MASK))
printk("cciss: not using DAC cycles\n");
else {
printk("cciss: no suitable DMA available\n");

View File

@ -285,6 +285,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
@ -381,6 +388,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) {

View File

@ -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

View File

@ -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)

View File

@ -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;
}

View File

@ -767,10 +767,8 @@ static void fcp_scsi_done (Scsi_Cmnd *SCpnt)
{
unsigned long flags;
spin_lock_irqsave(SCpnt->device->host->host_lock, flags);
if (FCP_CMND(SCpnt)->done)
FCP_CMND(SCpnt)->done(SCpnt);
spin_unlock_irqrestore(SCpnt->device->host->host_lock, flags);
}
static int fcp_scsi_queue_it(fc_channel *fc, Scsi_Cmnd *SCpnt, fcp_cmnd *fcmd, int prepare)
@ -912,9 +910,7 @@ int fcp_scsi_abort(Scsi_Cmnd *SCpnt)
unsigned long flags;
SCpnt->result = DID_ABORT;
spin_lock_irqsave(SCpnt->device->host->host_lock, flags);
fcmd->done(SCpnt);
spin_unlock_irqrestore(SCpnt->device->host->host_lock, flags);
printk("FC: soft abort\n");
return SUCCESS;
} else {
@ -987,7 +983,10 @@ int fcp_scsi_dev_reset(Scsi_Cmnd *SCpnt)
fc->rst_pkt->request->rq_status = RQ_SCSI_BUSY;
fc->rst_pkt->done = fcp_scsi_reset_done;
spin_lock_irqsave(SCpnt->device->host->host_lock, flags);
fcp_scsi_queue_it(fc, fc->rst_pkt, fcmd, 0);
spin_unlock_irqrestore(SCpnt->device->host->host_lock, flags);
down(&sem);
@ -1006,13 +1005,7 @@ int fcp_scsi_dev_reset(Scsi_Cmnd *SCpnt)
return SUCCESS;
}
int fcp_scsi_bus_reset(Scsi_Cmnd *SCpnt)
{
printk ("FC: bus reset!\n");
return FAILED;
}
int fcp_scsi_host_reset(Scsi_Cmnd *SCpnt)
static int __fcp_scsi_host_reset(Scsi_Cmnd *SCpnt)
{
fc_channel *fc = FC_SCMND(SCpnt);
fcp_cmnd *fcmd = FCP_CMND(SCpnt);
@ -1033,6 +1026,17 @@ int fcp_scsi_host_reset(Scsi_Cmnd *SCpnt)
else return FAILED;
}
int fcp_scsi_host_reset(Scsi_Cmnd *SCpnt)
{
int rc;
spin_lock_irqsave(SCpnt->device->host->host_lock, flags);
rc = __fcp_scsi_host_reset(SCpnt);
spin_unlock_irqrestore(SCpnt->device->host->host_lock, flags);
return rc;
}
static int fcp_els_queue_it(fc_channel *fc, fcp_cmnd *fcmd)
{
long i;

View File

@ -27,7 +27,6 @@ EXPORT_SYMBOL(fc_do_prli);
EXPORT_SYMBOL(fcp_scsi_queuecommand);
EXPORT_SYMBOL(fcp_scsi_abort);
EXPORT_SYMBOL(fcp_scsi_dev_reset);
EXPORT_SYMBOL(fcp_scsi_bus_reset);
EXPORT_SYMBOL(fcp_scsi_host_reset);
#endif /* CONFIG_MODULES */

View File

@ -158,7 +158,6 @@ int fc_do_prli(fc_channel *, unsigned char);
int fcp_scsi_queuecommand(Scsi_Cmnd *, void (* done)(Scsi_Cmnd *));
int fcp_scsi_abort(Scsi_Cmnd *);
int fcp_scsi_dev_reset(Scsi_Cmnd *);
int fcp_scsi_bus_reset(Scsi_Cmnd *);
int fcp_scsi_host_reset(Scsi_Cmnd *);
#endif /* !(_FCP_SCSI_H) */

View File

@ -1071,7 +1071,7 @@ static int sbp2_handle_physdma_read(struct hpsb_host *host, int nodeid, quadlet_
static __inline__ int sbp2_command_conversion_device_type(u8 device_type)
{
return (((device_type == TYPE_DISK) ||
(device_type == TYPE_SDAD) ||
(device_type == TYPE_RBC) ||
(device_type == TYPE_ROM)) ? 1:0);
}
@ -2112,102 +2112,6 @@ static int sbp2_send_command(struct scsi_id_instance_data *scsi_id,
*/
static void sbp2_check_sbp2_command(struct scsi_id_instance_data *scsi_id, unchar *cmd)
{
unchar new_cmd[16];
u8 device_type = SBP2_DEVICE_TYPE (scsi_id->sbp2_device_type_and_lun);
SBP2_DEBUG("sbp2_check_sbp2_command");
switch (*cmd) {
case READ_6:
if (sbp2_command_conversion_device_type(device_type)) {
SBP2_DEBUG("Convert READ_6 to READ_10");
/*
* Need to turn read_6 into read_10
*/
new_cmd[0] = 0x28;
new_cmd[1] = (cmd[1] & 0xe0);
new_cmd[2] = 0x0;
new_cmd[3] = (cmd[1] & 0x1f);
new_cmd[4] = cmd[2];
new_cmd[5] = cmd[3];
new_cmd[6] = 0x0;
new_cmd[7] = 0x0;
new_cmd[8] = cmd[4];
new_cmd[9] = cmd[5];
memcpy(cmd, new_cmd, 10);
}
break;
case WRITE_6:
if (sbp2_command_conversion_device_type(device_type)) {
SBP2_DEBUG("Convert WRITE_6 to WRITE_10");
/*
* Need to turn write_6 into write_10
*/
new_cmd[0] = 0x2a;
new_cmd[1] = (cmd[1] & 0xe0);
new_cmd[2] = 0x0;
new_cmd[3] = (cmd[1] & 0x1f);
new_cmd[4] = cmd[2];
new_cmd[5] = cmd[3];
new_cmd[6] = 0x0;
new_cmd[7] = 0x0;
new_cmd[8] = cmd[4];
new_cmd[9] = cmd[5];
memcpy(cmd, new_cmd, 10);
}
break;
case MODE_SENSE:
if (sbp2_command_conversion_device_type(device_type)) {
SBP2_DEBUG("Convert MODE_SENSE_6 to MODE_SENSE_10");
/*
* Need to turn mode_sense_6 into mode_sense_10
*/
new_cmd[0] = 0x5a;
new_cmd[1] = cmd[1];
new_cmd[2] = cmd[2];
new_cmd[3] = 0x0;
new_cmd[4] = 0x0;
new_cmd[5] = 0x0;
new_cmd[6] = 0x0;
new_cmd[7] = 0x0;
new_cmd[8] = cmd[4];
new_cmd[9] = cmd[5];
memcpy(cmd, new_cmd, 10);
}
break;
case MODE_SELECT:
/*
* TODO. Probably need to change mode select to 10 byte version
*/
default:
break;
}
return;
}
/*
@ -2248,7 +2152,6 @@ static void sbp2_check_sbp2_response(struct scsi_id_instance_data *scsi_id,
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");
@ -2272,14 +2175,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
*/
@ -2288,27 +2183,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;
}
@ -2580,8 +2454,6 @@ static void sbp2scsi_complete_command(struct scsi_id_instance_data *scsi_id,
u32 scsi_status, struct scsi_cmnd *SCpnt,
void (*done)(struct scsi_cmnd *))
{
unsigned long flags;
SBP2_DEBUG("sbp2scsi_complete_command");
/*
@ -2680,18 +2552,15 @@ static void sbp2scsi_complete_command(struct scsi_id_instance_data *scsi_id,
/*
* Tell scsi stack that we're done with this command
*/
spin_lock_irqsave(scsi_id->scsi_host->host_lock,flags);
done (SCpnt);
spin_unlock_irqrestore(scsi_id->scsi_host->host_lock,flags);
return;
}
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;
}
@ -2747,7 +2616,7 @@ static int sbp2scsi_abort(struct scsi_cmnd *SCpnt)
/*
* Called by scsi stack when something has really gone wrong.
*/
static int sbp2scsi_reset(struct scsi_cmnd *SCpnt)
static int __sbp2scsi_reset(struct scsi_cmnd *SCpnt)
{
struct scsi_id_instance_data *scsi_id =
(struct scsi_id_instance_data *)SCpnt->device->host->hostdata[0];
@ -2762,6 +2631,18 @@ static int sbp2scsi_reset(struct scsi_cmnd *SCpnt)
return(SUCCESS);
}
static int sbp2scsi_reset(struct scsi_cmnd *SCpnt)
{
unsigned long flags;
int rc;
spin_lock_irqsave(SCpnt->device->host->host_lock, flags);
rc = __sbp2scsi_reset(SCpnt);
spin_unlock_irqrestore(SCpnt->device->host->host_lock, flags);
return rc;
}
static const char *sbp2scsi_info (struct Scsi_Host *host)
{
return "SCSI emulation for IEEE-1394 SBP-2 Devices";

View File

@ -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")

View File

@ -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).

View File

@ -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

View File

@ -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

View File

@ -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.
* --------------------------------------------------------------------------
*/

View File

@ -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
---------- -------- -------- -------- -------- -------- --------

View File

@ -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.
* --------------------------------------------------------------------------
*/

View File

@ -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;

View File

@ -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
{

View File

@ -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.
* --------------------------------------------------------------------------
*/

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */
/****************************************************************************/

View File

@ -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)

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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 $
*/
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*

View 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);

View File

@ -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) {

View File

@ -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

View File

@ -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);

View 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);

View File

@ -97,11 +97,6 @@ MODULE_PARM_DESC(loglevel,
"FC ERP QDIO CIO Config FSF SCSI Other, "
"levels: 0=none 1=normal 2=devel 3=trace");
#ifdef ZFCP_PRINT_FLAGS
u32 flags_dump = 0;
module_param(flags_dump, uint, 0);
#endif
/****************************************************************/
/************** Functions without logging ***********************/
/****************************************************************/
@ -223,13 +218,20 @@ zfcp_in_els_dbf_event(struct zfcp_adapter *adapter, const char *text,
* Parse "device=..." parameter string.
*/
static int __init
zfcp_device_setup(char *str)
zfcp_device_setup(char *devstr)
{
char *tmp;
char *tmp, *str;
size_t len;
if (!str)
if (!devstr)
return 0;
len = strlen(devstr) + 1;
str = (char *) kmalloc(len, GFP_KERNEL);
if (!str)
goto err_out;
memcpy(str, devstr, len);
tmp = strchr(str, ',');
if (!tmp)
goto err_out;
@ -246,10 +248,12 @@ zfcp_device_setup(char *str)
zfcp_data.init_fcp_lun = simple_strtoull(tmp, &tmp, 0);
if (*tmp != '\0')
goto err_out;
kfree(str);
return 1;
err_out:
ZFCP_LOG_NORMAL("Parse error for device parameter string %s\n", str);
kfree(str);
return 0;
}
@ -525,7 +529,7 @@ zfcp_cfdc_dev_ioctl(struct file *file, unsigned int command,
out:
if (fsf_req != NULL)
zfcp_fsf_req_cleanup(fsf_req);
zfcp_fsf_req_free(fsf_req);
if ((adapter != NULL) && (retval != -ENXIO))
zfcp_adapter_put(adapter);
@ -1154,7 +1158,7 @@ zfcp_adapter_enqueue(struct ccw_device *ccw_device)
INIT_LIST_HEAD(&adapter->port_remove_lh);
/* initialize list of fsf requests */
rwlock_init(&adapter->fsf_req_list_lock);
spin_lock_init(&adapter->fsf_req_list_lock);
INIT_LIST_HEAD(&adapter->fsf_req_list_head);
/* initialize abort lock */
@ -1239,9 +1243,9 @@ zfcp_adapter_dequeue(struct zfcp_adapter *adapter)
zfcp_sysfs_adapter_remove_files(&adapter->ccw_device->dev);
dev_set_drvdata(&adapter->ccw_device->dev, NULL);
/* sanity check: no pending FSF requests */
read_lock_irqsave(&adapter->fsf_req_list_lock, flags);
spin_lock_irqsave(&adapter->fsf_req_list_lock, flags);
retval = !list_empty(&adapter->fsf_req_list_head);
read_unlock_irqrestore(&adapter->fsf_req_list_lock, flags);
spin_unlock_irqrestore(&adapter->fsf_req_list_lock, flags);
if (retval) {
ZFCP_LOG_NORMAL("bug: adapter %s (%p) still in use, "
"%i requests outstanding\n",
@ -1483,19 +1487,15 @@ zfcp_fsf_incoming_els_rscn(struct zfcp_adapter *adapter,
fcp_rscn_element++;
switch (fcp_rscn_element->addr_format) {
case ZFCP_PORT_ADDRESS:
ZFCP_LOG_FLAGS(1, "ZFCP_PORT_ADDRESS\n");
range_mask = ZFCP_PORTS_RANGE_PORT;
break;
case ZFCP_AREA_ADDRESS:
ZFCP_LOG_FLAGS(1, "ZFCP_AREA_ADDRESS\n");
range_mask = ZFCP_PORTS_RANGE_AREA;
break;
case ZFCP_DOMAIN_ADDRESS:
ZFCP_LOG_FLAGS(1, "ZFCP_DOMAIN_ADDRESS\n");
range_mask = ZFCP_PORTS_RANGE_DOMAIN;
break;
case ZFCP_FABRIC_ADDRESS:
ZFCP_LOG_FLAGS(1, "ZFCP_FABRIC_ADDRESS\n");
range_mask = ZFCP_PORTS_RANGE_FABRIC;
break;
default:
@ -1762,7 +1762,10 @@ static void zfcp_ns_gid_pn_handler(unsigned long data)
ct_iu_req = zfcp_sg_to_address(ct->req);
ct_iu_resp = zfcp_sg_to_address(ct->resp);
if ((ct->status != 0) || zfcp_check_ct_response(&ct_iu_resp->header)) {
if (ct->status != 0)
goto failed;
if (zfcp_check_ct_response(&ct_iu_resp->header)) {
/* FIXME: do we need some specific erp entry points */
atomic_set_mask(ZFCP_STATUS_PORT_INVALID_WWPN, &port->status);
goto failed;

View File

@ -62,9 +62,6 @@
#include <linux/syscalls.h>
#include <linux/ioctl.h>
/************************ DEBUG FLAGS *****************************************/
#define ZFCP_PRINT_FLAGS
/********************* GENERAL DEFINES *********************************/
@ -152,8 +149,10 @@ typedef u32 scsi_lun_t;
#define FSF_QTCB_UNSOLICITED_STATUS 0x6305
#define ZFCP_STATUS_READ_FAILED_THRESHOLD 3
#define ZFCP_STATUS_READS_RECOM FSF_STATUS_READS_RECOM
#define ZFCP_EXCHANGE_CONFIG_DATA_RETRIES 6
#define ZFCP_EXCHANGE_CONFIG_DATA_SLEEP 50
/* Do 1st retry in 1 second, then double the timeout for each following retry */
#define ZFCP_EXCHANGE_CONFIG_DATA_FIRST_SLEEP 100
#define ZFCP_EXCHANGE_CONFIG_DATA_RETRIES 7
/* timeout value for "default timer" for fsf requests */
#define ZFCP_FSF_REQUEST_TIMEOUT (60*HZ);
@ -472,17 +471,6 @@ do { \
ZFCP_LOG(ZFCP_LOG_LEVEL_TRACE, fmt , ##args)
#endif
#ifndef ZFCP_PRINT_FLAGS
# define ZFCP_LOG_FLAGS(level, fmt, args...)
#else
extern u32 flags_dump;
# define ZFCP_LOG_FLAGS(level, fmt, args...) \
do { \
if (level <= flags_dump) \
_ZFCP_LOG(fmt, ##args); \
} while (0)
#endif
/*************** ADAPTER/PORT/UNIT AND FSF_REQ STATUS FLAGS ******************/
/*
@ -502,6 +490,7 @@ do { \
#define ZFCP_STATUS_COMMON_CLOSING 0x02000000
#define ZFCP_STATUS_COMMON_ERP_INUSE 0x01000000
#define ZFCP_STATUS_COMMON_ACCESS_DENIED 0x00800000
#define ZFCP_STATUS_COMMON_ACCESS_BOXED 0x00400000
/* adapter status */
#define ZFCP_STATUS_ADAPTER_QDIOUP 0x00000002
@ -763,6 +752,7 @@ typedef void (*zfcp_send_els_handler_t)(unsigned long);
/**
* struct zfcp_send_els - used to pass parameters to function zfcp_fsf_send_els
* @adapter: adapter where request is sent from
* @port: port where ELS is destinated (port reference count has to be increased)
* @d_id: destiniation id of port where request is sent to
* @req: scatter-gather list for request
* @resp: scatter-gather list for response
@ -777,6 +767,7 @@ typedef void (*zfcp_send_els_handler_t)(unsigned long);
*/
struct zfcp_send_els {
struct zfcp_adapter *adapter;
struct zfcp_port *port;
fc_id_t d_id;
struct scatterlist *req;
struct scatterlist *resp;
@ -871,7 +862,7 @@ struct zfcp_adapter {
u32 ports; /* number of remote ports */
struct timer_list scsi_er_timer; /* SCSI err recovery watch */
struct list_head fsf_req_list_head; /* head of FSF req list */
rwlock_t fsf_req_list_lock; /* lock for ops on list of
spinlock_t fsf_req_list_lock; /* lock for ops on list of
FSF requests */
atomic_t fsf_reqs_active; /* # active FSF reqs */
struct zfcp_qdio_queue request_queue; /* request queue */

View File

@ -35,7 +35,7 @@
#include "zfcp_ext.h"
static int zfcp_erp_adisc(struct zfcp_adapter *, fc_id_t);
static int zfcp_erp_adisc(struct zfcp_port *);
static void zfcp_erp_adisc_handler(unsigned long);
static int zfcp_erp_adapter_reopen_internal(struct zfcp_adapter *, int);
@ -295,12 +295,12 @@ zfcp_erp_unit_shutdown(struct zfcp_unit *unit, int clear_mask)
/**
* zfcp_erp_adisc - send ADISC ELS command
* @adapter: adapter structure
* @d_id: d_id of port where ADISC is sent to
* @port: port structure
*/
int
zfcp_erp_adisc(struct zfcp_adapter *adapter, fc_id_t d_id)
zfcp_erp_adisc(struct zfcp_port *port)
{
struct zfcp_adapter *adapter = port->adapter;
struct zfcp_send_els *send_els;
struct zfcp_ls_adisc *adisc;
void *address = NULL;
@ -332,7 +332,8 @@ zfcp_erp_adisc(struct zfcp_adapter *adapter, fc_id_t d_id)
send_els->req_count = send_els->resp_count = 1;
send_els->adapter = adapter;
send_els->d_id = d_id;
send_els->port = port;
send_els->d_id = port->d_id;
send_els->handler = zfcp_erp_adisc_handler;
send_els->handler_data = (unsigned long) send_els;
@ -350,7 +351,7 @@ zfcp_erp_adisc(struct zfcp_adapter *adapter, fc_id_t d_id)
ZFCP_LOG_INFO("ADISC request from s_id 0x%08x to d_id 0x%08x "
"(wwpn=0x%016Lx, wwnn=0x%016Lx, "
"hard_nport_id=0x%08x, nport_id=0x%08x)\n",
adapter->s_id, d_id, (wwn_t) adisc->wwpn,
adapter->s_id, send_els->d_id, (wwn_t) adisc->wwpn,
(wwn_t) adisc->wwnn, adisc->hard_nport_id,
adisc->nport_id);
@ -367,7 +368,7 @@ zfcp_erp_adisc(struct zfcp_adapter *adapter, fc_id_t d_id)
retval = zfcp_fsf_send_els(send_els);
if (retval != 0) {
ZFCP_LOG_NORMAL("error: initiation of Send ELS failed for port "
"0x%08x on adapter %s\n", d_id,
"0x%08x on adapter %s\n", send_els->d_id,
zfcp_get_busid_by_adapter(adapter));
del_timer(send_els->timer);
goto freemem;
@ -411,14 +412,9 @@ zfcp_erp_adisc_handler(unsigned long data)
del_timer(send_els->timer);
adapter = send_els->adapter;
port = send_els->port;
d_id = send_els->d_id;
read_lock(&zfcp_data.config_lock);
port = zfcp_get_port_by_did(send_els->adapter, send_els->d_id);
read_unlock(&zfcp_data.config_lock);
BUG_ON(port == NULL);
/* request rejected or timed out */
if (send_els->status != 0) {
ZFCP_LOG_NORMAL("ELS request rejected/timed out, "
@ -482,7 +478,7 @@ zfcp_test_link(struct zfcp_port *port)
int retval;
zfcp_port_get(port);
retval = zfcp_erp_adisc(port->adapter, port->d_id);
retval = zfcp_erp_adisc(port);
if (retval != 0) {
zfcp_port_put(port);
ZFCP_LOG_NORMAL("reopen needed for port 0x%016Lx "
@ -895,7 +891,7 @@ zfcp_erp_strategy_check_fsfreq(struct zfcp_erp_action *erp_action)
if (erp_action->fsf_req) {
/* take lock to ensure that request is not being deleted meanwhile */
write_lock(&adapter->fsf_req_list_lock);
spin_lock(&adapter->fsf_req_list_lock);
/* check whether fsf req does still exist */
list_for_each_entry(fsf_req, &adapter->fsf_req_list_head, list)
if (fsf_req == erp_action->fsf_req)
@ -938,7 +934,7 @@ zfcp_erp_strategy_check_fsfreq(struct zfcp_erp_action *erp_action)
*/
erp_action->fsf_req = NULL;
}
write_unlock(&adapter->fsf_req_list_lock);
spin_unlock(&adapter->fsf_req_list_lock);
} else
debug_text_event(adapter->erp_dbf, 3, "a_ca_noreq");
@ -2286,12 +2282,12 @@ zfcp_erp_adapter_strategy_open_fsf_xconfig(struct zfcp_erp_action *erp_action)
{
int retval = ZFCP_ERP_SUCCEEDED;
int retries;
int sleep = ZFCP_EXCHANGE_CONFIG_DATA_FIRST_SLEEP;
struct zfcp_adapter *adapter = erp_action->adapter;
atomic_clear_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK, &adapter->status);
retries = ZFCP_EXCHANGE_CONFIG_DATA_RETRIES;
do {
for (retries = ZFCP_EXCHANGE_CONFIG_DATA_RETRIES; retries; retries--) {
atomic_clear_mask(ZFCP_STATUS_ADAPTER_HOST_CON_INIT,
&adapter->status);
ZFCP_LOG_DEBUG("Doing exchange config data\n");
@ -2329,16 +2325,17 @@ zfcp_erp_adapter_strategy_open_fsf_xconfig(struct zfcp_erp_action *erp_action)
zfcp_get_busid_by_adapter(adapter));
break;
}
if (atomic_test_mask(ZFCP_STATUS_ADAPTER_HOST_CON_INIT,
&adapter->status)) {
ZFCP_LOG_DEBUG("host connection still initialising... "
"waiting and retrying...\n");
/* sleep a little bit before retry */
msleep(jiffies_to_msecs(ZFCP_EXCHANGE_CONFIG_DATA_SLEEP));
}
} while ((retries--) &&
atomic_test_mask(ZFCP_STATUS_ADAPTER_HOST_CON_INIT,
&adapter->status));
if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_HOST_CON_INIT,
&adapter->status))
break;
ZFCP_LOG_DEBUG("host connection still initialising... "
"waiting and retrying...\n");
/* sleep a little bit before retry */
msleep(jiffies_to_msecs(sleep));
sleep *= 2;
}
if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK,
&adapter->status)) {
@ -3484,6 +3481,45 @@ zfcp_erp_action_to_ready(struct zfcp_erp_action *erp_action)
list_move(&erp_action->list, &erp_action->adapter->erp_ready_head);
}
/*
* function: zfcp_erp_port_boxed
*
* purpose:
*/
void
zfcp_erp_port_boxed(struct zfcp_port *port)
{
struct zfcp_adapter *adapter = port->adapter;
unsigned long flags;
debug_text_event(adapter->erp_dbf, 3, "p_access_boxed");
debug_event(adapter->erp_dbf, 3, &port->wwpn, sizeof(wwn_t));
read_lock_irqsave(&zfcp_data.config_lock, flags);
zfcp_erp_modify_port_status(port,
ZFCP_STATUS_COMMON_ACCESS_BOXED,
ZFCP_SET);
read_unlock_irqrestore(&zfcp_data.config_lock, flags);
zfcp_erp_port_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED);
}
/*
* function: zfcp_erp_unit_boxed
*
* purpose:
*/
void
zfcp_erp_unit_boxed(struct zfcp_unit *unit)
{
struct zfcp_adapter *adapter = unit->port->adapter;
debug_text_event(adapter->erp_dbf, 3, "u_access_boxed");
debug_event(adapter->erp_dbf, 3, &unit->fcp_lun, sizeof(fcp_lun_t));
zfcp_erp_modify_unit_status(unit,
ZFCP_STATUS_COMMON_ACCESS_BOXED,
ZFCP_SET);
zfcp_erp_unit_reopen(unit, ZFCP_STATUS_COMMON_ERP_FAILED);
}
/*
* function: zfcp_erp_port_access_denied
*
@ -3495,11 +3531,13 @@ zfcp_erp_port_access_denied(struct zfcp_port *port)
struct zfcp_adapter *adapter = port->adapter;
unsigned long flags;
debug_text_event(adapter->erp_dbf, 3, "p_access_block");
debug_text_event(adapter->erp_dbf, 3, "p_access_denied");
debug_event(adapter->erp_dbf, 3, &port->wwpn, sizeof(wwn_t));
read_lock_irqsave(&zfcp_data.config_lock, flags);
zfcp_erp_modify_port_status(port, ZFCP_STATUS_COMMON_ERP_FAILED |
ZFCP_STATUS_COMMON_ACCESS_DENIED, ZFCP_SET);
zfcp_erp_modify_port_status(port,
ZFCP_STATUS_COMMON_ERP_FAILED |
ZFCP_STATUS_COMMON_ACCESS_DENIED,
ZFCP_SET);
read_unlock_irqrestore(&zfcp_data.config_lock, flags);
}
@ -3513,10 +3551,12 @@ zfcp_erp_unit_access_denied(struct zfcp_unit *unit)
{
struct zfcp_adapter *adapter = unit->port->adapter;
debug_text_event(adapter->erp_dbf, 3, "u_access_block");
debug_text_event(adapter->erp_dbf, 3, "u_access_denied");
debug_event(adapter->erp_dbf, 3, &unit->fcp_lun, sizeof(fcp_lun_t));
zfcp_erp_modify_unit_status(unit, ZFCP_STATUS_COMMON_ERP_FAILED |
ZFCP_STATUS_COMMON_ACCESS_DENIED, ZFCP_SET);
zfcp_erp_modify_unit_status(unit,
ZFCP_STATUS_COMMON_ERP_FAILED |
ZFCP_STATUS_COMMON_ACCESS_DENIED,
ZFCP_SET);
}
/*
@ -3530,7 +3570,7 @@ zfcp_erp_adapter_access_changed(struct zfcp_adapter *adapter)
struct zfcp_port *port;
unsigned long flags;
debug_text_event(adapter->erp_dbf, 3, "a_access_unblock");
debug_text_event(adapter->erp_dbf, 3, "a_access_recover");
debug_event(adapter->erp_dbf, 3, &adapter->name, 8);
read_lock_irqsave(&zfcp_data.config_lock, flags);
@ -3553,10 +3593,12 @@ zfcp_erp_port_access_changed(struct zfcp_port *port)
struct zfcp_adapter *adapter = port->adapter;
struct zfcp_unit *unit;
debug_text_event(adapter->erp_dbf, 3, "p_access_unblock");
debug_text_event(adapter->erp_dbf, 3, "p_access_recover");
debug_event(adapter->erp_dbf, 3, &port->wwpn, sizeof(wwn_t));
if (!atomic_test_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED,
&port->status) &&
!atomic_test_mask(ZFCP_STATUS_COMMON_ACCESS_BOXED,
&port->status)) {
if (!atomic_test_mask(ZFCP_STATUS_PORT_WKA, &port->status))
list_for_each_entry(unit, &port->unit_list_head, list)
@ -3583,10 +3625,13 @@ zfcp_erp_unit_access_changed(struct zfcp_unit *unit)
{
struct zfcp_adapter *adapter = unit->port->adapter;
debug_text_event(adapter->erp_dbf, 3, "u_access_unblock");
debug_text_event(adapter->erp_dbf, 3, "u_access_recover");
debug_event(adapter->erp_dbf, 3, &unit->fcp_lun, sizeof(fcp_lun_t));
if (!atomic_test_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED, &unit->status))
if (!atomic_test_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED,
&unit->status) &&
!atomic_test_mask(ZFCP_STATUS_COMMON_ACCESS_BOXED,
&unit->status))
return;
ZFCP_LOG_NORMAL("reopen of unit 0x%016Lx on port 0x%016Lx "

View File

@ -116,7 +116,7 @@ extern int zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *,
struct timer_list*, int);
extern int zfcp_fsf_req_complete(struct zfcp_fsf_req *);
extern void zfcp_fsf_incoming_els(struct zfcp_fsf_req *);
extern void zfcp_fsf_req_cleanup(struct zfcp_fsf_req *);
extern void zfcp_fsf_req_free(struct zfcp_fsf_req *);
extern struct zfcp_fsf_req *zfcp_fsf_send_fcp_command_task_management(
struct zfcp_adapter *, struct zfcp_unit *, u8, int);
extern struct zfcp_fsf_req *zfcp_fsf_abort_fcp_command(
@ -171,6 +171,8 @@ extern int zfcp_erp_async_handler(struct zfcp_erp_action *, unsigned long);
extern int zfcp_test_link(struct zfcp_port *);
extern void zfcp_erp_port_boxed(struct zfcp_port *);
extern void zfcp_erp_unit_boxed(struct zfcp_unit *);
extern void zfcp_erp_port_access_denied(struct zfcp_port *);
extern void zfcp_erp_unit_access_denied(struct zfcp_unit *);
extern void zfcp_erp_adapter_access_changed(struct zfcp_adapter *);

File diff suppressed because it is too large Load Diff

View File

@ -229,52 +229,14 @@ zfcp_qdio_handler_error_check(struct zfcp_adapter *adapter,
ZFCP_LOG_TRACE("status is"
" QDIO_STATUS_OUTBOUND_INT \n");
}
} // if (ZFCP_LOG_CHECK(ZFCP_LOG_LEVEL_TRACE))
}
if (unlikely(status & QDIO_STATUS_LOOK_FOR_ERROR)) {
retval = -EIO;
ZFCP_LOG_FLAGS(1, "QDIO_STATUS_LOOK_FOR_ERROR \n");
ZFCP_LOG_INFO("QDIO problem occurred (status=0x%x, "
"qdio_error=0x%x, siga_error=0x%x)\n",
status, qdio_error, siga_error);
if (status & QDIO_STATUS_ACTIVATE_CHECK_CONDITION) {
ZFCP_LOG_FLAGS(2,
"QDIO_STATUS_ACTIVATE_CHECK_CONDITION\n");
}
if (status & QDIO_STATUS_MORE_THAN_ONE_QDIO_ERROR) {
ZFCP_LOG_FLAGS(2,
"QDIO_STATUS_MORE_THAN_ONE_QDIO_ERROR\n");
}
if (status & QDIO_STATUS_MORE_THAN_ONE_SIGA_ERROR) {
ZFCP_LOG_FLAGS(2,
"QDIO_STATUS_MORE_THAN_ONE_SIGA_ERROR\n");
}
if (siga_error & QDIO_SIGA_ERROR_ACCESS_EXCEPTION) {
ZFCP_LOG_FLAGS(2, "QDIO_SIGA_ERROR_ACCESS_EXCEPTION\n");
}
if (siga_error & QDIO_SIGA_ERROR_B_BIT_SET) {
ZFCP_LOG_FLAGS(2, "QDIO_SIGA_ERROR_B_BIT_SET\n");
}
switch (qdio_error) {
case 0:
ZFCP_LOG_FLAGS(3, "QDIO_OK");
break;
case SLSB_P_INPUT_ERROR:
ZFCP_LOG_FLAGS(1, "SLSB_P_INPUT_ERROR\n");
break;
case SLSB_P_OUTPUT_ERROR:
ZFCP_LOG_FLAGS(1, "SLSB_P_OUTPUT_ERROR\n");
break;
default:
ZFCP_LOG_NORMAL("bug: unknown QDIO error 0x%x\n",
qdio_error);
break;
}
/* Restarting IO on the failed adapter from scratch */
debug_text_event(adapter->erp_dbf, 1, "qdio_err");
/*
@ -484,37 +446,37 @@ int
zfcp_qdio_reqid_check(struct zfcp_adapter *adapter, void *sbale_addr)
{
struct zfcp_fsf_req *fsf_req;
int retval = 0;
/* invalid (per convention used in this driver) */
if (unlikely(!sbale_addr)) {
ZFCP_LOG_NORMAL("bug: invalid reqid\n");
retval = -EINVAL;
goto out;
return -EINVAL;
}
/* valid request id and thus (hopefully :) valid fsf_req address */
fsf_req = (struct zfcp_fsf_req *) sbale_addr;
/* serialize with zfcp_fsf_req_dismiss_all */
spin_lock(&adapter->fsf_req_list_lock);
if (list_empty(&adapter->fsf_req_list_head)) {
spin_unlock(&adapter->fsf_req_list_lock);
return 0;
}
list_del(&fsf_req->list);
atomic_dec(&adapter->fsf_reqs_active);
spin_unlock(&adapter->fsf_req_list_lock);
if (unlikely(adapter != fsf_req->adapter)) {
ZFCP_LOG_NORMAL("bug: invalid reqid (fsf_req=%p, "
"fsf_req->adapter=%p, adapter=%p)\n",
fsf_req, fsf_req->adapter, adapter);
retval = -EINVAL;
goto out;
}
ZFCP_LOG_TRACE("fsf_req at %p, QTCB at %p\n", fsf_req, fsf_req->qtcb);
if (likely(fsf_req->qtcb)) {
ZFCP_LOG_TRACE("hex dump of QTCB:\n");
ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_TRACE, (char *) fsf_req->qtcb,
sizeof(struct fsf_qtcb));
return -EINVAL;
}
/* finish the FSF request */
zfcp_fsf_req_complete(fsf_req);
out:
return retval;
return 0;
}
/**

View File

@ -433,7 +433,7 @@ zfcp_port_lookup(struct zfcp_adapter *adapter, int channel, scsi_id_t id)
* FAILED - otherwise
*/
int
zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
__zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
{
int retval = SUCCESS;
struct zfcp_fsf_req *new_fsf_req, *old_fsf_req;
@ -575,7 +575,7 @@ zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
*(u64 *) & new_fsf_req->qtcb->header.fsf_status_qual.word[0];
dbf_fsf_qual[1] =
*(u64 *) & new_fsf_req->qtcb->header.fsf_status_qual.word[2];
zfcp_fsf_req_cleanup(new_fsf_req);
zfcp_fsf_req_free(new_fsf_req);
#else
retval = zfcp_fsf_req_wait_and_cleanup(new_fsf_req,
ZFCP_UNINTERRUPTIBLE, &status);
@ -611,6 +611,17 @@ zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
return retval;
}
int
zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
{
int rc;
struct Scsi_Host *scsi_host = scpnt->device->host;
spin_lock_irq(scsi_host->host_lock);
rc = __zfcp_scsi_eh_abort_handler(scpnt);
spin_unlock_irq(scsi_host->host_lock);
return rc;
}
/*
* function: zfcp_scsi_eh_device_reset_handler
*
@ -625,8 +636,6 @@ zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *scpnt)
struct zfcp_unit *unit = (struct zfcp_unit *) scpnt->device->hostdata;
struct Scsi_Host *scsi_host = scpnt->device->host;
spin_unlock_irq(scsi_host->host_lock);
if (!unit) {
ZFCP_LOG_NORMAL("bug: Tried reset for nonexistent unit\n");
retval = SUCCESS;
@ -669,7 +678,6 @@ zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *scpnt)
retval = SUCCESS;
}
out:
spin_lock_irq(scsi_host->host_lock);
return retval;
}
@ -723,8 +731,6 @@ zfcp_scsi_eh_bus_reset_handler(struct scsi_cmnd *scpnt)
struct zfcp_unit *unit;
struct Scsi_Host *scsi_host = scpnt->device->host;
spin_unlock_irq(scsi_host->host_lock);
unit = (struct zfcp_unit *) scpnt->device->hostdata;
ZFCP_LOG_NORMAL("bus reset because of problems with "
"unit 0x%016Lx\n", unit->fcp_lun);
@ -732,7 +738,6 @@ zfcp_scsi_eh_bus_reset_handler(struct scsi_cmnd *scpnt)
zfcp_erp_wait(unit->port->adapter);
retval = SUCCESS;
spin_lock_irq(scsi_host->host_lock);
return retval;
}
@ -750,8 +755,6 @@ zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *scpnt)
struct zfcp_unit *unit;
struct Scsi_Host *scsi_host = scpnt->device->host;
spin_unlock_irq(scsi_host->host_lock);
unit = (struct zfcp_unit *) scpnt->device->hostdata;
ZFCP_LOG_NORMAL("host reset because of problems with "
"unit 0x%016Lx\n", unit->fcp_lun);
@ -759,7 +762,6 @@ zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *scpnt)
zfcp_erp_wait(unit->port->adapter);
retval = SUCCESS;
spin_lock_irq(scsi_host->host_lock);
return retval;
}

View File

@ -1695,8 +1695,6 @@ static int twa_scsi_eh_reset(struct scsi_cmnd *SCpnt)
tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
spin_unlock_irq(tw_dev->host->host_lock);
tw_dev->num_resets++;
printk(KERN_WARNING "3w-9xxx: scsi%d: WARNING: (0x%02X:0x%04X): Unit #%d: Command (0x%x) timed out, resetting card.\n", tw_dev->host->host_no, TW_DRIVER, 0x2c, SCpnt->device->id, SCpnt->cmnd[0]);
@ -1709,7 +1707,6 @@ static int twa_scsi_eh_reset(struct scsi_cmnd *SCpnt)
retval = SUCCESS;
out:
spin_lock_irq(tw_dev->host->host_lock);
return retval;
} /* End twa_scsi_eh_reset() */

View File

@ -1430,8 +1430,6 @@ static int tw_scsi_eh_reset(struct scsi_cmnd *SCpnt)
tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
spin_unlock_irq(tw_dev->host->host_lock);
tw_dev->num_resets++;
printk(KERN_WARNING "3w-xxxx: scsi%d: WARNING: Unit #%d: Command (0x%x) timed out, resetting card.\n", tw_dev->host->host_no, SCpnt->device->id, SCpnt->cmnd[0]);
@ -1444,7 +1442,6 @@ static int tw_scsi_eh_reset(struct scsi_cmnd *SCpnt)
retval = SUCCESS;
out:
spin_lock_irq(tw_dev->host->host_lock);
return retval;
} /* End tw_scsi_eh_reset() */

View File

@ -170,7 +170,6 @@ MODULE_LICENSE("GPL");
STATIC int NCR_700_queuecommand(struct scsi_cmnd *, void (*done)(struct scsi_cmnd *));
STATIC int NCR_700_abort(struct scsi_cmnd * SCpnt);
STATIC int NCR_700_bus_reset(struct scsi_cmnd * SCpnt);
STATIC int NCR_700_dev_reset(struct scsi_cmnd * SCpnt);
STATIC int NCR_700_host_reset(struct scsi_cmnd * SCpnt);
STATIC void NCR_700_chip_setup(struct Scsi_Host *host);
STATIC void NCR_700_chip_reset(struct Scsi_Host *host);
@ -330,7 +329,6 @@ NCR_700_detect(struct scsi_host_template *tpnt,
/* Fill in the missing routines from the host template */
tpnt->queuecommand = NCR_700_queuecommand;
tpnt->eh_abort_handler = NCR_700_abort;
tpnt->eh_device_reset_handler = NCR_700_dev_reset;
tpnt->eh_bus_reset_handler = NCR_700_bus_reset;
tpnt->eh_host_reset_handler = NCR_700_host_reset;
tpnt->can_queue = NCR_700_COMMAND_SLOTS_PER_HOST;
@ -1959,34 +1957,31 @@ NCR_700_bus_reset(struct scsi_cmnd * SCp)
printk(KERN_INFO "scsi%d (%d:%d) New error handler wants BUS reset, cmd %p\n\t",
SCp->device->host->host_no, SCp->device->id, SCp->device->lun, SCp);
scsi_print_command(SCp);
/* In theory, eh_complete should always be null because the
* eh is single threaded, but just in case we're handling a
* reset via sg or something */
while(hostdata->eh_complete != NULL) {
spin_lock_irq(SCp->device->host->host_lock);
while (hostdata->eh_complete != NULL) {
spin_unlock_irq(SCp->device->host->host_lock);
msleep_interruptible(100);
spin_lock_irq(SCp->device->host->host_lock);
}
hostdata->eh_complete = &complete;
NCR_700_internal_bus_reset(SCp->device->host);
spin_unlock_irq(SCp->device->host->host_lock);
wait_for_completion(&complete);
spin_lock_irq(SCp->device->host->host_lock);
hostdata->eh_complete = NULL;
/* Revalidate the transport parameters of the failing device */
if(hostdata->fast)
spi_schedule_dv_device(SCp->device);
return SUCCESS;
}
STATIC int
NCR_700_dev_reset(struct scsi_cmnd * SCp)
{
printk(KERN_INFO "scsi%d (%d:%d) New error handler wants device reset\n\t",
SCp->device->host->host_no, SCp->device->id, SCp->device->lun);
scsi_print_command(SCp);
return FAILED;
spin_unlock_irq(SCp->device->host->host_lock);
return SUCCESS;
}
STATIC int
@ -1996,8 +1991,13 @@ NCR_700_host_reset(struct scsi_cmnd * SCp)
SCp->device->host->host_no, SCp->device->id, SCp->device->lun);
scsi_print_command(SCp);
spin_lock_irq(SCp->device->host->host_lock);
NCR_700_internal_bus_reset(SCp->device->host);
NCR_700_chip_reset(SCp->device->host);
spin_unlock_irq(SCp->device->host->host_lock);
return SUCCESS;
}

View File

@ -2746,9 +2746,15 @@ static int BusLogic_host_reset(struct scsi_cmnd * SCpnt)
unsigned int id = SCpnt->device->id;
struct BusLogic_TargetStatistics *stats = &HostAdapter->TargetStatistics[id];
int rc;
spin_lock_irq(SCpnt->device->host->host_lock);
BusLogic_IncrementErrorCounter(&stats->HostAdapterResetsRequested);
return BusLogic_ResetHostAdapter(HostAdapter, false);
rc = BusLogic_ResetHostAdapter(HostAdapter, false);
spin_unlock_irq(SCpnt->device->host->host_lock);
return rc;
}
/*

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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 \

View File

@ -2825,39 +2825,17 @@ static int NCR5380_abort(Scsi_Cmnd * cmd) {
* Locks: host lock taken by caller
*/
static int NCR5380_bus_reset(Scsi_Cmnd * cmd) {
NCR5380_local_declare();
NCR5380_setup(cmd->device->host);
static int NCR5380_bus_reset(Scsi_Cmnd * cmd)
{
struct Scsi_Host *instance = cmd->device->host;
NCR5380_local_declare();
NCR5380_setup(instance);
NCR5380_print_status(instance);
spin_lock_irq(instance->host_lock);
do_reset(instance);
spin_unlock_irq(instance->host_lock);
NCR5380_print_status(cmd->device->host);
do_reset(cmd->device->host);
return SUCCESS;
}
/*
* Function : int NCR5380_device_reset (Scsi_Cmnd *cmd)
*
* Purpose : reset a SCSI device
*
* Returns : FAILED
*
* Locks: io_request_lock held by caller
*/
static int NCR5380_device_reset(Scsi_Cmnd * cmd) {
return FAILED;
}
/*
* Function : int NCR5380_host_reset (Scsi_Cmnd *cmd)
*
* Purpose : reset a SCSI device
*
* Returns : FAILED
*
* Locks: io_request_lock held by caller
*/
static int NCR5380_host_reset(Scsi_Cmnd * cmd) {
return FAILED;
}

View File

@ -306,8 +306,6 @@ static void NCR5380_print(struct Scsi_Host *instance);
#endif
static int NCR5380_abort(Scsi_Cmnd * cmd);
static int NCR5380_bus_reset(Scsi_Cmnd * cmd);
static int NCR5380_host_reset(Scsi_Cmnd * cmd);
static int NCR5380_device_reset(Scsi_Cmnd * cmd);
static int NCR5380_queue_command(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *));
static int NCR5380_proc_info(struct Scsi_Host *instance, char *buffer, char **start,
off_t offset, int length, int inout);

View File

@ -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);
@ -1467,14 +1467,12 @@ int esp_reset(Scsi_Cmnd *SCptr)
{
struct NCR_ESP *esp = (struct NCR_ESP *) SCptr->device->host->hostdata;
spin_lock_irq(esp->ehost->host_lock);
(void) esp_do_resetbus(esp, esp->eregs);
spin_unlock_irq(esp->ehost->host_lock);
wait_event(esp->reset_queue, (esp->resetting_bus == 0));
spin_lock_irq(esp->ehost->host_lock);
return SUCCESS;
}

View File

@ -722,15 +722,12 @@ static int NCR53c406a_queue(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
return 0;
}
static int NCR53c406a_abort(Scsi_Cmnd * SCpnt)
{
DEB(printk("NCR53c406a_abort called\n"));
return FAILED; /* Don't know how to abort */
}
static int NCR53c406a_host_reset(Scsi_Cmnd * SCpnt)
{
DEB(printk("NCR53c406a_reset called\n"));
spin_lock_irq(SCpnt->device->host->host_lock);
outb(C4_IMG, CONFIG4); /* Select reg set 0 */
outb(CHIP_RESET, CMD_REG);
outb(SCSI_NOP, CMD_REG); /* required after reset */
@ -738,19 +735,12 @@ static int NCR53c406a_host_reset(Scsi_Cmnd * SCpnt)
chip_init();
rtrc(2);
spin_unlock_irq(SCpnt->device->host->host_lock);
return SUCCESS;
}
static int NCR53c406a_device_reset(Scsi_Cmnd * SCpnt)
{
return FAILED;
}
static int NCR53c406a_bus_reset(Scsi_Cmnd * SCpnt)
{
return FAILED;
}
static int NCR53c406a_biosparm(struct scsi_device *disk,
struct block_device *dev,
sector_t capacity, int *info_array)
@ -1075,9 +1065,6 @@ static Scsi_Host_Template driver_template =
.release = NCR53c406a_release,
.info = NCR53c406a_info /* info */,
.queuecommand = NCR53c406a_queue /* queuecommand */,
.eh_abort_handler = NCR53c406a_abort /* abort */,
.eh_bus_reset_handler = NCR53c406a_bus_reset /* reset */,
.eh_device_reset_handler = NCR53c406a_device_reset /* reset */,
.eh_host_reset_handler = NCR53c406a_host_reset /* reset */,
.bios_param = NCR53c406a_biosparm /* biosparm */,
.can_queue = 1 /* can_queue */,

View File

@ -221,7 +221,14 @@ int __init a2091_detect(Scsi_Host_Template *tpnt)
static int a2091_bus_reset(Scsi_Cmnd *cmd)
{
/* FIXME perform bus-specific reset */
/* FIXME 2: kill this function, and let midlayer fall back
to the same action, calling wd33c93_host_reset() */
spin_lock_irq(cmd->device->host->host_lock);
wd33c93_host_reset(cmd);
spin_unlock_irq(cmd->device->host->host_lock);
return SUCCESS;
}

View File

@ -208,7 +208,14 @@ fail_register:
static int a3000_bus_reset(Scsi_Cmnd *cmd)
{
/* FIXME perform bus-specific reset */
/* FIXME 2: kill this entire function, which should
cause mid-layer to call wd33c93_host_reset anyway? */
spin_lock_irq(cmd->device->host->host_lock);
wd33c93_host_reset(cmd);
spin_unlock_irq(cmd->device->host->host_lock);
return SUCCESS;
}

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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
*/

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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;
}
@ -360,14 +366,6 @@ static int aac_ioctl(struct scsi_device *sdev, int cmd, void __user * arg)
return aac_do_ioctl(dev, cmd, arg);
}
/*
* XXX: does aac really need no error handling??
*/
static int aac_eh_abort(struct scsi_cmnd *cmd)
{
return FAILED;
}
/*
* aac_eh_reset - Reset command handling
* @scsi_cmd: SCSI command block causing the reset
@ -386,10 +384,13 @@ static int aac_eh_reset(struct scsi_cmnd* cmd)
AAC_DRIVERNAME);
spin_lock_irq(host->host_lock);
aac = (struct aac_dev *)host->hostdata;
if (aac_adapter_check_health(aac)) {
printk(KERN_ERR "%s: Host adapter appears dead\n",
AAC_DRIVERNAME);
spin_unlock_irq(host->host_lock);
return -ENODEV;
}
/*
@ -420,6 +421,7 @@ static int aac_eh_reset(struct scsi_cmnd* cmd)
ssleep(1);
spin_lock_irq(host->host_lock);
}
spin_unlock_irq(host->host_lock);
printk(KERN_ERR "%s: SCSI bus appears hung\n", AAC_DRIVERNAME);
return -ETIMEDOUT;
}
@ -439,11 +441,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 +491,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;
@ -526,6 +529,134 @@ static long aac_compat_cfg_ioctl(struct file *file, unsigned cmd, unsigned long
}
#endif
static ssize_t aac_show_model(struct class_device *class_dev,
char *buf)
{
struct aac_dev *dev = (struct aac_dev*)class_to_shost(class_dev)->hostdata;
int len;
len = snprintf(buf, PAGE_SIZE, "%s\n",
aac_drivers[dev->cardtype].model);
return len;
}
static ssize_t aac_show_vendor(struct class_device *class_dev,
char *buf)
{
struct aac_dev *dev = (struct aac_dev*)class_to_shost(class_dev)->hostdata;
int len;
len = snprintf(buf, PAGE_SIZE, "%s\n",
aac_drivers[dev->cardtype].vname);
return len;
}
static ssize_t aac_show_kernel_version(struct class_device *class_dev,
char *buf)
{
struct aac_dev *dev = (struct aac_dev*)class_to_shost(class_dev)->hostdata;
int len, tmp;
tmp = le32_to_cpu(dev->adapter_info.kernelrev);
len = snprintf(buf, PAGE_SIZE, "%d.%d-%d[%d]\n",
tmp >> 24, (tmp >> 16) & 0xff, tmp & 0xff,
le32_to_cpu(dev->adapter_info.kernelbuild));
return len;
}
static ssize_t aac_show_monitor_version(struct class_device *class_dev,
char *buf)
{
struct aac_dev *dev = (struct aac_dev*)class_to_shost(class_dev)->hostdata;
int len, tmp;
tmp = le32_to_cpu(dev->adapter_info.monitorrev);
len = snprintf(buf, PAGE_SIZE, "%d.%d-%d[%d]\n",
tmp >> 24, (tmp >> 16) & 0xff, tmp & 0xff,
le32_to_cpu(dev->adapter_info.monitorbuild));
return len;
}
static ssize_t aac_show_bios_version(struct class_device *class_dev,
char *buf)
{
struct aac_dev *dev = (struct aac_dev*)class_to_shost(class_dev)->hostdata;
int len, tmp;
tmp = le32_to_cpu(dev->adapter_info.biosrev);
len = snprintf(buf, PAGE_SIZE, "%d.%d-%d[%d]\n",
tmp >> 24, (tmp >> 16) & 0xff, tmp & 0xff,
le32_to_cpu(dev->adapter_info.biosbuild));
return len;
}
static ssize_t aac_show_serial_number(struct class_device *class_dev,
char *buf)
{
struct aac_dev *dev = (struct aac_dev*)class_to_shost(class_dev)->hostdata;
int len = 0;
if (le32_to_cpu(dev->adapter_info.serial[0]) != 0xBAD0)
len = snprintf(buf, PAGE_SIZE, "%x\n",
le32_to_cpu(dev->adapter_info.serial[0]));
return len;
}
static struct class_device_attribute aac_model = {
.attr = {
.name = "model",
.mode = S_IRUGO,
},
.show = aac_show_model,
};
static struct class_device_attribute aac_vendor = {
.attr = {
.name = "vendor",
.mode = S_IRUGO,
},
.show = aac_show_vendor,
};
static struct class_device_attribute aac_kernel_version = {
.attr = {
.name = "hba_kernel_version",
.mode = S_IRUGO,
},
.show = aac_show_kernel_version,
};
static struct class_device_attribute aac_monitor_version = {
.attr = {
.name = "hba_monitor_version",
.mode = S_IRUGO,
},
.show = aac_show_monitor_version,
};
static struct class_device_attribute aac_bios_version = {
.attr = {
.name = "hba_bios_version",
.mode = S_IRUGO,
},
.show = aac_show_bios_version,
};
static struct class_device_attribute aac_serial_number = {
.attr = {
.name = "serial_number",
.mode = S_IRUGO,
},
.show = aac_show_serial_number,
};
static struct class_device_attribute *aac_attrs[] = {
&aac_model,
&aac_vendor,
&aac_kernel_version,
&aac_monitor_version,
&aac_bios_version,
&aac_serial_number,
NULL
};
static struct file_operations aac_cfg_fops = {
.owner = THIS_MODULE,
.ioctl = aac_cfg_ioctl,
@ -538,7 +669,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
@ -546,8 +677,8 @@ static struct scsi_host_template aac_driver_template = {
#endif
.queuecommand = aac_queuecommand,
.bios_param = aac_biosparm,
.shost_attrs = aac_attrs,
.slave_configure = aac_slave_configure,
.eh_abort_handler = aac_eh_abort,
.eh_host_reset_handler = aac_eh_reset,
.can_queue = AAC_NUM_IO_FIB,
.this_id = 16,
@ -612,7 +743,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 +763,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

View File

@ -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')) {

View File

@ -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')) {

View File

@ -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);
}
/**

View File

@ -1225,8 +1225,6 @@ static int aha152x_device_reset(Scsi_Cmnd * SCpnt)
}
DO_UNLOCK(flags);
spin_lock_irq(shpnt->host_lock);
return ret;
}

View File

@ -1348,20 +1348,6 @@ static int aha1542_restart(struct Scsi_Host *shost)
return 0;
}
static int aha1542_abort(Scsi_Cmnd * SCpnt)
{
/*
* The abort command does not leave the device in a clean state where
* it is available to be used again. Until this gets worked out, we
* will leave it commented out.
*/
printk(KERN_ERR "aha1542.c: Unable to abort command for target %d\n",
SCpnt->device->id);
return FAILED;
}
/*
* This is a device reset. This is handled by sending a special command
* to the device.
@ -1478,8 +1464,8 @@ static int aha1542_bus_reset(Scsi_Cmnd * SCpnt)
* check for timeout, and if we are doing something like this
* we are pretty desperate anyways.
*/
spin_unlock_irq(SCpnt->device->host->host_lock);
ssleep(4);
spin_lock_irq(SCpnt->device->host->host_lock);
WAIT(STATUS(SCpnt->device->host->io_port),
@ -1517,9 +1503,11 @@ static int aha1542_bus_reset(Scsi_Cmnd * SCpnt)
}
}
spin_unlock_irq(SCpnt->device->host->host_lock);
return SUCCESS;
fail:
spin_unlock_irq(SCpnt->device->host->host_lock);
return FAILED;
}
@ -1542,7 +1530,6 @@ static int aha1542_host_reset(Scsi_Cmnd * SCpnt)
* check for timeout, and if we are doing something like this
* we are pretty desperate anyways.
*/
spin_unlock_irq(SCpnt->device->host->host_lock);
ssleep(4);
spin_lock_irq(SCpnt->device->host->host_lock);
@ -1586,9 +1573,11 @@ static int aha1542_host_reset(Scsi_Cmnd * SCpnt)
}
}
spin_unlock_irq(SCpnt->device->host->host_lock);
return SUCCESS;
fail:
spin_unlock_irq(SCpnt->device->host->host_lock);
return FAILED;
}
@ -1817,7 +1806,6 @@ static Scsi_Host_Template driver_template = {
.detect = aha1542_detect,
.release = aha1542_release,
.queuecommand = aha1542_queuecommand,
.eh_abort_handler = aha1542_abort,
.eh_device_reset_handler= aha1542_dev_reset,
.eh_bus_reset_handler = aha1542_bus_reset,
.eh_host_reset_handler = aha1542_host_reset,

View File

@ -133,7 +133,6 @@ struct ccb { /* Command Control Block 5.3 */
static int aha1542_detect(Scsi_Host_Template *);
static int aha1542_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
static int aha1542_abort(Scsi_Cmnd * SCpnt);
static int aha1542_bus_reset(Scsi_Cmnd * SCpnt);
static int aha1542_dev_reset(Scsi_Cmnd * SCpnt);
static int aha1542_host_reset(Scsi_Cmnd * SCpnt);

View File

@ -44,109 +44,6 @@
#include <linux/device.h>
#include <linux/eisa.h>
#define EISA_MFCTR_CHAR0(ID) (char)(((ID>>26) & 0x1F) | '@') /* Bits 26-30 */
#define EISA_MFCTR_CHAR1(ID) (char)(((ID>>21) & 0x1F) | '@') /* Bits 21-25 */
#define EISA_MFCTR_CHAR2(ID) (char)(((ID>>16) & 0x1F) | '@') /* Bits 16-20 */
#define EISA_PRODUCT_ID(ID) (short)((ID>>4) & 0xFFF) /* Bits 4-15 */
#define EISA_REVISION_ID(ID) (uint8_t)(ID & 0x0F) /* Bits 0-3 */
static int aic7770_eisa_dev_probe(struct device *dev);
static int aic7770_eisa_dev_remove(struct device *dev);
static struct eisa_driver aic7770_driver = {
.driver = {
.name = "aic7xxx",
.probe = aic7770_eisa_dev_probe,
.remove = aic7770_eisa_dev_remove,
}
};
typedef struct device *aic7770_dev_t;
static int aic7770_linux_config(struct aic7770_identity *entry,
aic7770_dev_t dev, u_int eisaBase);
int
ahc_linux_eisa_init(void)
{
struct eisa_device_id *eid;
struct aic7770_identity *id;
int i;
if (aic7xxx_probe_eisa_vl == 0)
return -ENODEV;
/*
* Linux requires the EISA IDs to be specified in
* the EISA ID string format. Perform the conversion
* and setup a table with a NUL terminal entry.
*/
aic7770_driver.id_table = malloc(sizeof(struct eisa_device_id) *
(ahc_num_aic7770_devs + 1),
M_DEVBUF, M_NOWAIT);
if (aic7770_driver.id_table == NULL)
return -ENOMEM;
for (eid = (struct eisa_device_id *)aic7770_driver.id_table,
id = aic7770_ident_table, i = 0;
i < ahc_num_aic7770_devs; eid++, id++, i++) {
sprintf(eid->sig, "%c%c%c%03X%01X",
EISA_MFCTR_CHAR0(id->full_id),
EISA_MFCTR_CHAR1(id->full_id),
EISA_MFCTR_CHAR2(id->full_id),
EISA_PRODUCT_ID(id->full_id),
EISA_REVISION_ID(id->full_id));
eid->driver_data = i;
}
eid->sig[0] = 0;
return eisa_driver_register(&aic7770_driver);
}
void
ahc_linux_eisa_exit(void)
{
if(aic7xxx_probe_eisa_vl != 0 && aic7770_driver.id_table != NULL) {
eisa_driver_unregister(&aic7770_driver);
free(aic7770_driver.id_table, M_DEVBUF);
}
}
static int
aic7770_linux_config(struct aic7770_identity *entry, aic7770_dev_t dev,
u_int eisaBase)
{
struct ahc_softc *ahc;
char buf[80];
char *name;
int error;
/*
* Allocate a softc for this card and
* set it up for attachment by our
* common detect routine.
*/
sprintf(buf, "ahc_eisa:%d", eisaBase >> 12);
name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT);
if (name == NULL)
return (ENOMEM);
strcpy(name, buf);
ahc = ahc_alloc(&aic7xxx_driver_template, name);
if (ahc == NULL)
return (ENOMEM);
error = aic7770_config(ahc, entry, eisaBase);
if (error != 0) {
ahc->bsh.ioport = 0;
ahc_free(ahc);
return (error);
}
dev->driver_data = (void *)ahc;
if (aic7xxx_detect_complete)
error = ahc_linux_register_host(ahc, &aic7xxx_driver_template);
return (error);
}
int
aic7770_map_registers(struct ahc_softc *ahc, u_int port)
{
@ -178,37 +75,79 @@ aic7770_map_int(struct ahc_softc *ahc, u_int irq)
}
static int
aic7770_eisa_dev_probe(struct device *dev)
aic7770_probe(struct device *dev)
{
struct eisa_device *edev;
struct eisa_device *edev = to_eisa_device(dev);
u_int eisaBase = edev->base_addr+AHC_EISA_SLOT_OFFSET;
struct ahc_softc *ahc;
char buf[80];
char *name;
int error;
edev = to_eisa_device(dev);
return (aic7770_linux_config(aic7770_ident_table + edev->id.driver_data,
dev, edev->base_addr+AHC_EISA_SLOT_OFFSET));
sprintf(buf, "ahc_eisa:%d", eisaBase >> 12);
name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT);
if (name == NULL)
return (ENOMEM);
strcpy(name, buf);
ahc = ahc_alloc(&aic7xxx_driver_template, name);
if (ahc == NULL)
return (ENOMEM);
error = aic7770_config(ahc, aic7770_ident_table + edev->id.driver_data,
eisaBase);
if (error != 0) {
ahc->bsh.ioport = 0;
ahc_free(ahc);
return (error);
}
dev_set_drvdata(dev, ahc);
if (aic7xxx_detect_complete)
error = ahc_linux_register_host(ahc, &aic7xxx_driver_template);
return (error);
}
static int
aic7770_eisa_dev_remove(struct device *dev)
aic7770_remove(struct device *dev)
{
struct ahc_softc *ahc;
u_long l;
struct ahc_softc *ahc = dev_get_drvdata(dev);
u_long s;
/*
* We should be able to just perform
* the free directly, but check our
* list for extra sanity.
*/
ahc_list_lock(&l);
ahc = ahc_find_softc((struct ahc_softc *)dev->driver_data);
if (ahc != NULL) {
u_long s;
ahc_lock(ahc, &s);
ahc_intr_enable(ahc, FALSE);
ahc_unlock(ahc, &s);
ahc_lock(ahc, &s);
ahc_intr_enable(ahc, FALSE);
ahc_unlock(ahc, &s);
ahc_free(ahc);
}
ahc_list_unlock(&l);
return (0);
ahc_free(ahc);
return 0;
}
static struct eisa_device_id aic7770_ids[] = {
{ "ADP7771", 0 }, /* AHA 274x */
{ "ADP7756", 1 }, /* AHA 284x BIOS enabled */
{ "ADP7757", 2 }, /* AHA 284x BIOS disabled */
{ "ADP7782", 3 }, /* AHA 274x Olivetti OEM */
{ "ADP7783", 4 }, /* AHA 274x Olivetti OEM (Differential) */
{ "ADP7770", 5 }, /* AIC7770 generic */
{ "" }
};
static struct eisa_driver aic7770_driver = {
.id_table = aic7770_ids,
.driver = {
.name = "aic7xxx",
.probe = aic7770_probe,
.remove = aic7770_remove,
}
};
int
ahc_linux_eisa_init(void)
{
return eisa_driver_register(&aic7770_driver);
}
void
ahc_linux_eisa_exit(void)
{
eisa_driver_unregister(&aic7770_driver);
}

View File

@ -941,7 +941,7 @@ ahd_linux_queue(Scsi_Cmnd * cmd, void (*scsi_done) (Scsi_Cmnd *))
*/
cmd->scsi_done = scsi_done;
ahd_midlayer_entrypoint_lock(ahd, &flags);
ahd_lock(ahd, &flags);
/*
* Close the race of a command that was in the process of
@ -955,7 +955,7 @@ ahd_linux_queue(Scsi_Cmnd * cmd, void (*scsi_done) (Scsi_Cmnd *))
ahd_cmd_set_transaction_status(cmd, CAM_REQUEUE_REQ);
ahd_linux_queue_cmd_complete(ahd, cmd);
ahd_schedule_completeq(ahd);
ahd_midlayer_entrypoint_unlock(ahd, &flags);
ahd_unlock(ahd, &flags);
return (0);
}
dev = ahd_linux_get_device(ahd, cmd->device->channel,
@ -965,7 +965,7 @@ ahd_linux_queue(Scsi_Cmnd * cmd, void (*scsi_done) (Scsi_Cmnd *))
ahd_cmd_set_transaction_status(cmd, CAM_RESRC_UNAVAIL);
ahd_linux_queue_cmd_complete(ahd, cmd);
ahd_schedule_completeq(ahd);
ahd_midlayer_entrypoint_unlock(ahd, &flags);
ahd_unlock(ahd, &flags);
printf("%s: aic79xx_linux_queue - Unable to allocate device!\n",
ahd_name(ahd));
return (0);
@ -979,7 +979,7 @@ ahd_linux_queue(Scsi_Cmnd * cmd, void (*scsi_done) (Scsi_Cmnd *))
dev->flags |= AHD_DEV_ON_RUN_LIST;
ahd_linux_run_device_queues(ahd);
}
ahd_midlayer_entrypoint_unlock(ahd, &flags);
ahd_unlock(ahd, &flags);
return (0);
}
@ -1511,17 +1511,17 @@ ahd_linux_dev_reset(Scsi_Cmnd *cmd)
ahd_name(ahd), cmd->device->channel, cmd->device->id,
cmd->device->lun, cmd);
#endif
ahd_midlayer_entrypoint_lock(ahd, &s);
ahd_lock(ahd, &s);
dev = ahd_linux_get_device(ahd, cmd->device->channel, cmd->device->id,
cmd->device->lun, /*alloc*/FALSE);
if (dev == NULL) {
ahd_midlayer_entrypoint_unlock(ahd, &s);
ahd_unlock(ahd, &s);
kfree(recovery_cmd);
return (FAILED);
}
if ((scb = ahd_get_scb(ahd, AHD_NEVER_COL_IDX)) == NULL) {
ahd_midlayer_entrypoint_unlock(ahd, &s);
ahd_unlock(ahd, &s);
kfree(recovery_cmd);
return (FAILED);
}
@ -1570,7 +1570,7 @@ ahd_linux_dev_reset(Scsi_Cmnd *cmd)
spin_lock_irq(&ahd->platform_data->spin_lock);
ahd_schedule_runq(ahd);
ahd_linux_run_complete_queue(ahd);
ahd_midlayer_entrypoint_unlock(ahd, &s);
ahd_unlock(ahd, &s);
printf("%s: Device reset returning 0x%x\n", ahd_name(ahd), retval);
return (retval);
}
@ -1591,11 +1591,11 @@ ahd_linux_bus_reset(Scsi_Cmnd *cmd)
printf("%s: Bus reset called for cmd %p\n",
ahd_name(ahd), cmd);
#endif
ahd_midlayer_entrypoint_lock(ahd, &s);
ahd_lock(ahd, &s);
found = ahd_reset_channel(ahd, cmd->device->channel + 'A',
/*initiate reset*/TRUE);
ahd_linux_run_complete_queue(ahd);
ahd_midlayer_entrypoint_unlock(ahd, &s);
ahd_unlock(ahd, &s);
if (bootverbose)
printf("%s: SCSI bus reset delivered. "

View File

@ -112,23 +112,6 @@ typedef Scsi_Cmnd *ahd_io_ctx_t;
#define ahd_le32toh(x) le32_to_cpu(x)
#define ahd_le64toh(x) le64_to_cpu(x)
#ifndef LITTLE_ENDIAN
#define LITTLE_ENDIAN 1234
#endif
#ifndef BIG_ENDIAN
#define BIG_ENDIAN 4321
#endif
#ifndef BYTE_ORDER
#if defined(__BIG_ENDIAN)
#define BYTE_ORDER BIG_ENDIAN
#endif
#if defined(__LITTLE_ENDIAN)
#define BYTE_ORDER LITTLE_ENDIAN
#endif
#endif /* BYTE_ORDER */
/************************* Configuration Data *********************************/
extern uint32_t aic79xx_allow_memio;
extern int aic79xx_detect_complete;

View File

@ -346,7 +346,6 @@ typedef enum {
* controller.
*/
AHC_NEWEEPROM_FMT = 0x4000,
AHC_RESOURCE_SHORTAGE = 0x8000,
AHC_TQINFIFO_BLOCKED = 0x10000, /* Blocked waiting for ATIOs */
AHC_INT50_SPEEDFLEX = 0x20000, /*
* Internal 50pin connector
@ -1200,7 +1199,6 @@ void ahc_pause_and_flushwork(struct ahc_softc *ahc);
int ahc_suspend(struct ahc_softc *ahc);
int ahc_resume(struct ahc_softc *ahc);
void ahc_softc_insert(struct ahc_softc *);
struct ahc_softc *ahc_find_softc(struct ahc_softc *ahc);
void ahc_set_unit(struct ahc_softc *, int);
void ahc_set_name(struct ahc_softc *, char *);
void ahc_alloc_scbs(struct ahc_softc *ahc);

View File

@ -3934,22 +3934,6 @@ ahc_softc_insert(struct ahc_softc *ahc)
ahc->init_level++;
}
/*
* Verify that the passed in softc pointer is for a
* controller that is still configured.
*/
struct ahc_softc *
ahc_find_softc(struct ahc_softc *ahc)
{
struct ahc_softc *list_ahc;
TAILQ_FOREACH(list_ahc, &ahc_tailq, links) {
if (list_ahc == ahc)
return (ahc);
}
return (NULL);
}
void
ahc_set_unit(struct ahc_softc *ahc, int unit)
{

File diff suppressed because it is too large Load Diff

View File

@ -79,6 +79,8 @@
#include <scsi/scsi_device.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_tcq.h>
#include <scsi/scsi_transport.h>
#include <scsi/scsi_transport_spi.h>
/* Core SCSI definitions */
#define AIC_LIB_PREFIX ahc
@ -127,23 +129,6 @@ typedef struct scsi_cmnd *ahc_io_ctx_t;
#define ahc_le32toh(x) le32_to_cpu(x)
#define ahc_le64toh(x) le64_to_cpu(x)
#ifndef LITTLE_ENDIAN
#define LITTLE_ENDIAN 1234
#endif
#ifndef BIG_ENDIAN
#define BIG_ENDIAN 4321
#endif
#ifndef BYTE_ORDER
#if defined(__BIG_ENDIAN)
#define BYTE_ORDER BIG_ENDIAN
#endif
#if defined(__LITTLE_ENDIAN)
#define BYTE_ORDER LITTLE_ENDIAN
#endif
#endif /* BYTE_ORDER */
/************************* Configuration Data *********************************/
extern u_int aic7xxx_no_probe;
extern u_int aic7xxx_allow_memio;
@ -283,35 +268,6 @@ ahc_scb_timer_reset(struct scb *scb, u_int usec)
#define AIC7XXX_DRIVER_VERSION "6.2.36"
/**************************** Front End Queues ********************************/
/*
* Data structure used to cast the Linux struct scsi_cmnd to something
* that allows us to use the queue macros. The linux structure has
* plenty of space to hold the links fields as required by the queue
* macros, but the queue macors require them to have the correct type.
*/
struct ahc_cmd_internal {
/* Area owned by the Linux scsi layer. */
uint8_t private[offsetof(struct scsi_cmnd, SCp.Status)];
union {
STAILQ_ENTRY(ahc_cmd) ste;
LIST_ENTRY(ahc_cmd) le;
TAILQ_ENTRY(ahc_cmd) tqe;
} links;
uint32_t end;
};
struct ahc_cmd {
union {
struct ahc_cmd_internal icmd;
struct scsi_cmnd scsi_cmd;
} un;
};
#define acmd_icmd(cmd) ((cmd)->un.icmd)
#define acmd_scsi_cmd(cmd) ((cmd)->un.scsi_cmd)
#define acmd_links un.icmd.links
/*************************** Device Data Structures ***************************/
/*
* A per probed device structure used to deal with some error recovery
@ -320,7 +276,6 @@ struct ahc_cmd {
* after a successfully completed inquiry command to the target when
* that inquiry data indicates a lun is present.
*/
TAILQ_HEAD(ahc_busyq, ahc_cmd);
typedef enum {
AHC_DEV_FREEZE_TIL_EMPTY = 0x02, /* Freeze queue until active == 0 */
AHC_DEV_Q_BASIC = 0x10, /* Allow basic device queuing */
@ -330,8 +285,6 @@ typedef enum {
struct ahc_linux_target;
struct ahc_linux_device {
TAILQ_ENTRY(ahc_linux_device) links;
/*
* The number of transactions currently
* queued to the device.
@ -401,17 +354,10 @@ struct ahc_linux_device {
*/
u_int commands_since_idle_or_otag;
#define AHC_OTAG_THRESH 500
int lun;
struct scsi_device *scsi_device;
struct ahc_linux_target *target;
};
struct ahc_linux_target {
struct ahc_linux_device *devices[AHC_NUM_LUNS];
int channel;
int target;
int refcount;
struct scsi_device *sdev[AHC_NUM_LUNS];
struct ahc_transinfo last_tinfo;
struct ahc_softc *ahc;
};
@ -445,7 +391,7 @@ struct ahc_platform_data {
/*
* Fields accessed from interrupt context.
*/
struct ahc_linux_target *targets[AHC_NUM_TARGETS];
struct scsi_target *starget[AHC_NUM_TARGETS];
spinlock_t spin_lock;
u_int qfrozen;
@ -659,7 +605,6 @@ typedef enum
/**************************** VL/EISA Routines ********************************/
#ifdef CONFIG_EISA
extern uint32_t aic7xxx_probe_eisa_vl;
int ahc_linux_eisa_init(void);
void ahc_linux_eisa_exit(void);
int aic7770_map_registers(struct ahc_softc *ahc,
@ -924,7 +869,6 @@ ahc_notify_xfer_settings_change(struct ahc_softc *ahc,
static __inline void
ahc_platform_scb_free(struct ahc_softc *ahc, struct scb *scb)
{
ahc->flags &= ~AHC_RESOURCE_SHORTAGE;
}
int ahc_platform_alloc(struct ahc_softc *ahc, void *platform_arg);

View File

@ -140,27 +140,17 @@ struct pci_driver aic7xxx_pci_driver = {
static void
ahc_linux_pci_dev_remove(struct pci_dev *pdev)
{
struct ahc_softc *ahc;
u_long l;
struct ahc_softc *ahc = pci_get_drvdata(pdev);
u_long s;
/*
* We should be able to just perform
* the free directly, but check our
* list for extra sanity.
*/
ahc_list_lock(&l);
ahc = ahc_find_softc((struct ahc_softc *)pci_get_drvdata(pdev));
if (ahc != NULL) {
u_long s;
ahc_list_lock(&s);
TAILQ_REMOVE(&ahc_tailq, ahc, links);
ahc_list_unlock(&s);
TAILQ_REMOVE(&ahc_tailq, ahc, links);
ahc_list_unlock(&l);
ahc_lock(ahc, &s);
ahc_intr_enable(ahc, FALSE);
ahc_unlock(ahc, &s);
ahc_free(ahc);
} else
ahc_list_unlock(&l);
ahc_lock(ahc, &s);
ahc_intr_enable(ahc, FALSE);
ahc_unlock(ahc, &s);
ahc_free(ahc);
}
static int
@ -174,22 +164,6 @@ ahc_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
char *name;
int error;
/*
* Some BIOSen report the same device multiple times.
*/
TAILQ_FOREACH(ahc, &ahc_tailq, links) {
struct pci_dev *probed_pdev;
probed_pdev = ahc->dev_softc;
if (probed_pdev->bus->number == pdev->bus->number
&& probed_pdev->devfn == pdev->devfn)
break;
}
if (ahc != NULL) {
/* Skip duplicate. */
return (-ENODEV);
}
pci = pdev;
entry = ahc_find_pci_device(pci);
if (entry == NULL)

View File

@ -50,7 +50,7 @@ static void ahc_dump_target_state(struct ahc_softc *ahc,
u_int our_id, char channel,
u_int target_id, u_int target_offset);
static void ahc_dump_device_state(struct info_str *info,
struct ahc_linux_device *dev);
struct scsi_device *dev);
static int ahc_proc_write_seeprom(struct ahc_softc *ahc,
char *buffer, int length);
@ -142,6 +142,7 @@ ahc_dump_target_state(struct ahc_softc *ahc, struct info_str *info,
u_int target_offset)
{
struct ahc_linux_target *targ;
struct scsi_target *starget;
struct ahc_initiator_tinfo *tinfo;
struct ahc_tmode_tstate *tstate;
int lun;
@ -153,7 +154,8 @@ ahc_dump_target_state(struct ahc_softc *ahc, struct info_str *info,
copy_info(info, "Target %d Negotiation Settings\n", target_id);
copy_info(info, "\tUser: ");
ahc_format_transinfo(info, &tinfo->user);
targ = ahc->platform_data->targets[target_offset];
starget = ahc->platform_data->starget[target_offset];
targ = scsi_transport_target_data(starget);
if (targ == NULL)
return;
@ -163,22 +165,25 @@ ahc_dump_target_state(struct ahc_softc *ahc, struct info_str *info,
ahc_format_transinfo(info, &tinfo->curr);
for (lun = 0; lun < AHC_NUM_LUNS; lun++) {
struct ahc_linux_device *dev;
struct scsi_device *sdev;
dev = targ->devices[lun];
sdev = targ->sdev[lun];
if (dev == NULL)
if (sdev == NULL)
continue;
ahc_dump_device_state(info, dev);
ahc_dump_device_state(info, sdev);
}
}
static void
ahc_dump_device_state(struct info_str *info, struct ahc_linux_device *dev)
ahc_dump_device_state(struct info_str *info, struct scsi_device *sdev)
{
struct ahc_linux_device *dev = scsi_transport_device_data(sdev);
copy_info(info, "\tChannel %c Target %d Lun %d Settings\n",
dev->target->channel + 'A', dev->target->target, dev->lun);
sdev->sdev_target->channel + 'A',
sdev->sdev_target->id, sdev->lun);
copy_info(info, "\t\tCommands Queued %ld\n", dev->commands_issued);
copy_info(info, "\t\tCommands Active %d\n", dev->active);
@ -292,20 +297,13 @@ int
ahc_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
off_t offset, int length, int inout)
{
struct ahc_softc *ahc;
struct ahc_softc *ahc = *(struct ahc_softc **)shost->hostdata;
struct info_str info;
char ahc_info[256];
u_long s;
u_int max_targ;
u_int i;
int retval;
retval = -EINVAL;
ahc_list_lock(&s);
ahc = ahc_find_softc(*(struct ahc_softc **)shost->hostdata);
if (ahc == NULL)
goto done;
/* Has data been written to the file? */
if (inout == TRUE) {
retval = ahc_proc_write_seeprom(ahc, buffer, length);
@ -367,6 +365,5 @@ ahc_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
}
retval = info.pos > info.offset ? info.pos - info.offset : 0;
done:
ahc_list_unlock(&s);
return (retval);
}

View File

@ -10358,7 +10358,7 @@ aic7xxx_queue(Scsi_Cmnd *cmd, void (*fn)(Scsi_Cmnd *))
* Returns an enumerated type that indicates the status of the operation.
*-F*************************************************************************/
static int
aic7xxx_bus_device_reset(Scsi_Cmnd *cmd)
__aic7xxx_bus_device_reset(Scsi_Cmnd *cmd)
{
struct aic7xxx_host *p;
struct aic7xxx_scb *scb;
@ -10551,6 +10551,18 @@ aic7xxx_bus_device_reset(Scsi_Cmnd *cmd)
return SUCCESS;
}
static int
aic7xxx_bus_device_reset(Scsi_Cmnd *cmd)
{
int rc;
spin_lock_irq(cmd->device->host->host_lock);
rc = __aic7xxx_bus_device_reset(cmd);
spin_unlock_irq(cmd->device->host->host_lock);
return rc;
}
/*+F*************************************************************************
* Function:
@ -10585,7 +10597,7 @@ aic7xxx_panic_abort(struct aic7xxx_host *p, Scsi_Cmnd *cmd)
* Abort the current SCSI command(s).
*-F*************************************************************************/
static int
aic7xxx_abort(Scsi_Cmnd *cmd)
__aic7xxx_abort(Scsi_Cmnd *cmd)
{
struct aic7xxx_scb *scb = NULL;
struct aic7xxx_host *p;
@ -10802,6 +10814,19 @@ success:
return SUCCESS;
}
static int
aic7xxx_abort(Scsi_Cmnd *cmd)
{
int rc;
spin_lock_irq(cmd->device->host->host_lock);
rc = __aic7xxx_abort(cmd);
spin_unlock_irq(cmd->device->host->host_lock);
return rc;
}
/*+F*************************************************************************
* Function:
* aic7xxx_reset
@ -10820,6 +10845,8 @@ aic7xxx_reset(Scsi_Cmnd *cmd)
struct aic_dev_data *aic_dev;
p = (struct aic7xxx_host *) cmd->device->host->hostdata;
spin_lock_irq(p->host->host_lock);
aic_dev = AIC_DEV(cmd);
if(aic7xxx_position(cmd) < p->scb_data->numscbs)
{
@ -10859,6 +10886,7 @@ aic7xxx_reset(Scsi_Cmnd *cmd)
* longer have it.
*/
unpause_sequencer(p, FALSE);
spin_unlock_irq(p->host->host_lock);
return SUCCESS;
}
@ -10882,7 +10910,6 @@ aic7xxx_reset(Scsi_Cmnd *cmd)
unpause_sequencer(p, FALSE);
spin_unlock_irq(p->host->host_lock);
ssleep(2);
spin_lock_irq(p->host->host_lock);
return SUCCESS;
}

View File

@ -244,9 +244,7 @@ static Scsi_Host_Template cumanascsi_template = {
.info = cumanascsi_info,
.queuecommand = cumanascsi_queue_command,
.eh_abort_handler = NCR5380_abort,
.eh_device_reset_handler= NCR5380_device_reset,
.eh_bus_reset_handler = NCR5380_bus_reset,
.eh_host_reset_handler = NCR5380_host_reset,
.can_queue = 16,
.this_id = 7,
.sg_tablesize = SG_ALL,

View File

@ -162,9 +162,7 @@ static Scsi_Host_Template ecoscsi_template = {
.info = ecoscsi_info,
.queuecommand = ecoscsi_queue_command,
.eh_abort_handler = NCR5380_abort,
.eh_device_reset_handler= NCR5380_device_reset,
.eh_bus_reset_handler = NCR5380_bus_reset,
.eh_host_reset_handler = NCR5380_host_reset,
.can_queue = 16,
.this_id = 7,
.sg_tablesize = SG_ALL,

View File

@ -2659,6 +2659,8 @@ int fas216_eh_host_reset(Scsi_Cmnd *SCpnt)
{
FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
spin_lock_irq(info->host->host_lock);
fas216_checkmagic(info);
printk("scsi%d.%c: %s: resetting host\n",
@ -2686,6 +2688,7 @@ int fas216_eh_host_reset(Scsi_Cmnd *SCpnt)
fas216_init_chip(info);
spin_unlock_irq(info->host->host_lock);
return SUCCESS;
}

View File

@ -118,9 +118,7 @@ static Scsi_Host_Template oakscsi_template = {
.info = oakscsi_info,
.queuecommand = oakscsi_queue_command,
.eh_abort_handler = NCR5380_abort,
.eh_device_reset_handler= NCR5380_device_reset,
.eh_bus_reset_handler = NCR5380_bus_reset,
.eh_host_reset_handler = NCR5380_host_reset,
.can_queue = 16,
.this_id = 7,
.sg_tablesize = SG_ALL,

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -1310,7 +1310,7 @@ static void reset_dev_param(struct AdapterCtlBlk *acb)
* @cmd - some command for this host (for fetching hooks)
* Returns: SUCCESS (0x2002) on success, else FAILED (0x2003).
*/
static int dc395x_eh_bus_reset(struct scsi_cmnd *cmd)
static int __dc395x_eh_bus_reset(struct scsi_cmnd *cmd)
{
struct AdapterCtlBlk *acb =
(struct AdapterCtlBlk *)cmd->device->host->hostdata;
@ -1356,6 +1356,16 @@ static int dc395x_eh_bus_reset(struct scsi_cmnd *cmd)
return SUCCESS;
}
static int dc395x_eh_bus_reset(struct scsi_cmnd *cmd)
{
int rc;
spin_lock_irq(cmd->device->host->host_lock);
rc = __dc395x_eh_bus_reset(cmd);
spin_unlock_irq(cmd->device->host->host_lock);
return rc;
}
/*
* abort an errant SCSI command

View File

@ -61,8 +61,6 @@ static struct scsi_host_template dmx3191d_driver_template = {
.queuecommand = NCR5380_queue_command,
.eh_abort_handler = NCR5380_abort,
.eh_bus_reset_handler = NCR5380_bus_reset,
.eh_device_reset_handler= NCR5380_device_reset,
.eh_host_reset_handler = NCR5380_host_reset,
.can_queue = 32,
.this_id = 7,
.sg_tablesize = SG_ALL,

View File

@ -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 {
@ -747,7 +746,7 @@ static int adpt_bus_reset(struct scsi_cmnd* cmd)
}
// This version of reset is called by the eh_error_handler
static int adpt_reset(struct scsi_cmnd* cmd)
static int __adpt_reset(struct scsi_cmnd* cmd)
{
adpt_hba* pHba;
int rcode;
@ -763,6 +762,17 @@ static int adpt_reset(struct scsi_cmnd* cmd)
}
}
static int adpt_reset(struct scsi_cmnd* cmd)
{
int rc;
spin_lock_irq(cmd->device->host->host_lock);
rc = __adpt_reset(cmd);
spin_unlock_irq(cmd->device->host->host_lock);
return rc;
}
// This version of reset is called by the ioctls and indirectly from eh_error_handler via adpt_reset
static int adpt_hba_reset(adpt_hba* pHba)
{
@ -875,7 +885,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 +944,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 +953,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 +1018,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 +1074,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 +1447,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 +1993,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 +2018,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 +2031,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 +2224,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 +2316,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 +2431,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 +2978,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++;
}

View File

@ -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);

View File

@ -482,8 +482,6 @@ static Scsi_Host_Template driver_template = {
.queuecommand = dtc_queue_command,
.eh_abort_handler = dtc_abort,
.eh_bus_reset_handler = dtc_bus_reset,
.eh_device_reset_handler = dtc_device_reset,
.eh_host_reset_handler = dtc_host_reset,
.bios_param = dtc_biosparam,
.can_queue = CAN_QUEUE,
.this_id = 7,

View File

@ -34,8 +34,6 @@ static int dtc_biosparam(struct scsi_device *, struct block_device *,
static int dtc_detect(Scsi_Host_Template *);
static int dtc_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
static int dtc_bus_reset(Scsi_Cmnd *);
static int dtc_device_reset(Scsi_Cmnd *);
static int dtc_host_reset(Scsi_Cmnd *);
#ifndef CMD_PER_LUN
#define CMD_PER_LUN 2
@ -86,8 +84,6 @@ static int dtc_host_reset(Scsi_Cmnd *);
#define NCR5380_queue_command dtc_queue_command
#define NCR5380_abort dtc_abort
#define NCR5380_bus_reset dtc_bus_reset
#define NCR5380_device_reset dtc_device_reset
#define NCR5380_host_reset dtc_host_reset
#define NCR5380_proc_info dtc_proc_info
/* 15 12 11 10

View File

@ -518,8 +518,6 @@ static struct scsi_host_template driver_template = {
.release = eata2x_release,
.queuecommand = eata2x_queuecommand,
.eh_abort_handler = eata2x_eh_abort,
.eh_device_reset_handler = NULL,
.eh_bus_reset_handler = NULL,
.eh_host_reset_handler = eata2x_eh_host_reset,
.bios_param = eata2x_bios_param,
.slave_configure = eata2x_slave_configure,
@ -1950,16 +1948,20 @@ static int eata2x_eh_host_reset(struct scsi_cmnd *SCarg)
ha->board_name, SCarg->device->channel, SCarg->device->id,
SCarg->device->lun, SCarg->pid);
spin_lock_irq(shost->host_lock);
if (SCarg->host_scribble == NULL)
printk("%s: reset, pid %ld inactive.\n", ha->board_name, SCarg->pid);
if (ha->in_reset) {
printk("%s: reset, exit, already in reset.\n", ha->board_name);
spin_unlock_irq(shost->host_lock);
return FAILED;
}
if (wait_on_busy(shost->io_port, MAXLOOP)) {
printk("%s: reset, exit, timeout error.\n", ha->board_name);
spin_unlock_irq(shost->host_lock);
return FAILED;
}
@ -2014,6 +2016,7 @@ static int eata2x_eh_host_reset(struct scsi_cmnd *SCarg)
if (do_dma(shost->io_port, 0, RESET_PIO)) {
printk("%s: reset, cannot reset, timeout error.\n", ha->board_name);
spin_unlock_irq(shost->host_lock);
return FAILED;
}
@ -2026,9 +2029,12 @@ static int eata2x_eh_host_reset(struct scsi_cmnd *SCarg)
ha->in_reset = 1;
spin_unlock_irq(shost->host_lock);
/* FIXME: use a sleep instead */
time = jiffies;
while ((jiffies - time) < (10 * HZ) && limit++ < 200000)
udelay(100L);
spin_lock_irq(shost->host_lock);
printk("%s: reset, interrupts disabled, loops %d.\n", ha->board_name, limit);
@ -2078,6 +2084,7 @@ static int eata2x_eh_host_reset(struct scsi_cmnd *SCarg)
else
printk("%s: reset, exit.\n", ha->board_name);
spin_unlock_irq(shost->host_lock);
return SUCCESS;
}

View File

@ -486,8 +486,11 @@ static int eata_pio_host_reset(struct scsi_cmnd *cmd)
DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_reset called pid:%ld target:" " %x lun: %x reason %x\n", cmd->pid, cmd->device->id, cmd->device->lun, cmd->abort_reason));
spin_lock_irq(host->host_lock);
if (HD(cmd)->state == RESET) {
printk(KERN_WARNING "eata_pio_reset: exit, already in reset.\n");
spin_unlock_irq(host->host_lock);
return FAILED;
}
@ -536,6 +539,8 @@ static int eata_pio_host_reset(struct scsi_cmnd *cmd)
HD(cmd)->state = 0;
spin_unlock_irq(host->host_lock);
if (success) { /* hmmm... */
DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_reset: exit, success.\n"));
return SUCCESS;

View File

@ -311,7 +311,6 @@ static Scsi_Host_Template driver_template = {
.use_clustering = ENABLE_CLUSTERING,
.eh_abort_handler = fcp_scsi_abort,
.eh_device_reset_handler = fcp_scsi_dev_reset,
.eh_bus_reset_handler = fcp_scsi_bus_reset,
.eh_host_reset_handler = fcp_scsi_host_reset,
};
#include "scsi_module.c"

View File

@ -1241,18 +1241,9 @@ static int fd_mcs_abort(Scsi_Cmnd * SCpnt)
return SUCCESS;
}
static int fd_mcs_host_reset(Scsi_Cmnd * SCpnt)
{
return FAILED;
}
static int fd_mcs_device_reset(Scsi_Cmnd * SCpnt)
{
return FAILED;
}
static int fd_mcs_bus_reset(Scsi_Cmnd * SCpnt) {
struct Scsi_Host *shpnt = SCpnt->device->host;
unsigned long flags;
#if DEBUG_RESET
static int called_once = 0;
@ -1269,6 +1260,8 @@ static int fd_mcs_bus_reset(Scsi_Cmnd * SCpnt) {
called_once = 1;
#endif
spin_lock_irqsave(shpnt->host_lock, flags);
outb(1, SCSI_Cntl_port);
do_pause(2);
outb(0, SCSI_Cntl_port);
@ -1276,6 +1269,8 @@ static int fd_mcs_bus_reset(Scsi_Cmnd * SCpnt) {
outb(0, SCSI_Mode_Cntl_port);
outb(PARITY_MASK, TMC_Cntl_port);
spin_unlock_irqrestore(shpnt->host_lock, flags);
/* Unless this is the very first call (i.e., SCPnt == NULL), everything
is probably hosed at this point. We will, however, try to keep
things going by informing the high-level code that we need help. */
@ -1357,8 +1352,6 @@ static Scsi_Host_Template driver_template = {
.queuecommand = fd_mcs_queue,
.eh_abort_handler = fd_mcs_abort,
.eh_bus_reset_handler = fd_mcs_bus_reset,
.eh_host_reset_handler = fd_mcs_host_reset,
.eh_device_reset_handler = fd_mcs_device_reset,
.bios_param = fd_mcs_biosparam,
.can_queue = 1,
.this_id = 7,

View File

@ -1543,12 +1543,18 @@ static int fdomain_16x0_abort(struct scsi_cmnd *SCpnt)
int fdomain_16x0_bus_reset(struct scsi_cmnd *SCpnt)
{
unsigned long flags;
local_irq_save(flags);
outb(1, port_base + SCSI_Cntl);
do_pause( 2 );
outb(0, port_base + SCSI_Cntl);
do_pause( 115 );
outb(0, port_base + SCSI_Mode_Cntl);
outb(PARITY_MASK, port_base + TMC_Cntl);
local_irq_restore(flags);
return SUCCESS;
}

Some files were not shown because too many files have changed in this diff Show More