Automatic merge of ../scsi-misc-2.6-old/

This commit is contained in:
James Bottomley 2005-05-26 14:14:55 -04:00
commit 153b1e1fd9
97 changed files with 12220 additions and 17636 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

@ -290,6 +290,13 @@ void elv_requeue_request(request_queue_t *q, struct request *rq)
rq = rq->end_io_data;
}
/*
* the request is prepped and may have some resources allocated.
* allowing unprepped requests to pass this one may cause resource
* deadlock. turn on softbarrier.
*/
rq->flags |= REQ_SOFTBARRIER;
/*
* if iosched has an explicit requeue hook, then use that. otherwise
* just put the request at the front of the queue
@ -386,6 +393,12 @@ struct request *elv_next_request(request_queue_t *q)
if (ret == BLKPREP_OK) {
break;
} else if (ret == BLKPREP_DEFER) {
/*
* the request may have been (partially) prepped.
* we need to keep this request in the front to
* avoid resource deadlock. turn on softbarrier.
*/
rq->flags |= REQ_SOFTBARRIER;
rq = NULL;
break;
} else if (ret == BLKPREP_KILL) {

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

@ -1070,7 +1070,7 @@ static int sbp2_handle_physdma_read(struct hpsb_host *host, int nodeid, quadlet_
static __inline__ int sbp2_command_conversion_device_type(u8 device_type)
{
return (((device_type == TYPE_DISK) ||
(device_type == TYPE_SDAD) ||
(device_type == TYPE_RBC) ||
(device_type == TYPE_ROM)) ? 1:0);
}
@ -2111,102 +2111,6 @@ static int sbp2_send_command(struct scsi_id_instance_data *scsi_id,
*/
static void sbp2_check_sbp2_command(struct scsi_id_instance_data *scsi_id, unchar *cmd)
{
unchar new_cmd[16];
u8 device_type = SBP2_DEVICE_TYPE (scsi_id->sbp2_device_type_and_lun);
SBP2_DEBUG("sbp2_check_sbp2_command");
switch (*cmd) {
case READ_6:
if (sbp2_command_conversion_device_type(device_type)) {
SBP2_DEBUG("Convert READ_6 to READ_10");
/*
* Need to turn read_6 into read_10
*/
new_cmd[0] = 0x28;
new_cmd[1] = (cmd[1] & 0xe0);
new_cmd[2] = 0x0;
new_cmd[3] = (cmd[1] & 0x1f);
new_cmd[4] = cmd[2];
new_cmd[5] = cmd[3];
new_cmd[6] = 0x0;
new_cmd[7] = 0x0;
new_cmd[8] = cmd[4];
new_cmd[9] = cmd[5];
memcpy(cmd, new_cmd, 10);
}
break;
case WRITE_6:
if (sbp2_command_conversion_device_type(device_type)) {
SBP2_DEBUG("Convert WRITE_6 to WRITE_10");
/*
* Need to turn write_6 into write_10
*/
new_cmd[0] = 0x2a;
new_cmd[1] = (cmd[1] & 0xe0);
new_cmd[2] = 0x0;
new_cmd[3] = (cmd[1] & 0x1f);
new_cmd[4] = cmd[2];
new_cmd[5] = cmd[3];
new_cmd[6] = 0x0;
new_cmd[7] = 0x0;
new_cmd[8] = cmd[4];
new_cmd[9] = cmd[5];
memcpy(cmd, new_cmd, 10);
}
break;
case MODE_SENSE:
if (sbp2_command_conversion_device_type(device_type)) {
SBP2_DEBUG("Convert MODE_SENSE_6 to MODE_SENSE_10");
/*
* Need to turn mode_sense_6 into mode_sense_10
*/
new_cmd[0] = 0x5a;
new_cmd[1] = cmd[1];
new_cmd[2] = cmd[2];
new_cmd[3] = 0x0;
new_cmd[4] = 0x0;
new_cmd[5] = 0x0;
new_cmd[6] = 0x0;
new_cmd[7] = 0x0;
new_cmd[8] = cmd[4];
new_cmd[9] = cmd[5];
memcpy(cmd, new_cmd, 10);
}
break;
case MODE_SELECT:
/*
* TODO. Probably need to change mode select to 10 byte version
*/
default:
break;
}
return;
}
/*
@ -2247,7 +2151,6 @@ static void sbp2_check_sbp2_response(struct scsi_id_instance_data *scsi_id,
struct scsi_cmnd *SCpnt)
{
u8 *scsi_buf = SCpnt->request_buffer;
u8 device_type = SBP2_DEVICE_TYPE (scsi_id->sbp2_device_type_and_lun);
SBP2_DEBUG("sbp2_check_sbp2_response");
@ -2271,14 +2174,6 @@ static void sbp2_check_sbp2_response(struct scsi_id_instance_data *scsi_id,
scsi_buf[4] = 36 - 5;
}
/*
* Check for Simple Direct Access Device and change it to TYPE_DISK
*/
if ((scsi_buf[0] & 0x1f) == TYPE_SDAD) {
SBP2_DEBUG("Changing TYPE_SDAD to TYPE_DISK");
scsi_buf[0] &= 0xe0;
}
/*
* Fix ansi revision and response data format
*/
@ -2287,27 +2182,6 @@ static void sbp2_check_sbp2_response(struct scsi_id_instance_data *scsi_id,
break;
case MODE_SENSE:
if (sbp2_command_conversion_device_type(device_type)) {
SBP2_DEBUG("Modify mode sense response (10 byte version)");
scsi_buf[0] = scsi_buf[1]; /* Mode data length */
scsi_buf[1] = scsi_buf[2]; /* Medium type */
scsi_buf[2] = scsi_buf[3]; /* Device specific parameter */
scsi_buf[3] = scsi_buf[7]; /* Block descriptor length */
memcpy(scsi_buf + 4, scsi_buf + 8, scsi_buf[0]);
}
break;
case MODE_SELECT:
/*
* TODO. Probably need to change mode select to 10 byte version
*/
default:
break;
}
@ -2690,7 +2564,8 @@ static void sbp2scsi_complete_command(struct scsi_id_instance_data *scsi_id,
static int sbp2scsi_slave_configure (struct scsi_device *sdev)
{
blk_queue_dma_alignment(sdev->request_queue, (512 - 1));
sdev->use_10_for_rw = 1;
sdev->use_10_for_ms = 1;
return 0;
}

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

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

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

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;
}
@ -439,11 +445,11 @@ static int aac_eh_reset(struct scsi_cmnd* cmd)
static int aac_cfg_open(struct inode *inode, struct file *file)
{
struct aac_dev *aac;
unsigned minor = iminor(inode);
unsigned minor_number = iminor(inode);
int err = -ENODEV;
list_for_each_entry(aac, &aac_devices, entry) {
if (aac->id == minor) {
if (aac->id == minor_number) {
file->private_data = aac;
err = 0;
break;
@ -489,6 +495,7 @@ static long aac_compat_do_ioctl(struct aac_dev *dev, unsigned cmd, unsigned long
case FSACTL_DELETE_DISK:
case FSACTL_FORCE_DELETE_DISK:
case FSACTL_GET_CONTAINERS:
case FSACTL_SEND_LARGE_FIB:
ret = aac_do_ioctl(dev, cmd, (void __user *)arg);
break;
@ -538,7 +545,7 @@ static struct file_operations aac_cfg_fops = {
static struct scsi_host_template aac_driver_template = {
.module = THIS_MODULE,
.name = "AAC",
.proc_name = "aacraid",
.proc_name = AAC_DRIVERNAME,
.info = aac_info,
.ioctl = aac_ioctl,
#ifdef CONFIG_COMPAT
@ -612,7 +619,7 @@ static int __devinit aac_probe_one(struct pci_dev *pdev,
aac->cardtype = index;
INIT_LIST_HEAD(&aac->entry);
aac->fibs = kmalloc(sizeof(struct fib) * AAC_NUM_FIB, GFP_KERNEL);
aac->fibs = kmalloc(sizeof(struct fib) * (shost->can_queue + AAC_NUM_MGT_FIB), GFP_KERNEL);
if (!aac->fibs)
goto out_free_host;
spin_lock_init(&aac->fib_lock);
@ -632,6 +639,24 @@ static int __devinit aac_probe_one(struct pci_dev *pdev,
aac_get_adapter_info(aac);
/*
* Lets override negotiations and drop the maximum SG limit to 34
*/
if ((aac_drivers[index].quirks & AAC_QUIRK_34SG) &&
(aac->scsi_host_ptr->sg_tablesize > 34)) {
aac->scsi_host_ptr->sg_tablesize = 34;
aac->scsi_host_ptr->max_sectors
= (aac->scsi_host_ptr->sg_tablesize * 8) + 112;
}
/*
* Firware printf works only with older firmware.
*/
if (aac_drivers[index].quirks & AAC_QUIRK_34SG)
aac->printf_enabled = 1;
else
aac->printf_enabled = 0;
/*
* max channel will be the physical channels plus 1 virtual channel
* all containers are on the virtual channel 0
* physical channels are address by their actual physical number+1

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

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

@ -113,7 +113,6 @@ static struct i2o_sys_tbl *sys_tbl = NULL;
static int sys_tbl_ind = 0;
static int sys_tbl_len = 0;
static adpt_hba* hbas[DPTI_MAX_HBA];
static adpt_hba* hba_chain = NULL;
static int hba_count = 0;
@ -691,7 +690,7 @@ static int adpt_device_reset(struct scsi_cmnd* cmd)
u32 msg[4];
u32 rcode;
int old_state;
struct adpt_device* d = (void*) cmd->device->hostdata;
struct adpt_device* d = cmd->device->hostdata;
pHba = (void*) cmd->device->host->hostdata[0];
printk(KERN_INFO"%s: Trying to reset device\n",pHba->name);
@ -707,7 +706,7 @@ static int adpt_device_reset(struct scsi_cmnd* cmd)
old_state = d->state;
d->state |= DPTI_DEV_RESET;
if( (rcode = adpt_i2o_post_wait(pHba, (void*)msg,sizeof(msg), FOREVER)) ){
if( (rcode = adpt_i2o_post_wait(pHba, msg,sizeof(msg), FOREVER)) ){
d->state = old_state;
if(rcode == -EOPNOTSUPP ){
printk(KERN_INFO"%s: Device reset not supported\n",pHba->name);
@ -737,7 +736,7 @@ static int adpt_bus_reset(struct scsi_cmnd* cmd)
msg[1] = (I2O_HBA_BUS_RESET<<24|HOST_TID<<12|pHba->channel[cmd->device->channel].tid);
msg[2] = 0;
msg[3] = 0;
if(adpt_i2o_post_wait(pHba, (void*)msg,sizeof(msg), FOREVER) ){
if(adpt_i2o_post_wait(pHba, msg,sizeof(msg), FOREVER) ){
printk(KERN_WARNING"%s: Bus reset failed.\n",pHba->name);
return FAILED;
} else {
@ -875,7 +874,6 @@ static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev
void __iomem *msg_addr_virt = NULL;
int raptorFlag = FALSE;
int i;
if(pci_enable_device(pDev)) {
return -EINVAL;
@ -935,12 +933,6 @@ static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev
memset(pHba, 0, sizeof(adpt_hba));
down(&adpt_configuration_lock);
for(i=0;i<DPTI_MAX_HBA;i++) {
if(hbas[i]==NULL) {
hbas[i]=pHba;
break;
}
}
if(hba_chain != NULL){
for(p = hba_chain; p->next; p = p->next);
@ -950,7 +942,7 @@ static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev
}
pHba->next = NULL;
pHba->unit = hba_count;
sprintf(pHba->name, "dpti%d", i);
sprintf(pHba->name, "dpti%d", hba_count);
hba_count++;
up(&adpt_configuration_lock);
@ -1015,11 +1007,6 @@ static void adpt_i2o_delete_hba(adpt_hba* pHba)
if(pHba->host){
free_irq(pHba->host->irq, pHba);
}
for(i=0;i<DPTI_MAX_HBA;i++) {
if(hbas[i]==pHba) {
hbas[i] = NULL;
}
}
p2 = NULL;
for( p1 = hba_chain; p1; p2 = p1,p1=p1->next){
if(p1 == pHba) {
@ -1076,12 +1063,7 @@ static void adpt_i2o_delete_hba(adpt_hba* pHba)
static int adpt_init(void)
{
int i;
printk("Loading Adaptec I2O RAID: Version " DPT_I2O_VERSION "\n");
for (i = 0; i < DPTI_MAX_HBA; i++) {
hbas[i] = NULL;
}
#ifdef REBOOT_NOTIFIER
register_reboot_notifier(&adpt_reboot_notifier);
#endif
@ -1454,7 +1436,7 @@ static int adpt_i2o_parse_lct(adpt_hba* pHba)
return -ENOMEM;
}
d->controller = (void*)pHba;
d->controller = pHba;
d->next = NULL;
memcpy(&d->lct_data, &lct->lct_entry[i], sizeof(i2o_lct_entry));
@ -2000,7 +1982,7 @@ static irqreturn_t adpt_isr(int irq, void *dev_id, struct pt_regs *regs)
struct scsi_cmnd* cmd;
adpt_hba* pHba = dev_id;
u32 m;
ulong reply;
void __iomem *reply;
u32 status=0;
u32 context;
ulong flags = 0;
@ -2025,11 +2007,11 @@ static irqreturn_t adpt_isr(int irq, void *dev_id, struct pt_regs *regs)
goto out;
}
}
reply = (ulong)bus_to_virt(m);
reply = bus_to_virt(m);
if (readl(reply) & MSG_FAIL) {
u32 old_m = readl(reply+28);
ulong msg;
void __iomem *msg;
u32 old_context;
PDEBUG("%s: Failed message\n",pHba->name);
if(old_m >= 0x100000){
@ -2038,16 +2020,16 @@ static irqreturn_t adpt_isr(int irq, void *dev_id, struct pt_regs *regs)
continue;
}
// Transaction context is 0 in failed reply frame
msg = (ulong)(pHba->msg_addr_virt + old_m);
msg = pHba->msg_addr_virt + old_m;
old_context = readl(msg+12);
writel(old_context, reply+12);
adpt_send_nop(pHba, old_m);
}
context = readl(reply+8);
if(context & 0x40000000){ // IOCTL
ulong p = (ulong)(readl(reply+12));
if( p != 0) {
memcpy((void*)p, (void*)reply, REPLY_FRAME_SIZE * 4);
void *p = (void *)readl(reply+12);
if( p != NULL) {
memcpy_fromio(p, reply, REPLY_FRAME_SIZE * 4);
}
// All IOCTLs will also be post wait
}
@ -2231,7 +2213,7 @@ static s32 adpt_scsi_register(adpt_hba* pHba,struct scsi_host_template * sht)
}
static s32 adpt_i2o_to_scsi(ulong reply, struct scsi_cmnd* cmd)
static s32 adpt_i2o_to_scsi(void __iomem *reply, struct scsi_cmnd* cmd)
{
adpt_hba* pHba;
u32 hba_status;
@ -2323,7 +2305,7 @@ static s32 adpt_i2o_to_scsi(ulong reply, struct scsi_cmnd* cmd)
u32 len = sizeof(cmd->sense_buffer);
len = (len > 40) ? 40 : len;
// Copy over the sense data
memcpy(cmd->sense_buffer, (void*)(reply+28) , len);
memcpy_fromio(cmd->sense_buffer, (reply+28) , len);
if(cmd->sense_buffer[0] == 0x70 /* class 7 */ &&
cmd->sense_buffer[2] == DATA_PROTECT ){
/* This is to handle an array failed */
@ -2438,7 +2420,7 @@ static s32 adpt_i2o_reparse_lct(adpt_hba* pHba)
return -ENOMEM;
}
d->controller = (void*)pHba;
d->controller = pHba;
d->next = NULL;
memcpy(&d->lct_data, &lct->lct_entry[i], sizeof(i2o_lct_entry));
@ -2985,8 +2967,8 @@ static int adpt_i2o_build_sys_table(void)
sys_tbl->iops[count].frame_size = pHba->status_block->inbound_frame_size;
sys_tbl->iops[count].last_changed = sys_tbl_ind - 1; // ??
sys_tbl->iops[count].iop_capabilities = pHba->status_block->iop_capabilities;
sys_tbl->iops[count].inbound_low = (u32)virt_to_bus((void*)pHba->post_port);
sys_tbl->iops[count].inbound_high = (u32)((u64)virt_to_bus((void*)pHba->post_port)>>32);
sys_tbl->iops[count].inbound_low = (u32)virt_to_bus(pHba->post_port);
sys_tbl->iops[count].inbound_high = (u32)((u64)virt_to_bus(pHba->post_port)>>32);
count++;
}

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

@ -1053,7 +1053,7 @@ static void ipr_log_array_error(struct ipr_ioa_cfg *ioa_cfg,
array_entry->dev_res_addr.lun);
}
if (array_entry->dev_res_addr.bus >= IPR_MAX_NUM_BUSES) {
if (array_entry->expected_dev_res_addr.bus >= IPR_MAX_NUM_BUSES) {
ipr_err("Expected Location: unknown\n");
} else {
ipr_err("Expected Location: %d:%d:%d:%d\n",
@ -5886,6 +5886,7 @@ static void __ipr_remove(struct pci_dev *pdev)
spin_unlock_irqrestore(ioa_cfg->host->host_lock, host_lock_flags);
wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload);
flush_scheduled_work();
spin_lock_irqsave(ioa_cfg->host->host_lock, host_lock_flags);
spin_lock(&ipr_driver_lock);
@ -5916,8 +5917,6 @@ static void ipr_remove(struct pci_dev *pdev)
ENTER;
ioa_cfg->allow_cmds = 0;
flush_scheduled_work();
ipr_remove_trace_file(&ioa_cfg->host->shost_classdev.kobj,
&ipr_trace_attr);
ipr_remove_dump_file(&ioa_cfg->host->shost_classdev.kobj,

View file

@ -36,8 +36,8 @@
/*
* Literals
*/
#define IPR_DRIVER_VERSION "2.0.13"
#define IPR_DRIVER_DATE "(February 21, 2005)"
#define IPR_DRIVER_VERSION "2.0.14"
#define IPR_DRIVER_DATE "(May 2, 2005)"
/*
* IPR_DBG_TRACE: Setting this to 1 will turn on some general function tracing

View file

@ -27,6 +27,7 @@
#include <linux/list.h>
#include <linux/version.h>
#include <linux/moduleparam.h>
#include <linux/dma-mapping.h>
#include <asm/semaphore.h>
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>

View file

@ -10,7 +10,7 @@
* 2 of the License, or (at your option) any later version.
*
* FILE : megaraid_mbox.c
* Version : v2.20.4.5 (Feb 03 2005)
* Version : v2.20.4.6 (Mar 07 2005)
*
* Authors:
* Atul Mukker <Atul.Mukker@lsil.com>
@ -202,7 +202,7 @@ MODULE_PARM_DESC(debug_level, "Debug level for driver (default=0)");
* ### global data ###
*/
static uint8_t megaraid_mbox_version[8] =
{ 0x02, 0x20, 0x04, 0x05, 2, 3, 20, 5 };
{ 0x02, 0x20, 0x04, 0x06, 3, 7, 20, 5 };
/*
@ -229,9 +229,9 @@ static struct pci_device_id pci_id_table_g[] = {
},
{
PCI_VENDOR_ID_LSI_LOGIC,
PCI_DEVICE_ID_PERC4_QC,
PCI_VENDOR_ID_DELL,
PCI_SUBSYS_ID_PERC4_QC,
PCI_DEVICE_ID_VERDE,
PCI_ANY_ID,
PCI_ANY_ID,
},
{
PCI_VENDOR_ID_DELL,
@ -271,15 +271,9 @@ static struct pci_device_id pci_id_table_g[] = {
},
{
PCI_VENDOR_ID_LSI_LOGIC,
PCI_DEVICE_ID_PERC4E_DC_320_2E,
PCI_VENDOR_ID_DELL,
PCI_SUBSYS_ID_PERC4E_DC_320_2E,
},
{
PCI_VENDOR_ID_LSI_LOGIC,
PCI_DEVICE_ID_PERC4E_SC_320_1E,
PCI_VENDOR_ID_DELL,
PCI_SUBSYS_ID_PERC4E_SC_320_1E,
PCI_DEVICE_ID_DOBSON,
PCI_ANY_ID,
PCI_ANY_ID,
},
{
PCI_VENDOR_ID_AMI,
@ -329,36 +323,6 @@ static struct pci_device_id pci_id_table_g[] = {
PCI_VENDOR_ID_LSI_LOGIC,
PCI_SUBSYS_ID_MEGARAID_SCSI_320_2,
},
{
PCI_VENDOR_ID_LSI_LOGIC,
PCI_DEVICE_ID_MEGARAID_SCSI_320_0x,
PCI_VENDOR_ID_LSI_LOGIC,
PCI_SUBSYS_ID_MEGARAID_SCSI_320_0x,
},
{
PCI_VENDOR_ID_LSI_LOGIC,
PCI_DEVICE_ID_MEGARAID_SCSI_320_2x,
PCI_VENDOR_ID_LSI_LOGIC,
PCI_SUBSYS_ID_MEGARAID_SCSI_320_2x,
},
{
PCI_VENDOR_ID_LSI_LOGIC,
PCI_DEVICE_ID_MEGARAID_SCSI_320_4x,
PCI_VENDOR_ID_LSI_LOGIC,
PCI_SUBSYS_ID_MEGARAID_SCSI_320_4x,
},
{
PCI_VENDOR_ID_LSI_LOGIC,
PCI_DEVICE_ID_MEGARAID_SCSI_320_1E,
PCI_VENDOR_ID_LSI_LOGIC,
PCI_SUBSYS_ID_MEGARAID_SCSI_320_1E,
},
{
PCI_VENDOR_ID_LSI_LOGIC,
PCI_DEVICE_ID_MEGARAID_SCSI_320_2E,
PCI_VENDOR_ID_LSI_LOGIC,
PCI_SUBSYS_ID_MEGARAID_SCSI_320_2E,
},
{
PCI_VENDOR_ID_LSI_LOGIC,
PCI_DEVICE_ID_MEGARAID_I4_133_RAID,
@ -379,21 +343,9 @@ static struct pci_device_id pci_id_table_g[] = {
},
{
PCI_VENDOR_ID_LSI_LOGIC,
PCI_DEVICE_ID_MEGARAID_SATA_300_4x,
PCI_VENDOR_ID_LSI_LOGIC,
PCI_SUBSYS_ID_MEGARAID_SATA_300_4x,
},
{
PCI_VENDOR_ID_LSI_LOGIC,
PCI_DEVICE_ID_MEGARAID_SATA_300_8x,
PCI_VENDOR_ID_LSI_LOGIC,
PCI_SUBSYS_ID_MEGARAID_SATA_300_8x,
},
{
PCI_VENDOR_ID_LSI_LOGIC,
PCI_DEVICE_ID_INTEL_RAID_SRCU42X,
PCI_VENDOR_ID_INTEL,
PCI_SUBSYS_ID_INTEL_RAID_SRCU42X,
PCI_DEVICE_ID_LINDSAY,
PCI_ANY_ID,
PCI_ANY_ID,
},
{
PCI_VENDOR_ID_LSI_LOGIC,
@ -401,60 +353,12 @@ static struct pci_device_id pci_id_table_g[] = {
PCI_VENDOR_ID_INTEL,
PCI_SUBSYS_ID_INTEL_RAID_SRCS16,
},
{
PCI_VENDOR_ID_LSI_LOGIC,
PCI_DEVICE_ID_INTEL_RAID_SRCU42E,
PCI_VENDOR_ID_INTEL,
PCI_SUBSYS_ID_INTEL_RAID_SRCU42E,
},
{
PCI_VENDOR_ID_LSI_LOGIC,
PCI_DEVICE_ID_INTEL_RAID_SRCZCRX,
PCI_VENDOR_ID_INTEL,
PCI_SUBSYS_ID_INTEL_RAID_SRCZCRX,
},
{
PCI_VENDOR_ID_LSI_LOGIC,
PCI_DEVICE_ID_INTEL_RAID_SRCS28X,
PCI_VENDOR_ID_INTEL,
PCI_SUBSYS_ID_INTEL_RAID_SRCS28X,
},
{
PCI_VENDOR_ID_LSI_LOGIC,
PCI_DEVICE_ID_INTEL_RAID_SROMBU42E_ALIEF,
PCI_VENDOR_ID_INTEL,
PCI_SUBSYS_ID_INTEL_RAID_SROMBU42E_ALIEF,
},
{
PCI_VENDOR_ID_LSI_LOGIC,
PCI_DEVICE_ID_INTEL_RAID_SROMBU42E_HARWICH,
PCI_VENDOR_ID_INTEL,
PCI_SUBSYS_ID_INTEL_RAID_SROMBU42E_HARWICH,
},
{
PCI_VENDOR_ID_LSI_LOGIC,
PCI_DEVICE_ID_INTEL_RAID_SRCU41L_LAKE_SHETEK,
PCI_VENDOR_ID_INTEL,
PCI_SUBSYS_ID_INTEL_RAID_SRCU41L_LAKE_SHETEK,
},
{
PCI_VENDOR_ID_LSI_LOGIC,
PCI_DEVICE_ID_FSC_MEGARAID_PCI_EXPRESS_ROMB,
PCI_SUBSYS_ID_FSC,
PCI_SUBSYS_ID_FSC_MEGARAID_PCI_EXPRESS_ROMB,
},
{
PCI_VENDOR_ID_LSI_LOGIC,
PCI_DEVICE_ID_MEGARAID_ACER_ROMB_2E,
PCI_VENDOR_ID_AI,
PCI_SUBSYS_ID_MEGARAID_ACER_ROMB_2E,
},
{
PCI_VENDOR_ID_LSI_LOGIC,
PCI_DEVICE_ID_MEGARAID_NEC_ROMB_2E,
PCI_VENDOR_ID_NEC,
PCI_SUBSYS_ID_MEGARAID_NEC_ROMB_2E,
},
{0} /* Terminating entry */
};
MODULE_DEVICE_TABLE(pci, pci_id_table_g);
@ -539,7 +443,8 @@ megaraid_init(void)
// register as a PCI hot-plug driver module
if ((rval = pci_module_init(&megaraid_pci_driver_g))) {
rval = pci_register_driver(&megaraid_pci_driver_g);
if (rval < 0) {
con_log(CL_ANN, (KERN_WARNING
"megaraid: could not register hotplug support.\n"));
}
@ -619,7 +524,7 @@ megaraid_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
// Setup the default DMA mask. This would be changed later on
// depending on hardware capabilities
if (pci_set_dma_mask(adapter->pdev, 0xFFFFFFFF) != 0) {
if (pci_set_dma_mask(adapter->pdev, DMA_32BIT_MASK) != 0) {
con_log(CL_ANN, (KERN_WARNING
"megaraid: pci_set_dma_mask failed:%d\n", __LINE__));
@ -1031,7 +936,7 @@ megaraid_init_mbox(adapter_t *adapter)
// Set the DMA mask to 64-bit. All supported controllers as capable of
// DMA in this range
if (pci_set_dma_mask(adapter->pdev, 0xFFFFFFFFFFFFFFFFULL) != 0) {
if (pci_set_dma_mask(adapter->pdev, DMA_64BIT_MASK) != 0) {
con_log(CL_ANN, (KERN_WARNING
"megaraid: could not set DMA mask for 64-bit.\n"));

View file

@ -21,8 +21,8 @@
#include "megaraid_ioctl.h"
#define MEGARAID_VERSION "2.20.4.5"
#define MEGARAID_EXT_VERSION "(Release Date: Thu Feb 03 12:27:22 EST 2005)"
#define MEGARAID_VERSION "2.20.4.6"
#define MEGARAID_EXT_VERSION "(Release Date: Mon Mar 07 12:27:22 EST 2005)"
/*
@ -37,8 +37,7 @@
#define PCI_DEVICE_ID_PERC4_DC 0x1960
#define PCI_SUBSYS_ID_PERC4_DC 0x0518
#define PCI_DEVICE_ID_PERC4_QC 0x0407
#define PCI_SUBSYS_ID_PERC4_QC 0x0531
#define PCI_DEVICE_ID_VERDE 0x0407
#define PCI_DEVICE_ID_PERC4_DI_EVERGLADES 0x000F
#define PCI_SUBSYS_ID_PERC4_DI_EVERGLADES 0x014A
@ -58,11 +57,7 @@
#define PCI_DEVICE_ID_PERC4E_DI_GUADALUPE 0x0013
#define PCI_SUBSYS_ID_PERC4E_DI_GUADALUPE 0x0170
#define PCI_DEVICE_ID_PERC4E_DC_320_2E 0x0408
#define PCI_SUBSYS_ID_PERC4E_DC_320_2E 0x0002
#define PCI_DEVICE_ID_PERC4E_SC_320_1E 0x0408
#define PCI_SUBSYS_ID_PERC4E_SC_320_1E 0x0001
#define PCI_DEVICE_ID_DOBSON 0x0408
#define PCI_DEVICE_ID_MEGARAID_SCSI_320_0 0x1960
#define PCI_SUBSYS_ID_MEGARAID_SCSI_320_0 0xA520
@ -73,21 +68,6 @@
#define PCI_DEVICE_ID_MEGARAID_SCSI_320_2 0x1960
#define PCI_SUBSYS_ID_MEGARAID_SCSI_320_2 0x0518
#define PCI_DEVICE_ID_MEGARAID_SCSI_320_0x 0x0407
#define PCI_SUBSYS_ID_MEGARAID_SCSI_320_0x 0x0530
#define PCI_DEVICE_ID_MEGARAID_SCSI_320_2x 0x0407
#define PCI_SUBSYS_ID_MEGARAID_SCSI_320_2x 0x0532
#define PCI_DEVICE_ID_MEGARAID_SCSI_320_4x 0x0407
#define PCI_SUBSYS_ID_MEGARAID_SCSI_320_4x 0x0531
#define PCI_DEVICE_ID_MEGARAID_SCSI_320_1E 0x0408
#define PCI_SUBSYS_ID_MEGARAID_SCSI_320_1E 0x0001
#define PCI_DEVICE_ID_MEGARAID_SCSI_320_2E 0x0408
#define PCI_SUBSYS_ID_MEGARAID_SCSI_320_2E 0x0002
#define PCI_DEVICE_ID_MEGARAID_I4_133_RAID 0x1960
#define PCI_SUBSYS_ID_MEGARAID_I4_133_RAID 0x0522
@ -97,52 +77,18 @@
#define PCI_DEVICE_ID_MEGARAID_SATA_150_6 0x1960
#define PCI_SUBSYS_ID_MEGARAID_SATA_150_6 0x0523
#define PCI_DEVICE_ID_MEGARAID_SATA_300_4x 0x0409
#define PCI_SUBSYS_ID_MEGARAID_SATA_300_4x 0x3004
#define PCI_DEVICE_ID_MEGARAID_SATA_300_8x 0x0409
#define PCI_SUBSYS_ID_MEGARAID_SATA_300_8x 0x3008
#define PCI_DEVICE_ID_INTEL_RAID_SRCU42X 0x0407
#define PCI_SUBSYS_ID_INTEL_RAID_SRCU42X 0x0532
#define PCI_DEVICE_ID_LINDSAY 0x0409
#define PCI_DEVICE_ID_INTEL_RAID_SRCS16 0x1960
#define PCI_SUBSYS_ID_INTEL_RAID_SRCS16 0x0523
#define PCI_DEVICE_ID_INTEL_RAID_SRCU42E 0x0408
#define PCI_SUBSYS_ID_INTEL_RAID_SRCU42E 0x0002
#define PCI_DEVICE_ID_INTEL_RAID_SRCZCRX 0x0407
#define PCI_SUBSYS_ID_INTEL_RAID_SRCZCRX 0x0530
#define PCI_DEVICE_ID_INTEL_RAID_SRCS28X 0x0409
#define PCI_SUBSYS_ID_INTEL_RAID_SRCS28X 0x3008
#define PCI_DEVICE_ID_INTEL_RAID_SROMBU42E_ALIEF 0x0408
#define PCI_SUBSYS_ID_INTEL_RAID_SROMBU42E_ALIEF 0x3431
#define PCI_DEVICE_ID_INTEL_RAID_SROMBU42E_HARWICH 0x0408
#define PCI_SUBSYS_ID_INTEL_RAID_SROMBU42E_HARWICH 0x3499
#define PCI_DEVICE_ID_INTEL_RAID_SRCU41L_LAKE_SHETEK 0x1960
#define PCI_SUBSYS_ID_INTEL_RAID_SRCU41L_LAKE_SHETEK 0x0520
#define PCI_DEVICE_ID_FSC_MEGARAID_PCI_EXPRESS_ROMB 0x0408
#define PCI_SUBSYS_ID_FSC_MEGARAID_PCI_EXPRESS_ROMB 0x1065
#define PCI_DEVICE_ID_MEGARAID_ACER_ROMB_2E 0x0408
#define PCI_SUBSYS_ID_MEGARAID_ACER_ROMB_2E 0x004D
#define PCI_SUBSYS_ID_PERC3_QC 0x0471
#define PCI_SUBSYS_ID_PERC3_DC 0x0493
#define PCI_SUBSYS_ID_PERC3_SC 0x0475
#define PCI_DEVICE_ID_MEGARAID_NEC_ROMB_2E 0x0408
#define PCI_SUBSYS_ID_MEGARAID_NEC_ROMB_2E 0x8287
#ifndef PCI_SUBSYS_ID_FSC
#define PCI_SUBSYS_ID_FSC 0x1734
#endif
#define MBOX_MAX_SCSI_CMDS 128 // number of cmds reserved for kernel
#define MBOX_MAX_USER_CMDS 32 // number of cmds for applications

View file

@ -10,13 +10,12 @@
* 2 of the License, or (at your option) any later version.
*
* FILE : megaraid_mm.c
* Version : v2.20.2.5 (Jan 21 2005)
* Version : v2.20.2.6 (Mar 7 2005)
*
* Common management module
*/
#include "megaraid_mm.h"
#include <linux/smp_lock.h>
// Entry points for char node driver
@ -61,7 +60,7 @@ EXPORT_SYMBOL(mraid_mm_unregister_adp);
EXPORT_SYMBOL(mraid_mm_adapter_app_handle);
static int majorno;
static uint32_t drvr_ver = 0x02200201;
static uint32_t drvr_ver = 0x02200206;
static int adapters_count_g;
static struct list_head adapters_list_g;
@ -1231,9 +1230,9 @@ mraid_mm_compat_ioctl(struct file *filep, unsigned int cmd,
unsigned long arg)
{
int err;
lock_kernel();
err = mraid_mm_ioctl(NULL, filep, cmd, arg);
unlock_kernel();
return err;
}
#endif

View file

@ -29,9 +29,9 @@
#include "megaraid_ioctl.h"
#define LSI_COMMON_MOD_VERSION "2.20.2.5"
#define LSI_COMMON_MOD_VERSION "2.20.2.6"
#define LSI_COMMON_MOD_EXT_VERSION \
"(Release Date: Fri Jan 21 00:01:03 EST 2005)"
"(Release Date: Mon Mar 7 00:01:03 EST 2005)"
#define LSI_DBGLVL dbglevel

View file

@ -1,836 +0,0 @@
/****************************************************************************
* Perceptive Solutions, Inc. PCI-2000 device driver for Linux.
*
* pci2000.c - Linux Host Driver for PCI-2000 IntelliCache SCSI Adapters
*
* Copyright (c) 1997-1999 Perceptive Solutions, Inc.
* All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that redistributions of source
* code retain the above copyright notice and this comment without
* modification.
*
* Technical updates and product information at:
* http://www.psidisk.com
*
* Please send questions, comments, bug reports to:
* tech@psidisk.com Technical Support
*
*
* Revisions 1.10 Jan-21-1999
* - Fixed sign on message to reflect proper controller name.
* - Added support for RAID status monitoring and control.
*
* Revisions 1.11 Mar-22-1999
* - Fixed control timeout to not lock up the entire system if
* controller goes offline completely.
*
* Revisions 1.12 Mar-26-1999
* - Fixed spinlock and PCI configuration.
*
* Revisions 1.20 Mar-27-2000
* - Added support for dynamic DMA
*
****************************************************************************/
#define PCI2000_VERSION "1.20"
#include <linux/blkdev.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/string.h>
#include <linux/pci.h>
#include <linux/ioport.h>
#include <linux/delay.h>
#include <linux/sched.h>
#include <linux/proc_fs.h>
#include <linux/stat.h>
#include <linux/spinlock.h>
#include <asm/dma.h>
#include <asm/system.h>
#include <asm/io.h>
#include "scsi.h"
#include <scsi/scsi_host.h>
#include "pci2000.h"
#include "psi_roy.h"
//#define DEBUG 1
#ifdef DEBUG
#define DEB(x) x
#define STOP_HERE {int st;for(st=0;st<100;st++){st=1;}}
#else
#define DEB(x)
#define STOP_HERE
#endif
typedef struct
{
unsigned int address;
unsigned int length;
} SCATGATH, *PSCATGATH;
typedef struct
{
Scsi_Cmnd *SCpnt;
PSCATGATH scatGath;
dma_addr_t scatGathDma;
UCHAR *cdb;
dma_addr_t cdbDma;
UCHAR tag;
} DEV2000, *PDEV2000;
typedef struct
{
ULONG basePort;
ULONG mb0;
ULONG mb1;
ULONG mb2;
ULONG mb3;
ULONG mb4;
ULONG cmd;
ULONG tag;
ULONG irqOwned;
struct pci_dev *pdev;
DEV2000 dev[MAX_BUS][MAX_UNITS];
} ADAPTER2000, *PADAPTER2000;
#define HOSTDATA(host) ((PADAPTER2000)&host->hostdata)
#define consistentLen (MAX_BUS * MAX_UNITS * (16 * sizeof (SCATGATH) + MAX_COMMAND_SIZE))
static struct Scsi_Host *PsiHost[MAXADAPTER] = {NULL,}; // One for each adapter
static int NumAdapters = 0;
/****************************************************************
* Name: WaitReady :LOCAL
*
* Description: Wait for controller ready.
*
* Parameters: padapter - Pointer adapter data structure.
*
* Returns: TRUE on not ready.
*
****************************************************************/
static int WaitReady (PADAPTER2000 padapter)
{
ULONG z;
for ( z = 0; z < (TIMEOUT_COMMAND * 4); z++ )
{
if ( !inb_p (padapter->cmd) )
return FALSE;
udelay (250);
};
return TRUE;
}
/****************************************************************
* Name: WaitReadyLong :LOCAL
*
* Description: Wait for controller ready.
*
* Parameters: padapter - Pointer adapter data structure.
*
* Returns: TRUE on not ready.
*
****************************************************************/
static int WaitReadyLong (PADAPTER2000 padapter)
{
ULONG z;
for ( z = 0; z < (5000 * 4); z++ )
{
if ( !inb_p (padapter->cmd) )
return FALSE;
udelay (250);
};
return TRUE;
}
/****************************************************************
* Name: OpDone :LOCAL
*
* Description: Clean up operation and issue done to caller.
*
* Parameters: SCpnt - Pointer to SCSI command structure.
* status - Caller status.
*
* Returns: Nothing.
*
****************************************************************/
static void OpDone (Scsi_Cmnd *SCpnt, ULONG status)
{
SCpnt->result = status;
SCpnt->scsi_done (SCpnt);
}
/****************************************************************
* Name: Command :LOCAL
*
* Description: Issue queued command to the PCI-2000.
*
* Parameters: padapter - Pointer to adapter information structure.
* cmd - PCI-2000 command byte.
*
* Returns: Non-zero command tag if operation is accepted.
*
****************************************************************/
static UCHAR Command (PADAPTER2000 padapter, UCHAR cmd)
{
outb_p (cmd, padapter->cmd);
if ( WaitReady (padapter) )
return 0;
if ( inw_p (padapter->mb0) )
return 0;
return inb_p (padapter->mb1);
}
/****************************************************************
* Name: BuildSgList :LOCAL
*
* Description: Build the scatter gather list for controller.
*
* Parameters: SCpnt - Pointer to SCSI command structure.
* padapter - Pointer to adapter information structure.
* pdev - Pointer to adapter device structure.
*
* Returns: Non-zero in not scatter gather.
*
****************************************************************/
static int BuildSgList (Scsi_Cmnd *SCpnt, PADAPTER2000 padapter, PDEV2000 pdev)
{
int z;
int zc;
struct scatterlist *sg;
if ( SCpnt->use_sg )
{
sg = (struct scatterlist *)SCpnt->request_buffer;
zc = pci_map_sg (padapter->pdev, sg, SCpnt->use_sg, SCpnt->sc_data_direction);
for ( z = 0; z < zc; z++ )
{
pdev->scatGath[z].address = cpu_to_le32 (sg_dma_address (sg));
pdev->scatGath[z].length = cpu_to_le32 (sg_dma_len (sg++));
}
outl (pdev->scatGathDma, padapter->mb2);
outl ((zc << 24) | SCpnt->request_bufflen, padapter->mb3);
return FALSE;
}
if ( !SCpnt->request_bufflen)
{
outl (0, padapter->mb2);
outl (0, padapter->mb3);
return TRUE;
}
SCpnt->SCp.have_data_in = pci_map_single (padapter->pdev,
SCpnt->request_buffer, SCpnt->request_bufflen,
SCpnt->sc_data_direction);
outl (SCpnt->SCp.have_data_in, padapter->mb2);
outl (SCpnt->request_bufflen, padapter->mb3);
return TRUE;
}
/*********************************************************************
* Name: PsiRaidCmd
*
* Description: Execute a simple command.
*
* Parameters: padapter - Pointer to adapter control structure.
* cmd - Roy command byte.
*
* Returns: Return error status.
*
********************************************************************/
static int PsiRaidCmd (PADAPTER2000 padapter, char cmd)
{
if ( WaitReady (padapter) ) // test for command register ready
return DID_TIME_OUT;
outb_p (cmd, padapter->cmd); // issue command
if ( WaitReadyLong (padapter) ) // wait for adapter ready
return DID_TIME_OUT;
return DID_OK;
}
/****************************************************************
* Name: Irq_Handler :LOCAL
*
* Description: Interrupt handler.
*
* Parameters: irq - Hardware IRQ number.
* dev_id -
* regs -
*
* Returns: TRUE if drive is not ready in time.
*
****************************************************************/
static irqreturn_t Irq_Handler (int irq, void *dev_id, struct pt_regs *regs)
{
struct Scsi_Host *shost = NULL; // Pointer to host data block
PADAPTER2000 padapter; // Pointer to adapter control structure
PDEV2000 pdev;
Scsi_Cmnd *SCpnt;
UCHAR tag = 0;
UCHAR tag0;
ULONG error;
int pun;
int bus;
int z;
unsigned long flags;
int handled = 0;
DEB(printk ("\npci2000 received interrupt "));
for ( z = 0; z < NumAdapters; z++ ) // scan for interrupt to process
{
if ( PsiHost[z]->irq == (UCHAR)(irq & 0xFF) )
{
tag = inb_p (HOSTDATA(PsiHost[z])->tag);
if ( tag )
{
shost = PsiHost[z];
break;
}
}
}
if ( !shost )
{
DEB (printk ("\npci2000: not my interrupt"));
goto out;
}
handled = 1;
spin_lock_irqsave(shost->host_lock, flags);
padapter = HOSTDATA(shost);
tag0 = tag & 0x7F; // mask off the error bit
for ( bus = 0; bus < MAX_BUS; bus++ ) // scan the busses
{
for ( pun = 0; pun < MAX_UNITS; pun++ ) // scan the targets
{
pdev = &padapter->dev[bus][pun];
if ( !pdev->tag )
continue;
if ( pdev->tag == tag0 ) // is this it?
{
pdev->tag = 0;
SCpnt = pdev->SCpnt;
goto unmapProceed;
}
}
}
outb_p (0xFF, padapter->tag); // clear the op interrupt
outb_p (CMD_DONE, padapter->cmd); // complete the op
goto irq_return; // done, but, with what?
unmapProceed:;
if ( !bus )
{
switch ( SCpnt->cmnd[0] )
{
case SCSIOP_TEST_UNIT_READY:
pci_unmap_single (padapter->pdev, SCpnt->SCp.have_data_in, sizeof (SCpnt->sense_buffer), PCI_DMA_FROMDEVICE);
goto irqProceed;
case SCSIOP_READ_CAPACITY:
pci_unmap_single (padapter->pdev, SCpnt->SCp.have_data_in, 8, PCI_DMA_FROMDEVICE);
goto irqProceed;
case SCSIOP_VERIFY:
case SCSIOP_START_STOP_UNIT:
case SCSIOP_MEDIUM_REMOVAL:
goto irqProceed;
}
}
if ( SCpnt->SCp.have_data_in )
pci_unmap_single (padapter->pdev, SCpnt->SCp.have_data_in, SCpnt->request_bufflen, SCpnt->sc_data_direction);
else
{
if ( SCpnt->use_sg )
pci_unmap_sg (padapter->pdev, (struct scatterlist *)SCpnt->request_buffer, SCpnt->use_sg, SCpnt->sc_data_direction);
}
irqProceed:;
if ( tag & ERR08_TAGGED ) // is there an error here?
{
if ( WaitReady (padapter) )
{
OpDone (SCpnt, DID_TIME_OUT << 16);
goto irq_return;
}
outb_p (tag0, padapter->mb0); // get real error code
outb_p (CMD_ERROR, padapter->cmd);
if ( WaitReady (padapter) ) // wait for controller to suck up the op
{
OpDone (SCpnt, DID_TIME_OUT << 16);
goto irq_return;
}
error = inl (padapter->mb0); // get error data
outb_p (0xFF, padapter->tag); // clear the op interrupt
outb_p (CMD_DONE, padapter->cmd); // complete the op
DEB (printk ("status: %lX ", error));
if ( error == 0x00020002 ) // is this error a check condition?
{
if ( bus ) // are we doint SCSI commands?
{
OpDone (SCpnt, (DID_OK << 16) | 2);
goto irq_return;
}
if ( *SCpnt->cmnd == SCSIOP_TEST_UNIT_READY )
OpDone (SCpnt, (DRIVER_SENSE << 24) | (DID_OK << 16) | 2); // test caller we have sense data too
else
OpDone (SCpnt, DID_ERROR << 16);
goto irq_return;
}
OpDone (SCpnt, DID_ERROR << 16);
goto irq_return;
}
outb_p (0xFF, padapter->tag); // clear the op interrupt
outb_p (CMD_DONE, padapter->cmd); // complete the op
OpDone (SCpnt, DID_OK << 16);
irq_return:
spin_unlock_irqrestore(shost->host_lock, flags);
out:
return IRQ_RETVAL(handled);
}
/****************************************************************
* Name: Pci2000_QueueCommand
*
* Description: Process a queued command from the SCSI manager.
*
* Parameters: SCpnt - Pointer to SCSI command structure.
* done - Pointer to done function to call.
*
* Returns: Status code.
*
****************************************************************/
int Pci2000_QueueCommand (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
{
UCHAR *cdb = (UCHAR *)SCpnt->cmnd; // Pointer to SCSI CDB
PADAPTER2000 padapter = HOSTDATA(SCpnt->device->host); // Pointer to adapter control structure
int rc = -1; // command return code
UCHAR bus = SCpnt->device->channel;
UCHAR pun = SCpnt->device->id;
UCHAR lun = SCpnt->device->lun;
UCHAR cmd;
PDEV2000 pdev = &padapter->dev[bus][pun];
if ( !done )
{
printk("pci2000_queuecommand: %02X: done can't be NULL\n", *cdb);
return 0;
}
SCpnt->scsi_done = done;
SCpnt->SCp.have_data_in = 0;
pdev->SCpnt = SCpnt; // Save this command data
if ( WaitReady (padapter) )
{
rc = DID_ERROR;
goto finished;
}
outw_p (pun | (lun << 8), padapter->mb0);
if ( bus )
{
DEB (if(*cdb) printk ("\nCDB: %X- %X %X %X %X %X %X %X %X %X %X ", SCpnt->cmd_len, cdb[0], cdb[1], cdb[2], cdb[3], cdb[4], cdb[5], cdb[6], cdb[7], cdb[8], cdb[9]));
DEB (if(*cdb) printk ("\ntimeout_per_command: %d, timeout_total: %d, timeout: %d", SCpnt->timeout_per_command,
SCpnt->timeout_total, SCpnt->timeout));
outl (SCpnt->timeout_per_command, padapter->mb1);
outb_p (CMD_SCSI_TIMEOUT, padapter->cmd);
if ( WaitReady (padapter) )
{
rc = DID_ERROR;
goto finished;
}
outw_p (pun | (lun << 8), padapter->mb0);
outw_p (SCpnt->cmd_len << 8, padapter->mb0 + 2);
memcpy (pdev->cdb, cdb, MAX_COMMAND_SIZE);
outl (pdev->cdbDma, padapter->mb1);
if ( BuildSgList (SCpnt, padapter, pdev) )
cmd = CMD_SCSI_THRU;
else
cmd = CMD_SCSI_THRU_SG;
if ( (pdev->tag = Command (padapter, cmd)) == 0 )
rc = DID_TIME_OUT;
goto finished;
}
else
{
if ( lun )
{
rc = DID_BAD_TARGET;
goto finished;
}
}
switch ( *cdb )
{
case SCSIOP_INQUIRY: // inquiry CDB
if ( cdb[2] == SC_MY_RAID )
{
switch ( cdb[3] )
{
case MY_SCSI_REBUILD:
OpDone (SCpnt, PsiRaidCmd (padapter, CMD_RAID_REBUILD) << 16);
return 0;
case MY_SCSI_ALARMMUTE:
OpDone (SCpnt, PsiRaidCmd (padapter, CMD_RAID_MUTE) << 16);
return 0;
case MY_SCSI_DEMOFAIL:
OpDone (SCpnt, PsiRaidCmd (padapter, CMD_RAID_FAIL) << 16);
return 0;
default:
if ( SCpnt->use_sg )
{
rc = DID_ERROR;
goto finished;
}
else
{
SCpnt->SCp.have_data_in = pci_map_single (padapter->pdev, SCpnt->request_buffer, SCpnt->request_bufflen,
SCpnt->sc_data_direction);
outl (SCpnt->SCp.have_data_in, padapter->mb2);
}
outl (cdb[5], padapter->mb0);
outl (cdb[3], padapter->mb3);
cmd = CMD_DASD_RAID_RQ;
break;
}
break;
}
if ( SCpnt->use_sg )
{
SCpnt->SCp.have_data_in = pci_map_single (padapter->pdev,
((struct scatterlist *)SCpnt->request_buffer)->address,
SCpnt->request_bufflen,
SCpnt->sc_data_direction);
}
else
{
SCpnt->SCp.have_data_in = pci_map_single (padapter->pdev, SCpnt->request_buffer,
SCpnt->request_bufflen,
SCpnt->sc_data_direction);
}
outl (SCpnt->SCp.have_data_in, padapter->mb2);
outl (SCpnt->request_bufflen, padapter->mb3);
cmd = CMD_DASD_SCSI_INQ;
break;
case SCSIOP_TEST_UNIT_READY: // test unit ready CDB
SCpnt->SCp.have_data_in = pci_map_single (padapter->pdev, SCpnt->sense_buffer, sizeof (SCpnt->sense_buffer), PCI_DMA_FROMDEVICE);
outl (SCpnt->SCp.have_data_in, padapter->mb2);
outl (sizeof (SCpnt->sense_buffer), padapter->mb3);
cmd = CMD_TEST_READY;
break;
case SCSIOP_READ_CAPACITY: // read capacity CDB
if ( SCpnt->use_sg )
{
SCpnt->SCp.have_data_in = pci_map_single (padapter->pdev, ((struct scatterlist *)(SCpnt->request_buffer))->address,
8, PCI_DMA_FROMDEVICE);
}
else
SCpnt->SCp.have_data_in = pci_map_single (padapter->pdev, SCpnt->request_buffer, 8, PCI_DMA_FROMDEVICE);
outl (SCpnt->SCp.have_data_in, padapter->mb2);
outl (8, padapter->mb3);
cmd = CMD_DASD_CAP;
break;
case SCSIOP_VERIFY: // verify CDB
outw_p ((USHORT)cdb[8] | ((USHORT)cdb[7] << 8), padapter->mb0 + 2);
outl (XSCSI2LONG (&cdb[2]), padapter->mb1);
cmd = CMD_READ_SG;
break;
case SCSIOP_READ: // read10 CDB
outw_p ((USHORT)cdb[8] | ((USHORT)cdb[7] << 8), padapter->mb0 + 2);
outl (XSCSI2LONG (&cdb[2]), padapter->mb1);
if ( BuildSgList (SCpnt, padapter, pdev) )
cmd = CMD_READ;
else
cmd = CMD_READ_SG;
break;
case SCSIOP_READ6: // read6 CDB
outw_p (cdb[4], padapter->mb0 + 2);
outl ((SCSI2LONG (&cdb[1])) & 0x001FFFFF, padapter->mb1);
if ( BuildSgList (SCpnt, padapter, pdev) )
cmd = CMD_READ;
else
cmd = CMD_READ_SG;
break;
case SCSIOP_WRITE: // write10 CDB
outw_p ((USHORT)cdb[8] | ((USHORT)cdb[7] << 8), padapter->mb0 + 2);
outl (XSCSI2LONG (&cdb[2]), padapter->mb1);
if ( BuildSgList (SCpnt, padapter, pdev) )
cmd = CMD_WRITE;
else
cmd = CMD_WRITE_SG;
break;
case SCSIOP_WRITE6: // write6 CDB
outw_p (cdb[4], padapter->mb0 + 2);
outl ((SCSI2LONG (&cdb[1])) & 0x001FFFFF, padapter->mb1);
if ( BuildSgList (SCpnt, padapter, pdev) )
cmd = CMD_WRITE;
else
cmd = CMD_WRITE_SG;
break;
case SCSIOP_START_STOP_UNIT:
cmd = CMD_EJECT_MEDIA;
break;
case SCSIOP_MEDIUM_REMOVAL:
switch ( cdb[4] )
{
case 0:
cmd = CMD_UNLOCK_DOOR;
break;
case 1:
cmd = CMD_LOCK_DOOR;
break;
default:
cmd = 0;
break;
}
if ( cmd )
break;
default:
DEB (printk ("pci2000_queuecommand: Unsupported command %02X\n", *cdb));
OpDone (SCpnt, DID_ERROR << 16);
return 0;
}
if ( (pdev->tag = Command (padapter, cmd)) == 0 )
rc = DID_TIME_OUT;
finished:;
if ( rc != -1 )
OpDone (SCpnt, rc << 16);
return 0;
}
/****************************************************************
* Name: Pci2000_Detect
*
* Description: Detect and initialize our boards.
*
* Parameters: tpnt - Pointer to SCSI host template structure.
*
* Returns: Number of adapters installed.
*
****************************************************************/
int Pci2000_Detect (Scsi_Host_Template *tpnt)
{
int found = 0;
int installed = 0;
struct Scsi_Host *pshost;
PADAPTER2000 padapter;
int z, zz;
int setirq;
struct pci_dev *pdev = NULL;
UCHAR *consistent;
dma_addr_t consistentDma;
while ( (pdev = pci_find_device (VENDOR_PSI, DEVICE_ROY_1, pdev)) != NULL )
{
if (pci_enable_device(pdev))
continue;
pshost = scsi_register (tpnt, sizeof(ADAPTER2000));
if(pshost == NULL)
continue;
padapter = HOSTDATA(pshost);
padapter->basePort = pci_resource_start (pdev, 1);
DEB (printk ("\nBase Regs = %#04X", padapter->basePort)); // get the base I/O port address
padapter->mb0 = padapter->basePort + RTR_MAILBOX; // get the 32 bit mail boxes
padapter->mb1 = padapter->basePort + RTR_MAILBOX + 4;
padapter->mb2 = padapter->basePort + RTR_MAILBOX + 8;
padapter->mb3 = padapter->basePort + RTR_MAILBOX + 12;
padapter->mb4 = padapter->basePort + RTR_MAILBOX + 16;
padapter->cmd = padapter->basePort + RTR_LOCAL_DOORBELL; // command register
padapter->tag = padapter->basePort + RTR_PCI_DOORBELL; // tag/response register
padapter->pdev = pdev;
if ( WaitReady (padapter) )
goto unregister;
outb_p (0x84, padapter->mb0);
outb_p (CMD_SPECIFY, padapter->cmd);
if ( WaitReady (padapter) )
goto unregister;
consistent = pci_alloc_consistent (pdev, consistentLen, &consistentDma);
if ( !consistent )
{
printk ("Unable to allocate DMA memory for PCI-2000 controller.\n");
goto unregister;
}
scsi_set_device(pshost, &pdev->dev);
pshost->irq = pdev->irq;
setirq = 1;
padapter->irqOwned = 0;
for ( z = 0; z < installed; z++ ) // scan for shared interrupts
{
if ( PsiHost[z]->irq == pshost->irq ) // if shared then, don't posses
setirq = 0;
}
if ( setirq ) // if not shared, posses
{
if ( request_irq (pshost->irq, Irq_Handler, SA_SHIRQ, "pci2000", padapter) < 0 )
{
if ( request_irq (pshost->irq, Irq_Handler, SA_INTERRUPT | SA_SHIRQ, "pci2000", padapter) < 0 )
{
printk ("Unable to allocate IRQ for PCI-2000 controller.\n");
pci_free_consistent (pdev, consistentLen, consistent, consistentDma);
goto unregister;
}
}
padapter->irqOwned = pshost->irq; // set IRQ as owned
}
PsiHost[installed] = pshost; // save SCSI_HOST pointer
pshost->io_port = padapter->basePort;
pshost->n_io_port = 0xFF;
pshost->unique_id = padapter->basePort;
pshost->max_id = 16;
pshost->max_channel = 1;
for ( zz = 0; zz < MAX_BUS; zz++ )
for ( z = 0; z < MAX_UNITS; z++ )
{
padapter->dev[zz][z].tag = 0;
padapter->dev[zz][z].scatGath = (PSCATGATH)consistent;
padapter->dev[zz][z].scatGathDma = consistentDma;
consistent += 16 * sizeof (SCATGATH);
consistentDma += 16 * sizeof (SCATGATH);
padapter->dev[zz][z].cdb = (UCHAR *)consistent;
padapter->dev[zz][z].cdbDma = consistentDma;
consistent += MAX_COMMAND_SIZE;
consistentDma += MAX_COMMAND_SIZE;
}
printk("\nPSI-2000 Intelligent Storage SCSI CONTROLLER: at I/O = %lX IRQ = %d\n", padapter->basePort, pshost->irq);
printk("Version %s, Compiled %s %s\n\n", PCI2000_VERSION, __DATE__, __TIME__);
found++;
if ( ++installed < MAXADAPTER )
continue;
break;
unregister:;
scsi_unregister (pshost);
found++;
}
NumAdapters = installed;
return installed;
}
/****************************************************************
* Name: Pci2000_Abort
*
* Description: Process the Abort command from the SCSI manager.
*
* Parameters: SCpnt - Pointer to SCSI command structure.
*
* Returns: Allways snooze.
*
****************************************************************/
int Pci2000_Abort (Scsi_Cmnd *SCpnt)
{
DEB (printk ("pci2000_abort\n"));
return SCSI_ABORT_SNOOZE;
}
/****************************************************************
* Name: Pci2000_Reset
*
* Description: Process the Reset command from the SCSI manager.
*
* Parameters: SCpnt - Pointer to SCSI command structure.
* flags - Flags about the reset command
*
* Returns: No active command at this time, so this means
* that each time we got some kind of response the
* last time through. Tell the mid-level code to
* request sense information in order to decide what
* to do next.
*
****************************************************************/
int Pci2000_Reset (Scsi_Cmnd *SCpnt, unsigned int reset_flags)
{
return SCSI_RESET_PUNT;
}
/****************************************************************
* Name: Pci2000_Release
*
* Description: Release resources allocated for a single each adapter.
*
* Parameters: pshost - Pointer to SCSI command structure.
*
* Returns: zero.
*
****************************************************************/
int Pci2000_Release (struct Scsi_Host *pshost)
{
PADAPTER2000 padapter = HOSTDATA (pshost);
if ( padapter->irqOwned )
free_irq (pshost->irq, padapter);
pci_free_consistent (padapter->pdev, consistentLen, padapter->dev[0][0].scatGath, padapter->dev[0][0].scatGathDma);
release_region (pshost->io_port, pshost->n_io_port);
scsi_unregister(pshost);
return 0;
}
/****************************************************************
* Name: Pci2000_BiosParam
*
* Description: Process the biosparam request from the SCSI manager to
* return C/H/S data.
*
* Parameters: disk - Pointer to SCSI disk structure.
* dev - Major/minor number from kernel.
* geom - Pointer to integer array to place geometry data.
*
* Returns: zero.
*
****************************************************************/
int Pci2000_BiosParam (struct scsi_device *sdev, struct block_device *dev,
sector_t capacity, int geom[])
{
PADAPTER2000 padapter;
padapter = HOSTDATA(sdev->host);
if ( WaitReady (padapter) )
return 0;
outb_p (sdev->id, padapter->mb0);
outb_p (CMD_GET_PARMS, padapter->cmd);
if ( WaitReady (padapter) )
return 0;
geom[0] = inb_p (padapter->mb2 + 3);
geom[1] = inb_p (padapter->mb2 + 2);
geom[2] = inw_p (padapter->mb2);
return 0;
}
MODULE_LICENSE("Dual BSD/GPL");
static Scsi_Host_Template driver_template = {
.proc_name = "pci2000",
.name = "PCI-2000 SCSI Intelligent Disk Controller",
.detect = Pci2000_Detect,
.release = Pci2000_Release,
.queuecommand = Pci2000_QueueCommand,
.abort = Pci2000_Abort,
.reset = Pci2000_Reset,
.bios_param = Pci2000_BiosParam,
.can_queue = 16,
.this_id = -1,
.sg_tablesize = 16,
.cmd_per_lun = 1,
.use_clustering = DISABLE_CLUSTERING,
};
#include "scsi_module.c"

File diff suppressed because it is too large Load diff

View file

@ -1,39 +0,0 @@
/****************************************************************************
* Perceptive Solutions, Inc. PCI-2220I device driver for Linux.
*
* pci2220i.h - Linux Host Driver for PCI-2220i EIDE Adapters
*
* Copyright (c) 1997-1999 Perceptive Solutions, Inc.
* All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that redistributions of source
* code retain the above copyright notice and this comment without
* modification.
*
* Technical updates and product information at:
* http://www.psidisk.com
*
* Please send questions, comments, bug reports to:
* tech@psidisk.com Technical Support
*
****************************************************************************/
#ifndef _PCI2220I_H
#define _PCI2220I_H
#ifndef LINUX_VERSION_CODE
#include <linux/version.h>
#endif
#define LINUXVERSION(v,p,s) (((v)<<16) + ((p)<<8) + (s))
// function prototypes
int Pci2220i_Detect (Scsi_Host_Template *tpnt);
int Pci2220i_Command (Scsi_Cmnd *SCpnt);
int Pci2220i_QueueCommand (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *));
int Pci2220i_Abort (Scsi_Cmnd *SCpnt);
int Pci2220i_Reset (Scsi_Cmnd *SCpnt, unsigned int flags);
int Pci2220i_Release (struct Scsi_Host *pshost);
int Pci2220i_BiosParam (struct scsi_device *sdev,
struct block_device *dev,
sector_t capacity, int geom[]);
#endif

View file

@ -1,564 +0,0 @@
/****************************************************************************
* Perceptive Solutions, Inc. PCI-2220I device driver for Linux.
*
* psi_dalei.h - Linux Host Driver for PCI-2220i EIDE Adapters
*
* Copyright (c) 1997-1999 Perceptive Solutions, Inc.
* All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that redistributions of source
* code retain the above copyright notice and this comment without
* modification.
*
* Technical updates and product information at:
* http://www.psidisk.com
*
* Please send questions, comments, bug reports to:
* tech@psidisk.com Technical Support
*
****************************************************************************/
/************************************************/
/* Some defines that we like */
/************************************************/
#define CHAR char
#define UCHAR unsigned char
#define SHORT short
#define USHORT unsigned short
#define BOOL unsigned short
#define LONG long
#define ULONG unsigned long
#define VOID void
/************************************************/
/* Dale PCI setup */
/************************************************/
#define VENDOR_PSI 0x1256
#define DEVICE_DALE_1 0x4401 /* 'D1' */
#define DEVICE_BIGD_1 0x4201 /* 'B1' */
#define DEVICE_BIGD_2 0x4202 /* 'B2' */
/************************************************/
/* Misc konstants */
/************************************************/
#define DALE_MAXDRIVES 4
#define BIGD_MAXDRIVES 8
#define SECTORSXFER 8
#define ATAPI_TRANSFER 8192
#define BYTES_PER_SECTOR 512
#define DEFAULT_TIMING_MODE 5
/************************************************/
/* EEPROM locations */
/************************************************/
#define DALE_FLASH_PAGE_SIZE 128 // number of bytes per page
#define DALE_FLASH_SIZE 65536L
#define DALE_FLASH_BIOS 0x00080000L // BIOS base address
#define DALE_FLASH_SETUP 0x00088000L // SETUP PROGRAM base address offset from BIOS
#define DALE_FLASH_RAID 0x00088400L // RAID signature storage
#define DALE_FLASH_FACTORY 0x00089000L // FACTORY data base address offset from BIOS
#define DALE_FLASH_BIOS_SIZE 32768U // size of FLASH BIOS REGION
/************************************************/
/* DALE Register address offsets */
/************************************************/
#define REG_DATA 0x80
#define REG_ERROR 0x84
#define REG_SECTOR_COUNT 0x88
#define REG_LBA_0 0x8C
#define REG_LBA_8 0x90
#define REG_LBA_16 0x94
#define REG_LBA_24 0x98
#define REG_STAT_CMD 0x9C
#define REG_STAT_SEL 0xA0
#define REG_FAIL 0xB0
#define REG_ALT_STAT 0xB8
#define REG_DRIVE_ADRS 0xBC
#define DALE_DATA_SLOW 0x00040000L
#define DALE_DATA_MODE2 0x00040000L
#define DALE_DATA_MODE3 0x00050000L
#define DALE_DATA_MODE4 0x00060000L
#define DALE_DATA_MODE5 0x00070000L
#define BIGD_DATA_SLOW 0x00000000L
#define BIGD_DATA_MODE0 0x00000000L
#define BIGD_DATA_MODE2 0x00000000L
#define BIGD_DATA_MODE3 0x00000008L
#define BIGD_DATA_MODE4 0x00000010L
#define BIGD_DATA_MODE5 0x00000020L
#define RTR_LOCAL_RANGE 0x000
#define RTR_LOCAL_REMAP 0x004
#define RTR_EXP_RANGE 0x010
#define RTR_EXP_REMAP 0x014
#define RTR_REGIONS 0x018
#define RTR_DM_MASK 0x01C
#define RTR_DM_LOCAL_BASE 0x020
#define RTR_DM_IO_BASE 0x024
#define RTR_DM_PCI_REMAP 0x028
#define RTR_DM_IO_CONFIG 0x02C
#define RTR_MAILBOX 0x040
#define RTR_LOCAL_DOORBELL 0x060
#define RTR_PCI_DOORBELL 0x064
#define RTR_INT_CONTROL_STATUS 0x068
#define RTR_EEPROM_CONTROL_STATUS 0x06C
#define RTR_DMA0_MODE 0x0080
#define RTR_DMA0_PCI_ADDR 0x0084
#define RTR_DMA0_LOCAL_ADDR 0x0088
#define RTR_DMA0_COUNT 0x008C
#define RTR_DMA0_DESC_PTR 0x0090
#define RTR_DMA1_MODE 0x0094
#define RTR_DMA1_PCI_ADDR 0x0098
#define RTR_DMA1_LOCAL_ADDR 0x009C
#define RTR_DMA1_COUNT 0x00A0
#define RTR_DMA1_DESC_PTR 0x00A4
#define RTR_DMA_COMMAND_STATUS 0x00A8
#define RTR_DMA_ARB0 0x00AC
#define RTR_DMA_ARB1 0x00B0
#define RTL_DMA0_MODE 0x00
#define RTL_DMA0_PCI_ADDR 0x04
#define RTL_DMA0_LOCAL_ADDR 0x08
#define RTL_DMA0_COUNT 0x0C
#define RTL_DMA0_DESC_PTR 0x10
#define RTL_DMA1_MODE 0x14
#define RTL_DMA1_PCI_ADDR 0x18
#define RTL_DMA1_LOCAL_ADDR 0x1C
#define RTL_DMA1_COUNT 0x20
#define RTL_DMA1_DESC_PTR 0x24
#define RTL_DMA_COMMAND_STATUS 0x28
#define RTL_DMA_ARB0 0x2C
#define RTL_DMA_ARB1 0x30
/************************************************/
/* Dale Scratchpad locations */
/************************************************/
#define DALE_CHANNEL_DEVICE_0 0 // device channel locations
#define DALE_CHANNEL_DEVICE_1 1
#define DALE_CHANNEL_DEVICE_2 2
#define DALE_CHANNEL_DEVICE_3 3
#define DALE_SCRATCH_DEVICE_0 4 // device type codes
#define DALE_SCRATCH_DEVICE_1 5
#define DALE_SCRATCH_DEVICE_2 6
#define DALE_SCRATCH_DEVICE_3 7
#define DALE_RAID_0_STATUS 8
#define DALE_RAID_1_STATUS 9
#define DALE_TIMING_MODE 12 // bus master timing mode (2, 3, 4, 5)
#define DALE_NUM_DRIVES 13 // number of addressable drives on this board
#define DALE_RAID_ON 14 // RAID status On
#define DALE_LAST_ERROR 15 // Last error code from BIOS
/************************************************/
/* BigD Scratchpad locations */
/************************************************/
#define BIGD_DEVICE_0 0 // device channel locations
#define BIGD_DEVICE_1 1
#define BIGD_DEVICE_2 2
#define BIGD_DEVICE_3 3
#define BIGD_DEVICE_4 4 // device type codes
#define BIGD_DEVICE_5 5
#define BIGD_DEVICE_6 6
#define BIGD_DEVICE_7 7
#define BIGD_ALARM_IMAGE 11 // ~image of alarm fail register
#define BIGD_TIMING_MODE 12 // bus master timing mode (2, 3, 4, 5)
#define BIGD_NUM_DRIVES 13 // number of addressable drives on this board
#define BIGD_RAID_ON 14 // RAID status is on for the whole board
#define BIGD_LAST_ERROR 15 // Last error code from BIOS
#define BIGD_RAID_0_STATUS 16
#define BIGD_RAID_1_STATUS 17
#define BIGD_RAID_2_STATUS 18
#define BIGD_RAID_3_STATUS 19
#define BIGD_RAID_4_STATUS 20
#define BIGD_RAID_5_STATUS 21
#define BIGD_RAID_6_STATUS 22
#define BIGD_RAID_7_STATUS 23
/************************************************/
/* Dale cable select bits */
/************************************************/
#define SEL_NONE 0x00
#define SEL_1 0x01
#define SEL_2 0x02
#define SEL_3 0x04
#define SEL_4 0x08
#define SEL_NEW_SPEED_1 0x20
#define SEL_COPY 0x40
#define SEL_IRQ_OFF 0x80
/************************************************/
/* Device/Geometry controls */
/************************************************/
#define GEOMETRY_NONE 0x0 // No device
#define GEOMETRY_SET 0x1 // Geometry set
#define GEOMETRY_LBA 0x2 // Geometry set in default LBA mode
#define GEOMETRY_PHOENIX 0x3 // Geometry set in Pheonix BIOS compatibility mode
#define DEVICE_NONE 0x0 // No device present
#define DEVICE_INACTIVE 0x1 // device present but not registered active
#define DEVICE_ATAPI 0x2 // ATAPI device (CD_ROM, Tape, Etc...)
#define DEVICE_DASD_NONLBA 0x3 // Non LBA incompatible device
#define DEVICE_DASD_LBA 0x4 // LBA compatible device
/************************************************/
/* BigD fail register bits */
/************************************************/
#define FAIL_NONE 0x00
#define FAIL_0 0x01
#define FAIL_1 0x02
#define FAIL_2 0x04
#define FAIL_MULTIPLE 0x08
#define FAIL_GOOD 0x20
#define FAIL_AUDIBLE 0x40
#define FAIL_ANY 0x80
/************************************************/
/* Setup Structure Definitions */
/************************************************/
typedef struct // device setup parameters
{
UCHAR geometryControl; // geometry control flags
UCHAR device; // device code
USHORT sectors; // number of sectors per track
USHORT heads; // number of heads
USHORT cylinders; // number of cylinders for this device
ULONG blocks; // number of blocks on device
ULONG realCapacity; // number of real blocks on this device for drive changed testing
} SETUP_DEVICE, *PSETUP_DEVICE;
typedef struct // master setup structure
{
USHORT startupDelay;
BOOL promptBIOS;
BOOL fastFormat;
BOOL shareInterrupt;
BOOL rebootRebuild;
USHORT timingMode;
USHORT spare5;
USHORT spare6;
SETUP_DEVICE setupDevice[BIGD_MAXDRIVES];
} SETUP, *PSETUP;
/************************************************/
/* RAID Structure Definitions */
/************************************************/
typedef struct
{
UCHAR signature; // 0x55 our mirror signature
UCHAR status; // current status bits
UCHAR pairIdentifier; // unique identifier for pair
ULONG reconstructPoint; // recontruction point for hot reconstruct
} DISK_MIRROR;
typedef struct DEVICE_RAID1
{
long TotalSectors;
DISK_MIRROR DiskRaid1;
} DEVICE_RAID1, *PDEVICE_RAID1;
#define DISK_MIRROR_POSITION 0x01A8
#define SIGNATURE 0x55
#define MASK_SERIAL_NUMBER 0x0FFE // mask for serial number matching
#define MASK_SERIAL_UNIT 0x0001 // mask for unit portion of serial number
// Status bits
#define UCBF_MIRRORED 0x0010 // drive has a pair
#define UCBF_MATCHED 0x0020 // drive pair is matched
#define UCBF_SURVIVOR 0x0040 // this unit is a survivor of a pair
#define UCBF_REBUILD 0x0080 // rebuild in progress on this device
// SCSI controls for RAID
#define SC_MY_RAID 0xBF // our special CDB command byte for Win95... interface
#define MY_SCSI_QUERY1 0x32 // byte 1 subcommand to query driver for RAID 1 informatation
#define MY_SCSI_REBUILD 0x40 // byte 1 subcommand to reconstruct a mirrored pair
#define MY_SCSI_DEMOFAIL 0x54 // byte 1 subcommand for RAID failure demonstration
#define MY_SCSI_ALARMMUTE 0x60 // byte 1 subcommand to mute any alarm currently on
/************************************************/
/* Timeout konstants */
/************************************************/
#define TIMEOUT_READY 100 // 100 mSec
#define TIMEOUT_DRQ 300 // 300 mSec
#define TIMEOUT_DATA (3 * HZ) // 3 seconds
/************************************************/
/* Misc. macros */
/************************************************/
#define ANY2SCSI(up, p) \
((UCHAR *)up)[0] = (((ULONG)(p)) >> 8); \
((UCHAR *)up)[1] = ((ULONG)(p));
#define SCSI2LONG(up) \
( (((long)*(((UCHAR *)up))) << 16) \
+ (((long)(((UCHAR *)up)[1])) << 8) \
+ ((long)(((UCHAR *)up)[2])) )
#define XANY2SCSI(up, p) \
((UCHAR *)up)[0] = ((long)(p)) >> 24; \
((UCHAR *)up)[1] = ((long)(p)) >> 16; \
((UCHAR *)up)[2] = ((long)(p)) >> 8; \
((UCHAR *)up)[3] = ((long)(p));
#define XSCSI2LONG(up) \
( (((long)(((UCHAR *)up)[0])) << 24) \
+ (((long)(((UCHAR *)up)[1])) << 16) \
+ (((long)(((UCHAR *)up)[2])) << 8) \
+ ((long)(((UCHAR *)up)[3])) )
#define SelectSpigot(padapter,spigot) outb_p (spigot, padapter->regStatSel)
#define WriteCommand(padapter,cmd) outb_p (cmd, padapter->regStatCmd)
#define AtapiDevice(padapter,b) outb_p (b, padapter->regLba24);
#define AtapiCountLo(padapter,b) outb_p (b, padapter->regLba8)
#define AtapiCountHi(padapter,b) outb_p (b, padapter->regLba16)
/************************************************/
/* SCSI CDB operation codes */
/************************************************/
#define SCSIOP_TEST_UNIT_READY 0x00
#define SCSIOP_REZERO_UNIT 0x01
#define SCSIOP_REWIND 0x01
#define SCSIOP_REQUEST_BLOCK_ADDR 0x02
#define SCSIOP_REQUEST_SENSE 0x03
#define SCSIOP_FORMAT_UNIT 0x04
#define SCSIOP_READ_BLOCK_LIMITS 0x05
#define SCSIOP_REASSIGN_BLOCKS 0x07
#define SCSIOP_READ6 0x08
#define SCSIOP_RECEIVE 0x08
#define SCSIOP_WRITE6 0x0A
#define SCSIOP_PRINT 0x0A
#define SCSIOP_SEND 0x0A
#define SCSIOP_SEEK6 0x0B
#define SCSIOP_TRACK_SELECT 0x0B
#define SCSIOP_SLEW_PRINT 0x0B
#define SCSIOP_SEEK_BLOCK 0x0C
#define SCSIOP_PARTITION 0x0D
#define SCSIOP_READ_REVERSE 0x0F
#define SCSIOP_WRITE_FILEMARKS 0x10
#define SCSIOP_FLUSH_BUFFER 0x10
#define SCSIOP_SPACE 0x11
#define SCSIOP_INQUIRY 0x12
#define SCSIOP_VERIFY6 0x13
#define SCSIOP_RECOVER_BUF_DATA 0x14
#define SCSIOP_MODE_SELECT 0x15
#define SCSIOP_RESERVE_UNIT 0x16
#define SCSIOP_RELEASE_UNIT 0x17
#define SCSIOP_COPY 0x18
#define SCSIOP_ERASE 0x19
#define SCSIOP_MODE_SENSE 0x1A
#define SCSIOP_START_STOP_UNIT 0x1B
#define SCSIOP_STOP_PRINT 0x1B
#define SCSIOP_LOAD_UNLOAD 0x1B
#define SCSIOP_RECEIVE_DIAGNOSTIC 0x1C
#define SCSIOP_SEND_DIAGNOSTIC 0x1D
#define SCSIOP_MEDIUM_REMOVAL 0x1E
#define SCSIOP_READ_CAPACITY 0x25
#define SCSIOP_READ 0x28
#define SCSIOP_WRITE 0x2A
#define SCSIOP_SEEK 0x2B
#define SCSIOP_LOCATE 0x2B
#define SCSIOP_WRITE_VERIFY 0x2E
#define SCSIOP_VERIFY 0x2F
#define SCSIOP_SEARCH_DATA_HIGH 0x30
#define SCSIOP_SEARCH_DATA_EQUAL 0x31
#define SCSIOP_SEARCH_DATA_LOW 0x32
#define SCSIOP_SET_LIMITS 0x33
#define SCSIOP_READ_POSITION 0x34
#define SCSIOP_SYNCHRONIZE_CACHE 0x35
#define SCSIOP_COMPARE 0x39
#define SCSIOP_COPY_COMPARE 0x3A
#define SCSIOP_WRITE_DATA_BUFF 0x3B
#define SCSIOP_READ_DATA_BUFF 0x3C
#define SCSIOP_CHANGE_DEFINITION 0x40
#define SCSIOP_READ_SUB_CHANNEL 0x42
#define SCSIOP_READ_TOC 0x43
#define SCSIOP_READ_HEADER 0x44
#define SCSIOP_PLAY_AUDIO 0x45
#define SCSIOP_PLAY_AUDIO_MSF 0x47
#define SCSIOP_PLAY_TRACK_INDEX 0x48
#define SCSIOP_PLAY_TRACK_RELATIVE 0x49
#define SCSIOP_PAUSE_RESUME 0x4B
#define SCSIOP_LOG_SELECT 0x4C
#define SCSIOP_LOG_SENSE 0x4D
#define SCSIOP_MODE_SELECT10 0x55
#define SCSIOP_MODE_SENSE10 0x5A
#define SCSIOP_LOAD_UNLOAD_SLOT 0xA6
#define SCSIOP_MECHANISM_STATUS 0xBD
#define SCSIOP_READ_CD 0xBE
// IDE command definitions
#define IDE_COMMAND_ATAPI_RESET 0x08
#define IDE_COMMAND_READ 0x20
#define IDE_COMMAND_WRITE 0x30
#define IDE_COMMAND_RECALIBRATE 0x10
#define IDE_COMMAND_SEEK 0x70
#define IDE_COMMAND_SET_PARAMETERS 0x91
#define IDE_COMMAND_VERIFY 0x40
#define IDE_COMMAND_ATAPI_PACKET 0xA0
#define IDE_COMMAND_ATAPI_IDENTIFY 0xA1
#define IDE_CMD_READ_MULTIPLE 0xC4
#define IDE_CMD_WRITE_MULTIPLE 0xC5
#define IDE_CMD_SET_MULTIPLE 0xC6
#define IDE_COMMAND_IDENTIFY 0xEC
// IDE status definitions
#define IDE_STATUS_ERROR 0x01
#define IDE_STATUS_INDEX 0x02
#define IDE_STATUS_CORRECTED_ERROR 0x04
#define IDE_STATUS_DRQ 0x08
#define IDE_STATUS_DSC 0x10
#define IDE_STATUS_WRITE_FAULT 0x20
#define IDE_STATUS_DRDY 0x40
#define IDE_STATUS_BUSY 0x80
typedef struct _ATAPI_STATUS
{
CHAR check :1;
CHAR reserved1 :1;
CHAR corr :1;
CHAR drq :1;
CHAR dsc :1;
CHAR reserved2 :1;
CHAR drdy :1;
CHAR bsy :1;
} ATAPI_STATUS;
typedef struct _ATAPI_REASON
{
CHAR cod :1;
CHAR io :1;
CHAR reserved1 :6;
} ATAPI_REASON;
typedef struct _ATAPI_ERROR
{
CHAR ili :1;
CHAR eom :1;
CHAR abort :1;
CHAR mcr :1;
CHAR senseKey :4;
} ATAPI_ERROR;
// IDE error definitions
#define IDE_ERROR_AMNF 0x01
#define IDE_ERROR_TKONF 0x02
#define IDE_ERROR_ABRT 0x04
#define IDE_ERROR_MCR 0x08
#define IDE_ERROR_IDFN 0x10
#define IDE_ERROR_MC 0x20
#define IDE_ERROR_UNC 0x40
#define IDE_ERROR_BBK 0x80
// SCSI read capacity structure
typedef struct _READ_CAPACITY_DATA
{
ULONG blks; /* total blocks (converted to little endian) */
ULONG blksiz; /* size of each (converted to little endian) */
} READ_CAPACITY_DATA, *PREAD_CAPACITY_DATA;
// SCSI inquiry data
typedef struct _INQUIRYDATA
{
UCHAR DeviceType :5;
UCHAR DeviceTypeQualifier :3;
UCHAR DeviceTypeModifier :7;
UCHAR RemovableMedia :1;
UCHAR Versions;
UCHAR ResponseDataFormat;
UCHAR AdditionalLength;
UCHAR Reserved[2];
UCHAR SoftReset :1;
UCHAR CommandQueue :1;
UCHAR Reserved2 :1;
UCHAR LinkedCommands :1;
UCHAR Synchronous :1;
UCHAR Wide16Bit :1;
UCHAR Wide32Bit :1;
UCHAR RelativeAddressing :1;
UCHAR VendorId[8];
UCHAR ProductId[16];
UCHAR ProductRevisionLevel[4];
UCHAR VendorSpecific[20];
UCHAR Reserved3[40];
} INQUIRYDATA, *PINQUIRYDATA;
// IDE IDENTIFY data
#pragma pack (1)
typedef struct _IDENTIFY_DATA
{
USHORT GeneralConfiguration; // 0
USHORT NumberOfCylinders; // 1
USHORT Reserved1; // 2
USHORT NumberOfHeads; // 3
USHORT UnformattedBytesPerTrack; // 4
USHORT UnformattedBytesPerSector; // 5
USHORT SectorsPerTrack; // 6
USHORT NumBytesISG; // 7 Byte Len - inter-sector gap
USHORT NumBytesSync; // 8 - sync field
USHORT NumWordsVUS; // 9 Len - Vendor Unique Info
USHORT SerialNumber[10]; // 10
USHORT BufferType; // 20
USHORT BufferSectorSize; // 21
USHORT NumberOfEccBytes; // 22
USHORT FirmwareRevision[4]; // 23
USHORT ModelNumber[20]; // 27
USHORT NumSectorsPerInt :8; // 47 Multiple Mode - Sec/Blk
USHORT Reserved2 :8; // 47
USHORT DoubleWordMode; // 48 flag for double word mode capable
USHORT VendorUnique1 :8; // 49
USHORT SupportDMA :1; // 49 DMA supported
USHORT SupportLBA :1; // 49 LBA supported
USHORT SupportIORDYDisable :1; // 49 IORDY can be disabled
USHORT SupportIORDY :1; // 49 IORDY supported
USHORT ReservedPsuedoDMA :1; // 49 reserved for pseudo DMA mode support
USHORT Reserved3 :3; // 49
USHORT Reserved4; // 50
USHORT Reserved5 :8; // 51 Transfer Cycle Timing - PIO
USHORT PIOCycleTime :8; // 51 Transfer Cycle Timing - PIO
USHORT Reserved6 :8; // 52 - DMA
USHORT DMACycleTime :8; // 52 - DMA
USHORT Valid_54_58 :1; // 53 words 54 - 58 are valid
USHORT Valid_64_70 :1; // 53 words 64 - 70 are valid
USHORT Reserved7 :14; // 53
USHORT LogNumCyl; // 54 Current Translation - Num Cyl
USHORT LogNumHeads; // 55 Num Heads
USHORT LogSectorsPerTrack; // 56 Sec/Trk
ULONG LogTotalSectors; // 57 Total Sec
USHORT CurrentNumSecPerInt :8; // 59 current setting for number of sectors per interrupt
USHORT ValidNumSecPerInt :1; // 59 Current setting is valid for number of sectors per interrupt
USHORT Reserved8 :7; // 59
ULONG LBATotalSectors; // 60 LBA Mode - Sectors
USHORT DMASWordFlags; // 62
USHORT DMAMWordFlags; // 63
USHORT AdvancedPIOSupport :8; // 64 Flow control PIO transfer modes supported
USHORT Reserved9 :8; // 64
USHORT MinMultiDMACycle; // 65 minimum multiword DMA transfer cycle time per word
USHORT RecomendDMACycle; // 66 Manufacturer's recommende multiword DMA transfer cycle time
USHORT MinPIOCycleWithoutFlow; // 67 Minimum PIO transfer cycle time without flow control
USHORT MinPIOCylceWithFlow; // 68 Minimum PIO transfer cycle time with IORDY flow control
USHORT ReservedSpace[256-69]; // 69
} IDENTIFY_DATA, *PIDENTIFY_DATA;
// ATAPI configuration bits
typedef struct _ATAPI_GENERAL_0
{
USHORT CmdPacketSize :2; // Command packet size
USHORT Reserved1 :3;
USHORT CmdDrqType :2;
USHORT Removable :1;
USHORT DeviceType :5;
USHORT Reserved2 :1;
USHORT ProtocolType :2;
} ATAPI_GENERAL_0;
#pragma pack ()

View file

@ -1,331 +0,0 @@
/****************************************************************************
* Perceptive Solutions, Inc. PCI-2000 device driver for Linux.
*
* psi_roy.h - Linux Host Driver for PCI-2000 IntelliCache SCSI Adapters
*
* Copyright (c) 1997-1999 Perceptive Solutions, Inc.
* All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that redistributions of source
* code retain the above copyright notice and this comment without
* modification.
*
* Technical updates and product information at:
* http://www.psidisk.com
*
* Please send questions, comments, bug reports to:
* tech@psidisk.com Technical Support
*
****************************************************************************/
#ifndef ROY_HOST
#define ROY_HOST
/************************************************/
/* PCI setup */
/************************************************/
#define VENDOR_PSI 0x1256
#define DEVICE_ROY_1 0x5201 /* 'R1' */
/************************************************/
/* controller constants */
/************************************************/
#define MAXADAPTER 4 // Increase this and the sizes of the arrays below, if you need more.
#define MAX_BUS 2
#define MAX_UNITS 16
#define TIMEOUT_COMMAND 400 // number of milliSecondos for command busy timeout
/************************************************/
/* I/O address offsets */
/************************************************/
#define RTR_MAILBOX 0x040
#define RTR_LOCAL_DOORBELL 0x060
#define RTR_PCI_DOORBELL 0x064
/************************************************/
/* */
/* Host command codes */
/* */
/************************************************/
#define CMD_READ_CHS 0x01 /* read sectors as specified (CHS mode) */
#define CMD_READ 0x02 /* read sectors as specified (RBA mode) */
#define CMD_READ_SG 0x03 /* read sectors using scatter/gather list */
#define CMD_WRITE_CHS 0x04 /* write sectors as specified (CHS mode) */
#define CMD_WRITE 0x05 /* write sectors as specified (RBA mode) */
#define CMD_WRITE_SG 0x06 /* write sectors using scatter/gather list (LBA mode) */
#define CMD_READ_CHS_SG 0x07 /* read sectors using scatter/gather list (CHS mode) */
#define CMD_WRITE_CHS_SG 0x08 /* write sectors using scatter/gather list (CHS mode) */
#define CMD_VERIFY_CHS 0x09 /* verify data on sectors as specified (CHS mode) */
#define CMD_VERIFY 0x0A /* verify data on sectors as specified (RBA mode) */
#define CMD_DASD_CDB 0x0B /* process CDB for a DASD device */
#define CMD_DASD_CDB_SG 0x0C /* process CDB for a DASD device with scatter/gather */
#define CMD_READ_ABS 0x10 /* read absolute disk */
#define CMD_WRITE_ABS 0x11 /* write absolute disk */
#define CMD_VERIFY_ABS 0x12 /* verify absolute disk */
#define CMD_TEST_READY 0x13 /* test unit ready and return status code */
#define CMD_LOCK_DOOR 0x14 /* lock device door */
#define CMD_UNLOCK_DOOR 0x15 /* unlock device door */
#define CMD_EJECT_MEDIA 0x16 /* eject the media */
#define CMD_UPDATE_CAP 0x17 /* update capacity information */
#define CMD_TEST_PRIV 0x18 /* test and setup private format media */
#define CMD_SCSI_THRU 0x30 /* SCSI pass through CDB */
#define CMD_SCSI_THRU_SG 0x31 /* SCSI pass through CDB with scatter/gather */
#define CMD_SCSI_REQ_SENSE 0x32 /* SCSI pass through request sense after check condition */
#define CMD_DASD_RAID_RQ 0x35 /* request DASD RAID drive data */
#define CMD_DASD_RAID_RQ0 0x31 /* byte 1 subcommand to query for RAID 0 informatation */
#define CMD_DASD_RAID_RQ1 0x32 /* byte 1 subcommand to query for RAID 1 informatation */
#define CMD_DASD_RAID_RQ5 0x33 /* byte 1 subcommand to query for RAID 5 informatation */
#define CMD_DASD_SCSI_INQ 0x36 /* do DASD inquire and return in SCSI format */
#define CMD_DASD_CAP 0x37 /* read DASD capacity */
#define CMD_DASD_INQ 0x38 /* do DASD inquire for type data and return SCSI/EIDE inquiry */
#define CMD_SCSI_INQ 0x39 /* do SCSI inquire */
#define CMD_READ_SETUP 0x3A /* Get setup structures from controller */
#define CMD_WRITE_SETUP 0x3B /* Put setup structures in controller and burn in flash */
#define CMD_READ_CONFIG 0x3C /* Get the entire configuration and setup structures */
#define CMD_WRITE_CONFIG 0x3D /* Put the entire configuration and setup structures in flash */
#define CMD_TEXT_DEVICE 0x3E /* obtain device text */
#define CMD_TEXT_SIGNON 0x3F /* get sign on banner */
#define CMD_QUEUE 0x40 /* any command below this generates a queue tag interrupt to host*/
#define CMD_PREFETCH 0x40 /* prefetch sectors as specified */
#define CMD_TEST_WRITE 0x41 /* Test a device for write protect */
#define CMD_LAST_STATUS 0x42 /* get last command status and error data*/
#define CMD_ABORT 0x43 /* abort command as specified */
#define CMD_ERROR 0x44 /* fetch error code from a tagged op */
#define CMD_DONE 0x45 /* done with operation */
#define CMD_DIAGNOSTICS 0x46 /* execute controller diagnostics and wait for results */
#define CMD_FEATURE_MODE 0x47 /* feature mode control word */
#define CMD_DASD_INQUIRE 0x48 /* inquire as to DASD SCSI device (32 possible) */
#define CMD_FEATURE_QUERY 0x49 /* query the feature control word */
#define CMD_DASD_EJECT 0x4A /* Eject removable media for DASD type */
#define CMD_DASD_LOCK 0x4B /* Lock removable media for DASD type */
#define CMD_DASD_TYPE 0x4C /* obtain DASD device type */
#define CMD_NUM_DEV 0x4D /* obtain the number of devices connected to the controller */
#define CMD_GET_PARMS 0x4E /* obtain device parameters */
#define CMD_SPECIFY 0x4F /* specify operating system for scatter/gather operations */
#define CMD_RAID_GET_DEV 0x50 /* read RAID device geometry */
#define CMD_RAID_READ 0x51 /* read RAID 1 parameter block */
#define CMD_RAID_WRITE 0x52 /* write RAID 1 parameter block */
#define CMD_RAID_LITEUP 0x53 /* Light up the drive light for identification */
#define CMD_RAID_REBUILD 0x54 /* issue a RAID 1 pair rebuild */
#define CMD_RAID_MUTE 0x55 /* mute RAID failure alarm */
#define CMD_RAID_FAIL 0x56 /* induce a RAID failure */
#define CMD_RAID_STATUS 0x57 /* get status of RAID pair */
#define CMD_RAID_STOP 0x58 /* stop any reconstruct in progress */
#define CMD_RAID_START 0x59 /* start reconstruct */
#define CMD_RAID0_READ 0x5A /* read RAID 0 parameter block */
#define CMD_RAID0_WRITE 0x5B /* write RAID 0 parameter block */
#define CMD_RAID5_READ 0x5C /* read RAID 5 parameter block */
#define CMD_RAID5_WRITE 0x5D /* write RAID 5 parameter block */
#define CMD_ERASE_TABLES 0x5F /* erase partition table and RAID signatutures */
#define CMD_SCSI_GET 0x60 /* get SCSI pass through devices */
#define CMD_SCSI_TIMEOUT 0x61 /* set SCSI pass through timeout */
#define CMD_SCSI_ERROR 0x62 /* get SCSI pass through request sense length and residual data count */
#define CMD_GET_SPARMS 0x63 /* get SCSI bus and user parms */
#define CMD_SCSI_ABORT 0x64 /* abort by setting time-out to zero */
#define CMD_CHIRP_CHIRP 0x77 /* make a chirp chirp sound */
#define CMD_GET_LAST_DONE 0x78 /* get tag of last done in progress */
#define CMD_GET_FEATURES 0x79 /* get feature code and ESN */
#define CMD_CLEAR_CACHE 0x7A /* Clear cache on specified device */
#define CMD_BIOS_TEST 0x7B /* Test whether or not to load BIOS */
#define CMD_WAIT_FLUSH 0x7C /* wait for cache flushed and invalidate read cache */
#define CMD_RESET_BUS 0x7D /* reset the SCSI bus */
#define CMD_STARTUP_QRY 0x7E /* startup in progress query */
#define CMD_RESET 0x7F /* reset the controller */
#define CMD_RESTART_RESET 0x80 /* reload and restart the controller at any reset issued */
#define CMD_SOFT_RESET 0x81 /* do a soft reset NOW! */
/************************************************/
/* */
/* Host return errors */
/* */
/************************************************/
#define ERR08_TAGGED 0x80 /* doorbell error ored with tag */
#define ERR16_NONE 0x0000 /* no errors */
#define ERR16_SC_COND_MET 0x0004 /* SCSI status - Condition Met */
#define ERR16_CMD 0x0101 /* command error */
#define ERR16_SC_CHECK_COND 0x0002 /* SCSI status - Check Condition */
#define ERR16_CMD_NOT 0x0201 /* command not supported */
#define ERR16_NO_DEVICE 0x0301 /* invalid device selection */
#define ERR16_SECTOR 0x0202 /* bad sector */
#define ERR16_PROTECT 0x0303 /* write protected */
#define ERR16_NOSECTOR 0x0404 /* sector not found */
#define ERR16_MEDIA 0x0C0C /* invalid media */
#define ERR16_CONTROL 0x2020 /* controller error */
#define ERR16_CONTROL_DMA 0x2120 /* controller DMA engine error */
#define ERR16_NO_ALARM 0x2220 /* alarm is not active */
#define ERR16_OP_BUSY 0x2320 /* operation busy */
#define ERR16_SEEK 0x4040 /* seek failure */
#define ERR16_DEVICE_FAIL 0x4140 /* device has failed */
#define ERR16_TIMEOUT 0x8080 /* timeout error */
#define ERR16_DEV_NOT_READY 0xAAAA /* drive not ready */
#define ERR16_UNDEFINED 0xBBBB /* undefined error */
#define ERR16_WRITE_FAULT 0xCCCC /* write fault */
#define ERR16_INVALID_DEV 0x4001 /* invalid device access */
#define ERR16_DEVICE_BUSY 0x4002 /* device is busy */
#define ERR16_MEMORY 0x4003 /* device pass thru requires too much memory */
#define ERR16_NO_FEATURE 0x40FA /* feature no implemented */
#define ERR16_NOTAG 0x40FD /* no tag space available */
#define ERR16_NOT_READY 0x40FE /* controller not ready error */
#define ERR16_SETUP_FLASH 0x5050 /* error when writing setup to flash memory */
#define ERR16_SETUP_SIZE 0x5051 /* setup block size error */
#define ERR16_SENSE 0xFFFF /* sense opereration failed */
#define ERR16_SC_BUSY 0x0008 /* SCSI status - Busy */
#define ERR16_SC_RES_CONFL 0x0018 /* SCSI status - Reservation Conflict */
#define ERR16_SC_CMD_TERM 0x0022 /* SCSI status - Command Terminated */
#define ERR16_SC_OTHER 0x00FF /* SCSI status - not recognized (any value masked) */
#define ERR16_MEDIA_CHANGED 0x8001 /* devices media has been changed */
#define ERR32_NONE 0x00000000 /* no errors */
#define ERR32_SC_COND_MET 0x00000004 /* SCSI status - Condition Met */
#define ERR32_CMD 0x00010101 /* command error */
#define ERR32_SC_CHECK_COND 0x00020002 /* SCSI status - Check Condition */
#define ERR32_CMD_NOT 0x00030201 /* command not supported */
#define ERR32_NO_DEVICE 0x00040301 /* invalid device selection */
#define ERR32_SECTOR 0x00050202 /* bad sector */
#define ERR32_PROTECT 0x00060303 /* write protected */
#define ERR32_NOSECTOR 0x00070404 /* sector not found */
#define ERR32_MEDIA 0x00080C0C /* invalid media */
#define ERR32_CONTROL 0x00092020 /* controller error */
#define ERR32_CONTROL_DMA 0x000A2120 /* Controller DMA error */
#define ERR32_NO_ALARM 0x000B2220 /* alarm is not active */
#define ERR32_OP_BUSY 0x000C2320 /* operation busy */
#define ERR32_SEEK 0x000D4040 /* seek failure */
#define ERR32_DEVICE_FAIL 0x000E4140 /* device has failed */
#define ERR32_TIMEOUT 0x000F8080 /* timeout error */
#define ERR32_DEV_NOT_READY 0x0010AAAA /* drive not ready */
#define ERR32_UNDEFINED 0x0011BBBB /* undefined error */
#define ERR32_WRITE_FAULT 0x0012CCCC /* write fault */
#define ERR32_INVALID_DEV 0x00134001 /* invalid device access */
#define ERR32_DEVICE_BUSY 0x00144002 /* device is busy */
#define ERR32_MEMORY 0x00154003 /* device pass thru requires too much memory */
#define ERR32_NO_FEATURE 0x001640FA /* feature no implemented */
#define ERR32_NOTAG 0x001740FD /* no tag space available */
#define ERR32_NOT_READY 0x001840FE /* controller not ready error */
#define ERR32_SETUP_FLASH 0x00195050 /* error when writing setup to flash memory */
#define ERR32_SETUP_SIZE 0x001A5051 /* setup block size error */
#define ERR32_SENSE 0x001BFFFF /* sense opereration failed */
#define ERR32_SC_BUSY 0x001C0008 /* SCSI status - Busy */
#define ERR32_SC_RES_CONFL 0x001D0018 /* SCSI status - Reservation Conflict */
#define ERR32_SC_CMD_TERM 0x001E0022 /* SCSI status - Command Terminated */
#define ERR32_SC_OTHER 0x001F00FF /* SCSI status - not recognized (any value masked) */
#define ERR32_MEDIA_CHANGED 0x00208001 /* devices media has been changed */
/************************************************/
/* */
/* Host Operating System specification codes */
/* */
/************************************************/
#define SPEC_INTERRUPT 0x80 /* specification requires host interrupt */
#define SPEC_BACKWARD_SG 0x40 /* specification requires scatter/gather items reversed */
#define SPEC_DOS_BLOCK 0x01 /* DOS DASD blocking on pass through */
#define SPEC_OS2_V3 0x02 /* OS/2 Warp */
#define SPCE_SCO_3242 0x04 /* SCO 3.4.2.2 */
#define SPEC_QNX_4X 0x05 /* QNX 4.XX */
#define SPEC_NOVELL_NWPA 0x08 /* Novell NWPA scatter/gather support */
/************************************************/
/* */
/* Inquire structures */
/* */
/************************************************/
typedef struct _CNT_SCSI_INQ
{
UCHAR devt; /* 00: device type */
UCHAR devtm; /* 01: device type modifier */
UCHAR svers; /* 02: SCSI version */
UCHAR rfmt; /* 03: response data format */
UCHAR adlen; /* 04: additional length of data */
UCHAR res1; /* 05: */
UCHAR res2; /* 06: */
UCHAR fncs; /* 07: functional capabilities */
UCHAR vid[8]; /* 08: vendor ID */
UCHAR pid[16]; /* 10: product ID */
UCHAR rev[4]; /* 20: product revision */
} CNT_SCSI_INQ;
typedef struct _CNT_IDE_INQ
{
USHORT GeneralConfiguration; /* 00 */
USHORT NumberOfCylinders; /* 02 */
USHORT Reserved1; /* 04 */
USHORT NumberOfHeads; /* 06 */
USHORT UnformattedBytesPerTrack; /* 08 */
USHORT UnformattedBytesPerSector; /* 0A */
USHORT SectorsPerTrack; /* 0C */
USHORT VendorUnique1[3]; /* 0E */
USHORT SerialNumber[10]; /* 14 */
USHORT BufferType; /* 28 */
USHORT BufferSectorSize; /* 2A */
USHORT NumberOfEccBytes; /* 2C */
USHORT FirmwareRevision[4]; /* 2E */
USHORT ModelNumber[20]; /* 36 */
UCHAR MaximumBlockTransfer; /* 5E */
UCHAR VendorUnique2; /* 5F */
USHORT DoubleWordIo; /* 60 */
USHORT Capabilities; /* 62 */
USHORT Reserved2; /* 64 */
UCHAR VendorUnique3; /* 66 */
UCHAR PioCycleTimingMode; /* 67 */
UCHAR VendorUnique4; /* 68 */
UCHAR DmaCycleTimingMode; /* 69 */
USHORT TranslationFieldsValid; /* 6A */
USHORT NumberOfCurrentCylinders; /* 6C */
USHORT NumberOfCurrentHeads; /* 6E */
USHORT CurrentSectorsPerTrack; /* 70 */
ULONG CurrentSectorCapacity; /* 72 */
} CNT_IDE_INQ;
typedef struct _DASD_INQUIRE
{
ULONG type; /* 0 = SCSI, 1 = IDE */
union
{
CNT_SCSI_INQ scsi; /* SCSI inquire data */
CNT_IDE_INQ ide; /* IDE inquire data */
} inq;
} DASD_INQUIRE;
/************************************************/
/* */
/* Device Codes */
/* */
/************************************************/
#define DEVC_DASD 0x00 /* Direct-access Storage Device */
#define DEVC_SEQACESS 0x01 /* Sequential-access device */
#define DEVC_PRINTER 0x02 /* Printer device */
#define DEVC_PROCESSOR 0x03 /* Processor device */
#define DEVC_WRITEONCE 0x04 /* Write-once device */
#define DEVC_CDROM 0x05 /* CD-ROM device */
#define DEVC_SCANNER 0x06 /* Scanner device */
#define DEVC_OPTICAL 0x07 /* Optical memory device */
#define DEVC_MEDCHGR 0x08 /* Medium changer device */
#define DEVC_DASD_REMOVABLE 0x80 /* Direct-access storage device, Removable */
#define DEVC_NONE 0xFF /* no device */
// SCSI controls for RAID
#define SC_MY_RAID 0xBF // our special CDB command byte for Win95... interface
#define MY_SCSI_QUERY0 0x31 // byte 1 subcommand to query driver for RAID 0 informatation
#define MY_SCSI_QUERY1 0x32 // byte 1 subcommand to query driver for RAID 1 informatation
#define MY_SCSI_QUERY5 0x33 // byte 1 subcommand to query driver for RAID 5 informatation
#define MY_SCSI_REBUILD 0x40 // byte 1 subcommand to reconstruct a mirrored pair
#define MY_SCSI_DEMOFAIL 0x54 // byte 1 subcommand for RAID failure demonstration
#define MY_SCSI_ALARMMUTE 0x60 // byte 1 subcommand to mute any alarm currently on
#endif

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -4038,11 +4038,10 @@ qla1280_status_entry(struct scsi_qla_host *ha, struct response *pkt,
scsi_status, handle);
}
/* Target busy */
if (scsi_status & SS_BUSY_CONDITION &&
scsi_status != SS_RESERVE_CONFLICT) {
CMD_RESULT(cmd) =
DID_BUS_BUSY << 16 | (scsi_status & 0xff);
/* Target busy or queue full */
if ((scsi_status & 0xFF) == SAM_STAT_TASK_SET_FULL ||
(scsi_status & 0xFF) == SAM_STAT_BUSY) {
CMD_RESULT(cmd) = scsi_status & 0xff;
} else {
/* Save ISP completion status */

View file

@ -1063,8 +1063,7 @@ qla2x00_print_scsi_cmd(struct scsi_cmnd * cmd)
return;
printk(" sp flags=0x%x\n", sp->flags);
printk(" r_start=0x%lx, u_start=0x%lx, f_start=0x%lx, state=%d\n",
sp->r_start, sp->u_start, sp->f_start, sp->state);
printk(" state=%d\n", sp->state);
}
#if defined(QL_DEBUG_ROUTINES)

View file

@ -252,31 +252,12 @@ typedef struct srb {
/* Request state */
uint16_t state;
/* Timing counts. */
unsigned long e_start; /* Start of extend timeout */
unsigned long r_start; /* Start of request */
unsigned long u_start; /* When sent to RISC */
unsigned long f_start; /* When placed in FO queue*/
/* Single transfer DMA context */
dma_addr_t dma_handle;
uint32_t request_sense_length;
uint8_t *request_sense_ptr;
int ext_history;
/* Suspend delay */
int delay;
/* Raw completion info for use by failover ? */
uint8_t fo_retry_cnt; /* Retry count this request */
uint8_t err_id; /* error id */
#define SRB_ERR_PORT 1 /* Request failed -- "port down" */
#define SRB_ERR_LOOP 2 /* Request failed -- "loop down" */
#define SRB_ERR_DEVICE 3 /* Request failed -- "device error" */
#define SRB_ERR_OTHER 4
/* SRB magic number */
uint16_t magic;
#define SRB_MAGIC 0x10CB
@ -2082,23 +2063,8 @@ typedef struct scsi_qla_host {
uint32_t current_outstanding_cmd;
srb_t *status_srb; /* Status continuation entry. */
unsigned long last_irq_cpu; /* cpu where we got our last irq */
uint16_t revision;
uint8_t ports;
u_long actthreads;
u_long ipreq_cnt;
u_long qthreads;
uint32_t total_isr_cnt; /* Interrupt count */
uint32_t total_isp_aborts; /* controller err cnt */
uint32_t total_lip_cnt; /* LIP cnt */
uint32_t total_dev_errs; /* device error cnt */
uint32_t total_ios; /* IO cnt */
uint64_t total_bytes; /* xfr byte cnt */
uint32_t total_mbx_timeout; /* mailbox timeout cnt */
uint32_t total_loop_resync; /* loop resyn cnt */
uint32_t dropped_frame_error_cnt;
/* ISP configuration data. */
uint16_t loop_id; /* Host adapter loop id */
@ -2124,8 +2090,6 @@ typedef struct scsi_qla_host {
#define P2P_LOOP 3
uint8_t marker_needed;
uint8_t sns_retry_cnt;
uint8_t mem_err;
uint8_t interrupts_on;
@ -2138,16 +2102,11 @@ typedef struct scsi_qla_host {
uint16_t nvram_base;
uint16_t loop_reset_delay;
uint16_t minimum_timeout;
uint8_t retry_count;
uint8_t login_timeout;
uint16_t r_a_tov;
int port_down_retry_count;
uint8_t loop_down_timeout;
uint8_t mbx_count;
uint16_t max_probe_luns;
uint16_t max_luns;
uint16_t max_targets;
uint16_t last_loop_id;
uint32_t login_retry_count;
@ -2181,7 +2140,6 @@ typedef struct scsi_qla_host {
uint8_t dpc_active; /* DPC routine is active */
/* Timeout timers. */
uint8_t queue_restart_timer;
uint8_t loop_down_abort_time; /* port down timer */
atomic_t loop_down_timer; /* loop down timer */
uint8_t link_down_timeout; /* link down timeout */
@ -2230,18 +2188,6 @@ typedef struct scsi_qla_host {
mbx_cmd_t mc;
uint8_t *cmdline;
uint32_t failover_type;
uint32_t failback_delay;
unsigned long cfg_flags;
#define CFG_ACTIVE 0 /* CFG during a failover, event update, or ioctl */
#define CFG_FAILOVER 1 /* CFG during path change */
uint32_t binding_type;
#define BIND_BY_PORT_NAME 0
#define BIND_BY_PORT_ID 1
/* Basic firmware related information. */
struct qla_board_info *brd_info;
uint16_t fw_major_version;
@ -2274,12 +2220,6 @@ typedef struct scsi_qla_host {
uint8_t nvram_version;
uint32_t isp_abort_cnt;
/* Adapter I/O statistics for failover */
uint64_t IosRequested;
uint64_t BytesRequested;
uint64_t IosExecuted;
uint64_t BytesExecuted;
/* Needed for BEACON */
uint16_t beacon_blink_led;
uint16_t beacon_green_on;

View file

@ -53,27 +53,13 @@ extern void qla2x00_reg_remote_port(scsi_qla_host_t *, fc_port_t *);
*/
extern char qla2x00_version_str[];
extern int num_hosts;
extern int apiHBAInstance;
extern struct _qla2x00stats qla2x00_stats;
extern int ql2xretrycount;
extern int ql2xlogintimeout;
extern int qlport_down_retry;
extern int ql2xmaxqdepth;
extern int displayConfig;
extern int ql2xplogiabsentdevice;
extern int ql2xenablezio;
extern int ql2xintrdelaytimer;
extern int ql2xloginretrycount;
extern int ConfigRequired;
extern int Bind;
extern int ql2xsuspendcount;
#if defined(MODULE)
extern char *ql2xopts;
#endif
extern void qla2x00_sp_compl(scsi_qla_host_t *, srb_t *);
extern char *qla2x00_get_fw_version_str(struct scsi_qla_host *, char *);

View file

@ -85,9 +85,7 @@ qla2x00_initialize_adapter(scsi_qla_host_t *ha)
atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME);
atomic_set(&ha->loop_state, LOOP_DOWN);
ha->device_flags = 0;
ha->sns_retry_cnt = 0;
ha->dpc_flags = 0;
ha->failback_delay = 0;
ha->flags.management_server_logged_in = 0;
ha->marker_needed = 0;
ha->mbx_flags = 0;
@ -171,8 +169,6 @@ check_fw_ready_again:
if (wait_time == 0)
rval = QLA_FUNCTION_FAILED;
if (ha->mem_err)
restart_risc = 1;
} else if (ha->device_flags & DFLG_NO_CABLE)
/* If no cable, then all is good. */
rval = QLA_SUCCESS;
@ -1410,13 +1406,8 @@ qla2x00_nvram_config(scsi_qla_host_t *ha)
/* Set minimum RATOV to 200 tenths of a second. */
ha->r_a_tov = 200;
ha->minimum_timeout =
(ha->login_timeout * ha->retry_count) + nv->port_down_retry_count;
ha->loop_reset_delay = nv->reset_delay;
/* Will get the value from NVRAM. */
ha->loop_down_timeout = LOOP_DOWN_TIMEOUT;
/* Link Down Timeout = 0:
*
* When Port Down timer expires we will start returning
@ -1429,18 +1420,13 @@ qla2x00_nvram_config(scsi_qla_host_t *ha)
*/
if (nv->link_down_timeout == 0) {
ha->loop_down_abort_time =
(LOOP_DOWN_TIME - ha->loop_down_timeout);
(LOOP_DOWN_TIME - LOOP_DOWN_TIMEOUT);
} else {
ha->link_down_timeout = nv->link_down_timeout;
ha->loop_down_abort_time =
(LOOP_DOWN_TIME - ha->link_down_timeout);
}
ha->max_luns = MAX_LUNS;
ha->max_probe_luns = le16_to_cpu(nv->max_luns_per_target);
if (ha->max_probe_luns == 0)
ha->max_probe_luns = MIN_LUNS;
/*
* Need enough time to try and get the port back.
*/
@ -1457,16 +1443,6 @@ qla2x00_nvram_config(scsi_qla_host_t *ha)
if (ql2xloginretrycount)
ha->login_retry_count = ql2xloginretrycount;
ha->binding_type = Bind;
if (ha->binding_type != BIND_BY_PORT_NAME &&
ha->binding_type != BIND_BY_PORT_ID) {
qla_printk(KERN_WARNING, ha,
"Invalid binding type specified (%d), "
"defaulting to BIND_BY_PORT_NAME!!!\n", ha->binding_type);
ha->binding_type = BIND_BY_PORT_NAME;
}
icb->lun_enables = __constant_cpu_to_le16(0);
icb->command_resource_count = 0;
icb->immediate_notify_resource_count = 0;
@ -1578,7 +1554,6 @@ qla2x00_configure_loop(scsi_qla_host_t *ha)
*/
clear_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags);
clear_bit(RSCN_UPDATE, &ha->dpc_flags);
ha->mem_err = 0 ;
/* Determine what we need to do */
if (ha->current_topology == ISP_CFG_FL &&
@ -2707,7 +2682,6 @@ qla2x00_loop_resync(scsi_qla_host_t *ha)
rval = QLA_SUCCESS;
atomic_set(&ha->loop_state, LOOP_UPDATE);
qla2x00_stats.loop_resync++;
clear_bit(ISP_ABORT_RETRY, &ha->dpc_flags);
if (ha->flags.online) {
if (!(rval = qla2x00_fw_ready(ha))) {
@ -2786,9 +2760,6 @@ qla2x00_abort_isp(scsi_qla_host_t *ha)
if (ha->flags.online) {
ha->flags.online = 0;
clear_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
qla2x00_stats.ispAbort++;
ha->total_isp_aborts++; /* used by ioctl */
ha->sns_retry_cnt = 0;
qla_printk(KERN_INFO, ha,
"Performing ISP error recovery - ha= %p.\n", ha);
@ -2810,8 +2781,6 @@ qla2x00_abort_isp(scsi_qla_host_t *ha)
sp = ha->outstanding_cmds[cnt];
if (sp) {
ha->outstanding_cmds[cnt] = NULL;
if (ha->actthreads)
ha->actthreads--;
sp->flags = 0;
sp->cmd->result = DID_RESET << 16;
sp->cmd->host_scribble = (unsigned char *)NULL;

View file

@ -433,11 +433,8 @@ qla2x00_start_scsi(srb_t *sp)
} else
ha->request_ring_ptr++;
ha->actthreads++;
ha->total_ios++;
sp->flags |= SRB_DMA_VALID;
sp->state = SRB_ACTIVE_STATE;
sp->u_start = jiffies;
/* Set chip new ring index. */
WRT_REG_WORD(ISP_REQ_Q_IN(ha, reg), ha->req_ring_index);

View file

@ -91,9 +91,6 @@ qla2100_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
}
spin_unlock_irqrestore(&ha->hardware_lock, flags);
ha->last_irq_cpu = _smp_processor_id();
ha->total_isr_cnt++;
if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
(status & MBX_INTERRUPT) && ha->flags.mbox_int) {
spin_lock_irqsave(&ha->mbx_reg_lock, flags);
@ -200,9 +197,6 @@ qla2300_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
}
spin_unlock_irqrestore(&ha->hardware_lock, flags);
ha->last_irq_cpu = _smp_processor_id();
ha->total_isr_cnt++;
if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
(status & MBX_INTERRUPT) && ha->flags.mbox_int) {
spin_lock_irqsave(&ha->mbx_reg_lock, flags);
@ -417,7 +411,6 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint32_t mbx)
/* Update AEN queue. */
qla2x00_enqueue_aen(ha, MBA_LIP_OCCURRED, NULL);
ha->total_lip_cnt++;
break;
case MBA_LOOP_UP: /* Loop Up Event */
@ -485,7 +478,6 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint32_t mbx)
/* Update AEN queue. */
qla2x00_enqueue_aen(ha, MBA_LIP_RESET, NULL);
ha->total_lip_cnt++;
break;
case MBA_POINT_TO_POINT: /* Point-to-Point */
@ -695,14 +687,11 @@ qla2x00_process_completed_request(struct scsi_qla_host *ha, uint32_t index)
/* Free outstanding command slot. */
ha->outstanding_cmds[index] = NULL;
if (ha->actthreads)
ha->actthreads--;
CMD_COMPL_STATUS(sp->cmd) = 0L;
CMD_SCSI_STATUS(sp->cmd) = 0L;
/* Save ISP completion status */
sp->cmd->result = DID_OK << 16;
sp->fo_retry_cnt = 0;
qla2x00_sp_compl(ha, sp);
} else {
DEBUG2(printk("scsi(%ld): Invalid ISP SCSI completion handle\n",
@ -865,9 +854,6 @@ qla2x00_status_entry(scsi_qla_host_t *ha, sts_entry_t *pkt)
return;
}
if (ha->actthreads)
ha->actthreads--;
comp_status = le16_to_cpu(pkt->comp_status);
/* Mask of reserved bits 12-15, before we examine the scsi status */
scsi_status = le16_to_cpu(pkt->scsi_status) & SS_MASK;
@ -1026,7 +1012,6 @@ qla2x00_status_entry(scsi_qla_host_t *ha, sts_entry_t *pkt)
cp->request_bufflen));
cp->result = DID_BUS_BUSY << 16;
ha->dropped_frame_error_cnt++;
break;
}
@ -1233,8 +1218,7 @@ qla2x00_error_entry(scsi_qla_host_t *ha, sts_entry_t *pkt)
if (sp) {
/* Free outstanding command slot. */
ha->outstanding_cmds[pkt->handle] = NULL;
if (ha->actthreads)
ha->actthreads--;
/* Bad payload or header */
if (pkt->entry_status &
(RF_INV_E_ORDER | RF_INV_E_COUNT |

View file

@ -219,10 +219,8 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp)
ha->flags.mbox_int = 0;
clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
if (ha->mailbox_out[0] != MBS_COMMAND_COMPLETE) {
qla2x00_stats.mboxerr++;
if (ha->mailbox_out[0] != MBS_COMMAND_COMPLETE)
rval = QLA_FUNCTION_FAILED;
}
/* Load return mailbox registers. */
iptr2 = mcp->mb;
@ -249,8 +247,6 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp)
qla2x00_dump_regs(ha);
#endif
qla2x00_stats.mboxtout++;
ha->total_mbx_timeout++;
rval = QLA_FUNCTION_TIMEOUT;
}

View file

@ -36,27 +36,12 @@ char qla2x00_version_str[40];
/*
* SRB allocation cache
*/
char srb_cachep_name[16];
kmem_cache_t *srb_cachep;
/*
* Stats for all adpaters.
*/
struct _qla2x00stats qla2x00_stats;
static kmem_cache_t *srb_cachep;
/*
* Ioctl related information.
*/
int num_hosts;
int apiHBAInstance;
/*
* Module parameter information and variables
*/
int ql2xmaxqdepth;
module_param(ql2xmaxqdepth, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(ql2xmaxqdepth,
"Maximum queue depth to report for target devices.");
static int num_hosts;
int ql2xlogintimeout = 20;
module_param(ql2xlogintimeout, int, S_IRUGO|S_IRUSR);
@ -69,12 +54,6 @@ MODULE_PARM_DESC(qlport_down_retry,
"Maximum number of command retries to a port that returns"
"a PORT-DOWN status.");
int ql2xretrycount = 20;
module_param(ql2xretrycount, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(ql2xretrycount,
"Maximum number of mid-layer retries allowed for a command. "
"Default value is 20, ");
int ql2xplogiabsentdevice;
module_param(ql2xplogiabsentdevice, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(ql2xplogiabsentdevice,
@ -95,25 +74,6 @@ MODULE_PARM_DESC(ql2xintrdelaytimer,
"ZIO: Waiting time for Firmware before it generates an "
"interrupt to the host to notify completion of request.");
int ConfigRequired;
module_param(ConfigRequired, int, S_IRUGO|S_IRUSR);
MODULE_PARM_DESC(ConfigRequired,
"If 1, then only configured devices passed in through the"
"ql2xopts parameter will be presented to the OS");
int Bind = BIND_BY_PORT_NAME;
module_param(Bind, int, S_IRUGO|S_IRUSR);
MODULE_PARM_DESC(Bind,
"Target persistent binding method: "
"0 by Portname (default); 1 by PortID; 2 by Nodename. ");
int ql2xsuspendcount = SUSPEND_COUNT;
module_param(ql2xsuspendcount, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(ql2xsuspendcount,
"Number of 6-second suspend iterations to perform while a "
"target returns a <NOT READY> status. Default is 10 "
"iterations.");
int ql2xloginretrycount = 0;
module_param(ql2xloginretrycount, int, S_IRUGO|S_IRUSR);
MODULE_PARM_DESC(ql2xloginretrycount,
@ -330,7 +290,6 @@ qla2x00_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
sp->fcport = fcport;
sp->cmd = cmd;
sp->flags = 0;
sp->err_id = 0;
CMD_SP(cmd) = (void *)sp;
cmd->scsi_done = done;
@ -474,7 +433,6 @@ qla2x00_wait_for_loop_ready(scsi_qla_host_t *ha)
while ((!atomic_read(&ha->loop_down_timer) &&
atomic_read(&ha->loop_state) == LOOP_DOWN) ||
test_bit(CFG_ACTIVE, &ha->cfg_flags) ||
atomic_read(&ha->loop_state) != LOOP_READY) {
msleep(1000);
if (time_after_eq(jiffies, loop_timeout)) {
@ -1194,34 +1152,24 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info)
spin_lock_init(&ha->hardware_lock);
/* 4.23 Initialize /proc/scsi/qla2x00 counters */
ha->actthreads = 0;
ha->qthreads = 0;
ha->total_isr_cnt = 0;
ha->total_isp_aborts = 0;
ha->total_lip_cnt = 0;
ha->total_dev_errs = 0;
ha->total_ios = 0;
ha->total_bytes = 0;
ha->prev_topology = 0;
ha->ports = MAX_BUSES;
if (IS_QLA2100(ha)) {
ha->max_targets = MAX_TARGETS_2100;
host->max_id = MAX_TARGETS_2100;
ha->mbx_count = MAILBOX_REGISTER_COUNT_2100;
ha->request_q_length = REQUEST_ENTRY_CNT_2100;
ha->response_q_length = RESPONSE_ENTRY_CNT_2100;
ha->last_loop_id = SNS_LAST_LOOP_ID_2100;
host->sg_tablesize = 32;
} else if (IS_QLA2200(ha)) {
ha->max_targets = MAX_TARGETS_2200;
host->max_id = MAX_TARGETS_2200;
ha->mbx_count = MAILBOX_REGISTER_COUNT;
ha->request_q_length = REQUEST_ENTRY_CNT_2200;
ha->response_q_length = RESPONSE_ENTRY_CNT_2100;
ha->last_loop_id = SNS_LAST_LOOP_ID_2100;
} else /*if (IS_QLA2300(ha))*/ {
ha->max_targets = MAX_TARGETS_2200;
host->max_id = MAX_TARGETS_2200;
ha->mbx_count = MAILBOX_REGISTER_COUNT;
ha->request_q_length = REQUEST_ENTRY_CNT_2200;
ha->response_q_length = RESPONSE_ENTRY_CNT_2300;
@ -1265,8 +1213,7 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info)
host->unique_id = ha->instance;
host->max_cmd_len = MAX_CMDSZ;
host->max_channel = ha->ports - 1;
host->max_id = ha->max_targets;
host->max_lun = ha->max_luns;
host->max_lun = MAX_LUNS;
host->transportt = qla2xxx_transport_template;
if (scsi_add_host(host, &pdev->dev))
goto probe_alloc_failed;
@ -2336,8 +2283,7 @@ static int __init
qla2x00_module_init(void)
{
/* Allocate cache for SRBs. */
sprintf(srb_cachep_name, "qla2xxx_srbs");
srb_cachep = kmem_cache_create(srb_cachep_name, sizeof(srb_t), 0,
srb_cachep = kmem_cache_create("qla2xxx_srbs", sizeof(srb_t), 0,
SLAB_HWCACHE_ALIGN, NULL, NULL);
if (srb_cachep == NULL) {
printk(KERN_ERR
@ -2365,16 +2311,7 @@ qla2x00_module_init(void)
static void __exit
qla2x00_module_exit(void)
{
/* Free SRBs cache. */
if (srb_cachep != NULL) {
if (kmem_cache_destroy(srb_cachep) != 0) {
printk(KERN_ERR
"qla2xxx: Unable to free SRB cache...Memory pools "
"still active?\n");
}
srb_cachep = NULL;
}
kmem_cache_destroy(srb_cachep);
fc_release_transport(qla2xxx_transport_template);
}

View file

@ -638,10 +638,12 @@ int scsi_dispatch_cmd(struct scsi_cmnd *cmd)
}
spin_unlock_irqrestore(host->host_lock, flags);
if (rtn) {
atomic_inc(&cmd->device->iodone_cnt);
scsi_queue_insert(cmd,
(rtn == SCSI_MLQUEUE_DEVICE_BUSY) ?
rtn : SCSI_MLQUEUE_HOST_BUSY);
if (scsi_delete_timer(cmd)) {
atomic_inc(&cmd->device->iodone_cnt);
scsi_queue_insert(cmd,
(rtn == SCSI_MLQUEUE_DEVICE_BUSY) ?
rtn : SCSI_MLQUEUE_HOST_BUSY);
}
SCSI_LOG_MLQUEUE(3,
printk("queuecommand : request rejected\n"));
}

View file

@ -434,8 +434,7 @@ static void scsi_eh_times_out(struct scsi_cmnd *scmd)
SCSI_LOG_ERROR_RECOVERY(3, printk("%s: scmd:%p\n", __FUNCTION__,
scmd));
if (scmd->device->host->eh_action)
up(scmd->device->host->eh_action);
up(scmd->device->host->eh_action);
}
/**
@ -457,8 +456,7 @@ static void scsi_eh_done(struct scsi_cmnd *scmd)
SCSI_LOG_ERROR_RECOVERY(3, printk("%s scmd: %p result: %x\n",
__FUNCTION__, scmd, scmd->result));
if (scmd->device->host->eh_action)
up(scmd->device->host->eh_action);
up(scmd->device->host->eh_action);
}
}
@ -770,6 +768,7 @@ static int scsi_eh_tur(struct scsi_cmnd *scmd)
{
static unsigned char tur_command[6] = {TEST_UNIT_READY, 0, 0, 0, 0, 0};
int retry_cnt = 1, rtn;
int saved_result;
retry_tur:
memcpy(scmd->cmnd, tur_command, sizeof(tur_command));
@ -780,6 +779,7 @@ retry_tur:
*/
memset(scmd->sense_buffer, 0, sizeof(scmd->sense_buffer));
saved_result = scmd->result;
scmd->request_buffer = NULL;
scmd->request_bufflen = 0;
scmd->use_sg = 0;
@ -794,6 +794,7 @@ retry_tur:
* the original request, so let's restore the original data. (db)
*/
scsi_setup_cmd_retry(scmd);
scmd->result = saved_result;
/*
* hey, we are done. let's look to see what happened.
@ -896,6 +897,7 @@ static int scsi_eh_try_stu(struct scsi_cmnd *scmd)
{
static unsigned char stu_command[6] = {START_STOP, 0, 0, 0, 1, 0};
int rtn;
int saved_result;
if (!scmd->device->allow_restart)
return 1;
@ -908,6 +910,7 @@ static int scsi_eh_try_stu(struct scsi_cmnd *scmd)
*/
memset(scmd->sense_buffer, 0, sizeof(scmd->sense_buffer));
saved_result = scmd->result;
scmd->request_buffer = NULL;
scmd->request_bufflen = 0;
scmd->use_sg = 0;
@ -922,6 +925,7 @@ static int scsi_eh_try_stu(struct scsi_cmnd *scmd)
* the original request, so let's restore the original data. (db)
*/
scsi_setup_cmd_retry(scmd);
scmd->result = saved_result;
/*
* hey, we are done. let's look to see what happened.
@ -1561,6 +1565,11 @@ static void scsi_eh_flush_done_q(struct list_head *done_q)
scmd));
scsi_queue_insert(scmd, SCSI_MLQUEUE_EH_RETRY);
} else {
/*
* If just we got sense for the device (called
* scsi_eh_get_sense), scmd->result is already
* set, do not set DRIVER_TIMEOUT.
*/
if (!scmd->result)
scmd->result |= (DRIVER_TIMEOUT << 24);
SCSI_LOG_ERROR_RECOVERY(3, printk("%s: flush finish"
@ -1870,7 +1879,6 @@ scsi_reset_provider(struct scsi_device *dev, int flag)
rtn = FAILED;
}
scsi_delete_timer(scmd);
scsi_next_command(scmd);
return rtn;
}

View file

@ -92,10 +92,12 @@ int scsi_insert_special_req(struct scsi_request *sreq, int at_head)
*/
sreq->sr_request->flags &= ~REQ_DONTPREP;
blk_insert_request(sreq->sr_device->request_queue, sreq->sr_request,
at_head, sreq, 0);
at_head, sreq);
return 0;
}
static void scsi_run_queue(struct request_queue *q);
/*
* Function: scsi_queue_insert()
*
@ -119,18 +121,14 @@ int scsi_queue_insert(struct scsi_cmnd *cmd, int reason)
{
struct Scsi_Host *host = cmd->device->host;
struct scsi_device *device = cmd->device;
struct request_queue *q = device->request_queue;
unsigned long flags;
SCSI_LOG_MLQUEUE(1,
printk("Inserting command %p into mlqueue\n", cmd));
/*
* We are inserting the command into the ml queue. First, we
* cancel the timer, so it doesn't time out.
*/
scsi_delete_timer(cmd);
/*
* Next, set the appropriate busy bit for the device/host.
* Set the appropriate busy bit for the device/host.
*
* If the host/device isn't busy, assume that something actually
* completed, and that we should be able to queue a command now.
@ -160,17 +158,22 @@ int scsi_queue_insert(struct scsi_cmnd *cmd, int reason)
scsi_device_unbusy(device);
/*
* Insert this command at the head of the queue for it's device.
* It will go before all other commands that are already in the queue.
* Requeue this command. It will go before all other commands
* that are already in the queue.
*
* NOTE: there is magic here about the way the queue is plugged if
* we have no outstanding commands.
*
* Although this *doesn't* plug the queue, it does call the request
* Although we *don't* plug the queue, we call the request
* function. The SCSI request function detects the blocked condition
* and plugs the queue appropriately.
*/
blk_insert_request(device->request_queue, cmd->request, 1, cmd, 1);
*/
spin_lock_irqsave(q->queue_lock, flags);
blk_requeue_request(q, cmd->request);
spin_unlock_irqrestore(q->queue_lock, flags);
scsi_run_queue(q);
return 0;
}
@ -485,8 +488,13 @@ static void scsi_run_queue(struct request_queue *q)
*/
static void scsi_requeue_command(struct request_queue *q, struct scsi_cmnd *cmd)
{
unsigned long flags;
cmd->request->flags &= ~REQ_DONTPREP;
blk_insert_request(q, cmd->request, 1, cmd, 1);
spin_lock_irqsave(q->queue_lock, flags);
blk_requeue_request(q, cmd->request);
spin_unlock_irqrestore(q->queue_lock, flags);
scsi_run_queue(q);
}
@ -941,10 +949,8 @@ static int scsi_init_io(struct scsi_cmnd *cmd)
* if sg table allocation fails, requeue request later.
*/
sgpnt = scsi_alloc_sgtable(cmd, GFP_ATOMIC);
if (unlikely(!sgpnt)) {
req->flags |= REQ_SPECIAL;
if (unlikely(!sgpnt))
return BLKPREP_DEFER;
}
cmd->request_buffer = (char *) sgpnt;
cmd->request_bufflen = req->nr_sectors << 9;

View file

@ -293,6 +293,10 @@ static void scsi_target_dev_release(struct device *dev)
{
struct device *parent = dev->parent;
struct scsi_target *starget = to_scsi_target(dev);
struct Scsi_Host *shost = dev_to_shost(parent);
if (shost->hostt->target_destroy)
shost->hostt->target_destroy(starget);
kfree(starget);
put_device(parent);
}
@ -360,9 +364,23 @@ static struct scsi_target *scsi_alloc_target(struct device *parent,
list_add_tail(&starget->siblings, &shost->__targets);
spin_unlock_irqrestore(shost->host_lock, flags);
/* allocate and add */
transport_setup_device(&starget->dev);
device_add(&starget->dev);
transport_add_device(&starget->dev);
transport_setup_device(dev);
device_add(dev);
transport_add_device(dev);
if (shost->hostt->target_alloc) {
int error = shost->hostt->target_alloc(starget);
if(error) {
dev_printk(KERN_ERR, dev, "target allocation failed, error %d\n", error);
/* don't want scsi_target_reap to do the final
* put because it will be under the host lock */
get_device(dev);
scsi_target_reap(starget);
put_device(dev);
return NULL;
}
}
return starget;
found:
@ -625,6 +643,7 @@ static int scsi_add_lun(struct scsi_device *sdev, char *inq_result, int *bflags)
case TYPE_MEDIUM_CHANGER:
case TYPE_ENCLOSURE:
case TYPE_COMM:
case TYPE_RBC:
sdev->writeable = 1;
break;
case TYPE_WORM:

View file

@ -1368,17 +1368,26 @@ sd_read_write_protect_flag(struct scsi_disk *sdkp, char *diskname,
*/
static void
sd_read_cache_type(struct scsi_disk *sdkp, char *diskname,
struct scsi_request *SRpnt, unsigned char *buffer) {
struct scsi_request *SRpnt, unsigned char *buffer)
{
int len = 0, res;
const int dbd = 0; /* DBD */
const int modepage = 0x08; /* current values, cache page */
int dbd;
int modepage;
struct scsi_mode_data data;
struct scsi_sense_hdr sshdr;
if (sdkp->device->skip_ms_page_8)
goto defaults;
if (sdkp->device->type == TYPE_RBC) {
modepage = 6;
dbd = 8;
} else {
modepage = 8;
dbd = 0;
}
/* cautiously ask */
res = sd_do_mode_sense(SRpnt, dbd, modepage, buffer, 4, &data);
@ -1409,11 +1418,20 @@ sd_read_cache_type(struct scsi_disk *sdkp, char *diskname,
"write back, no read (daft)"
};
int ct = 0;
int offset = data.header_length +
data.block_descriptor_length + 2;
int offset = data.header_length + data.block_descriptor_length;
sdkp->WCE = ((buffer[offset] & 0x04) != 0);
sdkp->RCD = ((buffer[offset] & 0x01) != 0);
if ((buffer[offset] & 0x3f) != modepage) {
printk(KERN_ERR "%s: got wrong page\n", diskname);
goto defaults;
}
if (modepage == 8) {
sdkp->WCE = ((buffer[offset + 2] & 0x04) != 0);
sdkp->RCD = ((buffer[offset + 2] & 0x01) != 0);
} else {
sdkp->WCE = ((buffer[offset + 2] & 0x01) == 0);
sdkp->RCD = 0;
}
ct = sdkp->RCD + 2*sdkp->WCE;
@ -1533,7 +1551,7 @@ static int sd_probe(struct device *dev)
int error;
error = -ENODEV;
if ((sdp->type != TYPE_DISK) && (sdp->type != TYPE_MOD))
if (sdp->type != TYPE_DISK && sdp->type != TYPE_MOD && sdp->type != TYPE_RBC)
goto out;
SCSI_LOG_HLQUEUE(3, printk("sd_attach: scsi device: <%d,%d,%d,%d>\n",
@ -1570,7 +1588,7 @@ static int sd_probe(struct device *dev)
sdkp->openers = 0;
if (!sdp->timeout) {
if (sdp->type == TYPE_DISK)
if (sdp->type != TYPE_MOD)
sdp->timeout = SD_TIMEOUT;
else
sdp->timeout = SD_MOD_TIMEOUT;

View file

@ -17,7 +17,7 @@
Last modified: 18-JAN-1998 Richard Gooch <rgooch@atnf.csiro.au> Devfs support
*/
static char *verstr = "20050312";
static char *verstr = "20050501";
#include <linux/module.h>
@ -29,6 +29,7 @@ static char *verstr = "20050312";
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/mtio.h>
#include <linux/cdrom.h>
#include <linux/ioctl.h>
#include <linux/fcntl.h>
#include <linux/spinlock.h>
@ -50,6 +51,7 @@ static char *verstr = "20050312";
#include <scsi/scsi_host.h>
#include <scsi/scsi_ioctl.h>
#include <scsi/scsi_request.h>
#include <scsi/sg.h>
/* The driver prints some debugging information on the console if DEBUG
@ -3463,7 +3465,10 @@ static int st_ioctl(struct inode *inode, struct file *file,
case SCSI_IOCTL_GET_BUS_NUMBER:
break;
default:
if (!capable(CAP_SYS_ADMIN))
if ((cmd_in == SG_IO ||
cmd_in == SCSI_IOCTL_SEND_COMMAND ||
cmd_in == CDROM_SEND_PACKET) &&
!capable(CAP_SYS_RAWIO))
i = -EPERM;
else
i = scsi_cmd_ioctl(file, STp->disk, cmd_in, p);
@ -3471,10 +3476,12 @@ static int st_ioctl(struct inode *inode, struct file *file,
return i;
break;
}
if (!capable(CAP_SYS_ADMIN) &&
(cmd_in == SCSI_IOCTL_START_UNIT || cmd_in == SCSI_IOCTL_STOP_UNIT))
return -EPERM;
return scsi_ioctl(STp->device, cmd_in, p);
retval = scsi_ioctl(STp->device, cmd_in, p);
if (!retval && cmd_in == SCSI_IOCTL_STOP_UNIT) { /* unload */
STp->rew_at_close = 0;
STp->ready = ST_NO_TAPE;
}
return retval;
out:
up(&STp->lock);

View file

@ -23,8 +23,6 @@
#include <asm/dvma.h>
#include <asm/irq.h>
extern struct NCR_ESP *espchain;
static void dma_barrier(struct NCR_ESP *esp);
static int dma_bytes_sent(struct NCR_ESP *esp, int fifo_count);
static int dma_can_transfer(struct NCR_ESP *esp, Scsi_Cmnd *sp);

View file

@ -40,7 +40,7 @@
#ifndef SYM_DEFS_H
#define SYM_DEFS_H
#define SYM_VERSION "2.2.0"
#define SYM_VERSION "2.2.1"
#define SYM_DRIVER_NAME "sym-" SYM_VERSION
/*

View file

@ -155,10 +155,11 @@ pci_get_base_address(struct pci_dev *pdev, int index, unsigned long *basep)
base = tmp;
if ((tmp & 0x7) == PCI_BASE_ADDRESS_MEM_TYPE_64) {
pci_read_config_dword(pdev, PCI_BAR_OFFSET(index++), &tmp);
if (tmp > 0)
if (tmp > 0) {
dev_err(&pdev->dev,
"BAR %d is 64-bit, disabling\n", index - 1);
base = 0;
base = 0;
}
}
if ((base & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) {
@ -389,13 +390,20 @@ static int sym_scatter_no_sglist(struct sym_hcb *np, struct sym_ccb *cp, struct
{
struct sym_tblmove *data = &cp->phys.data[SYM_CONF_MAX_SG-1];
int segment;
unsigned int len = cmd->request_bufflen;
cp->data_len = cmd->request_bufflen;
if (cmd->request_bufflen) {
if (len) {
dma_addr_t baddr = map_scsi_single_data(np, cmd);
if (baddr) {
sym_build_sge(np, data, baddr, cmd->request_bufflen);
if (len & 1) {
struct sym_tcb *tp = &np->target[cp->target];
if (tp->head.wval & EWS) {
len++;
cp->odd_byte_adjustment++;
}
}
cp->data_len = len;
sym_build_sge(np, data, baddr, len);
segment = 1;
} else {
segment = -2;
@ -418,6 +426,7 @@ static int sym_scatter(struct sym_hcb *np, struct sym_ccb *cp, struct scsi_cmnd
segment = sym_scatter_no_sglist(np, cp, cmd);
else if ((use_sg = map_scsi_sg_data(np, cmd)) > 0) {
struct scatterlist *scatter = (struct scatterlist *)cmd->buffer;
struct sym_tcb *tp = &np->target[cp->target];
struct sym_tblmove *data;
if (use_sg > SYM_CONF_MAX_SG) {
@ -431,6 +440,11 @@ static int sym_scatter(struct sym_hcb *np, struct sym_ccb *cp, struct scsi_cmnd
dma_addr_t baddr = sg_dma_address(&scatter[segment]);
unsigned int len = sg_dma_len(&scatter[segment]);
if ((len & 1) && (tp->head.wval & EWS)) {
len++;
cp->odd_byte_adjustment++;
}
sym_build_sge(np, &data[segment], baddr, len);
cp->data_len += len;
}
@ -456,10 +470,8 @@ static int sym_queue_command(struct sym_hcb *np, struct scsi_cmnd *cmd)
* Minimal checkings, so that we will not
* go outside our tables.
*/
if (sdev->id == np->myaddr ||
sdev->id >= SYM_CONF_MAX_TARGET ||
sdev->lun >= SYM_CONF_MAX_LUN) {
sym_xpt_done2(np, cmd, CAM_DEV_NOT_THERE);
if (sdev->id == np->myaddr) {
sym_xpt_done2(np, cmd, DID_NO_CONNECT);
return 0;
}
@ -468,28 +480,6 @@ static int sym_queue_command(struct sym_hcb *np, struct scsi_cmnd *cmd)
*/
tp = &np->target[sdev->id];
/*
* Complete the 1st INQUIRY command with error
* condition if the device is flagged NOSCAN
* at BOOT in the NVRAM. This may speed up
* the boot and maintain coherency with BIOS
* device numbering. Clearing the flag allows
* user to rescan skipped devices later.
* We also return error for devices not flagged
* for SCAN LUNS in the NVRAM since some mono-lun
* devices behave badly when asked for some non
* zero LUN. Btw, this is an absolute hack.:-)
*/
if (cmd->cmnd[0] == 0x12 || cmd->cmnd[0] == 0x0) {
if ((tp->usrflags & SYM_SCAN_BOOT_DISABLED) ||
((tp->usrflags & SYM_SCAN_LUNS_DISABLED) &&
sdev->lun != 0)) {
tp->usrflags &= ~SYM_SCAN_BOOT_DISABLED;
sym_xpt_done2(np, cmd, CAM_DEV_NOT_THERE);
return 0;
}
}
/*
* Select tagged/untagged.
*/
@ -511,23 +501,10 @@ static int sym_queue_command(struct sym_hcb *np, struct scsi_cmnd *cmd)
*/
static inline int sym_setup_cdb(struct sym_hcb *np, struct scsi_cmnd *cmd, struct sym_ccb *cp)
{
u32 cmd_ba;
int cmd_len;
/*
* CDB is 16 bytes max.
*/
if (cmd->cmd_len > sizeof(cp->cdb_buf)) {
sym_set_cam_status(cp->cmd, CAM_REQ_INVALID);
return -1;
}
memcpy(cp->cdb_buf, cmd->cmnd, cmd->cmd_len);
cmd_ba = CCB_BA (cp, cdb_buf[0]);
cmd_len = cmd->cmd_len;
cp->phys.cmd.addr = cpu_to_scr(cmd_ba);
cp->phys.cmd.size = cpu_to_scr(cmd_len);
cp->phys.cmd.addr = CCB_BA(cp, cdb_buf[0]);
cp->phys.cmd.size = cpu_to_scr(cmd->cmd_len);
return 0;
}
@ -554,10 +531,7 @@ int sym_setup_data_and_start(struct sym_hcb *np, struct scsi_cmnd *cmd, struct s
if (dir != DMA_NONE) {
cp->segments = sym_scatter(np, cp, cmd);
if (cp->segments < 0) {
if (cp->segments == -2)
sym_set_cam_status(cmd, CAM_RESRC_UNAVAIL);
else
sym_set_cam_status(cmd, CAM_REQ_TOO_BIG);
sym_set_cam_status(cmd, DID_ERROR);
goto out_abort;
}
} else {
@ -855,7 +829,7 @@ prepare:
ep->to_do = to_do;
/* Complete the command with locks held as required by the driver */
if (to_do == SYM_EH_DO_COMPLETE)
sym_xpt_done2(np, cmd, CAM_REQ_ABORTED);
sym_xpt_done2(np, cmd, DID_ABORT);
/* Wait for completion with locks released, as required by kernel */
if (to_do == SYM_EH_DO_WAIT) {
@ -921,7 +895,7 @@ static void sym_tune_dev_queuing(struct sym_tcb *tp, int lun, u_short reqtags)
lp->s.reqtags = reqtags;
if (reqtags != oldtags) {
dev_info(&tp->sdev->sdev_target->dev,
dev_info(&tp->starget->dev,
"tagged command queuing %s, command queue depth %d.\n",
lp->s.reqtags ? "enabled" : "disabled",
lp->started_limit);
@ -981,24 +955,36 @@ static int device_queue_depth(struct sym_hcb *np, int target, int lun)
return DEF_DEPTH;
}
static int sym53c8xx_slave_alloc(struct scsi_device *device)
static int sym53c8xx_slave_alloc(struct scsi_device *sdev)
{
struct sym_hcb *np = sym_get_hcb(device->host);
struct sym_tcb *tp = &np->target[device->id];
if (!tp->sdev)
tp->sdev = device;
struct sym_hcb *np;
struct sym_tcb *tp;
if (sdev->id >= SYM_CONF_MAX_TARGET || sdev->lun >= SYM_CONF_MAX_LUN)
return -ENXIO;
np = sym_get_hcb(sdev->host);
tp = &np->target[sdev->id];
/*
* Fail the device init if the device is flagged NOSCAN at BOOT in
* the NVRAM. This may speed up boot and maintain coherency with
* BIOS device numbering. Clearing the flag allows the user to
* rescan skipped devices later. We also return an error for
* devices not flagged for SCAN LUNS in the NVRAM since some single
* lun devices behave badly when asked for a non zero LUN.
*/
if ((tp->usrflags & SYM_SCAN_BOOT_DISABLED) ||
((tp->usrflags & SYM_SCAN_LUNS_DISABLED) && sdev->lun != 0)) {
tp->usrflags &= ~SYM_SCAN_BOOT_DISABLED;
return -ENXIO;
}
tp->starget = sdev->sdev_target;
return 0;
}
static void sym53c8xx_slave_destroy(struct scsi_device *device)
{
struct sym_hcb *np = sym_get_hcb(device->host);
struct sym_tcb *tp = &np->target[device->id];
if (tp->sdev == device)
tp->sdev = NULL;
}
/*
* Linux entry point for device queue sizing.
*/
@ -1897,6 +1883,7 @@ static int sym_detach(struct sym_hcb *np, struct pci_dev *pdev)
*/
printk("%s: resetting chip\n", sym_name(np));
OUTB(np, nc_istat, SRST);
INB(np, nc_mbox1);
udelay(10);
OUTB(np, nc_istat, 0);
@ -1915,7 +1902,6 @@ static struct scsi_host_template sym2_template = {
.queuecommand = sym53c8xx_queue_command,
.slave_alloc = sym53c8xx_slave_alloc,
.slave_configure = sym53c8xx_slave_configure,
.slave_destroy = sym53c8xx_slave_destroy,
.eh_abort_handler = sym53c8xx_eh_abort_handler,
.eh_device_reset_handler = sym53c8xx_eh_device_reset_handler,
.eh_bus_reset_handler = sym53c8xx_eh_bus_reset_handler,

View file

@ -141,33 +141,6 @@
#define cpu_to_scr(dw) cpu_to_le32(dw)
#define scr_to_cpu(dw) le32_to_cpu(dw)
/*
* Remap some status field values.
*/
#define CAM_REQ_CMP DID_OK
#define CAM_SEL_TIMEOUT DID_NO_CONNECT
#define CAM_CMD_TIMEOUT DID_TIME_OUT
#define CAM_REQ_ABORTED DID_ABORT
#define CAM_UNCOR_PARITY DID_PARITY
#define CAM_SCSI_BUS_RESET DID_RESET
#define CAM_REQUEUE_REQ DID_SOFT_ERROR
#define CAM_UNEXP_BUSFREE DID_ERROR
#define CAM_SCSI_BUSY DID_BUS_BUSY
#define CAM_DEV_NOT_THERE DID_NO_CONNECT
#define CAM_REQ_INVALID DID_ERROR
#define CAM_REQ_TOO_BIG DID_ERROR
#define CAM_RESRC_UNAVAIL DID_ERROR
/*
* Remap data direction values.
*/
#define CAM_DIR_NONE DMA_NONE
#define CAM_DIR_IN DMA_FROM_DEVICE
#define CAM_DIR_OUT DMA_TO_DEVICE
#define CAM_DIR_UNKNOWN DMA_BIDIRECTIONAL
/*
* These ones are used as return code from
* error recovery handlers under Linux.

View file

@ -97,7 +97,7 @@ static void sym_print_msg(struct sym_ccb *cp, char *label, u_char *msg)
static void sym_print_nego_msg(struct sym_hcb *np, int target, char *label, u_char *msg)
{
struct sym_tcb *tp = &np->target[target];
dev_info(&tp->sdev->sdev_target->dev, "%s: ", label);
dev_info(&tp->starget->dev, "%s: ", label);
sym_show_msg(msg);
printf(".\n");
@ -149,8 +149,10 @@ static char *sym_scsi_bus_mode(int mode)
static void sym_chip_reset (struct sym_hcb *np)
{
OUTB(np, nc_istat, SRST);
INB(np, nc_mbox1);
udelay(10);
OUTB(np, nc_istat, 0);
INB(np, nc_mbox1);
udelay(2000); /* For BUS MODE to settle */
}
@ -216,6 +218,7 @@ int sym_reset_scsi_bus(struct sym_hcb *np, int enab_int)
OUTB(np, nc_stest3, TE);
OUTB(np, nc_dcntl, (np->rv_dcntl & IRQM));
OUTB(np, nc_scntl1, CRST);
INB(np, nc_mbox1);
udelay(200);
if (!SYM_SETUP_SCSI_BUS_CHECK)
@ -280,8 +283,10 @@ static void sym_selectclock(struct sym_hcb *np, u_char scntl3)
if (!i)
printf("%s: the chip cannot lock the frequency\n",
sym_name(np));
} else
udelay((50+10));
} else {
INB(np, nc_mbox1);
udelay(50+10);
}
OUTB(np, nc_stest3, HSC); /* Halt the scsi clock */
OUTB(np, nc_scntl3, scntl3);
OUTB(np, nc_stest1, (DBLEN|DBLSEL));/* Select clock multiplier */
@ -1445,7 +1450,7 @@ static void sym_check_goals(struct sym_hcb *np, struct scsi_target *starget,
static int sym_prepare_nego(struct sym_hcb *np, struct sym_ccb *cp, u_char *msgptr)
{
struct sym_tcb *tp = &np->target[cp->target];
struct scsi_target *starget = tp->sdev->sdev_target;
struct scsi_target *starget = tp->starget;
struct sym_trans *goal = &tp->tgoal;
int msglen = 0;
int nego;
@ -1690,7 +1695,7 @@ static void sym_flush_comp_queue(struct sym_hcb *np, int cam_status)
if (cam_status)
sym_set_cam_status(cmd, cam_status);
#ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
if (sym_get_cam_status(cmd) == CAM_REQUEUE_REQ) {
if (sym_get_cam_status(cmd) == DID_SOFT_ERROR) {
struct sym_tcb *tp = &np->target[cp->target];
struct sym_lcb *lp = sym_lp(tp, cp->lun);
if (lp) {
@ -1791,12 +1796,13 @@ void sym_start_up (struct sym_hcb *np, int reason)
/*
* Wakeup all pending jobs.
*/
sym_flush_busy_queue(np, CAM_SCSI_BUS_RESET);
sym_flush_busy_queue(np, DID_RESET);
/*
* Init chip.
*/
OUTB(np, nc_istat, 0x00); /* Remove Reset, abort */
INB(np, nc_mbox1);
udelay(2000); /* The 895 needs time for the bus mode to settle */
OUTB(np, nc_scntl0, np->rv_scntl0 | 0xc0);
@ -1905,6 +1911,7 @@ void sym_start_up (struct sym_hcb *np, int reason)
if (np->features & (FE_ULTRA2|FE_ULTRA3)) {
OUTONW(np, nc_sien, SBMC);
if (reason == 0) {
INB(np, nc_mbox1);
mdelay(100);
INW(np, nc_sist);
}
@ -2074,7 +2081,7 @@ static void sym_settrans(struct sym_hcb *np, int target, u_char opts, u_char ofs
static void sym_setwide(struct sym_hcb *np, int target, u_char wide)
{
struct sym_tcb *tp = &np->target[target];
struct scsi_target *starget = tp->sdev->sdev_target;
struct scsi_target *starget = tp->starget;
if (spi_width(starget) == wide)
return;
@ -2102,7 +2109,7 @@ sym_setsync(struct sym_hcb *np, int target,
u_char ofs, u_char per, u_char div, u_char fak)
{
struct sym_tcb *tp = &np->target[target];
struct scsi_target *starget = tp->sdev->sdev_target;
struct scsi_target *starget = tp->starget;
u_char wide = (tp->head.wval & EWS) ? BUS_16_BIT : BUS_8_BIT;
sym_settrans(np, target, 0, ofs, per, wide, div, fak);
@ -2129,7 +2136,7 @@ sym_setpprot(struct sym_hcb *np, int target, u_char opts, u_char ofs,
u_char per, u_char wide, u_char div, u_char fak)
{
struct sym_tcb *tp = &np->target[target];
struct scsi_target *starget = tp->sdev->sdev_target;
struct scsi_target *starget = tp->starget;
sym_settrans(np, target, opts, ofs, per, wide, div, fak);
@ -2944,7 +2951,7 @@ unknown_int:
* Dequeue from the START queue all CCBs that match
* a given target/lun/task condition (-1 means all),
* and move them from the BUSY queue to the COMP queue
* with CAM_REQUEUE_REQ status condition.
* with DID_SOFT_ERROR status condition.
* This function is used during error handling/recovery.
* It is called with SCRIPTS not running.
*/
@ -2974,7 +2981,7 @@ sym_dequeue_from_squeue(struct sym_hcb *np, int i, int target, int lun, int task
if ((target == -1 || cp->target == target) &&
(lun == -1 || cp->lun == lun) &&
(task == -1 || cp->tag == task)) {
sym_set_cam_status(cp->cmd, CAM_REQUEUE_REQ);
sym_set_cam_status(cp->cmd, DID_SOFT_ERROR);
sym_remque(&cp->link_ccbq);
sym_insque_tail(&cp->link_ccbq, &np->comp_ccbq);
}
@ -3093,13 +3100,13 @@ static void sym_sir_bad_scsi_status(struct sym_hcb *np, int num, struct sym_ccb
/*
* Message table indirect structure.
*/
cp->phys.smsg.addr = cpu_to_scr(CCB_BA(cp, scsi_smsg2));
cp->phys.smsg.addr = CCB_BA(cp, scsi_smsg2);
cp->phys.smsg.size = cpu_to_scr(msglen);
/*
* sense command
*/
cp->phys.cmd.addr = cpu_to_scr(CCB_BA(cp, sensecmd));
cp->phys.cmd.addr = CCB_BA(cp, sensecmd);
cp->phys.cmd.size = cpu_to_scr(6);
/*
@ -3116,7 +3123,7 @@ static void sym_sir_bad_scsi_status(struct sym_hcb *np, int num, struct sym_ccb
* sense data
*/
memset(cp->sns_bbuf, 0, SYM_SNS_BBUF_LEN);
cp->phys.sense.addr = cpu_to_scr(CCB_BA(cp, sns_bbuf));
cp->phys.sense.addr = CCB_BA(cp, sns_bbuf);
cp->phys.sense.size = cpu_to_scr(SYM_SNS_BBUF_LEN);
/*
@ -3198,7 +3205,7 @@ int sym_clear_tasks(struct sym_hcb *np, int cam_status, int target, int lun, int
sym_insque_tail(&cp->link_ccbq, &np->comp_ccbq);
/* Preserve the software timeout condition */
if (sym_get_cam_status(cmd) != CAM_CMD_TIMEOUT)
if (sym_get_cam_status(cmd) != DID_TIME_OUT)
sym_set_cam_status(cmd, cam_status);
++i;
#if 0
@ -3366,7 +3373,7 @@ static void sym_sir_task_recovery(struct sym_hcb *np, int num)
* Make sure at least our IO to abort has been dequeued.
*/
#ifndef SYM_OPT_HANDLE_DEVICE_QUEUEING
assert(i && sym_get_cam_status(cp->cmd) == CAM_REQUEUE_REQ);
assert(i && sym_get_cam_status(cp->cmd) == DID_SOFT_ERROR);
#else
sym_remque(&cp->link_ccbq);
sym_insque_tail(&cp->link_ccbq, &np->comp_ccbq);
@ -3375,9 +3382,9 @@ static void sym_sir_task_recovery(struct sym_hcb *np, int num)
* Keep track in cam status of the reason of the abort.
*/
if (cp->to_abort == 2)
sym_set_cam_status(cp->cmd, CAM_CMD_TIMEOUT);
sym_set_cam_status(cp->cmd, DID_TIME_OUT);
else
sym_set_cam_status(cp->cmd, CAM_REQ_ABORTED);
sym_set_cam_status(cp->cmd, DID_ABORT);
/*
* Complete with error everything that we have dequeued.
@ -3491,7 +3498,7 @@ static void sym_sir_task_recovery(struct sym_hcb *np, int num)
* conditions not due to timeout.
*/
if (cp->to_abort == 2)
sym_set_cam_status(cp->cmd, CAM_CMD_TIMEOUT);
sym_set_cam_status(cp->cmd, DID_TIME_OUT);
cp->to_abort = 0; /* We donnot expect to fail here */
break;
@ -3502,7 +3509,7 @@ static void sym_sir_task_recovery(struct sym_hcb *np, int num)
case SIR_ABORT_SENT:
target = INB(np, nc_sdid) & 0xf;
tp = &np->target[target];
starget = tp->sdev->sdev_target;
starget = tp->starget;
/*
** If we didn't abort anything, leave here.
@ -3551,7 +3558,7 @@ static void sym_sir_task_recovery(struct sym_hcb *np, int num)
*/
i = (INL(np, nc_scratcha) - np->squeue_ba) / 4;
sym_dequeue_from_squeue(np, i, target, lun, -1);
sym_clear_tasks(np, CAM_REQ_ABORTED, target, lun, task);
sym_clear_tasks(np, DID_ABORT, target, lun, task);
sym_flush_comp_queue(np, 0);
/*
@ -3566,7 +3573,7 @@ static void sym_sir_task_recovery(struct sym_hcb *np, int num)
* Print to the log the message we intend to send.
*/
if (num == SIR_TARGET_SELECTED) {
dev_info(&tp->sdev->sdev_target->dev, "control msgout:");
dev_info(&tp->starget->dev, "control msgout:");
sym_printl_hex(np->abrt_msg, np->abrt_tbl.size);
np->abrt_tbl.size = cpu_to_scr(np->abrt_tbl.size);
}
@ -3877,6 +3884,8 @@ int sym_compute_residual(struct sym_hcb *np, struct sym_ccb *cp)
resid += (tmp & 0xffffff);
}
resid -= cp->odd_byte_adjustment;
/*
* Hopefully, the result is not too wrong.
*/
@ -4758,10 +4767,8 @@ struct sym_ccb *sym_get_ccb (struct sym_hcb *np, struct scsi_cmnd *cmd, u_char t
}
#endif
/*
* Remember all informations needed to free this CCB.
*/
cp->to_abort = 0;
cp->odd_byte_adjustment = 0;
cp->tag = tag;
cp->order = tag_order;
cp->target = tn;
@ -5104,7 +5111,7 @@ static void sym_alloc_lcb_tags (struct sym_hcb *np, u_char tn, u_char ln)
lp->itlq_tbl = sym_calloc_dma(SYM_CONF_MAX_TASK*4, "ITLQ_TBL");
if (!lp->itlq_tbl)
goto fail;
lp->cb_tags = kcalloc(SYM_CONF_MAX_TASK, 1, GFP_KERNEL);
lp->cb_tags = kcalloc(SYM_CONF_MAX_TASK, 1, GFP_ATOMIC);
if (!lp->cb_tags) {
sym_mfree_dma(lp->itlq_tbl, SYM_CONF_MAX_TASK*4, "ITLQ_TBL");
lp->itlq_tbl = NULL;
@ -5243,7 +5250,7 @@ int sym_queue_scsiio(struct sym_hcb *np, struct scsi_cmnd *cmd, struct sym_ccb *
/*
* message
*/
cp->phys.smsg.addr = cpu_to_scr(CCB_BA(cp, scsi_smsg));
cp->phys.smsg.addr = CCB_BA(cp, scsi_smsg);
cp->phys.smsg.size = cpu_to_scr(msglen);
/*
@ -5343,7 +5350,7 @@ int sym_abort_scsiio(struct sym_hcb *np, struct scsi_cmnd *cmd, int timed_out)
}
/*
* Complete execution of a SCSI command with extented
* Complete execution of a SCSI command with extended
* error, SCSI status error, or having been auto-sensed.
*
* The SCRIPTS processor is not running there, so we
@ -5441,7 +5448,7 @@ if (resid)
/*
* Let's requeue it to device.
*/
sym_set_cam_status(cmd, CAM_REQUEUE_REQ);
sym_set_cam_status(cmd, DID_SOFT_ERROR);
goto finish;
}
weirdness:

View file

@ -444,7 +444,7 @@ struct sym_tcb {
*/
u_char usrflags;
u_short usrtags;
struct scsi_device *sdev;
struct scsi_target *starget;
};
/*
@ -754,10 +754,8 @@ struct sym_ccb {
int segments; /* Number of SG segments */
u8 order; /* Tag type (if tagged command) */
unsigned char odd_byte_adjustment; /* odd-sized req on wide bus */
/*
* Miscellaneous status'.
*/
u_char nego_status; /* Negotiation status */
u_char xerr_status; /* Extended error flags */
u32 extra_bytes; /* Extraneous bytes transferred */
@ -809,7 +807,7 @@ struct sym_ccb {
#endif
};
#define CCB_BA(cp,lbl) (cp->ccb_ba + offsetof(struct sym_ccb, lbl))
#define CCB_BA(cp,lbl) cpu_to_scr(cp->ccb_ba + offsetof(struct sym_ccb, lbl))
#ifdef SYM_OPT_HANDLE_DIR_UNKNOWN
#define sym_goalp(cp) ((cp->host_flags & HF_DATA_IN) ? cp->goalp : cp->wgoalp)
@ -1138,33 +1136,33 @@ static inline void sym_setup_data_pointers(struct sym_hcb *np,
* No segments means no data.
*/
if (!cp->segments)
dir = CAM_DIR_NONE;
dir = DMA_NONE;
/*
* Set the data pointer.
*/
switch(dir) {
#ifdef SYM_OPT_HANDLE_DIR_UNKNOWN
case CAM_DIR_UNKNOWN:
case DMA_BIDIRECTIONAL:
#endif
case CAM_DIR_OUT:
case DMA_TO_DEVICE:
goalp = SCRIPTA_BA(np, data_out2) + 8;
lastp = goalp - 8 - (cp->segments * (2*4));
#ifdef SYM_OPT_HANDLE_DIR_UNKNOWN
cp->wgoalp = cpu_to_scr(goalp);
if (dir != CAM_DIR_UNKNOWN)
if (dir != DMA_BIDIRECTIONAL)
break;
cp->phys.head.wlastp = cpu_to_scr(lastp);
/* fall through */
#else
break;
#endif
case CAM_DIR_IN:
case DMA_FROM_DEVICE:
cp->host_flags |= HF_DATA_IN;
goalp = SCRIPTA_BA(np, data_in2) + 8;
lastp = goalp - 8 - (cp->segments * (2*4));
break;
case CAM_DIR_NONE:
case DMA_NONE:
default:
#ifdef SYM_OPT_HANDLE_DIR_UNKNOWN
cp->host_flags |= HF_DATA_IN;
@ -1185,7 +1183,7 @@ static inline void sym_setup_data_pointers(struct sym_hcb *np,
/*
* If direction is unknown, start at data_io.
*/
if (dir == CAM_DIR_UNKNOWN)
if (dir == DMA_BIDIRECTIONAL)
cp->phys.head.savep = cpu_to_scr(SCRIPTB_BA(np, data_io));
#endif
}

View file

@ -270,6 +270,7 @@ static void S24C16_set_bit(struct sym_device *np, u_char write_bit, u_char *gpre
}
OUTB(np, nc_gpreg, *gpreg);
INB(np, nc_mbox1);
udelay(5);
}
@ -547,6 +548,7 @@ static int sym_read_Symbios_nvram(struct sym_device *np, Symbios_nvram *nvram)
static void T93C46_Clk(struct sym_device *np, u_char *gpreg)
{
OUTB(np, nc_gpreg, *gpreg | 0x04);
INB(np, nc_mbox1);
udelay(2);
OUTB(np, nc_gpreg, *gpreg);
}
@ -574,6 +576,7 @@ static void T93C46_Write_Bit(struct sym_device *np, u_char write_bit, u_char *gp
*gpreg |= 0x10;
OUTB(np, nc_gpreg, *gpreg);
INB(np, nc_mbox1);
udelay(2);
T93C46_Clk(np, gpreg);
@ -586,6 +589,7 @@ static void T93C46_Stop(struct sym_device *np, u_char *gpreg)
{
*gpreg &= 0xef;
OUTB(np, nc_gpreg, *gpreg);
INB(np, nc_mbox1);
udelay(2);
T93C46_Clk(np, gpreg);
@ -733,7 +737,8 @@ static int sym_read_parisc_pdc(struct sym_device *np, struct pdc_initiator *pdc)
return SYM_PARISC_PDC;
}
#else
static int sym_read_parisc_pdc(struct sym_device *np, struct pdc_initiator *x)
static inline int sym_read_parisc_pdc(struct sym_device *np,
struct pdc_initiator *x)
{
return 0;
}

View file

@ -544,7 +544,7 @@ extern void blk_end_sync_rq(struct request *rq);
extern void blk_attempt_remerge(request_queue_t *, struct request *);
extern void __blk_attempt_remerge(request_queue_t *, struct request *);
extern struct request *blk_get_request(request_queue_t *, int, int);
extern void blk_insert_request(request_queue_t *, struct request *, int, void *, int);
extern void blk_insert_request(request_queue_t *, struct request *, int, void *);
extern void blk_requeue_request(request_queue_t *, struct request *);
extern void blk_plug_device(request_queue_t *);
extern int blk_remove_plug(request_queue_t *);

168
include/linux/chio.h Normal file
View file

@ -0,0 +1,168 @@
/*
* ioctl interface for the scsi media changer driver
*/
/* changer element types */
#define CHET_MT 0 /* media transport element (robot) */
#define CHET_ST 1 /* storage element (media slots) */
#define CHET_IE 2 /* import/export element */
#define CHET_DT 3 /* data transfer element (tape/cdrom/whatever) */
#define CHET_V1 4 /* vendor specific #1 */
#define CHET_V2 5 /* vendor specific #2 */
#define CHET_V3 6 /* vendor specific #3 */
#define CHET_V4 7 /* vendor specific #4 */
/*
* CHIOGPARAMS
* query changer properties
*
* CHIOVGPARAMS
* query vendor-specific element types
*
* accessing elements works by specifing type and unit of the element.
* for eample, storage elements are addressed with type = CHET_ST and
* unit = 0 .. cp_nslots-1
*
*/
struct changer_params {
int cp_curpicker; /* current transport element */
int cp_npickers; /* number of transport elements (CHET_MT) */
int cp_nslots; /* number of storage elements (CHET_ST) */
int cp_nportals; /* number of import/export elements (CHET_IE) */
int cp_ndrives; /* number of data transfer elements (CHET_DT) */
};
struct changer_vendor_params {
int cvp_n1; /* number of vendor specific elems (CHET_V1) */
char cvp_label1[16];
int cvp_n2; /* number of vendor specific elems (CHET_V2) */
char cvp_label2[16];
int cvp_n3; /* number of vendor specific elems (CHET_V3) */
char cvp_label3[16];
int cvp_n4; /* number of vendor specific elems (CHET_V4) */
char cvp_label4[16];
int reserved[8];
};
/*
* CHIOMOVE
* move a medium from one element to another
*/
struct changer_move {
int cm_fromtype; /* type/unit of source element */
int cm_fromunit;
int cm_totype; /* type/unit of destination element */
int cm_tounit;
int cm_flags;
};
#define CM_INVERT 1 /* flag: rotate media (for double-sided like MOD) */
/*
* CHIOEXCHANGE
* move one medium from element #1 to element #2,
* and another one from element #2 to element #3.
* element #1 and #3 are allowed to be identical.
*/
struct changer_exchange {
int ce_srctype; /* type/unit of element #1 */
int ce_srcunit;
int ce_fdsttype; /* type/unit of element #2 */
int ce_fdstunit;
int ce_sdsttype; /* type/unit of element #3 */
int ce_sdstunit;
int ce_flags;
};
#define CE_INVERT1 1
#define CE_INVERT2 2
/*
* CHIOPOSITION
* move the transport element (robot arm) to a specific element.
*/
struct changer_position {
int cp_type;
int cp_unit;
int cp_flags;
};
#define CP_INVERT 1
/*
* CHIOGSTATUS
* get element status for all elements of a specific type
*/
struct changer_element_status {
int ces_type;
unsigned char *ces_data;
};
#define CESTATUS_FULL 0x01 /* full */
#define CESTATUS_IMPEXP 0x02 /* media was imported (inserted by sysop) */
#define CESTATUS_EXCEPT 0x04 /* error condition */
#define CESTATUS_ACCESS 0x08 /* access allowed */
#define CESTATUS_EXENAB 0x10 /* element can export media */
#define CESTATUS_INENAB 0x20 /* element can import media */
/*
* CHIOGELEM
* get more detailed status informtion for a single element
*/
struct changer_get_element {
int cge_type; /* type/unit */
int cge_unit;
int cge_status; /* status */
int cge_errno; /* errno */
int cge_srctype; /* source element of the last move/exchange */
int cge_srcunit;
int cge_id; /* scsi id (for data transfer elements) */
int cge_lun; /* scsi lun (for data transfer elements) */
char cge_pvoltag[36]; /* primary volume tag */
char cge_avoltag[36]; /* alternate volume tag */
int cge_flags;
};
/* flags */
#define CGE_ERRNO 0x01 /* errno available */
#define CGE_INVERT 0x02 /* media inverted */
#define CGE_SRC 0x04 /* media src available */
#define CGE_IDLUN 0x08 /* ID+LUN available */
#define CGE_PVOLTAG 0x10 /* primary volume tag available */
#define CGE_AVOLTAG 0x20 /* alternate volume tag available */
/*
* CHIOSVOLTAG
* set volume tag
*/
struct changer_set_voltag {
int csv_type; /* type/unit */
int csv_unit;
char csv_voltag[36]; /* volume tag */
int csv_flags;
};
#define CSV_PVOLTAG 0x01 /* primary volume tag */
#define CSV_AVOLTAG 0x02 /* alternate volume tag */
#define CSV_CLEARTAG 0x04 /* clear volume tag */
/* ioctls */
#define CHIOMOVE _IOW('c', 1,struct changer_move)
#define CHIOEXCHANGE _IOW('c', 2,struct changer_exchange)
#define CHIOPOSITION _IOW('c', 3,struct changer_position)
#define CHIOGPICKER _IOR('c', 4,int) /* not impl. */
#define CHIOSPICKER _IOW('c', 5,int) /* not impl. */
#define CHIOGPARAMS _IOR('c', 6,struct changer_params)
#define CHIOGSTATUS _IOW('c', 8,struct changer_element_status)
#define CHIOGELEM _IOW('c',16,struct changer_get_element)
#define CHIOINITELEM _IO('c',17)
#define CHIOSVOLTAG _IOW('c',18,struct changer_set_voltag)
#define CHIOGVPARAMS _IOR('c',19,struct changer_vendor_params)
/* ---------------------------------------------------------------------- */
/*
* Local variables:
* c-basic-offset: 8
* End:
*/

View file

@ -100,6 +100,7 @@
#define I2O_MAJOR 80 /* 80->87 */
#define SHMIQ_MAJOR 85 /* Linux/mips, SGI /dev/shmiq */
#define SCSI_CHANGER_MAJOR 86
#define IDE6_MAJOR 88
#define IDE7_MAJOR 89

View file

@ -41,6 +41,7 @@ extern const char *const scsi_device_types[MAX_SCSI_DEVICE_CODE];
#define FORMAT_UNIT 0x04
#define READ_BLOCK_LIMITS 0x05
#define REASSIGN_BLOCKS 0x07
#define INITIALIZE_ELEMENT_STATUS 0x07
#define READ_6 0x08
#define WRITE_6 0x0a
#define SEEK_6 0x0b
@ -65,6 +66,7 @@ extern const char *const scsi_device_types[MAX_SCSI_DEVICE_CODE];
#define READ_10 0x28
#define WRITE_10 0x2a
#define SEEK_10 0x2b
#define POSITION_TO_ELEMENT 0x2b
#define WRITE_VERIFY 0x2e
#define VERIFY 0x2f
#define SEARCH_HIGH 0x30
@ -97,6 +99,7 @@ extern const char *const scsi_device_types[MAX_SCSI_DEVICE_CODE];
#define PERSISTENT_RESERVE_OUT 0x5f
#define REPORT_LUNS 0xa0
#define MOVE_MEDIUM 0xa5
#define EXCHANGE_MEDIUM 0xa6
#define READ_12 0xa8
#define WRITE_12 0xaa
#define WRITE_VERIFY_12 0xae
@ -210,6 +213,7 @@ static inline int scsi_status_is_good(int status)
#define TYPE_COMM 0x09 /* Communications device */
#define TYPE_ENCLOSURE 0x0d /* Enclosure Services Device */
#define TYPE_RAID 0x0c
#define TYPE_RBC 0x0e
#define TYPE_NO_LUN 0x7f
/*

View file

@ -154,7 +154,9 @@ struct scsi_target {
unsigned int id; /* target id ... replace
* scsi_device.id eventually */
unsigned long create:1; /* signal that it needs to be added */
unsigned long starget_data[0];
void *hostdata; /* available to low-level driver */
unsigned long starget_data[0]; /* for the transport */
/* starget_data must be the last element!!!! */
} __attribute__((aligned(sizeof(unsigned long))));
#define to_scsi_target(d) container_of(d, struct scsi_target, dev)

View file

@ -10,6 +10,7 @@ struct block_device;
struct module;
struct scsi_cmnd;
struct scsi_device;
struct scsi_target;
struct Scsi_Host;
struct scsi_host_cmd_pool;
struct scsi_transport_template;
@ -227,6 +228,30 @@ struct scsi_host_template {
*/
void (* slave_destroy)(struct scsi_device *);
/*
* Before the mid layer attempts to scan for a new device attached
* to a target where no target currently exists, it will call this
* entry in your driver. Should your driver need to allocate any
* structs or perform any other init items in order to send commands
* to a currently unused target, then this is where you can perform
* those allocations.
*
* Return values: 0 on success, non-0 on failure
*
* Status: OPTIONAL
*/
int (* target_alloc)(struct scsi_target *);
/*
* Immediately prior to deallocating the target structure, and
* after all activity to attached scsi devices has ceased, the
* midlayer calls this point so that the driver may deallocate
* and terminate any references to the target.
*
* Status: OPTIONAL
*/
void (* target_destroy)(struct scsi_target *);
/*
* fill in this function to allow the queue depth of this host
* to be changeable (on a per device basis). returns either

View file

@ -21,6 +21,7 @@
#define SCSI_TRANSPORT_H
#include <linux/transport_class.h>
#include <scsi/scsi_host.h>
struct scsi_transport_template {
/* the attribute containers */
@ -32,8 +33,11 @@ struct scsi_transport_template {
* space of this size will be left at the end of the
* scsi_* structure */
int device_size;
int device_private_offset;
int target_size;
int target_private_offset;
int host_size;
/* no private offset for the host; there's an alternative mechanism */
/*
* True if the transport wants to use a host-based work-queue
@ -45,4 +49,38 @@ struct scsi_transport_template {
dev_to_shost((tc)->dev)
/* Private area maintenance. The driver requested allocations come
* directly after the transport class allocations (if any). The idea
* is that you *must* call these only once. The code assumes that the
* initial values are the ones the transport specific code requires */
static inline void
scsi_transport_reserve_target(struct scsi_transport_template * t, int space)
{
BUG_ON(t->target_private_offset != 0);
t->target_private_offset = ALIGN(t->target_size, sizeof(void *));
t->target_size = t->target_private_offset + space;
}
static inline void
scsi_transport_reserve_device(struct scsi_transport_template * t, int space)
{
BUG_ON(t->device_private_offset != 0);
t->device_private_offset = ALIGN(t->device_size, sizeof(void *));
t->device_size = t->device_private_offset + space;
}
static inline void *
scsi_transport_target_data(struct scsi_target *starget)
{
struct Scsi_Host *shost = dev_to_shost(&starget->dev);
return (u8 *)starget->starget_data
+ shost->transportt->target_private_offset;
}
static inline void *
scsi_transport_device_data(struct scsi_device *sdev)
{
struct Scsi_Host *shost = sdev->host;
return (u8 *)sdev->sdev_data
+ shost->transportt->device_private_offset;
}
#endif /* SCSI_TRANSPORT_H */