mirror of
https://github.com/SCST-project/scst.git
synced 2026-07-25 01:23:14 +00:00
Merge branch 'svn-trunk'
This commit is contained in:
@@ -1,27 +0,0 @@
|
||||
diff -uprN -X/home/stasiu/work/linux-2.6/Documentation/dontdiff qla_isp/linux/isp_pci.c qla_isp-1.0.0/linux/isp_pci.c
|
||||
--- qla_isp/linux/isp_pci.c 2008-07-08 09:38:11.000000000 +0200
|
||||
+++ qla_isp-1.0.0/linux/isp_pci.c 2008-07-06 12:50:35.000000000 +0200
|
||||
@@ -536,10 +536,7 @@
|
||||
if (isp_debug) {
|
||||
isp->isp_dblev = isp_debug;
|
||||
} else {
|
||||
- isp->isp_dblev = ISP_LOGCONFIG|ISP_LOGINFO|ISP_LOGWARN|ISP_LOGERR;
|
||||
-#ifdef ISP_TARGET_MODE
|
||||
- isp->isp_dblev |= ISP_LOGTINFO;
|
||||
-#endif
|
||||
+ isp->isp_dblev = ISP_LOGERR;
|
||||
}
|
||||
|
||||
pci_read_config_word(pdev, PCI_COMMAND, &cmd);
|
||||
diff -uprN -X/home/stasiu/work/linux-2.6/Documentation/dontdiff qla_isp/linux/isp_scst.c qla_isp-1.0.0/linux/isp_scst.c
|
||||
--- qla_isp/linux/isp_scst.c 2008-07-08 09:38:11.000000000 +0200
|
||||
+++ qla_isp-1.0.0/linux/isp_scst.c 2008-07-06 12:49:07.000000000 +0200
|
||||
@@ -156,7 +156,7 @@ struct bus {
|
||||
struct scst_proc_data proc_data;
|
||||
};
|
||||
|
||||
-#define DEBUG 1
|
||||
+//#define DEBUG 1
|
||||
|
||||
#ifdef DEBUG
|
||||
#define SDprintk if (debug) printk
|
||||
@@ -1,45 +0,0 @@
|
||||
Summary of changes between versions 1.0.1 and 1.0.2
|
||||
---------------------------------------------------
|
||||
|
||||
- Support for 2532 chipset (8Gb/s).
|
||||
|
||||
- Fixed random firmware crash during startup.
|
||||
|
||||
- Fixed problem with N_port login.
|
||||
|
||||
- Synchronize with mainline Feral repository (various low level fixes).
|
||||
|
||||
- Firmware update, (again) add firmware with multichannel support.
|
||||
|
||||
- Fixed oops when stopping kernel thread.
|
||||
|
||||
- Fixed residual setting for 21xx/22xx/23xx chipsets.
|
||||
|
||||
- Fixed WWN setting for cards with scrambled NVRAM.
|
||||
|
||||
- Print information about loop state, link speed and topology in human
|
||||
readable form.
|
||||
|
||||
- Compilation fixes for kernel up to 2.6.32
|
||||
|
||||
Summary of changes between versions 1.0.0 and 1.0.1
|
||||
---------------------------------------------------
|
||||
|
||||
- Rewritten DMA mappings code.
|
||||
|
||||
- Fixed resources leakage when disabling target during pending I/O operations.
|
||||
|
||||
- Fixed 64 bit Type 3 request breakage.
|
||||
|
||||
- Recovery from not being able to push CTIO fix.
|
||||
|
||||
- Various task management fixes.
|
||||
|
||||
- Fixed OOPS when firmware provide bad VPIDX number.
|
||||
|
||||
- Fixed 24xx startup problems.
|
||||
|
||||
- In driver firmware images update.
|
||||
|
||||
- Various compilation fixes for different gcc and linux kernel versions.
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
Sat Aug 22 21:06:07 PDT 2009
|
||||
|
||||
Firmware binary modules provided by QLogic may be loaded with the standard
|
||||
linux firmware blob mechanism, and in fact this is the default.
|
||||
|
||||
It should be noted that pulling random firmware blobs will get random
|
||||
results. For example, 4.4.5 seems to crash and burn with target mode
|
||||
here on 24XX cards. Normally this would be a cause for panic, yet the
|
||||
more recent 4.6.0 version works fine. The trouble is that this firmware
|
||||
may not be available in binary from the QLogic ftp site.
|
||||
|
||||
You can either hack on Makefile definies and compile in the QLogic firmware
|
||||
sets included herein, or use the fwbin tool in the firmware directory to
|
||||
make your own binary modules.
|
||||
|
||||
If you want multi-id firmware support enabled for the binaries built
|
||||
with the fwbin module, change the in fwbin from
|
||||
|
||||
dowr '#define ISP_2400 1'
|
||||
dowr '#define ISP_2500 1'
|
||||
|
||||
to
|
||||
|
||||
dowr '#define ISP_2400_MULTI 1'
|
||||
dowr '#define ISP_2500_MULTI 1'
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
Copyright (c) 1997-2009 by Matthew Jacob
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
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 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
|
||||
|
||||
Alternatively, this software may be distributed under the terms of the
|
||||
the GNU Public License ("GPL") with platforms where the prevalant license
|
||||
is the GNU Public License:
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of The Version 2 GNU General Public License as published
|
||||
by the Free Software Foundation.
|
||||
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program.
|
||||
|
||||
|
||||
Matthew Jacob
|
||||
Feral Software
|
||||
421 Laurel Avenue
|
||||
Menlo Park, CA 94025
|
||||
USA
|
||||
|
||||
gplbsd at feral com
|
||||
|
||||
$Id: LICENSE,v 1.10 2008/02/11 23:59:06 mjacob Exp $
|
||||
@@ -1,25 +0,0 @@
|
||||
ifndef KVER
|
||||
KVER = $(shell uname -r)
|
||||
endif
|
||||
|
||||
ifndef KDIR
|
||||
KDIR := /lib/modules/$(KVER)/build
|
||||
endif
|
||||
|
||||
export KDIR
|
||||
|
||||
all:
|
||||
$(MAKE) -C linux-2.6 tgt
|
||||
|
||||
clean:
|
||||
$(MAKE) -C linux-2.6 clean
|
||||
|
||||
extraclean:
|
||||
$(MAKE) -C linux-2.6 extraclean
|
||||
|
||||
install:
|
||||
$(MAKE) -C linux-2.6 install
|
||||
|
||||
uninstall:
|
||||
$(MAKE) -C linux-2.6 uninstall
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
$Id: README,v 1.32 2009/05/02 23:25:49 mjacob Exp $
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
Supported Cards:
|
||||
|
||||
SBus ISP1000 && ISP1000U
|
||||
PCI SCSI ISP1020
|
||||
PCI Ultra SCSI ISP1040, ISP1240 (dual bus)
|
||||
PCI Ultra2 SCSI ISP1080, ISP1280 (dual bus)
|
||||
PCI Ultra3 SCSI ISP12160 (dual bus)
|
||||
PCI Fibre Channel
|
||||
1-Gbit:
|
||||
ISP2100, ISP2102
|
||||
ISP2200, ISP2202, ISP2204
|
||||
|
||||
2-Gbit:
|
||||
ISP2300, ISP2312, ISP2324, 2340, 2342
|
||||
ISP2322, ISP6322
|
||||
ISP200
|
||||
4-Gbit:
|
||||
ISP2422, ISP2432
|
||||
|
||||
8-GBit:
|
||||
ISP2532
|
||||
|
||||
You should note that some old non-Qlogic (or very old Qlogic) 2100 cards may
|
||||
have trouble loading firmware. The newer f/w for 2100s is > 0x8000 words,
|
||||
which PROM code on some cards has trouble loading- define the token
|
||||
USE_SMALLER_2100_FIRMWARE to select 1.15.37 f/w for the 2100.
|
||||
|
||||
For 23XX (but not 2322) 2K Login firmware is available and is the detfault.
|
||||
------------------------------------------------------------------------------
|
||||
@@ -1,162 +0,0 @@
|
||||
INTRODUCTION
|
||||
|
||||
This is an SCST driver for ISP Qlogic chipsets commonly used in many SCSI and
|
||||
FC host bus adapters. Supported chipsets are listed in the README file.
|
||||
|
||||
It is based on Matthew Jacob's multiplatform driver for ISP chipsets,
|
||||
which has its own page at http://www.feral.com/isp.html . The update for SCST
|
||||
was made by Stanislaw Gruszka <stf_xl@wp.pl> for Open-E Inc.
|
||||
|
||||
Driver operates on the same hardware as qla2x00t, but has one notable
|
||||
advantage over it: support of 24xx and 25xx series of Qlogic adapters.
|
||||
From other side, qla2x00t is simpler, smaller and much better tested
|
||||
on 22xx and 23xx, hence perform more reliable and, thus, is recommended
|
||||
for these adapters. Since 24xx/25xx become fully supported on qla2x00t we
|
||||
encourage users to switch to this driver.
|
||||
|
||||
INSTALLATION
|
||||
|
||||
Build driver with the following command
|
||||
$ make
|
||||
|
||||
Copy the firmware image appropriate for your HBA from the Qlogic server
|
||||
http://ldriver.qlogic.com/firmware/ to one of the Linux firmware
|
||||
loader directories (e.g. /lib/firmware, see the udev/hotplug documentation
|
||||
for your distribution).
|
||||
|
||||
The next step depends on whether you have other QLA modules installed. Note
|
||||
that you can't load an ISP driver when you build other Qlogic drivers in the
|
||||
kernel (kerel oops may occur). Other QLA modules are acceptable, but extra
|
||||
care is needed, first copy modules to a directory, e.g.:
|
||||
|
||||
$ mkdir /root/qla_isp
|
||||
$ cp linux-2.6/build/*.ko /root/qla_isp
|
||||
|
||||
Each time you want to run qla_isp, unload all other qla modules
|
||||
|
||||
$ rmmod qla2x00tgt
|
||||
$ rmmod qla2400
|
||||
$ rmmod qla2300
|
||||
$ rmmod qla2200
|
||||
$ rmmod qla2xxx
|
||||
|
||||
and load ISP modules directly from the created directory, e.g.:
|
||||
|
||||
$ insmod /root/qla_isp/isp_scst.ko
|
||||
$ insmod /root/qla_isp/isp_mod.ko
|
||||
|
||||
If you have neither other QLA drivers from SCST (qla2x00tgt) nor kernel
|
||||
(qla2xxx and friends) you can install in the standard /lib/modules directory:
|
||||
|
||||
$ make install
|
||||
$ depmod -ea
|
||||
|
||||
Then load the drivers manually the first time :
|
||||
|
||||
$ modprobe isp_scst
|
||||
$ modprobe isp_mod
|
||||
|
||||
Now whenever the system is booted and a QLA card is plugged, modules will load
|
||||
automatically.
|
||||
|
||||
When the driver is loaded, enable all channels for each HBA to work in target
|
||||
mode. For Fibre Channel adapters you need to write the "enable all" string
|
||||
into the procfs configuration file, e.g.:
|
||||
|
||||
$ echo "enable all" > /proc/scsi_tgt/qla_isp/3
|
||||
|
||||
To unload the isp_mod.ko module you must disable target mode for all cards,
|
||||
e.g.:
|
||||
|
||||
$ echo "disable all" > /proc/scsi_tgt/qla_isp/3
|
||||
$ echo "disable all" > /proc/scsi_tgt/qla_isp/4
|
||||
|
||||
To attach logical units continue with normal SCST setup.
|
||||
|
||||
SELECTING FIRMWARE
|
||||
|
||||
The firmware loading interface allows for choosing the appropriate firmware.
|
||||
However, some firmware images are not available from the Qlogic site, e.g.
|
||||
firmware with multichannel support. That is why you can build a firmware
|
||||
image into the isp_mod module. At the beginning of the isp_linux.h file you
|
||||
need to add the following line:
|
||||
|
||||
#define DISABLE_FW_LOADER 1
|
||||
|
||||
Then, if you load module with isp_vports parameter > 0, driver will use
|
||||
multichannel firmware.
|
||||
|
||||
SUPPORTED DEVICES
|
||||
|
||||
You can disable support for selected chipsets by editing the isp_linux.h file.
|
||||
In the following example, only the 2400 chipset is enabled:
|
||||
|
||||
#define ISP_DISABLE_1080_SUPPORT 1
|
||||
#define ISP_DISABLE_12160_SUPPORT 1
|
||||
#define ISP_DISABLE_2100_SUPPORT 1
|
||||
#define ISP_DISABLE_2200_SUPPORT 1
|
||||
#define ISP_DISABLE_2300_SUPPORT 1
|
||||
#define ISP_DISABLE_2322_SUPPORT 1
|
||||
//#define ISP_DISABLE_2400_SUPPORT 1
|
||||
|
||||
TARGET/INITIATOR ROLES
|
||||
|
||||
The driver can work as either a target or an initiator. Prior to performing
|
||||
the compilation you can establish the default mode the driver will work in
|
||||
by editing the file linux-2.6/build/Makefile - you need to set one of the
|
||||
following values instead of ISP_ROLE_NONE
|
||||
in -DISP_DEFAULT_ROLES=ISP_ROLE_NONE
|
||||
|
||||
ISP_ROLE_TARGET
|
||||
ISP_ROLE_INITIATOR
|
||||
ISP_ROLE_BOTH
|
||||
|
||||
You can also establish the driver role during module initialization using the
|
||||
isp_roles option, e.g:
|
||||
|
||||
$ modprobe isp_mod isp_roles="b0300=initiator"
|
||||
|
||||
Number "b0300" is a DEVID value based on an address on the PCI bus, which you
|
||||
can find in /proc/scsi/isp/N. Target role will be enabled automatically when
|
||||
activating channels/LUNs in /proc/scsi_tgt/qla_isp/N .
|
||||
|
||||
The driver can also work as both a target and an initiator simultaneously, but
|
||||
this will probably only function for P2P connections. To make the driver work
|
||||
as a target/initiator on one port with a FC switch, you can use N_PORT ID
|
||||
virtualization, as seen below.
|
||||
|
||||
N_PORT ID VIRTUALIZATION
|
||||
|
||||
You can add an isp_vports option to the ISP module. It denotes the number of
|
||||
ports(channels) and cannot be greater than 127. Each vport has its own WWN.
|
||||
From the driver point of view each vport is a separate channel. You can define
|
||||
separate role for each of the channels.
|
||||
|
||||
Note that firmware that supports multiple ids must be used.
|
||||
|
||||
PROCFS INTERFACE
|
||||
|
||||
Target configuration interface is located in the following file:
|
||||
/proc/scsi_tgt/qla_isp/N ; where N is the Linux SCSI host number and
|
||||
is the same as for proc/scsi/isp/N and /sys/class/scsi_host/hostN files.
|
||||
|
||||
The process for enabling options for this file is different for FC and SPI
|
||||
devices. For FC it is enabling/disabling channels, while SPI it is
|
||||
enabling/disabling channels and logical units. For example:
|
||||
FC:
|
||||
$ echo "enable 5" > /proc/scsi_tgt/qla_isp/4
|
||||
|
||||
SPI:
|
||||
$ echo "enable 0 1" > /proc/scsi_tgt/qla_isp/5
|
||||
|
||||
You may use the string "all" instead of a number e.g.:
|
||||
|
||||
$echo "disable all all" > /proc/scsi_tgt/qla_isp/5
|
||||
|
||||
When all LUNs and channels are disabled, the target role will also become
|
||||
inactive. For N_PORT ID virtualization, when enabling channels, you need to
|
||||
first enable channel 0; when disabling channels, you need to disable channel
|
||||
0 last.
|
||||
|
||||
Send questions about this driver to scst-devel@lists.sourceforge.net, CC
|
||||
Matthew Jacob <lydianconcepts@gmail.com> and Stanislaw Gruszka <stf_xl@wp.pl>.
|
||||
@@ -1 +0,0 @@
|
||||
r1266 - qla_isp-1.0.2
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,238 +0,0 @@
|
||||
/* $Id: isp_library.h,v 1.35 2009/05/10 16:25:09 mjacob Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 1997-2009 by Matthew Jacob
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* 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 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of the
|
||||
* the GNU Public License ("GPL") with platforms where the prevalant license
|
||||
* is the GNU Public License:
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of The Version 2 GNU General Public License as published
|
||||
* by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program.
|
||||
*
|
||||
*
|
||||
* Matthew Jacob
|
||||
* Feral Software
|
||||
* 421 Laurel Avenue
|
||||
* Menlo Park, CA 94025
|
||||
* USA
|
||||
*
|
||||
* gplbsd at feral com
|
||||
*/
|
||||
#ifndef _ISP_LIBRARY_H
|
||||
#define _ISP_LIBRARY_H
|
||||
|
||||
/*
|
||||
* Common command shipping routine.
|
||||
*
|
||||
* This used to be platform specific, but basically once you get the segment
|
||||
* stuff figured out, you can make all the code in one spot.
|
||||
*/
|
||||
typedef enum { ISP_TO_DEVICE, ISP_FROM_DEVICE, ISP_NOXFR} isp_ddir_t;
|
||||
int isp_send_cmd(ispsoftc_t *, void *, void *, uint32_t, uint32_t, isp_ddir_t);
|
||||
|
||||
/*
|
||||
* Handle management functions.
|
||||
*
|
||||
* These handles are associate with a command.
|
||||
*/
|
||||
int isp_save_xs(ispsoftc_t *, XS_T *, uint32_t *);
|
||||
XS_T * isp_find_xs(ispsoftc_t *, uint32_t);
|
||||
uint32_t isp_find_handle(ispsoftc_t *, XS_T *);
|
||||
uint32_t isp_handle_index(uint32_t);
|
||||
void isp_destroy_handle(ispsoftc_t *, uint32_t);
|
||||
|
||||
/*
|
||||
* Request Queue allocation
|
||||
*/
|
||||
void *isp_getrqentry(ispsoftc_t *);
|
||||
|
||||
/*
|
||||
* Queue Entry debug functions
|
||||
*/
|
||||
void isp_print_qentry (ispsoftc_t *, const char *, int, void *);
|
||||
void isp_print_bytes(ispsoftc_t *, const char *, int, void *);
|
||||
|
||||
/*
|
||||
* Fibre Channel specific routines and data.
|
||||
*/
|
||||
extern const char *isp_class3_roles[4];
|
||||
int isp_fc_runstate(ispsoftc_t *, int, int);
|
||||
void isp_dump_portdb(ispsoftc_t *, int);
|
||||
|
||||
const char *isp_fc_fw_statename(int);
|
||||
const char *isp_fc_loop_statename(int);
|
||||
const char *isp_fc_toponame(fcparam *);
|
||||
|
||||
int isp_fc_change_role(ispsoftc_t *, int, int);
|
||||
|
||||
|
||||
/*
|
||||
* Cleanup
|
||||
*/
|
||||
void isp_clear_commands(ispsoftc_t *);
|
||||
|
||||
/*
|
||||
* Common chip shutdown function
|
||||
*/
|
||||
void isp_shutdown(ispsoftc_t *);
|
||||
|
||||
/*
|
||||
* Put/Get routines to push from CPU view to device view
|
||||
* or to pull from device view to CPU view for various
|
||||
* data structures (IOCB)
|
||||
*/
|
||||
void isp_put_hdr(ispsoftc_t *, isphdr_t *, isphdr_t *);
|
||||
void isp_get_hdr(ispsoftc_t *, isphdr_t *, isphdr_t *);
|
||||
int isp_get_response_type(ispsoftc_t *, isphdr_t *);
|
||||
void isp_put_request(ispsoftc_t *, ispreq_t *, ispreq_t *);
|
||||
void isp_put_marker(ispsoftc_t *, isp_marker_t *, isp_marker_t *);
|
||||
void isp_put_marker_24xx(ispsoftc_t *, isp_marker_24xx_t *, isp_marker_24xx_t *);
|
||||
void isp_put_request_t2(ispsoftc_t *, ispreqt2_t *, ispreqt2_t *);
|
||||
void isp_put_request_t2e(ispsoftc_t *, ispreqt2e_t *, ispreqt2e_t *);
|
||||
void isp_put_request_t3(ispsoftc_t *, ispreqt3_t *, ispreqt3_t *);
|
||||
void isp_put_request_t3e(ispsoftc_t *, ispreqt3e_t *, ispreqt3e_t *);
|
||||
void isp_put_extended_request(ispsoftc_t *, ispextreq_t *, ispextreq_t *);
|
||||
void isp_put_request_t7(ispsoftc_t *, ispreqt7_t *, ispreqt7_t *);
|
||||
void isp_put_24xx_tmf(ispsoftc_t *, isp24xx_tmf_t *, isp24xx_tmf_t *);
|
||||
void isp_put_24xx_abrt(ispsoftc_t *, isp24xx_abrt_t *, isp24xx_abrt_t *);
|
||||
void isp_put_cont_req(ispsoftc_t *, ispcontreq_t *, ispcontreq_t *);
|
||||
void isp_put_cont64_req(ispsoftc_t *, ispcontreq64_t *, ispcontreq64_t *);
|
||||
void isp_get_response(ispsoftc_t *, ispstatusreq_t *, ispstatusreq_t *);
|
||||
void isp_get_24xx_response(ispsoftc_t *, isp24xx_statusreq_t *, isp24xx_statusreq_t *);
|
||||
void isp_get_24xx_abrt(ispsoftc_t *, isp24xx_abrt_t *, isp24xx_abrt_t *);
|
||||
void isp_get_rio2(ispsoftc_t *, isp_rio2_t *, isp_rio2_t *);
|
||||
void isp_put_icb(ispsoftc_t *, isp_icb_t *, isp_icb_t *);
|
||||
void isp_put_icb_2400(ispsoftc_t *, isp_icb_2400_t *, isp_icb_2400_t *);
|
||||
void isp_put_icb_2400_vpinfo(ispsoftc_t *, isp_icb_2400_vpinfo_t *, isp_icb_2400_vpinfo_t *);
|
||||
void isp_put_vp_port_info(ispsoftc_t *, vp_port_info_t *, vp_port_info_t *);
|
||||
void isp_get_vp_port_info(ispsoftc_t *, vp_port_info_t *, vp_port_info_t *);
|
||||
void isp_put_vp_ctrl_info(ispsoftc_t *, vp_ctrl_info_t *, vp_ctrl_info_t *);
|
||||
void isp_get_vp_ctrl_info(ispsoftc_t *, vp_ctrl_info_t *, vp_ctrl_info_t *);
|
||||
void isp_put_vp_modify(ispsoftc_t *, vp_modify_t *, vp_modify_t *);
|
||||
void isp_get_vp_modify(ispsoftc_t *, vp_modify_t *, vp_modify_t *);
|
||||
void isp_get_pdb_21xx(ispsoftc_t *, isp_pdb_21xx_t *, isp_pdb_21xx_t *);
|
||||
void isp_get_pdb_24xx(ispsoftc_t *, isp_pdb_24xx_t *, isp_pdb_24xx_t *);
|
||||
void isp_get_ridacq(ispsoftc_t *, isp_ridacq_t *, isp_ridacq_t *);
|
||||
void isp_get_plogx(ispsoftc_t *, isp_plogx_t *, isp_plogx_t *);
|
||||
void isp_put_plogx(ispsoftc_t *, isp_plogx_t *, isp_plogx_t *);
|
||||
void isp_get_ct_pt(ispsoftc_t *isp, isp_ct_pt_t *, isp_ct_pt_t *);
|
||||
void isp_get_ms(ispsoftc_t *isp, isp_ms_t *, isp_ms_t *);
|
||||
void isp_put_ct_pt(ispsoftc_t *isp, isp_ct_pt_t *, isp_ct_pt_t *);
|
||||
void isp_put_ms(ispsoftc_t *isp, isp_ms_t *, isp_ms_t *);
|
||||
void isp_put_sns_request(ispsoftc_t *, sns_screq_t *, sns_screq_t *);
|
||||
void isp_put_gid_ft_request(ispsoftc_t *, sns_gid_ft_req_t *, sns_gid_ft_req_t *);
|
||||
void isp_put_gxn_id_request(ispsoftc_t *, sns_gxn_id_req_t *, sns_gxn_id_req_t *);
|
||||
void isp_get_sns_response(ispsoftc_t *, sns_scrsp_t *, sns_scrsp_t *, int);
|
||||
void isp_get_gid_ft_response(ispsoftc_t *, sns_gid_ft_rsp_t *, sns_gid_ft_rsp_t *, int);
|
||||
void isp_get_gxn_id_response(ispsoftc_t *, sns_gxn_id_rsp_t *, sns_gxn_id_rsp_t *);
|
||||
void isp_get_gff_id_response(ispsoftc_t *, sns_gff_id_rsp_t *, sns_gff_id_rsp_t *);
|
||||
void isp_get_ga_nxt_response(ispsoftc_t *, sns_ga_nxt_rsp_t *, sns_ga_nxt_rsp_t *);
|
||||
void isp_get_els(ispsoftc_t *, els_t *, els_t *);
|
||||
void isp_put_els(ispsoftc_t *, els_t *, els_t *);
|
||||
void isp_get_fc_hdr(ispsoftc_t *, fc_hdr_t *, fc_hdr_t *);
|
||||
void isp_get_fcp_cmnd_iu(ispsoftc_t *, fcp_cmnd_iu_t *, fcp_cmnd_iu_t *);
|
||||
void isp_put_rft_id(ispsoftc_t *, rft_id_t *, rft_id_t *);
|
||||
void isp_get_ct_hdr(ispsoftc_t *isp, ct_hdr_t *, ct_hdr_t *);
|
||||
void isp_put_ct_hdr(ispsoftc_t *isp, ct_hdr_t *, ct_hdr_t *);
|
||||
|
||||
#define ISP_HANDLE_MASK 0x7fff
|
||||
|
||||
#ifdef ISP_TARGET_MODE
|
||||
#if defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
#include <dev/ic/isp_target.h>
|
||||
#elif defined(__FreeBSD__)
|
||||
#include <dev/isp/isp_target.h>
|
||||
#else
|
||||
#include "isp_target.h"
|
||||
#endif
|
||||
|
||||
int isp_send_tgt_cmd(ispsoftc_t *, void *, void *, uint32_t, uint32_t, isp_ddir_t, void *, uint32_t);
|
||||
|
||||
#define IS_TARGET_HANDLE(x) ((x) & 0x8000)
|
||||
|
||||
int isp_save_xs_tgt(ispsoftc_t *, void *, uint32_t *);
|
||||
void *isp_find_xs_tgt(ispsoftc_t *, uint32_t);
|
||||
uint32_t isp_find_tgt_handle(ispsoftc_t *, void *);
|
||||
void isp_destroy_tgt_handle(ispsoftc_t *, uint32_t);
|
||||
|
||||
int isp_find_pdb_by_wwn(ispsoftc_t *, int, uint64_t, fcportdb_t **);
|
||||
int isp_find_pdb_by_loopid(ispsoftc_t *, int, uint32_t, fcportdb_t **);
|
||||
int isp_find_pdb_by_sid(ispsoftc_t *, int, uint32_t, fcportdb_t **);
|
||||
void isp_find_chan_by_did(ispsoftc_t *, uint32_t, uint16_t *);
|
||||
void isp_add_wwn_entry(ispsoftc_t *, int, uint64_t, uint16_t, uint32_t);
|
||||
void isp_del_wwn_entry(ispsoftc_t *, int, uint64_t, uint16_t, uint32_t);
|
||||
void isp_del_all_wwn_entries(ispsoftc_t *, int);
|
||||
void isp_del_wwn_entries(ispsoftc_t *, isp_notify_t *);
|
||||
|
||||
void isp_put_atio(ispsoftc_t *, at_entry_t *, at_entry_t *);
|
||||
void isp_get_atio(ispsoftc_t *, at_entry_t *, at_entry_t *);
|
||||
void isp_put_atio2(ispsoftc_t *, at2_entry_t *, at2_entry_t *);
|
||||
void isp_put_atio2e(ispsoftc_t *, at2e_entry_t *, at2e_entry_t *);
|
||||
void isp_get_atio2(ispsoftc_t *, at2_entry_t *, at2_entry_t *);
|
||||
void isp_get_atio2e(ispsoftc_t *, at2e_entry_t *, at2e_entry_t *);
|
||||
void isp_get_atio7(ispsoftc_t *isp, at7_entry_t *, at7_entry_t *);
|
||||
void isp_put_ctio(ispsoftc_t *, ct_entry_t *, ct_entry_t *);
|
||||
void isp_get_ctio(ispsoftc_t *, ct_entry_t *, ct_entry_t *);
|
||||
void isp_put_ctio2(ispsoftc_t *, ct2_entry_t *, ct2_entry_t *);
|
||||
void isp_put_ctio2e(ispsoftc_t *, ct2e_entry_t *, ct2e_entry_t *);
|
||||
void isp_put_ctio7(ispsoftc_t *, ct7_entry_t *, ct7_entry_t *);
|
||||
void isp_get_ctio2(ispsoftc_t *, ct2_entry_t *, ct2_entry_t *);
|
||||
void isp_get_ctio2e(ispsoftc_t *, ct2e_entry_t *, ct2e_entry_t *);
|
||||
void isp_get_ctio7(ispsoftc_t *, ct7_entry_t *, ct7_entry_t *);
|
||||
void isp_put_enable_lun(ispsoftc_t *, lun_entry_t *, lun_entry_t *);
|
||||
void isp_get_enable_lun(ispsoftc_t *, lun_entry_t *, lun_entry_t *);
|
||||
void isp_put_notify(ispsoftc_t *, in_entry_t *, in_entry_t *);
|
||||
void isp_get_notify(ispsoftc_t *, in_entry_t *, in_entry_t *);
|
||||
void isp_put_notify_fc(ispsoftc_t *, in_fcentry_t *, in_fcentry_t *);
|
||||
void isp_put_notify_fc_e(ispsoftc_t *, in_fcentry_e_t *, in_fcentry_e_t *);
|
||||
void isp_put_notify_24xx(ispsoftc_t *, in_fcentry_24xx_t *, in_fcentry_24xx_t *);
|
||||
void isp_get_notify_fc(ispsoftc_t *, in_fcentry_t *, in_fcentry_t *);
|
||||
void isp_get_notify_fc_e(ispsoftc_t *, in_fcentry_e_t *, in_fcentry_e_t *);
|
||||
void isp_get_notify_24xx(ispsoftc_t *, in_fcentry_24xx_t *, in_fcentry_24xx_t *);
|
||||
void isp_put_notify_ack(ispsoftc_t *, na_entry_t *, na_entry_t *);
|
||||
void isp_get_notify_ack(ispsoftc_t *, na_entry_t *, na_entry_t *);
|
||||
void isp_put_notify_24xx_ack(ispsoftc_t *, na_fcentry_24xx_t *, na_fcentry_24xx_t *);
|
||||
void isp_put_notify_ack_fc(ispsoftc_t *, na_fcentry_t *, na_fcentry_t *);
|
||||
void isp_put_notify_ack_fc_e(ispsoftc_t *, na_fcentry_e_t *, na_fcentry_e_t *);
|
||||
void isp_put_notify_ack_24xx(ispsoftc_t *, na_fcentry_24xx_t *, na_fcentry_24xx_t *);
|
||||
void isp_get_notify_ack_fc(ispsoftc_t *, na_fcentry_t *, na_fcentry_t *);
|
||||
void isp_get_notify_ack_fc_e(ispsoftc_t *, na_fcentry_e_t *, na_fcentry_e_t *);
|
||||
void isp_get_notify_ack_24xx(ispsoftc_t *, na_fcentry_24xx_t *, na_fcentry_24xx_t *);
|
||||
void isp_get_abts(ispsoftc_t *, abts_t *, abts_t *);
|
||||
void isp_put_abts_rsp(ispsoftc_t *, abts_rsp_t *, abts_rsp_t *);
|
||||
void isp_get_abts_rsp(ispsoftc_t *, abts_rsp_t *, abts_rsp_t *);
|
||||
#endif /* ISP_TARGET_MODE */
|
||||
#endif /* _ISP_LIBRARY_H */
|
||||
@@ -1,253 +0,0 @@
|
||||
/* $Id: isp_stds.h,v 1.16 2009/03/30 04:19:19 mjacob Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 1997-2009 by Matthew Jacob
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* 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 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of the
|
||||
* the GNU Public License ("GPL") with platforms where the prevalant license
|
||||
* is the GNU Public License:
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of The Version 2 GNU General Public License as published
|
||||
* by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program.
|
||||
*
|
||||
*
|
||||
* Matthew Jacob
|
||||
* Feral Software
|
||||
* 421 Laurel Avenue
|
||||
* Menlo Park, CA 94025
|
||||
* USA
|
||||
*
|
||||
* gplbsd at feral com
|
||||
*/
|
||||
/*
|
||||
* Structures that derive directly from public standards.
|
||||
*/
|
||||
#ifndef _ISP_STDS_H
|
||||
#define _ISP_STDS_H
|
||||
|
||||
/*
|
||||
* FC Frame Header
|
||||
*
|
||||
* Source: dpANS-X3.xxx-199x, section 18 (AKA FC-PH-2)
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t r_ctl;
|
||||
uint8_t d_id[3];
|
||||
uint8_t cs_ctl;
|
||||
uint8_t s_id[3];
|
||||
uint8_t type;
|
||||
uint8_t f_ctl[3];
|
||||
uint8_t seq_id;
|
||||
uint8_t df_ctl;
|
||||
uint16_t seq_cnt;
|
||||
uint16_t ox_id;
|
||||
uint16_t rx_id;
|
||||
uint32_t parameter;
|
||||
} fc_hdr_t;
|
||||
|
||||
/*
|
||||
* FCP_CMND_IU Payload
|
||||
*
|
||||
* Source: NICTS T10, Project 1144D, Revision 07a, Section 9 (AKA fcp2-r07a)
|
||||
*
|
||||
* Notes:
|
||||
* When additional cdb length is defined in fcp_cmnd_alen_datadir,
|
||||
* bits 2..7, the actual cdb length is 16 + ((fcp_cmnd_alen_datadir>>2)*4),
|
||||
* with the datalength following in MSB format just after.
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t fcp_cmnd_lun[8];
|
||||
uint8_t fcp_cmnd_crn;
|
||||
uint8_t fcp_cmnd_task_attribute;
|
||||
uint8_t fcp_cmnd_task_management;
|
||||
uint8_t fcp_cmnd_alen_datadir;
|
||||
union {
|
||||
struct {
|
||||
uint8_t fcp_cmnd_cdb[16];
|
||||
uint32_t fcp_cmnd_dl;
|
||||
} sf;
|
||||
struct {
|
||||
uint8_t fcp_cmnd_cdb[1];
|
||||
} lf;
|
||||
} cdb_dl;
|
||||
} fcp_cmnd_iu_t;
|
||||
|
||||
|
||||
#define FCP_CMND_TASK_ATTR_SIMPLE 0x00
|
||||
#define FCP_CMND_TASK_ATTR_HEAD 0x01
|
||||
#define FCP_CMND_TASK_ATTR_ORDERED 0x02
|
||||
#define FCP_CMND_TASK_ATTR_ACA 0x04
|
||||
#define FCP_CMND_TASK_ATTR_UNTAGGED 0x05
|
||||
#define FCP_CMND_TASK_ATTR_MASK 0x07
|
||||
|
||||
#define FCP_CMND_ADDTL_CDBLEN_SHIFT 2
|
||||
|
||||
#define FCP_CMND_DATA_WRITE 0x01
|
||||
#define FCP_CMND_DATA_READ 0x02
|
||||
|
||||
#define FCP_CMND_DATA_DIR_MASK 0x03
|
||||
|
||||
#define FCP_CMND_TMF_CLEAR_ACA 0x40
|
||||
#define FCP_CMND_TMF_TGT_RESET 0x20
|
||||
#define FCP_CMND_TMF_LUN_RESET 0x10
|
||||
#define FCP_CMND_TMF_CLEAR_TASK_SET 0x04
|
||||
#define FCP_CMND_TMF_ABORT_TASK_SET 0x02
|
||||
|
||||
/*
|
||||
* Basic CT IU Header
|
||||
*
|
||||
* Source: X3.288-199x Generic Services 2 Rev 5.3 (FC-GS-2) Section 4.3.1
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
uint8_t ct_revision;
|
||||
uint8_t ct_in_id[3];
|
||||
uint8_t ct_fcs_type;
|
||||
uint8_t ct_fcs_subtype;
|
||||
uint8_t ct_options;
|
||||
uint8_t ct_reserved0;
|
||||
uint16_t ct_cmd_resp;
|
||||
uint16_t ct_bcnt_resid;
|
||||
uint8_t ct_reserved1;
|
||||
uint8_t ct_reason;
|
||||
uint8_t ct_explanation;
|
||||
uint8_t ct_vunique;
|
||||
} ct_hdr_t;
|
||||
#define CT_REVISION 1
|
||||
#define CT_FC_TYPE_FC 0xFC
|
||||
#define CT_FC_SUBTYPE_NS 0x02
|
||||
|
||||
/*
|
||||
* RFT_ID Requet CT_IU
|
||||
*
|
||||
* Source: NCITS xxx-200x Generic Services- 5 Rev 8.5 Section 5.2.5.30
|
||||
*/
|
||||
typedef struct {
|
||||
ct_hdr_t rftid_hdr;
|
||||
uint8_t rftid_reserved;
|
||||
uint8_t rftid_portid[3];
|
||||
uint32_t rftid_fc4types[8];
|
||||
} rft_id_t;
|
||||
|
||||
/*
|
||||
* FCP Response IU Bits of interest
|
||||
* Source: NCITS T10, Project 1144D, Revision 08 (aka FCP2r08)
|
||||
*/
|
||||
#define FCP_CONF_REQ 0x10
|
||||
#define FCP_RESID_UNDERFLOW 0x08
|
||||
#define FCP_RESID_OVERFLOW 0x04
|
||||
#define FCP_SNSLEN_VALID 0x02
|
||||
#define FCP_RSPLEN_VALID 0x01
|
||||
|
||||
#define FCP_MAX_RSPLEN 0x8
|
||||
/*
|
||||
* FCP Response Code Definitions
|
||||
* Source: NCITS T10, Project 1144D, Revision 08 (aka FCP2r08)
|
||||
*/
|
||||
#define FCP_RSPNS_CODE_OFFSET 3
|
||||
|
||||
#define FCP_RSPNS_TMF_DONE 0
|
||||
#define FCP_RSPNS_DLBRSTX 1
|
||||
#define FCP_RSPNS_BADCMND 2
|
||||
#define FCP_RSPNS_EROFS 3
|
||||
#define FCP_RSPNS_TMF_REJECT 4
|
||||
#define FCP_RSPNS_TMF_FAILED 5
|
||||
#define FCP_RSPNS_TMF_SUCCEEDED 8
|
||||
#define FCP_RSPNS_TMF_INCORRECT_LUN 9
|
||||
|
||||
|
||||
/* unconverted miscellany */
|
||||
/*
|
||||
* Basic FC Link Service defines
|
||||
*/
|
||||
/*
|
||||
* These are in the R_CTL field.
|
||||
*/
|
||||
#define ABTS 0x81
|
||||
#define BA_ACC 0x84 /* of ABORT SEQUENCE */
|
||||
#define BA_RJT 0x85 /* of ABORT SEQUENCE */
|
||||
|
||||
/*
|
||||
* Link Service Accept/Reject
|
||||
*/
|
||||
#define LS_ACC 0x8002
|
||||
#define LS_RJT 0x8001
|
||||
|
||||
/*
|
||||
* FC ELS Codes- bits 31-24 of the first payload word of an ELS frame.
|
||||
*/
|
||||
#define PLOGI 0x03
|
||||
#define FLOGI 0x04
|
||||
#define LOGO 0x05
|
||||
#define ABTX 0x06
|
||||
#define PRLI 0x20
|
||||
#define PRLO 0x21
|
||||
#define SCN 0x22
|
||||
#define TPRLO 0x24
|
||||
#define PDISC 0x50
|
||||
#define ADISC 0x52
|
||||
#define RNC 0x53
|
||||
|
||||
/*
|
||||
* FC4 defines
|
||||
*/
|
||||
#define FC4_IP 5 /* ISO/EEC 8802-2 LLC/SNAP */
|
||||
#define FC4_SCSI 8 /* SCSI-3 via Fibre Channel Protocol (FCP) */
|
||||
#define FC4_FC_SVC 0x20 /* Fibre Channel Services */
|
||||
|
||||
#ifndef MSG_ABORT
|
||||
#define MSG_ABORT 0x06
|
||||
#endif
|
||||
#ifndef MSG_BUS_DEV_RESET
|
||||
#define MSG_BUS_DEV_RESET 0x0c
|
||||
#endif
|
||||
#ifndef MSG_ABORT_TAG
|
||||
#define MSG_ABORT_TAG 0x0d
|
||||
#endif
|
||||
#ifndef MSG_CLEAR_QUEUE
|
||||
#define MSG_CLEAR_QUEUE 0x0e
|
||||
#endif
|
||||
#ifndef MSG_REL_RECOVERY
|
||||
#define MSG_REL_RECOVERY 0x10
|
||||
#endif
|
||||
#ifndef MSG_TERM_IO_PROC
|
||||
#define MSG_TERM_IO_PROC 0x11
|
||||
#endif
|
||||
#ifndef MSG_LUN_RESET
|
||||
#define MSG_LUN_RESET 0x17
|
||||
#endif
|
||||
|
||||
#endif /* _ISP_STDS_H */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,125 +0,0 @@
|
||||
/* $Id: isp_target.h,v 1.67 2009/05/02 23:18:31 mjacob Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 1997-2009 by Matthew Jacob
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* 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 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of the
|
||||
* the GNU Public License ("GPL") with platforms where the prevalant license
|
||||
* is the GNU Public License:
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of The Version 2 GNU General Public License as published
|
||||
* by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program.
|
||||
*
|
||||
*
|
||||
* Matthew Jacob
|
||||
* Feral Software
|
||||
* 421 Laurel Avenue
|
||||
* Menlo Park, CA 94025
|
||||
* USA
|
||||
*
|
||||
* gplbsd at feral com
|
||||
*/
|
||||
/*
|
||||
* Qlogic Target Mode Structure and Flag Definitions
|
||||
*/
|
||||
#ifndef _ISP_TARGET_H
|
||||
#define _ISP_TARGET_H
|
||||
|
||||
/*
|
||||
* Notify structure- these are for asynchronous events that need to be sent
|
||||
* as notifications to the outer layer. It should be pretty self-explanatory.
|
||||
*/
|
||||
typedef enum {
|
||||
NT_UNKNOWN=0x999,
|
||||
NT_ABORT_TASK=0x1000,
|
||||
NT_ABORT_TASK_SET,
|
||||
NT_CLEAR_ACA,
|
||||
NT_CLEAR_TASK_SET,
|
||||
NT_LUN_RESET,
|
||||
NT_TARGET_RESET,
|
||||
NT_BUS_RESET,
|
||||
NT_LIP_RESET,
|
||||
NT_LINK_UP,
|
||||
NT_LINK_DOWN,
|
||||
NT_LOGOUT,
|
||||
NT_GLOBAL_LOGOUT,
|
||||
NT_ARRIVED,
|
||||
NT_DEPARTED,
|
||||
NT_HBA_RESET
|
||||
} isp_ncode_t;
|
||||
|
||||
typedef struct isp_notify {
|
||||
void * nt_hba; /* HBA tag */
|
||||
void * nt_tmd;
|
||||
void * nt_lreserved;
|
||||
void * nt_hreserved;
|
||||
uint64_t nt_wwn; /* source (wwn) */
|
||||
uint64_t nt_tgt; /* destination (wwn) */
|
||||
uint64_t nt_tagval; /* tag value */
|
||||
uint32_t
|
||||
nt_sid : 24; /* source port id */
|
||||
uint32_t
|
||||
nt_failed : 1, /* notify operation failed */
|
||||
nt_need_ack : 1, /* this notify needs an ACK */
|
||||
nt_did : 24; /* destination port id */
|
||||
uint32_t
|
||||
nt_lun : 16, /* logical unit */
|
||||
nt_nphdl : 16; /* n-port handle */
|
||||
uint8_t nt_channel; /* channel id */
|
||||
isp_ncode_t nt_ncode; /* action */
|
||||
} isp_notify_t;
|
||||
#define MATCH_TMD(tmd, iid, lun, tag) \
|
||||
( \
|
||||
(tmd) && \
|
||||
(iid == INI_ANY || iid == tmd->cd_iid) && \
|
||||
(lun == LUN_ANY || lun == tmd->cd_lun) && \
|
||||
(tag == TAG_ANY || tag == tmd->cd_tagval) \
|
||||
)
|
||||
/*
|
||||
* Debug macros
|
||||
*/
|
||||
|
||||
#define ISP_TDQE(isp, msg, idx, arg) \
|
||||
if (isp->isp_dblev & ISP_LOGTDEBUG2) isp_print_qentry(isp, msg, idx, arg)
|
||||
|
||||
/*
|
||||
* Special Constatns
|
||||
*/
|
||||
#define INI_ANY ((uint64_t) -1)
|
||||
#define VALID_INI(ini) (ini != INI_NONE && ini != INI_ANY)
|
||||
#define LUN_ANY 0xffff
|
||||
#define TGT_ANY ((uint64_t) -1)
|
||||
#define TAG_ANY ((uint64_t) 0)
|
||||
#endif /* _ISP_TARGET_H */
|
||||
@@ -1,401 +0,0 @@
|
||||
/* $Id: isp_tpublic.h,v 1.46 2009/03/30 04:19:19 mjacob Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 1997-2009 by Matthew Jacob
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* 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 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of the
|
||||
* the GNU Public License ("GPL") with platforms where the prevalant license
|
||||
* is the GNU Public License:
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of The Version 2 GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program.
|
||||
*
|
||||
*
|
||||
* Matthew Jacob
|
||||
* Feral Software
|
||||
* 421 Laurel Avenue
|
||||
* Menlo Park, CA 94025
|
||||
* USA
|
||||
*
|
||||
* gplbsd at feral com
|
||||
*/
|
||||
/*
|
||||
* Host Adapter Public Target Interface Structures && Routines
|
||||
*/
|
||||
/*
|
||||
* A note about terminology:
|
||||
*
|
||||
* "Inner Layer" means this driver (isp and the isp_tpublic API).
|
||||
*
|
||||
* This module includes the both generic and platform specific pieces.
|
||||
*
|
||||
* "Outer Layer" means another (external) module.
|
||||
*
|
||||
* This is an additional module that actually implements SCSI target command
|
||||
* decode and is the recipient of incoming commands and the source of the
|
||||
* disposition for them.
|
||||
*/
|
||||
|
||||
#ifndef _ISP_TPUBLIC_H
|
||||
#define _ISP_TPUBLIC_H 1
|
||||
/*
|
||||
* Include general target definitions
|
||||
*/
|
||||
#include "isp_target.h"
|
||||
|
||||
/*
|
||||
* Action codes set by the Inner Layer for the outer layer to figure out what to do with.
|
||||
*/
|
||||
typedef enum {
|
||||
QOUT_HBA_REG=0, /* the argument is a pointer to a hba_register_t */
|
||||
QOUT_ENABLE, /* the argument is a pointer to a enadis_t */
|
||||
QOUT_DISABLE, /* the argument is a pointer to a enadis_t */
|
||||
QOUT_TMD_START, /* the argument is a pointer to a tmd_cmd_t */
|
||||
QOUT_TMD_DONE, /* the argument is a pointer to a tmd_xact_t */
|
||||
QOUT_NOTIFY, /* the argument is a pointer to a notify_t */
|
||||
QOUT_HBA_UNREG /* the argument is a pointer to a hba_register_t */
|
||||
} tact_e;
|
||||
|
||||
/*
|
||||
* Action codes set by the outer layer for the
|
||||
* inner layer to figure out what to do with.
|
||||
*/
|
||||
typedef enum {
|
||||
QIN_HBA_REG=99, /* the argument is a pointer to a hba_register_t */
|
||||
QIN_GETINFO, /* the argument is a pointer to a info_t */
|
||||
QIN_SETINFO, /* the argument is a pointer to a info_t */
|
||||
QIN_GETDLIST, /* the argument is a pointer to a fc_dlist_t */
|
||||
QIN_ENABLE, /* the argument is a pointer to a enadis_t */
|
||||
QIN_DISABLE, /* the argument is a pointer to a enadis_t */
|
||||
QIN_TMD_CONT, /* the argument is a pointer to a tmd_xact_t */
|
||||
QIN_TMD_FIN, /* the argument is a pointer to a tmd_cmd_t */
|
||||
QIN_NOTIFY_ACK, /* the argument is a pointer to a notify_t */
|
||||
QIN_HBA_UNREG, /* the argument is a pointer to a hba_register_t */
|
||||
} qact_e;
|
||||
|
||||
/*
|
||||
* This structure is used to register to the outer layer the
|
||||
* binding of an HBA identifier, driver name and instance and the
|
||||
* lun width capapbilities of this inner layer. It's up to each
|
||||
* platform to figure out how it wants to actually implement this.
|
||||
* A typical sequence would be for the MD layer to find some external
|
||||
* module's entry point and start by sending a QOUT_HBA_REG with info
|
||||
* filled in, and the external module to call back with a QIN_HBA_REG
|
||||
* that passes back the corresponding information.
|
||||
*
|
||||
* The r_version tag defines the version of this API.
|
||||
*/
|
||||
#define QR_VERSION 20
|
||||
typedef struct {
|
||||
/* NB: structure tags from here to r_version must never change */
|
||||
void * r_identity;
|
||||
void (*r_action)(qact_e, void *);
|
||||
char r_name[8];
|
||||
int r_inst;
|
||||
int r_version;
|
||||
uint32_t r_locator;
|
||||
uint32_t r_nchannels;
|
||||
enum { R_FC, R_SPI } r_type;
|
||||
void * r_private;
|
||||
} hba_register_t;
|
||||
|
||||
/*
|
||||
* An information structure that is used to get or set per-channel transport layer parameters.
|
||||
*/
|
||||
typedef struct {
|
||||
void * i_identity;
|
||||
enum { I_FC, I_SPI } i_type;
|
||||
int i_channel;
|
||||
int i_error;
|
||||
union {
|
||||
struct {
|
||||
uint64_t wwnn_nvram;
|
||||
uint64_t wwpn_nvram;
|
||||
uint64_t wwnn;
|
||||
uint64_t wwpn;
|
||||
} fc;
|
||||
struct {
|
||||
int iid;
|
||||
} spi;
|
||||
} i_id;
|
||||
} info_t;
|
||||
|
||||
/*
|
||||
* An information structure to return a list of logged in WWPNs. FC specific.
|
||||
*/
|
||||
typedef struct {
|
||||
void * d_identity;
|
||||
int d_channel;
|
||||
int d_error;
|
||||
int d_count;
|
||||
uint64_t * d_wwpns;
|
||||
} fc_dlist_t;
|
||||
|
||||
/*
|
||||
* Lun ENABLE/DISABLE
|
||||
*
|
||||
* A word about ENABLE/DISABLE: the argument is a pointer to a enadis_t
|
||||
* with en_hba, en_chan and en_lun filled out. We used to have an iid
|
||||
* and target pair, but this just gets silly so we made initiator id
|
||||
* and target id something you set, once, elsewhere.
|
||||
*
|
||||
* If an error occurs in either enabling or disabling the described lun
|
||||
* en_error is set with an appropriate non-zero value.
|
||||
*/
|
||||
typedef struct {
|
||||
void * en_private; /* for outer layer usage */
|
||||
void * en_hba; /* HBA tag */
|
||||
uint16_t en_lun; /* logical unit */
|
||||
uint16_t en_chan; /* channel on card */
|
||||
int en_error;
|
||||
} enadis_t;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Data Transaction
|
||||
*
|
||||
* A tmd_xact_t is a structure used to describe a transaction within
|
||||
* an overall command. It used to be part of the overall command,
|
||||
* but it became desirable to allow for multiple simultaneous
|
||||
* transfers for a command to happen. Generally these structures
|
||||
* define data to be moved (along with the relative offset within
|
||||
* the overall command) with the last structure containing status
|
||||
* and sense (if needed) as well.
|
||||
*
|
||||
* The td_cmd tag points back to the owning command.
|
||||
*
|
||||
* The td_data tag points to the (platform specific) data descriptor.
|
||||
*
|
||||
* The td_lprivate is for use by the Inner Layer for private usage.
|
||||
*
|
||||
* The td_xfrlen says whether this transaction is moving data- if nonzero.
|
||||
*
|
||||
* The td_offset states what the relative offset within the comamnd the
|
||||
* data transfer will start at. It is undefined if td_xfrlen is zero.
|
||||
*
|
||||
* The td_error flag will note any errors that occurred during an attempt
|
||||
* to start this transaction. The inner layer is responsible for setting
|
||||
* this.
|
||||
*
|
||||
* The td_hflags tag is set by the outer layer to indicate how the inner
|
||||
* layer is supposed to treat this transaction.
|
||||
*
|
||||
* The td_lflags tag is set by the inner layer to indicate whether this
|
||||
* transaction sent status and/or sense. Note that (much as it hurts),
|
||||
* this API allows the inner layer to *fail* to send sense even if asked
|
||||
* to- that is, AUTOSENSE is not a requirement of this API and the outer
|
||||
* layer has to be prepared for this (unlikely) eventuality.
|
||||
*/
|
||||
|
||||
typedef struct tmd_cmd tmd_cmd_t;
|
||||
typedef struct tmd_xact {
|
||||
tmd_cmd_t * td_cmd; /* cross-ref to tmd_cmd_t */
|
||||
void * td_data; /* data descriptor */
|
||||
void * td_lprivate; /* private for lower layer */
|
||||
uint32_t td_xfrlen; /* size of this data load */
|
||||
uint32_t td_offset; /* offset for this data load */
|
||||
int td_error; /* error with this transfer */
|
||||
uint8_t td_hflags; /* flags set by caller */
|
||||
uint8_t td_lflags; /* flags set by callee */
|
||||
} tmd_xact_t;
|
||||
|
||||
#define TDFH_STSVALID 0x01 /* status is valid - include it */
|
||||
#define TDFH_SNSVALID 0x02 /* sense data (from outer layer) good - include it */
|
||||
#define TDFH_DATA_IN 0x04 /* target (us) -> initiator (them) */
|
||||
#define TDFH_DATA_OUT 0x08 /* initiator (them) -> target (us) */
|
||||
#define TDFH_DATA_MASK 0x0C /* mask to cover data direction */
|
||||
#define TDFH_PRIVATE 0xF0 /* private outer layer usage */
|
||||
|
||||
#define TDFL_SENTSTATUS 0x01 /* this transaction sent status */
|
||||
#define TDFL_SENTSENSE 0x02 /* this transaction sent sense data */
|
||||
#define TDFL_ERROR 0x04 /* this transaction had an error */
|
||||
#define TDFL_SYNCERROR 0x08 /* ... and didn't even start because of it */
|
||||
#define TDFL_PRIVATE 0xF0 /* private inner layer usage */
|
||||
|
||||
/*
|
||||
* The command structure below the SCSI Command structure that is
|
||||
* is the whole point of this API. After a LUN is (or LUNS are)
|
||||
* enabled, initiators who send commands addressed to the port,
|
||||
* channel and lun that have been enabled cause an interrupt which
|
||||
* causes the chip to receive the command and present it to the
|
||||
* inner layer. The inner layer allocates one of this command
|
||||
* structures and copies relevant information to it and sends it
|
||||
* to the outer layer with the action QOUT_TMD_START.
|
||||
*
|
||||
* The outer layer is then responsible for command decode and is responsible
|
||||
* for sending any transactions back (via a QIN_TMD_CONT) to the inner layer
|
||||
* that (optionally) moves data and then sends closing status.
|
||||
*
|
||||
* The outer layer, when informed of the status of the final transaction
|
||||
* then releases this structure by sending it back to the inner layer
|
||||
* with the action QOUT_TMD_FIN.
|
||||
*
|
||||
* The structure tag meanings are as described below.
|
||||
*
|
||||
* The cd_hba tag is a tag that uniquely identifies the HBA this target
|
||||
* mode command is coming from. The outer layer has to pass this back
|
||||
* unchanged to avoid chaos. It is identical to the r_identity tag used
|
||||
* by the inner layer to register with the outer layer.
|
||||
*
|
||||
* The cd_iid, cd_channel, cd_tgt and cd_lun tags are used to identify the
|
||||
* the initiator who sent us a command, the channel on the this particular
|
||||
* hardware port we arrived on (for multiple channel devices), the target we
|
||||
* claim to be, and the lun on that target.
|
||||
*
|
||||
* The cd_tagval field is a tag that uniquely describes this tag. It may
|
||||
* or may not have any correspondence to an underying hardware tag. The
|
||||
* outer layer must pass this back unchanged or chaos will result.
|
||||
*
|
||||
* The tag cd_totlen is the total data amount expected to be moved
|
||||
* for this command. This will be set to non-zero for transports
|
||||
* that know this value from the transport level (e.g., Fibre Channel).
|
||||
* If it shows up in the outer layers set to zero, the total data length
|
||||
* must be inferred from the CDB.
|
||||
*
|
||||
* The tag cd_moved is the total amount of data moved so far. It is the
|
||||
* responsibilty of the inner layer to set this for every transaction and
|
||||
* to keep track of it so that transport level residuals may be correctly
|
||||
* set.
|
||||
*
|
||||
* The cd_cdb contains storage for the passed in SCSI command.
|
||||
*
|
||||
* The cd_tagtype field specifies what kind of command tag type, if
|
||||
* any, has been sent with this command.
|
||||
*
|
||||
* The tag cd_flags has some junk flags set but mostly has flags reserved for outer layer use.
|
||||
*
|
||||
* The tags cd_sense and cd_scsi_status are self-explanatory.
|
||||
*
|
||||
* The cd_xact tag is the first or only transaction structure related to this command.
|
||||
*
|
||||
* The tag cd_lreserved, cd_hreserved are scratch areas for use for the outer and inner layers respectively.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TMD_CDBLEN
|
||||
#define TMD_CDBLEN 16
|
||||
#endif
|
||||
#ifndef TMD_SENSELEN
|
||||
#define TMD_SENSELEN 18
|
||||
#endif
|
||||
#ifndef QCDS
|
||||
#define QCDS (sizeof (uint64_t))
|
||||
#endif
|
||||
#ifndef TMD_PRIV_LO
|
||||
#define TMD_PRIV_LO 4
|
||||
#endif
|
||||
#ifndef TMD_PRIV_HI
|
||||
#define TMD_PRIV_HI 4
|
||||
#endif
|
||||
|
||||
struct tmd_cmd {
|
||||
void * cd_hba; /* HBA tag */
|
||||
uint64_t cd_iid; /* initiator ID */
|
||||
uint64_t cd_tgt; /* target id */
|
||||
uint64_t cd_tagval; /* tag value */
|
||||
uint8_t cd_lun[8]; /* logical unit */
|
||||
uint32_t cd_totlen; /* total data load */
|
||||
uint32_t cd_moved; /* total data moved so far */
|
||||
uint16_t cd_channel; /* channel index */
|
||||
uint16_t cd_flags; /* flags */
|
||||
uint16_t cd_req_cnt; /* how many tmd_xact_t's are active */
|
||||
uint8_t cd_cdb[TMD_CDBLEN];
|
||||
uint8_t cd_tagtype; /* tag type */
|
||||
uint8_t cd_scsi_status;
|
||||
uint8_t cd_sense[TMD_SENSELEN];
|
||||
tmd_xact_t cd_xact; /* first or only transaction */
|
||||
union {
|
||||
void * ptrs[QCDS / sizeof (void *)]; /* (assume) one pointer */
|
||||
uint64_t llongs[QCDS / sizeof (uint64_t)]; /* one long long */
|
||||
uint32_t longs[QCDS / sizeof (uint32_t)]; /* two longs */
|
||||
uint16_t shorts[QCDS / sizeof (uint16_t)]; /* four shorts */
|
||||
uint8_t bytes[QCDS]; /* eight bytes */
|
||||
} cd_lreserved[TMD_PRIV_LO], cd_hreserved[TMD_PRIV_HI];
|
||||
};
|
||||
|
||||
#define CDF_NODISC 0x0001 /* disconnects disabled */
|
||||
#define CDF_DATA_IN 0x0002 /* target (us) -> initiator (them) */
|
||||
#define CDF_DATA_OUT 0x0004 /* initiator (them) -> target (us) */
|
||||
#define CDF_BIDIR 0x0006 /* bidirectional data */
|
||||
#define CDF_SNSVALID 0x0008 /* sense is set on incoming command */
|
||||
#define CDF_PRIVATE 0xff00 /* available for private use in outer layer */
|
||||
|
||||
/* defined tags */
|
||||
#define CD_UNTAGGED 0
|
||||
#define CD_SIMPLE_TAG 1
|
||||
#define CD_ORDERED_TAG 2
|
||||
#define CD_HEAD_TAG 3
|
||||
#define CD_ACA_TAG 4
|
||||
|
||||
#ifndef TMD_SIZE
|
||||
#define TMD_SIZE (sizeof (tmd_cmd_t))
|
||||
#endif
|
||||
|
||||
#define L0LUN_TO_FLATLUN(lptr) ((((lptr)[0] & 0x3f) << 8) | ((lptr)[1]))
|
||||
#define FLATLUN_TO_L0LUN(lptr, lun) \
|
||||
(lptr)[1] = lun & 0xff; \
|
||||
if (sizeof (lun) == 1) { \
|
||||
(lptr)[0] = 0; \
|
||||
} else { \
|
||||
uint16_t nl = lun; \
|
||||
if (nl == LUN_ANY) { \
|
||||
(lptr)[0] = (nl >> 8) & 0xff; \
|
||||
} else if (nl < 256) { \
|
||||
(lptr)[0] = 0; \
|
||||
} else { \
|
||||
(lptr)[0] = 0x40 | ((nl >> 8) & 0x3f); \
|
||||
} \
|
||||
} \
|
||||
memset(&(lptr)[2], 0, 6)
|
||||
|
||||
/*
|
||||
* Inner Layer Handler Function.
|
||||
*
|
||||
* The inner layer target handler function (the outer layer calls this)
|
||||
* should be be prototyped like so:
|
||||
*
|
||||
* void target_action(qact_e, void *arg)
|
||||
*
|
||||
* The outer layer target handler function (the inner layer calls this)
|
||||
* should be be prototyped like:
|
||||
*
|
||||
* void scsi_target_handler(tact_e, void *arg)
|
||||
*/
|
||||
|
||||
#endif /* _ISP_TPUBLIC_H */
|
||||
/*
|
||||
* vim:ts=4:sw=4:expandtab
|
||||
*/
|
||||
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
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
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
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
File diff suppressed because it is too large
Load Diff
@@ -1,102 +0,0 @@
|
||||
#/bin/sh
|
||||
#
|
||||
# $Id: fwbin,v 1.3 2009/06/07 22:27:50 mjacob Exp $
|
||||
#
|
||||
# Copyright (c) 1997-2008 by Matthew Jacob
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
# 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 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
# SUCH DAMAGE.
|
||||
#
|
||||
#
|
||||
# Alternatively, this software may be distributed under the terms of the
|
||||
# the GNU Public License ("GPL") with platforms where the prevalant license
|
||||
# is the GNU Public License:
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the Version 2 GNU General Public License as
|
||||
# published by the Free Software Foundation
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program.
|
||||
#
|
||||
#
|
||||
# Matthew Jacob
|
||||
# Feral Software
|
||||
# 421 Laurel Avenue
|
||||
# Menlo Park, CA 94025
|
||||
# USA
|
||||
#
|
||||
# gplbsd at feral com
|
||||
#
|
||||
dowr()
|
||||
{
|
||||
echo -n $* >> /tmp/x$$.c
|
||||
echo "" >> /tmp/x$$.c
|
||||
}
|
||||
|
||||
if [ $# -ne 1 ]; then
|
||||
echo "usage: $0 fwfile"
|
||||
exit 1
|
||||
fi
|
||||
name=`grep 'static const' $1 | head -1 | awk ' { print $4 }' | sed 's/..$//'`
|
||||
stok=`grep 'static const' $1 | head -1 | awk ' { print $3 }'`
|
||||
|
||||
cp /dev/null /tmp/x$$.c
|
||||
dowr '#include <unistd.h>'
|
||||
dowr '#include <stdlib.h>'
|
||||
dowr '#include <stdio.h>'
|
||||
dowr '#include <stdint.h>'
|
||||
dowr '#include <memory.h>'
|
||||
dowr '#include <fcntl.h>'
|
||||
dowr '#include <errno.h>'
|
||||
dowr '#define ISP_2400 1'
|
||||
dowr '#define ISP_2500 1'
|
||||
cat $1 >> /tmp/x$$.c
|
||||
dowr ' int main(void)'
|
||||
dowr '{'
|
||||
dowr ' size_t i, amt = (sizeof ' $name ') / sizeof (' $name '[0]);'
|
||||
dowr ' for (i = 0; i != amt; i++) {'
|
||||
case $stok in
|
||||
uint16_t)
|
||||
dowr ' putchar('$name '[i] >> 8);'
|
||||
dowr ' putchar('$name '[i] >> 0);'
|
||||
;;
|
||||
uint32_t)
|
||||
dowr ' putchar('$name '[i] >> 24);'
|
||||
dowr ' putchar('$name '[i] >> 16);'
|
||||
dowr ' putchar('$name '[i] >> 8);'
|
||||
dowr ' putchar('$name '[i] >> 0);'
|
||||
;;
|
||||
esac
|
||||
dowr ' }'
|
||||
dowr ' return (0);'
|
||||
dowr '}'
|
||||
cc -g -o /tmp/x$$ /tmp/x$$.c || exit 1
|
||||
/tmp/x$$ > `echo $1|sed 's/.[ch]//'`.bin
|
||||
rm -f /tmp/x$$*
|
||||
echo Result in `echo $1|sed 's/.[ch]//'`.bin
|
||||
@@ -1,100 +0,0 @@
|
||||
# $Id: Makefile,v 1.11 2008/03/15 18:17:51 mjacob Exp $
|
||||
#
|
||||
# Makefile
|
||||
#
|
||||
# Copyright (c) 2006-2008 by Matthew Jacob
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of The Version 2 GNU General Public License as published
|
||||
# by the Free Software Foundation.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program.
|
||||
#
|
||||
#
|
||||
# Matthew Jacob
|
||||
# Feral Software
|
||||
# 421 Laurel Avenue
|
||||
# Menlo Park, CA 94025
|
||||
# USA
|
||||
#
|
||||
# gpl at feral com
|
||||
#
|
||||
ifndef KDIR
|
||||
LVERS = $(shell uname -r)
|
||||
LINUX ?= /lib/modules/${LVERS}/build
|
||||
else
|
||||
LINUX = ${KDIR}
|
||||
endif
|
||||
|
||||
M ?= $(CURDIR)
|
||||
TDIR = $(M)/../
|
||||
SCST_INC = ${TDIR}/../scst/include
|
||||
SCST_DIR = ${TDIR}/../scst/src
|
||||
|
||||
all: links
|
||||
@$(MAKE) -C ${LINUX} M=${CURDIR}/build
|
||||
|
||||
tgt: links Modules.symvers Module.symvers
|
||||
@$(MAKE) -C ${LINUX} M=${CURDIR}/build SCST_INC=$(SCST_INC) ISP_TARGET_MODE=1
|
||||
|
||||
clean:
|
||||
@$(MAKE) -C ${LINUX} M=${CURDIR}/build clean
|
||||
@$(MAKE) -C build clean_links
|
||||
@$(RM) tags Modules.symvers Module.symvers
|
||||
|
||||
extraclean: clean
|
||||
rm -f *.orig *.rej
|
||||
|
||||
install:
|
||||
@$(MAKE) -C ${LINUX} M=${CURDIR}/build \
|
||||
$$([ -n "$(DESTDIR)$(INSTALL_MOD_PATH)" ] && echo DEPMOD=true) \
|
||||
modules_install
|
||||
|
||||
install_host_progs:
|
||||
@$(MAKE) -C build $@
|
||||
|
||||
links:
|
||||
@$(MAKE) -C build make_links
|
||||
|
||||
tools:
|
||||
cd ../linux && $(MAKE) tools
|
||||
|
||||
tags: FRC
|
||||
@ctags --recurse --append=no ../linux ../common ../../scst
|
||||
|
||||
FRC:
|
||||
|
||||
SCST_MOD_VERS := $(shell ls $(SCST_DIR)/Modules.symvers 2>/dev/null)
|
||||
ifneq ($(SCST_MOD_VERS),)
|
||||
Modules.symvers: $(SCST_DIR)/Modules.symvers
|
||||
cp $(SCST_DIR)/Modules.symvers ${CURDIR}/build
|
||||
else
|
||||
.PHONY: Modules.symvers
|
||||
endif
|
||||
|
||||
# It's renamed in 2.6.18
|
||||
SCST_MOD_VERS := $(shell ls $(SCST_DIR)/Module.symvers 2>/dev/null)
|
||||
ifneq ($(SCST_MOD_VERS),)
|
||||
Module.symvers: $(SCST_DIR)/Module.symvers
|
||||
cp $(SCST_DIR)/Module.symvers ${CURDIR}/build
|
||||
else
|
||||
.PHONY: Module.symvers
|
||||
endif
|
||||
|
||||
KVER := $(shell cat ${LINUX}/.kernelrelease 2> /dev/null )
|
||||
ifeq ($(KVER),)
|
||||
KVER := $(shell cat ${LINUX}/include/config/kernel.release 2> /dev/null )
|
||||
endif
|
||||
|
||||
uninstall:
|
||||
rm -f /lib/modules/${KVER}/extra/isp_mod.ko
|
||||
rm -f /lib/modules/${KVER}/extra/isp_scst.ko
|
||||
-/sbin/depmod -a ${KVER}
|
||||
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
# $Id: Makefile,v 1.13 2007/03/10 02:27:53 mjacob Exp $
|
||||
#
|
||||
# Copyright (c) 2006-2007 by Matthew Jacob
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of The Version 2 GNU General Public License as published
|
||||
# by the Free Software Foundation.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program.
|
||||
#
|
||||
#
|
||||
# Matthew Jacob
|
||||
# Feral Software
|
||||
# 421 Laurel Avenue
|
||||
# Menlo Park, CA 94025
|
||||
# USA
|
||||
#
|
||||
# gpl at feral com
|
||||
|
||||
M ?= $(CURDIR)
|
||||
TDIR = $(M)/../../
|
||||
COM_OBJ = isp.o isp_library.o isp_target.o
|
||||
LNX_OBJ = isp_cb_ops.o isp_linux.o isp_pci.o
|
||||
COM_DIR = ${TDIR}/common
|
||||
LNX_DIR = ${TDIR}/linux
|
||||
|
||||
STG_SRC = isp_scst.c
|
||||
|
||||
#EXTRA_CFLAGS += -Wall -Werror -Idrivers/scsi -I${COM_DIR} -I${LNX_DIR} -I${TDIR}/firmware -I${SCST_INC}
|
||||
EXTRA_CFLAGS += -Wall -Idrivers/scsi -I${COM_DIR} -I${LNX_DIR} -I${TDIR}/firmware -I${SCST_INC}
|
||||
|
||||
clean-files := *.o scsi_target_ctl Module.symvers
|
||||
|
||||
ifdef ISP_TARGET_MODE
|
||||
|
||||
EXTRA_CFLAGS += -DISP_TARGET_MODE=1 -DISP_DEFAULT_ROLES=ISP_ROLE_NONE
|
||||
|
||||
obj-m := isp_mod.o isp_scst.o
|
||||
|
||||
else
|
||||
|
||||
obj-m := isp_mod.o
|
||||
|
||||
endif
|
||||
|
||||
isp_mod-objs := ${COM_OBJ} ${LNX_OBJ}
|
||||
|
||||
clean_links:
|
||||
@${RM} $(COM_OBJ:.o=.c) $(LNX_OBJ:.o=.c) ${STG_SRC}
|
||||
|
||||
make_links: clean_links
|
||||
@for j in ${COM_OBJ:.o=.c}; do ln -s ${COM_DIR}/$$j; done
|
||||
@for j in ${LNX_OBJ:.o=.c}; do ln -s ${LNX_DIR}/$$j; done
|
||||
@for j in ${STG_SRC}; do ln -s ${LNX_DIR}/$$j; done
|
||||
@@ -1,755 +0,0 @@
|
||||
/* $Id: isp_cb_ops.c,v 1.101 2009/05/01 22:34:13 mjacob Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1997-2009 by Matthew Jacob
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* 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 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of the
|
||||
* the GNU Public License ("GPL") with platforms where the prevalant license
|
||||
* is the GNU Public License:
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of The Version 2 GNU General Public License as published
|
||||
* by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program.
|
||||
*
|
||||
*
|
||||
* Matthew Jacob
|
||||
* Feral Software
|
||||
* 421 Laurel Avenue
|
||||
* Menlo Park, CA 94025
|
||||
* USA
|
||||
*
|
||||
* gplbsd at feral com
|
||||
*/
|
||||
/*
|
||||
* Qlogic ISP Host Adapter procfs and open/close entry points
|
||||
* proc safe pretty print code courtesy of Gerard Roudier (groudier@free.fr)
|
||||
*/
|
||||
|
||||
#include "isp_linux.h"
|
||||
#include "isp_ioctl.h"
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
/*
|
||||
* 'safe' proc pretty print code
|
||||
*/
|
||||
struct info_str {
|
||||
char *buffer;
|
||||
int length;
|
||||
off_t offset;
|
||||
int pos;
|
||||
};
|
||||
|
||||
static void
|
||||
copy_mem_info(struct info_str *info, char *data, int len)
|
||||
{
|
||||
if (info->pos + len > info->offset + info->length) {
|
||||
len = info->offset + info->length - info->pos;
|
||||
}
|
||||
|
||||
if (info->pos + len < info->offset) {
|
||||
info->pos += len;
|
||||
return;
|
||||
}
|
||||
|
||||
if (info->pos < info->offset) {
|
||||
off_t partial;
|
||||
|
||||
partial = info->offset - info->pos;
|
||||
data += partial;
|
||||
info->pos += partial;
|
||||
len -= partial;
|
||||
}
|
||||
|
||||
if (len > 0) {
|
||||
memcpy(info->buffer, data, len);
|
||||
info->pos += len;
|
||||
info->buffer += len;
|
||||
}
|
||||
}
|
||||
|
||||
static int copy_info(struct info_str *, const char *, ...) __attribute__((__format__(__printf__, 2, 3)));
|
||||
|
||||
static int
|
||||
copy_info(struct info_str *info, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char buf[256];
|
||||
int len;
|
||||
|
||||
va_start(args, fmt);
|
||||
len = vsprintf(buf, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
copy_mem_info(info, buf, len);
|
||||
return (len);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
isplinux_proc_info(struct Scsi_Host *shp, char *buf, char **st, off_t off, int len, int io)
|
||||
{
|
||||
int i;
|
||||
struct info_str info;
|
||||
ispsoftc_t *isp = NULL;
|
||||
unsigned long flags;
|
||||
|
||||
for (i = 0; i < MAX_ISP; i++) {
|
||||
isp = isplist[i];
|
||||
if (isp == NULL) {
|
||||
continue;
|
||||
}
|
||||
if (isp->isp_host->host_no == shp->host_no) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isp == NULL) {
|
||||
return (-ENODEV);
|
||||
}
|
||||
|
||||
if (io) {
|
||||
buf[len] = 0;
|
||||
io = -ENOSYS;
|
||||
if (strncmp(buf, "debug=", 6) == 0) {
|
||||
unsigned long debug;
|
||||
char *p = &buf[6], *q;
|
||||
debug = simple_strtoul(p, &q, 16);
|
||||
if (q == &buf[6]) {
|
||||
isp_prt(isp, ISP_LOGERR, "Garbled Debug Line '%s'", buf);
|
||||
return (-EINVAL);
|
||||
}
|
||||
isp_prt(isp, ISP_LOGINFO, "setting debug level to 0x%lx", debug);
|
||||
ISP_LOCKU_SOFTC(isp);
|
||||
isp->isp_dblev = debug;
|
||||
ISP_UNLKU_SOFTC(isp);
|
||||
io = len;
|
||||
} else if (strncmp(buf, "rescan", 6) == 0) {
|
||||
if (IS_FC(isp)) {
|
||||
for (io = 0; io < isp->isp_nchan; io++) {
|
||||
isp_thread_event(isp, ISP_THREAD_FC_RESCAN, FCPARAM(isp, io), 1, __func__, __LINE__);
|
||||
}
|
||||
io = len;
|
||||
}
|
||||
} else if (strncmp(buf, "lip", 3) == 0) {
|
||||
if (IS_FC(isp)) {
|
||||
ISP_LOCKU_SOFTC(isp);
|
||||
(void) isp_control(isp, ISPCTL_SEND_LIP, 0);
|
||||
ISP_UNLKU_SOFTC(isp);
|
||||
io = len;
|
||||
}
|
||||
} else if (strncmp(buf, "busreset=", 9) == 0) {
|
||||
char *p = &buf[6], *q;
|
||||
int bus = (int) simple_strtoul(p, &q, 16);
|
||||
if (q == &buf[6]) {
|
||||
isp_prt(isp, ISP_LOGERR, "Garbled Bus Reset Line '%s'", buf);
|
||||
return (-EINVAL);
|
||||
}
|
||||
ISP_LOCKU_SOFTC(isp);
|
||||
(void) isp_control(isp, ISPCTL_RESET_BUS, bus);
|
||||
ISP_UNLKU_SOFTC(isp);
|
||||
io = len;
|
||||
} else if (strncmp(buf, "devreset=", 9) == 0) {
|
||||
char *p = &buf[6], *q;
|
||||
int dev = (int) simple_strtoul(p, &q, 16);
|
||||
if (q == &buf[6]) {
|
||||
isp_prt(isp, ISP_LOGERR, "Garbled Dev Reset Line '%s'", buf);
|
||||
return (-EINVAL);
|
||||
}
|
||||
/* always bus 0 */
|
||||
ISP_LOCKU_SOFTC(isp);
|
||||
(void) isp_control(isp, ISPCTL_RESET_DEV, 0, dev);
|
||||
ISP_UNLKU_SOFTC(isp);
|
||||
io = len;
|
||||
} else if (strncmp(buf, "reset", 5) == 0) {
|
||||
ISP_LOCKU_SOFTC(isp);
|
||||
isp_reinit(isp, 0);
|
||||
ISP_UNLKU_SOFTC(isp);
|
||||
io = len;
|
||||
} else if (strncmp(buf, "bins", 4) == 0) {
|
||||
ISP_LOCKU_SOFTC(isp);
|
||||
memset(isp->isp_osinfo.bins, 0, sizeof (isp->isp_osinfo.bins));
|
||||
ISP_UNLKU_SOFTC(isp);
|
||||
io = len;
|
||||
}
|
||||
return (io);
|
||||
}
|
||||
|
||||
ISP_LOCKU_SOFTC(isp);
|
||||
if (st) {
|
||||
*st = buf;
|
||||
}
|
||||
info.buffer = buf;
|
||||
info.length = len;
|
||||
info.offset = off;
|
||||
info.pos = 0;
|
||||
|
||||
copy_info(&info, (char *)isplinux_info(isp->isp_host));
|
||||
#ifdef HBA_VERSION
|
||||
copy_info(&info, "\n HBA Version %s, built %s, %s", HBA_VERSION, __DATE__, __TIME__);
|
||||
#endif
|
||||
copy_info(&info, "\n DEVID %x\n", isp->isp_osinfo.device_id);
|
||||
copy_info(&info,
|
||||
" Interrupt Stats:\n"
|
||||
" total=0x%016llx bogus=0x%016llx\n"
|
||||
" MboxC=0x%016llx async=0x%016llx\n"
|
||||
" CRslt=0x%016llx CPost=0x%016llx\n"
|
||||
" RspnsCHiWater=0x%04x FastPostC_Hiwater=0x%04x\n",
|
||||
(ull) isp->isp_intcnt, (ull) isp->isp_intbogus, (ull) isp->isp_intmboxc,
|
||||
(ull) isp->isp_intoasync, (ull) isp->isp_rsltccmplt, (ull) isp->isp_fphccmplt,
|
||||
isp->isp_rscchiwater, isp->isp_fpcchiwater);
|
||||
copy_info(&info,
|
||||
" Request In %d Request Out %d Result %d Nactv %d"
|
||||
" HiWater %u QAVAIL %d WtQHi %d\n",
|
||||
isp->isp_reqidx, isp->isp_reqodx, isp->isp_residx, isp->isp_nactive,
|
||||
isp->isp_osinfo.hiwater, ISP_QAVAIL(isp),
|
||||
isp->isp_osinfo.wqhiwater);
|
||||
for (i = 0; i < isp->isp_maxcmds; i++) {
|
||||
if (isp->isp_xflist[i]) {
|
||||
copy_info(&info, " %d:%p", i, isp->isp_xflist[i]);
|
||||
}
|
||||
}
|
||||
#ifdef ISP_TARGET_MODE
|
||||
copy_info(&info, "\n");
|
||||
for (i = 0; i < isp->isp_maxcmds; i++) {
|
||||
if (isp->isp_tgtlist[i]) {
|
||||
copy_info(&info, " %d:%p", i, isp->isp_tgtlist[i]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
copy_info(&info, "\n");
|
||||
if (isp->isp_osinfo.wqnext) {
|
||||
struct scsi_cmnd *f = isp->isp_osinfo.wqnext;
|
||||
copy_info(&info, "WaitQ(%d)", isp->isp_osinfo.wqcnt);
|
||||
while (f) {
|
||||
copy_info(&info, "->%p", f);
|
||||
f = (struct scsi_cmnd *) f->host_scribble;
|
||||
}
|
||||
copy_info(&info, "\n");
|
||||
}
|
||||
if (isp->isp_osinfo.dqnext) {
|
||||
struct scsi_cmnd *f = isp->isp_osinfo.dqnext;
|
||||
copy_info(&info, "DoneQ");
|
||||
while (f) {
|
||||
copy_info(&info, "->%p", f);
|
||||
f = (struct scsi_cmnd *) f->host_scribble;
|
||||
}
|
||||
copy_info(&info, "\n");
|
||||
}
|
||||
// copy_info(&info, "blocked %d qfdelay %d\n", isp->isp_blocked, isp->isp_qfdelay);
|
||||
|
||||
copy_info(&info, "\nxfer bins:\n");
|
||||
copy_info(&info, " <=1024 4096 32768 65536 131072 262144 524288 >0.5M\n");
|
||||
/* 123456 123456 123456 123456 123456 123456 123456 123456 */
|
||||
for (i = 0; i < 8; i++) {
|
||||
copy_info(&info, "% 7ld", isp->isp_osinfo.bins[i]);
|
||||
}
|
||||
copy_info(&info, "\n");
|
||||
#ifdef ISP_TARGET_MODE
|
||||
if (isp->isp_osinfo.cmds_started || isp->isp_osinfo.cmds_completed) {
|
||||
copy_info(&info, "\n");
|
||||
copy_info(&info, "Target cmds started: %llu; Target cmds completed ok: %llu", isp->isp_osinfo.cmds_started, isp->isp_osinfo.cmds_completed);
|
||||
copy_info(&info, "\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (IS_FC(isp)) {
|
||||
int chan;
|
||||
for (chan = 0; chan < isp->isp_nchan; chan++) {
|
||||
fcparam *fcp = FCPARAM(isp, chan);
|
||||
copy_info(&info, "Self Channel %d:\nHandle ID 0x%x PortID 0x%06x FW State %s Loop State %s Topology %s Link Speed %dGb\n", chan, fcp->isp_loopid, fcp->isp_portid,
|
||||
isp_fc_fw_statename(fcp->isp_fwstate), isp_fc_loop_statename(fcp->isp_loopstate), isp_fc_toponame(fcp), fcp->isp_gbspeed);
|
||||
copy_info(&info, "Port WWN 0x%016llx Node WWN 0x%016llx\n\n", (ull) fcp->isp_wwpn, (ull)fcp->isp_wwnn);
|
||||
copy_info(&info, "FC devices in port database:\n");
|
||||
for (i = 0; i < MAX_FC_TARG; i++) {
|
||||
if (fcp->portdb[i].state != FC_PORTDB_STATE_VALID) {
|
||||
continue;
|
||||
}
|
||||
if (fcp->portdb[i].dev_map_idx) {
|
||||
copy_info(&info, "\tdbidx %d handle 0x%x PortID 0x%06x role %s (target %d)\n\tPort WWN 0x%016llx Node WWN 0x%016llx\n\n",
|
||||
i, fcp->portdb[i].handle, fcp->portdb[i].portid, isp_class3_roles[fcp->portdb[i].roles],
|
||||
fcp->portdb[i].dev_map_idx - 1, (ull) fcp->portdb[i].port_wwn, (ull) fcp->portdb[i].node_wwn);
|
||||
} else {
|
||||
copy_info(&info, "\tdbidx %d handle 0x%x PortID 0x%06x role %s\n\tPort WWN 0x%016llx Node WWN 0x%016llx\n\n",
|
||||
i, fcp->portdb[i].handle, fcp->portdb[i].portid, isp_class3_roles[fcp->portdb[i].roles],
|
||||
(ull) fcp->portdb[i].port_wwn, (ull) fcp->portdb[i].node_wwn);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
sdparam *sdp = (sdparam *)isp->isp_param;
|
||||
|
||||
copy_info(&info, "Initiator ID: %d\n", sdp->isp_initiator_id);
|
||||
copy_info(&info, "Target Flag Period Offset\n");
|
||||
for (i = 0; i < MAX_TARGETS; i++) {
|
||||
copy_info(&info, "%6d: 0x%04x 0x%04x 0x%x\n", i, sdp->isp_devparam[i].actv_flags, sdp->isp_devparam[i].actv_offset,
|
||||
sdp->isp_devparam[i].actv_period);
|
||||
}
|
||||
if (IS_DUALBUS(isp)) {
|
||||
sdp++;
|
||||
copy_info(&info, "\nInitiator ID: %d, Channel B\n", sdp->isp_initiator_id);
|
||||
copy_info(&info,
|
||||
"Target CurFlag DevFlag Period Offset B-Channel\n");
|
||||
for (i = 0; i < MAX_TARGETS; i++) {
|
||||
copy_info(&info, "%6d: 0x%04x 0x%04x 0x%x\n", i, sdp->isp_devparam[i].actv_flags, sdp->isp_devparam[i].actv_offset,
|
||||
sdp->isp_devparam[i].actv_period);
|
||||
}
|
||||
}
|
||||
}
|
||||
ISP_UNLKU_SOFTC(isp);
|
||||
return (info.pos > info.offset ? info.pos - info.offset : 0);
|
||||
}
|
||||
#endif /* CONFIG_PROC_FS */
|
||||
|
||||
static int isp_open(struct inode *, struct file *);
|
||||
static int isp_close(struct inode *, struct file *);
|
||||
static int isp_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
|
||||
|
||||
dev_t isp_dev;
|
||||
struct cdev isp_cdev = {
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25)
|
||||
.kobj = { .k_name = ISP_NAME, },
|
||||
#endif
|
||||
.owner = THIS_MODULE
|
||||
};
|
||||
ISP_CLASS *isp_class;
|
||||
|
||||
struct file_operations isp_ioctl_operations = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = isp_open,
|
||||
.release = isp_close,
|
||||
.ioctl = isp_ioctl,
|
||||
};
|
||||
|
||||
static int
|
||||
isp_open(struct inode *ip, struct file *fp)
|
||||
{
|
||||
const int minor = iminor(ip);
|
||||
int i;
|
||||
ispsoftc_t *isp = NULL;
|
||||
|
||||
for (i = 0; i < MAX_ISP; i++) {
|
||||
if (isplist[i] && isplist[i]->isp_unit == minor) {
|
||||
isp = isplist[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isp == NULL) {
|
||||
return (-ENXIO);
|
||||
}
|
||||
if (isp->isp_isopen) {
|
||||
return (-EBUSY);
|
||||
}
|
||||
isp->isp_isopen = 1;
|
||||
fp->private_data = isp;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
isp_close(struct inode *ip, struct file *fp)
|
||||
{
|
||||
ispsoftc_t *isp = fp->private_data;
|
||||
isp->isp_isopen = 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
isp_ioctl(struct inode *ip, struct file *fp, unsigned int c, unsigned long arg)
|
||||
{
|
||||
ispsoftc_t *isp = fp->private_data;
|
||||
int i, rv, inarg, outarg;
|
||||
fcparam *fcp;
|
||||
uint16_t loopid, chan;
|
||||
mbreg_t mbs;
|
||||
unsigned long flags;
|
||||
|
||||
if (isp == (ispsoftc_t *)NULL) {
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
if (IS_SCSI(isp)) {
|
||||
switch (c) {
|
||||
case ISP_SDBLEV:
|
||||
case ISP_RESCAN:
|
||||
case ISP_GETROLE:
|
||||
case ISP_SETROLE:
|
||||
case ISP_RESETHBA:
|
||||
break;
|
||||
default:
|
||||
return (-EINVAL);
|
||||
}
|
||||
fcp = NULL;
|
||||
} else {
|
||||
fcp = isp->isp_param;
|
||||
}
|
||||
|
||||
rv = 0;
|
||||
isp_prt(isp, ISP_LOGDEBUG1, "isp_ioctl: cmd=%x", c);
|
||||
|
||||
switch (c) {
|
||||
case ISP_GET_STATS:
|
||||
{
|
||||
isp_stats_t stats;
|
||||
|
||||
memset(&stats, 0, sizeof stats);
|
||||
stats.isp_stat_version = ISP_STATS_VERSION;
|
||||
stats.isp_type = isp->isp_type;
|
||||
stats.isp_revision = isp->isp_revision;
|
||||
ISP_LOCK_SOFTC(isp);
|
||||
stats.isp_stats[ISP_INTCNT] = isp->isp_intcnt;
|
||||
stats.isp_stats[ISP_INTBOGUS] = isp->isp_intbogus;
|
||||
stats.isp_stats[ISP_INTMBOXC] = isp->isp_intmboxc;
|
||||
stats.isp_stats[ISP_INGOASYNC] = isp->isp_intoasync;
|
||||
stats.isp_stats[ISP_RSLTCCMPLT] = isp->isp_rsltccmplt;
|
||||
stats.isp_stats[ISP_FPHCCMCPLT] = isp->isp_fphccmplt;
|
||||
stats.isp_stats[ISP_RSCCHIWAT] = isp->isp_rscchiwater;
|
||||
stats.isp_stats[ISP_FPCCHIWAT] = isp->isp_fpcchiwater;
|
||||
ISP_UNLK_SOFTC(isp);
|
||||
if (COPYOUT(&stats, (void *)arg, sizeof (stats))) {
|
||||
rv = -EFAULT;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ISP_CLR_STATS:
|
||||
ISP_LOCK_SOFTC(isp);
|
||||
isp->isp_intcnt = 0;
|
||||
isp->isp_intbogus = 0;
|
||||
isp->isp_intmboxc = 0;
|
||||
isp->isp_intoasync = 0;
|
||||
isp->isp_rsltccmplt = 0;
|
||||
isp->isp_fphccmplt = 0;
|
||||
isp->isp_rscchiwater = 0;
|
||||
isp->isp_fpcchiwater = 0;
|
||||
ISP_UNLK_SOFTC(isp);
|
||||
break;
|
||||
|
||||
case ISP_SDBLEV:
|
||||
if (COPYIN((void *)arg, &inarg, sizeof (inarg))) {
|
||||
rv = -EFAULT;
|
||||
break;
|
||||
}
|
||||
outarg = isp->isp_dblev;
|
||||
isp->isp_dblev = inarg;
|
||||
if (COPYOUT(&outarg, (void *)arg, sizeof (outarg))) {
|
||||
rv = -EFAULT;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case ISP_RESCAN:
|
||||
if (IS_FC(isp)) {
|
||||
for (i = 0; i < isp->isp_nchan; i++) {
|
||||
FCPARAM(isp, i)->isp_loopstate = LOOP_PDB_RCVD;
|
||||
isp_thread_event(isp, ISP_THREAD_FC_RESCAN, FCPARAM(isp, i), 0, __func__, __LINE__);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ISP_GETROLE:
|
||||
if (COPYIN((void *)arg, &inarg, sizeof (inarg))) {
|
||||
rv = -EFAULT;
|
||||
break;
|
||||
}
|
||||
chan = inarg >> 16;
|
||||
if (chan >= isp->isp_nchan) {
|
||||
rv = -ENXIO;
|
||||
break;
|
||||
}
|
||||
if (IS_FC(isp)) {
|
||||
outarg = FCPARAM(isp, chan)->role;
|
||||
} else {
|
||||
outarg = SDPARAM(isp, chan)->role;
|
||||
}
|
||||
if (COPYOUT(&outarg, (void *)arg, sizeof (outarg))) {
|
||||
rv = -EFAULT;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ISP_SETROLE:
|
||||
if (COPYIN((void *)arg, &inarg, sizeof (inarg))) {
|
||||
rv = -EFAULT;
|
||||
break;
|
||||
}
|
||||
chan = inarg >> 16;
|
||||
if (chan >= isp->isp_nchan) {
|
||||
rv = -ENXIO;
|
||||
break;
|
||||
}
|
||||
inarg &= 0xffff;
|
||||
if (inarg & ~(ISP_ROLE_INITIATOR|ISP_ROLE_TARGET)) {
|
||||
rv = -EINVAL;
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* Check to see if we're already in that role.
|
||||
*/
|
||||
if (IS_FC(isp)) {
|
||||
if (FCPARAM(isp, chan)->role == inarg) {
|
||||
break;
|
||||
}
|
||||
outarg = FCPARAM(isp, chan)->role;
|
||||
if (COPYOUT(&outarg, (void *)arg, sizeof (outarg))) {
|
||||
rv = -EFAULT;
|
||||
break;
|
||||
}
|
||||
FCPARAM(isp, chan)->role = inarg;
|
||||
SET_DEFAULT_ROLE(isp, chan, FCPARAM(isp, chan)->role);
|
||||
} else {
|
||||
if (SDPARAM(isp, chan)->role == inarg) {
|
||||
break;
|
||||
}
|
||||
outarg = SDPARAM(isp, chan)->role;
|
||||
if (COPYOUT(&outarg, (void *)arg, sizeof (outarg))) {
|
||||
rv = -EFAULT;
|
||||
break;
|
||||
}
|
||||
SDPARAM(isp, chan)->role = inarg;
|
||||
SET_DEFAULT_ROLE(isp, chan, SDPARAM(isp, chan)->role);
|
||||
}
|
||||
break;
|
||||
case ISP_RESETHBA:
|
||||
{
|
||||
ISP_LOCK_SOFTC(isp);
|
||||
isp_reset(isp, 0);
|
||||
ISP_UNLK_SOFTC(isp);
|
||||
break;
|
||||
}
|
||||
case ISP_FC_LIP:
|
||||
if (COPYIN((void *)arg, &chan, sizeof (chan))) {
|
||||
chan = 0;
|
||||
}
|
||||
ISP_LOCK_SOFTC(isp);
|
||||
if (isp_control(isp, ISPCTL_SEND_LIP, chan)) {
|
||||
rv = -EIO;
|
||||
}
|
||||
ISP_UNLK_SOFTC(isp);
|
||||
break;
|
||||
case ISP_FC_GETDINFO:
|
||||
{
|
||||
struct isp_fc_device local, *ifc = &local;
|
||||
fcportdb_t *lp;
|
||||
|
||||
if (IS_SCSI(isp)) {
|
||||
rv = -EINVAL;
|
||||
break;
|
||||
}
|
||||
if (COPYIN((void *)arg, ifc, sizeof (*ifc))) {
|
||||
rv = -EFAULT;
|
||||
break;
|
||||
}
|
||||
if (ifc->chan >= isp->isp_nchan) {
|
||||
rv = -EINVAL;
|
||||
break;
|
||||
}
|
||||
if (ifc->loopid >= MAX_FC_TARG) {
|
||||
rv = -EINVAL;
|
||||
break;
|
||||
}
|
||||
ISP_LOCK_SOFTC(isp);
|
||||
lp = &FCPARAM(isp, ifc->chan)->portdb[ifc->loopid];
|
||||
if (lp->state == FC_PORTDB_STATE_VALID || lp->target_mode) {
|
||||
ifc->role = lp->roles;
|
||||
ifc->loopid = lp->handle;
|
||||
ifc->portid = lp->portid;
|
||||
ifc->node_wwn = lp->node_wwn;
|
||||
ifc->port_wwn = lp->port_wwn;
|
||||
} else {
|
||||
rv = -ENODEV;
|
||||
}
|
||||
ISP_UNLK_SOFTC(isp);
|
||||
if (rv == 0) {
|
||||
if (COPYOUT((void *)ifc, (void *)arg, sizeof (*ifc))) {
|
||||
rv = -EFAULT;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ISP_FC_GETHINFO:
|
||||
{
|
||||
struct isp_hba_device local, *hba = &local;
|
||||
if (COPYIN((void *)arg, hba, sizeof (*hba))) {
|
||||
rv = -EFAULT;
|
||||
break;
|
||||
}
|
||||
chan = hba->fc_channel;
|
||||
if (chan >= isp->isp_nchan) {
|
||||
rv = -EINVAL;
|
||||
break;
|
||||
}
|
||||
ISP_LOCK_SOFTC(isp);
|
||||
hba->fc_nchannels = isp->isp_nchan;
|
||||
hba->fc_nports = ISP_CAP_2KLOGIN(isp)? 2048 : 256;
|
||||
hba->fc_fw_major = ISP_FW_MAJORX(isp->isp_fwrev);
|
||||
hba->fc_fw_minor = ISP_FW_MINORX(isp->isp_fwrev);
|
||||
hba->fc_fw_micro = ISP_FW_MICROX(isp->isp_fwrev);
|
||||
hba->fc_speed = FCPARAM(isp, chan)->isp_gbspeed;
|
||||
hba->fc_topology = FCPARAM(isp, chan)->isp_topo + 1;
|
||||
hba->fc_loopid = FCPARAM(isp, chan)->isp_loopid;
|
||||
hba->nvram_node_wwn = FCPARAM(isp, chan)->isp_wwnn_nvram;
|
||||
hba->nvram_port_wwn = FCPARAM(isp, chan)->isp_wwpn_nvram;
|
||||
hba->active_node_wwn = FCPARAM(isp, chan)->isp_wwnn;
|
||||
hba->active_port_wwn = FCPARAM(isp, chan)->isp_wwpn;
|
||||
ISP_UNLK_SOFTC(isp);
|
||||
if (COPYOUT(hba, (void *)arg, sizeof (*hba))) {
|
||||
rv = -EFAULT;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ISP_TSK_MGMT:
|
||||
{
|
||||
int needmarker;
|
||||
struct isp_fc_tsk_mgmt local, *fct = (struct isp_fc_tsk_mgmt *) &local;
|
||||
|
||||
if (IS_SCSI(isp)) {
|
||||
rv = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (COPYIN((void *)arg, fct, sizeof (*fct))) {
|
||||
rv = -EFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
memset(&mbs, 0, sizeof (mbs));
|
||||
needmarker = 0;
|
||||
loopid = fct->loopid;
|
||||
if (ISP_CAP_2KLOGIN(isp) == 0) {
|
||||
loopid <<= 8;
|
||||
}
|
||||
switch (fct->action) {
|
||||
case IPT_CLEAR_ACA:
|
||||
mbs.param[0] = MBOX_CLEAR_ACA;
|
||||
mbs.param[1] = loopid;
|
||||
mbs.param[2] = fct->lun;
|
||||
break;
|
||||
case IPT_TARGET_RESET:
|
||||
mbs.param[0] = MBOX_TARGET_RESET;
|
||||
mbs.param[1] = loopid;
|
||||
needmarker = 1;
|
||||
break;
|
||||
case IPT_LUN_RESET:
|
||||
mbs.param[0] = MBOX_LUN_RESET;
|
||||
mbs.param[1] = loopid;
|
||||
mbs.param[2] = fct->lun;
|
||||
needmarker = 1;
|
||||
break;
|
||||
case IPT_CLEAR_TASK_SET:
|
||||
mbs.param[0] = MBOX_CLEAR_TASK_SET;
|
||||
mbs.param[1] = loopid;
|
||||
mbs.param[2] = fct->lun;
|
||||
needmarker = 1;
|
||||
break;
|
||||
case IPT_ABORT_TASK_SET:
|
||||
mbs.param[0] = MBOX_ABORT_TASK_SET;
|
||||
mbs.param[1] = loopid;
|
||||
mbs.param[2] = fct->lun;
|
||||
needmarker = 1;
|
||||
break;
|
||||
default:
|
||||
rv = -EINVAL;
|
||||
break;
|
||||
}
|
||||
if (rv == 0) {
|
||||
mbs.logval = MBLOGALL;
|
||||
mbs.timeout = 2000000;
|
||||
ISP_LOCKU_SOFTC(isp);
|
||||
if (needmarker) {
|
||||
ISP_SET_SENDMARKER(isp, 0, 1);
|
||||
}
|
||||
rv = isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs);
|
||||
ISP_UNLKU_SOFTC(isp);
|
||||
if (rv) {
|
||||
rv = -EIO;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ISP_FC_GETDLIST:
|
||||
{
|
||||
isp_dlist_t *ua;
|
||||
uint16_t nph, nphe, count, chan, lim;
|
||||
struct wwnpair pair, *uptr;
|
||||
|
||||
if (IS_SCSI(isp)) {
|
||||
rv = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
ua = (isp_dlist_t *)arg;
|
||||
uptr = &ua->wwns[0];
|
||||
|
||||
if (COPYIN((void *)&ua->count, &lim, sizeof (lim))) {
|
||||
rv = -EFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
if (COPYIN((void *)&ua->channel, &chan, sizeof (chan))) {
|
||||
rv = -EFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ISP_CAP_2KLOGIN(isp)) {
|
||||
nphe = NPH_MAX_2K;
|
||||
} else {
|
||||
nphe = NPH_MAX;
|
||||
}
|
||||
for (count = 0, nph = 0; count < lim && nph != nphe; nph++) {
|
||||
ISP_LOCKU_SOFTC(isp);
|
||||
rv = isp_control(isp, ISPCTL_GET_NAMES, chan, nph, &pair.wwnn, &pair.wwpn);
|
||||
ISP_UNLKU_SOFTC(isp);
|
||||
if (rv || (pair.wwpn == INI_NONE && pair.wwnn == INI_NONE)) {
|
||||
rv = 0;
|
||||
continue;
|
||||
}
|
||||
if (COPYOUT(&pair, (void *)uptr++, sizeof (pair))) {
|
||||
rv = -EFAULT;
|
||||
break;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
if (rv == 0) {
|
||||
if (COPYOUT(&count, (void *)&ua->count, sizeof (count))) {
|
||||
rv = -EFAULT;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
rv = -EINVAL;
|
||||
break;
|
||||
}
|
||||
return (rv);
|
||||
}
|
||||
/*
|
||||
* vim:ts=4:sw=4:expandtab
|
||||
*/
|
||||
@@ -1,236 +0,0 @@
|
||||
/* $Id: isp_ioctl.h,v 1.30 2009/03/30 04:17:34 mjacob Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1997-2009 by Matthew Jacob
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* 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 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of the
|
||||
* the GNU Public License ("GPL") with platforms where the prevalant license
|
||||
* is the GNU Public License:
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of The Version 2 GNU General Public License as published
|
||||
* by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program.
|
||||
*
|
||||
*
|
||||
* Matthew Jacob
|
||||
* Feral Software
|
||||
* 421 Laurel Avenue
|
||||
* Menlo Park, CA 94025
|
||||
* USA
|
||||
*
|
||||
* gplbsd at feral com
|
||||
*/
|
||||
/*
|
||||
* ioctl definitions for Qlogic FC/SCSI HBA driver
|
||||
*/
|
||||
#define ISP_IOC (0x4D4A5100) /* 'MJQ' << 8 */
|
||||
|
||||
/*
|
||||
* This ioctl sets/retrieves the debugging level for this hba instance.
|
||||
* Note that this is not a simple integer level- see ispvar.h for definitions.
|
||||
*
|
||||
* The arguments is a pointer to an integer with the new debugging level.
|
||||
* The old value is written into this argument.
|
||||
*/
|
||||
|
||||
#define ISP_SDBLEV (ISP_IOC | 1)
|
||||
|
||||
/*
|
||||
* This ioctl resets the HBA. Use with caution.
|
||||
*/
|
||||
#define ISP_RESETHBA (ISP_IOC | 2)
|
||||
|
||||
/*
|
||||
* This ioctl performs a fibre chanel rescan.
|
||||
*/
|
||||
#define ISP_RESCAN (ISP_IOC | 3)
|
||||
|
||||
/*
|
||||
* This ioctl performs a reset and then will set the adapter to the
|
||||
* role that was passed in (the old role will be returned). It almost
|
||||
* goes w/o saying: use with caution.
|
||||
*
|
||||
* Channel selector stored in bits 8..32 as input to driver.
|
||||
*/
|
||||
#define ISP_SETROLE (ISP_IOC | 4)
|
||||
|
||||
#define ISP_ROLE_NONE 0x0
|
||||
#define ISP_ROLE_TARGET 0x1
|
||||
#define ISP_ROLE_INITIATOR 0x2
|
||||
#define ISP_ROLE_BOTH (ISP_ROLE_TARGET|ISP_ROLE_INITIATOR)
|
||||
#ifndef ISP_DEFAULT_ROLES
|
||||
#define ISP_DEFAULT_ROLES ISP_ROLE_BOTH
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Get the current adapter role
|
||||
* Channel selector passed in first argument.
|
||||
*/
|
||||
#define ISP_GETROLE (ISP_IOC | 5)
|
||||
|
||||
/*
|
||||
* Get/Clear Stats
|
||||
*/
|
||||
#define ISP_STATS_VERSION 0
|
||||
typedef struct {
|
||||
uint8_t isp_stat_version;
|
||||
uint8_t isp_type; /* (ro) reflects chip type */
|
||||
uint8_t isp_revision; /* (ro) reflects chip version */
|
||||
uint8_t unused1;
|
||||
uint32_t unused2;
|
||||
/*
|
||||
* Statistics Counters
|
||||
*/
|
||||
#define ISP_NSTATS 16
|
||||
#define ISP_INTCNT 0
|
||||
#define ISP_INTBOGUS 1
|
||||
#define ISP_INTMBOXC 2
|
||||
#define ISP_INGOASYNC 3
|
||||
#define ISP_RSLTCCMPLT 4
|
||||
#define ISP_FPHCCMCPLT 5
|
||||
#define ISP_RSCCHIWAT 6
|
||||
#define ISP_FPCCHIWAT 7
|
||||
uint64_t isp_stats[ISP_NSTATS];
|
||||
} isp_stats_t;
|
||||
|
||||
#define ISP_GET_STATS (ISP_IOC | 6)
|
||||
#define ISP_CLR_STATS (ISP_IOC | 7)
|
||||
|
||||
/*
|
||||
* Initiate a LIP
|
||||
*/
|
||||
#define ISP_FC_LIP (ISP_IOC | 8)
|
||||
|
||||
/*
|
||||
* Return the Port Database structure for the named device, or ENODEV if none.
|
||||
* Caller fills in virtual loopid (0..255/2048), aka 'target'. The driver returns
|
||||
* ENODEV (if nothing valid there) or the actual loopid (for local loop devices
|
||||
* only), 24 bit Port ID and Node and Port WWNs.
|
||||
*/
|
||||
struct isp_fc_device {
|
||||
uint32_t loopid; /* 0..255/2048 */
|
||||
uint32_t
|
||||
chan : 6,
|
||||
role : 2,
|
||||
portid : 24; /* 24 bit Port ID */
|
||||
uint64_t node_wwn;
|
||||
uint64_t port_wwn;
|
||||
};
|
||||
#define ISP_FC_GETDINFO (ISP_IOC | 9)
|
||||
|
||||
/*
|
||||
* Get F/W crash dump
|
||||
*/
|
||||
#define ISP_GET_FW_CRASH_DUMP (ISP_IOC | 10)
|
||||
#define ISP_FORCE_CRASH_DUMP (ISP_IOC | 11)
|
||||
|
||||
/*
|
||||
* Get information about this Host Adapter, including current connection
|
||||
* topology and capabilities.
|
||||
*/
|
||||
struct isp_hba_device {
|
||||
uint32_t : 8,
|
||||
fc_speed : 4, /* Gbps */
|
||||
: 1,
|
||||
fc_topology : 3,
|
||||
fc_channel : 8, /* channel selector */
|
||||
fc_loopid : 16; /* loop id selector */
|
||||
uint8_t fc_fw_major; /* firmware major version */
|
||||
uint8_t fc_fw_minor; /* firmware minor version */
|
||||
uint8_t fc_fw_micro; /* firmware micro version */
|
||||
uint8_t fc_nchannels; /* number of supported channels */
|
||||
uint16_t fc_nports; /* number of supported ports */
|
||||
uint64_t nvram_node_wwn;
|
||||
uint64_t nvram_port_wwn;
|
||||
uint64_t active_node_wwn;
|
||||
uint64_t active_port_wwn;
|
||||
};
|
||||
|
||||
#define ISP_TOPO_UNKNOWN 0 /* connection topology unknown */
|
||||
#define ISP_TOPO_FCAL 1 /* private or PL_DA */
|
||||
#define ISP_TOPO_LPORT 2 /* public loop */
|
||||
#define ISP_TOPO_NPORT 3 /* N-port */
|
||||
#define ISP_TOPO_FPORT 4 /* F-port */
|
||||
|
||||
/* do not use this one any more */
|
||||
/* #define ISP_FC_GETHINFO (ISP_IOC|12) */
|
||||
#define ISP_FC_GETHINFO (ISP_IOC|13)
|
||||
|
||||
/*
|
||||
* Set Active WWNN/WWPN
|
||||
*/
|
||||
struct isp_wwn {
|
||||
uint32_t _reserved[2];
|
||||
uint64_t node_wwn;
|
||||
uint64_t port_wwn;
|
||||
};
|
||||
|
||||
#define ISP_FC_SET_WWN (ISP_IOC | 20)
|
||||
|
||||
/*
|
||||
* Various Reset Goodies
|
||||
*/
|
||||
struct isp_fc_tsk_mgmt {
|
||||
uint32_t loopid; /* 0..255/2048 */
|
||||
uint16_t lun;
|
||||
uint16_t chan;
|
||||
enum {
|
||||
IPT_CLEAR_ACA,
|
||||
IPT_TARGET_RESET,
|
||||
IPT_LUN_RESET,
|
||||
IPT_CLEAR_TASK_SET,
|
||||
IPT_ABORT_TASK_SET
|
||||
} action;
|
||||
};
|
||||
/* don't use 21 anymore */
|
||||
/* #define ISP_TSK_MGMT (ISP_IOC | 21) */
|
||||
#define ISP_TSK_MGMT (ISP_IOC | 22)
|
||||
|
||||
/*
|
||||
* Just gimme a list of WWPNs that are logged into us.
|
||||
*/
|
||||
typedef struct {
|
||||
uint16_t count;
|
||||
uint16_t channel;
|
||||
struct wwnpair {
|
||||
uint64_t wwnn;
|
||||
uint64_t wwpn;
|
||||
} wwns[1];
|
||||
} isp_dlist_t;
|
||||
/* do not recycle 22 */
|
||||
|
||||
#define ISP_FC_GETDLIST (ISP_IOC | 23)
|
||||
/*
|
||||
* vim:ts=4:sw=4:expandtab
|
||||
*/
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,977 +0,0 @@
|
||||
/* $Id: isp_linux.h,v 1.176 2009/09/06 00:37:07 mjacob Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1997-2009 by Matthew Jacob
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* 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 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of the
|
||||
* the GNU Public License ("GPL") with platforms where the prevalant license
|
||||
* is the GNU Public License:
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of The Version 2 GNU General Public License as published
|
||||
* by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program.
|
||||
*
|
||||
*
|
||||
* Matthew Jacob
|
||||
* Feral Software
|
||||
* 421 Laurel Avenue
|
||||
* Menlo Park, CA 94025
|
||||
* USA
|
||||
*
|
||||
* gplbsd at feral com
|
||||
*/
|
||||
/*
|
||||
* Qlogic ISP SCSI Host Adapter Linux Wrapper Definitions
|
||||
*/
|
||||
|
||||
#ifndef _ISP_LINUX_H
|
||||
#define _ISP_LINUX_H
|
||||
|
||||
#ifndef ISP_MODULE
|
||||
#define __NO_VERSION__
|
||||
#endif
|
||||
#ifdef MODULE
|
||||
#define EXPORT_SYMTAB 1
|
||||
#endif
|
||||
|
||||
#include <linux/version.h>
|
||||
#ifndef KERNEL_VERSION
|
||||
#define KERNEL_VERSION(v,p,s) (((v)<<16)+(p<<8)+s)
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) || LINUX_VERSION_CODE >= KERNEL_VERSION(2,7,0)
|
||||
#error "Only Linux 2.5/2.6 kernels are supported with this driver"
|
||||
#endif
|
||||
|
||||
#ifndef UNUSED_PARAMETER
|
||||
#define UNUSED_PARAMETER(x) (void) x
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 32)
|
||||
#include <linux/autoconf.h>
|
||||
#else
|
||||
#include <generated/autoconf.h>
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
#define __SMP__ 1
|
||||
#endif
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/blkdev.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/stat.h>
|
||||
#include <linux/pci.h>
|
||||
#include <asm/dma.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/irq.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/byteorder.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <scsi/scsi.h>
|
||||
#include <scsi/scsi_cmnd.h>
|
||||
#include <scsi/scsi_host.h>
|
||||
#include <scsi/scsi_tcq.h>
|
||||
#include <scsi/scsi_device.h>
|
||||
|
||||
#include <linux/cdev.h>
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13)
|
||||
#include <linux/devfs_fs_kernel.h>
|
||||
#define ISP_CLASS struct class_simple
|
||||
#define CREATE_ISP_CLASS class_simple_create
|
||||
#define DESTROY_ISP_CLASS class_simple_destroy
|
||||
|
||||
#define CREATE_ISP_DEV(isp, class) \
|
||||
class_simple_device_add(class, MKDEV(MAJOR(isp_dev), isp->isp_unit), NULL, "%s%d", ISP_NAME, isp->isp_unit), \
|
||||
devfs_mk_cdev(MKDEV(MAJOR(isp_dev), isp->isp_unit), S_IFCHR | S_IRUGO | S_IWUGO, "%s%d", ISP_NAME, isp->isp_unit)
|
||||
#define DESTROY_ISP_DEV(isp) \
|
||||
devfs_remove("%s%d", ISP_NAME, isp->isp_unit), class_simple_device_remove(MKDEV(MAJOR(isp_dev), isp->isp_unit))
|
||||
|
||||
#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26)
|
||||
#define ISP_CLASS struct class
|
||||
#define CREATE_ISP_CLASS class_create
|
||||
#define DESTROY_ISP_CLASS class_destroy
|
||||
|
||||
#define CREATE_ISP_DEV(isp, class) \
|
||||
class_device_create(class, NULL, MKDEV(MAJOR(isp_dev), isp->isp_unit), NULL, "%s%d", ISP_NAME, isp->isp_unit)
|
||||
#define DESTROY_ISP_DEV(isp) \
|
||||
class_device_destroy(isp_class, MKDEV(MAJOR(isp_dev), (isp)->isp_unit));
|
||||
|
||||
#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
|
||||
#define ISP_CLASS struct class
|
||||
#define CREATE_ISP_CLASS class_create
|
||||
#define DESTROY_ISP_CLASS class_destroy
|
||||
#define CREATE_ISP_DEV(i, c) (void) device_create(c, NULL, MKDEV(MAJOR(isp_dev), (i)->isp_unit), "%s%d", ISP_NAME, (i)->isp_unit);
|
||||
#define DESTROY_ISP_DEV(i) device_destroy(isp_class, MKDEV(MAJOR(isp_dev), (i)->isp_unit));
|
||||
#else
|
||||
#define ISP_CLASS struct class
|
||||
#define CREATE_ISP_CLASS class_create
|
||||
#define DESTROY_ISP_CLASS class_destroy
|
||||
#define CREATE_ISP_DEV(i, c) (void) device_create(c, NULL, MKDEV(MAJOR(isp_dev), (i)->isp_unit), NULL, "%s%d", ISP_NAME, (i)->isp_unit);
|
||||
#define DESTROY_ISP_DEV(i) device_destroy(isp_class, MKDEV(MAJOR(isp_dev), (i)->isp_unit));
|
||||
#endif
|
||||
|
||||
typedef struct scsi_cmnd Scsi_Cmnd;
|
||||
typedef struct scsi_request Scsi_Request;
|
||||
typedef struct scsi_host_template Scsi_Host_Template;
|
||||
#ifdef CONFIG_PROC_FS
|
||||
#include <linux/proc_fs.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Efficiency- get rid of SBus code && tests unless we need them.
|
||||
*/
|
||||
#if defined(__sparcv9__ ) || defined(__sparc__)
|
||||
#define ISP_SBUS_SUPPORTED 1
|
||||
#else
|
||||
#define ISP_SBUS_SUPPORTED 0
|
||||
#endif
|
||||
|
||||
#define ISP_PLATFORM_VERSION_MAJOR 6
|
||||
#define ISP_PLATFORM_VERSION_MINOR 1
|
||||
|
||||
#ifndef ISP_NAME
|
||||
#define ISP_NAME "isp"
|
||||
#endif
|
||||
|
||||
#ifndef BIG_ENDIAN
|
||||
#define BIG_ENDIAN 4321
|
||||
#endif
|
||||
#ifndef LITTLE_ENDIAN
|
||||
#define LITTLE_ENDIAN 1234
|
||||
#endif
|
||||
|
||||
#ifdef __BIG_ENDIAN
|
||||
#define BYTE_ORDER BIG_ENDIAN
|
||||
#endif
|
||||
#ifdef __LITTLE_ENDIAN
|
||||
#define BYTE_ORDER LITTLE_ENDIAN
|
||||
#endif
|
||||
|
||||
#ifndef __WORDSIZE
|
||||
#define __WORDSIZE BITS_PER_LONG
|
||||
#endif
|
||||
|
||||
#define DMA_HTYPE_T dma_addr_t
|
||||
#define QLA_HANDLE(cmd) (cmd)->SCp.dma_handle
|
||||
|
||||
#ifdef min
|
||||
#undef min
|
||||
#endif
|
||||
#ifdef max
|
||||
#undef max
|
||||
#endif
|
||||
|
||||
#define ull unsigned long long
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
|
||||
#define sg_page(_sg) ((_sg)->page)
|
||||
#define sg_assign_page(_sg, _pg) ((_sg)->page = (_pg))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Normally this should be taken care of by typedefs,
|
||||
* but linux includes are a complete dog's breakfast.
|
||||
*/
|
||||
|
||||
#define uint8_t u8
|
||||
#define uint16_t u16
|
||||
#define uint32_t u32
|
||||
#define uint64_t u64
|
||||
#define int8_t char
|
||||
#define int16_t short
|
||||
#define int32_t int
|
||||
|
||||
#define u_long unsigned long
|
||||
#define uint unsigned int
|
||||
#define u_char unsigned char
|
||||
typedef u_long vm_offset_t;
|
||||
|
||||
/* bit map using 8 bit arrays */
|
||||
typedef uint8_t isp_bmap_t;
|
||||
#define _ISP_WIX(isp, ix) (ix >> 3)
|
||||
#define _ISP_BIX(isp, ix) (1 << (ix & 0x7))
|
||||
#define ISP_NBPIDX(x) ((x + 7) / 8) /* index width from bits */
|
||||
#define ISP_BTST(map, ix) (((map)[_ISP_WIX(isp, ix)] & _ISP_BIX(isp, ix)) != 0)
|
||||
#define ISP_BSET(map, ix) (map)[_ISP_WIX(isp, ix)] |= _ISP_BIX(isp, ix)
|
||||
#define ISP_BCLR(map, ix) (map)[_ISP_WIX(isp, ix)] &= ~_ISP_BIX(isp, ix)
|
||||
|
||||
#ifdef ISP_TARGET_MODE
|
||||
|
||||
#include "isp_tpublic.h"
|
||||
|
||||
#ifndef DEFAULT_DEVICE_TYPE
|
||||
#define DEFAULT_DEVICE_TYPE 0
|
||||
#endif
|
||||
#define NTGT_CMDS 1024
|
||||
#define N_NOTIFIES 256
|
||||
#define DEFAULT_INQSIZE 32
|
||||
|
||||
typedef struct notify notify_t;
|
||||
|
||||
#define cd_action cd_lreserved[0].shorts[0]
|
||||
#define cd_oxid cd_lreserved[0].shorts[1]
|
||||
#define cd_lflags cd_lreserved[0].shorts[2]
|
||||
#define cd_nphdl cd_lreserved[0].shorts[3]
|
||||
#define cd_nseg cd_lreserved[1].longs[0]
|
||||
#define cd_portid cd_lreserved[1].longs[1]
|
||||
#define cd_next cd_lreserved[2].ptrs[0]
|
||||
#define cd_lastoff cd_lreserved[3].longs[0]
|
||||
#define cd_lastsize cd_lreserved[3].longs[1]
|
||||
|
||||
#define CDFL_LCL 0x8000
|
||||
#define CDFL_RESRC_FILL 0x4000
|
||||
#define CDFL_ABORTED 0x2000
|
||||
#define CDFL_NEED_CLNUP 0x1000
|
||||
#define CDFL_BUSY 0x0800
|
||||
|
||||
typedef struct enalun tgt_enalun_t;
|
||||
struct enalun {
|
||||
tgt_enalun_t * next;
|
||||
uint16_t lun;
|
||||
uint16_t bus;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
struct scatterlist sg;
|
||||
tmd_xact_t xact;
|
||||
} tgt_auxcmd_t;
|
||||
#define N_TGT_AUX 32
|
||||
|
||||
#define ISP_CT_TIMEOUT 120
|
||||
#endif /* ISP_TARGET_MODE */
|
||||
|
||||
typedef struct isp_thread_action isp_thread_action_t;
|
||||
struct isp_thread_action {
|
||||
isp_thread_action_t *next;
|
||||
enum {
|
||||
ISP_THREAD_NIL=1,
|
||||
ISP_THREAD_FC_RESCAN,
|
||||
ISP_THREAD_REINIT,
|
||||
ISP_THREAD_FW_CRASH_DUMP,
|
||||
ISP_THREAD_LOGOUT,
|
||||
ISP_THREAD_FINDIID,
|
||||
ISP_THREAD_FINDPORTID,
|
||||
ISP_THREAD_TERMINATE,
|
||||
ISP_THREAD_RESTART_AT7,
|
||||
ISP_THREAD_FC_PUTBACK,
|
||||
ISP_THREAD_SCSI_SCAN,
|
||||
} thread_action;
|
||||
void * arg;
|
||||
wait_queue_head_t thread_waiter;
|
||||
uint32_t
|
||||
waiting : 1,
|
||||
done : 1,
|
||||
count : 30;
|
||||
};
|
||||
#define MAX_THREAD_ACTION 128
|
||||
#define MAX_FC_CHAN 128
|
||||
|
||||
#define ISP_HOST2ISP(host) (ispsoftc_t *) host->hostdata
|
||||
|
||||
struct isposinfo {
|
||||
struct Scsi_Host * host;
|
||||
unsigned int device_id;
|
||||
u32 mcorig; /* original maxcmds */
|
||||
void *device; /* hardware device structure */
|
||||
Scsi_Cmnd *wqnext, *wqtail;
|
||||
Scsi_Cmnd *dqnext, *dqtail;
|
||||
void * storep;
|
||||
size_t storep_amt;
|
||||
size_t param_amt;
|
||||
const struct firmware *fwp;
|
||||
#ifdef CONFIG_PROC_FS
|
||||
struct proc_dir_entry *pdp;
|
||||
#endif
|
||||
char hbaname[16];
|
||||
long bins[8];
|
||||
u16 wqcnt;
|
||||
u16 wqhiwater;
|
||||
u16 hiwater;
|
||||
struct timer_list timer;
|
||||
struct semaphore mbox_sem;
|
||||
wait_queue_head_t mboxwq;
|
||||
struct semaphore mbox_c_sem;
|
||||
spinlock_t slock;
|
||||
uint32_t
|
||||
dogcnt : 5,
|
||||
isopen : 1,
|
||||
is_64bit_dma : 1,
|
||||
dogactive : 1,
|
||||
mboxcmd_done : 1,
|
||||
mbintsok : 1,
|
||||
intsok : 1;
|
||||
u16 scan_timeout;
|
||||
u16 rescan_timeout;
|
||||
u16 frame_size;
|
||||
u16 exec_throttle;
|
||||
struct task_struct *thread_task;
|
||||
wait_queue_head_t trq;
|
||||
spinlock_t tlock;
|
||||
isp_thread_action_t t_actions[MAX_THREAD_ACTION];
|
||||
isp_thread_action_t *t_free;
|
||||
isp_thread_action_t *t_busy, *t_busy_t;
|
||||
#ifdef ISP_TARGET_MODE
|
||||
u32 isget : 16,
|
||||
rstatus : 8,
|
||||
: 7,
|
||||
hcb : 1;
|
||||
struct semaphore tgt_inisem;
|
||||
struct semaphore * rsemap;
|
||||
tgt_enalun_t * luns; /* enabled { lun, port } tuples */
|
||||
struct tmd_cmd * pending_t; /* pending list of commands going upstream */
|
||||
struct tmd_cmd * waiting_t; /* pending list of commands waiting to be fleshed out */
|
||||
struct tmd_cmd * tfreelist; /* freelist head */
|
||||
struct tmd_cmd * bfreelist; /* freelist tail */
|
||||
struct tmd_cmd * pool; /* pool itself */
|
||||
notify_t * pending_n; /* pending list of notifies going upstream */
|
||||
notify_t * nfreelist; /* freelist */
|
||||
notify_t * npool; /* pool itself */
|
||||
struct tmd_xact * pending_x; /* pending list of xacts going upstream */
|
||||
/*
|
||||
* When we have inquiry commands that we have to xfer data with
|
||||
* locally we have to have some aux info (scatterlist, tmd_xact_t)
|
||||
* to manage those commands.
|
||||
*/
|
||||
tgt_auxcmd_t auxinfo[N_TGT_AUX];
|
||||
isp_bmap_t auxbmap[ISP_NBPIDX(N_TGT_AUX)];
|
||||
u8 inqdata[DEFAULT_INQSIZE];
|
||||
|
||||
u64 cmds_started;
|
||||
u64 cmds_completed;
|
||||
unsigned long out_of_tmds;
|
||||
#endif
|
||||
};
|
||||
#define mbtimer isp_osinfo.mbtimer
|
||||
#define dogactive isp_osinfo.dogactive
|
||||
#define mbintsok isp_osinfo.mbintsok
|
||||
#define intsok isp_osinfo.intsok
|
||||
#define mbox_waiting isp_osinfo.mbox_waiting
|
||||
#define mboxcmd_done isp_osinfo.mboxcmd_done
|
||||
#define isp_isopen isp_osinfo.isopen
|
||||
|
||||
/*
|
||||
* Locking macros...
|
||||
*/
|
||||
#define ISP_LOCK_INIT(isp) spin_lock_init(&isp->isp_osinfo.slock)
|
||||
#define ISP_LOCK_SOFTC(isp) spin_lock_irqsave(&isp->isp_osinfo.slock, flags)
|
||||
#define ISP_UNLK_SOFTC(isp) spin_unlock_irqrestore(&isp->isp_osinfo.slock, flags)
|
||||
#define ISP_ILOCK_SOFTC ISP_LOCK_SOFTC
|
||||
#define ISP_IUNLK_SOFTC ISP_UNLK_SOFTC
|
||||
#define ISP_IGET_LK_SOFTC(isp) spin_lock_irq(&isp->isp_osinfo.slock)
|
||||
#define ISP_DROP_LK_SOFTC(isp) spin_unlock_irq(&isp->isp_osinfo.slock)
|
||||
#define ISP_LOCK_SCSI_DONE(isp) do { } while(0)
|
||||
#define ISP_UNLK_SCSI_DONE(isp) do { } while(0)
|
||||
#define ISP_LOCKU_SOFTC ISP_ILOCK_SOFTC
|
||||
#define ISP_UNLKU_SOFTC ISP_IUNLK_SOFTC
|
||||
#define ISP_TLOCK_INIT(isp) spin_lock_init(&isp->isp_osinfo.tlock)
|
||||
#define ISP_DRIVER_ENTRY_LOCK(isp) spin_unlock_irq(isp->isp_osinfo.host->host_lock)
|
||||
#define ISP_DRIVER_EXIT_LOCK(isp) spin_lock_irq(isp->isp_osinfo.host->host_lock)
|
||||
#define ISP_DRIVER_CTL_ENTRY_LOCK(isp) do { } while (0)
|
||||
#define ISP_DRIVER_CTL_EXIT_LOCK(isp) do { } while (0)
|
||||
|
||||
#define ISP_MUST_POLL(isp) (in_interrupt() || isp->mbintsok == 0)
|
||||
|
||||
/*
|
||||
* Required Macros/Defines
|
||||
*/
|
||||
|
||||
#define ISP_FC_SCRLEN 0x1000
|
||||
|
||||
#define ISP_MEMZERO(b, a) memset(b, 0, a)
|
||||
#define ISP_MEMCPY memcpy
|
||||
#define ISP_SNPRINTF snprintf
|
||||
#define ISP_DELAY _isp_usec_delay
|
||||
#define ISP_SLEEP(isp, x) \
|
||||
ISP_DROP_LK_SOFTC(isp); \
|
||||
__set_current_state(TASK_UNINTERRUPTIBLE); \
|
||||
(void) schedule_timeout(_usec_to_jiffies(x)); \
|
||||
ISP_IGET_LK_SOFTC(isp)
|
||||
|
||||
#define ISP_INLINE inline
|
||||
|
||||
#define NANOTIME_T struct timeval
|
||||
/* for prior to 2.2.19, use do_gettimeofday, and, well, it'll be inaccurate */
|
||||
#define GET_NANOTIME(ptr) (ptr)->tv_sec = 0, (ptr)->tv_usec = 0, do_gettimeofday(ptr)
|
||||
#define GET_NANOSEC(x) ((uint64_t) ((((uint64_t)(x)->tv_sec) * 1000000 + (x)->tv_usec)))
|
||||
#define NANOTIME_SUB _isp_microtime_sub
|
||||
|
||||
#define MAXISPREQUEST(isp) (IS_24XX(isp)? 2048 : ((IS_FC(isp) || IS_ULTRA2(isp))? 1024 : 256))
|
||||
|
||||
#if defined(__powerpc__)
|
||||
#define MEMORYBARRIER(isp, type, offset, size) __asm__ __volatile__("eieio" ::: "memory")
|
||||
#else
|
||||
# ifdef mb
|
||||
# define MEMORYBARRIER(isp, type, offset, size) mb()
|
||||
# else
|
||||
# define MEMORYBARRIER(isp, type, offset, size) barrier()
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#define MBOX_ACQUIRE(isp) down_trylock(&isp->isp_osinfo.mbox_sem)
|
||||
#define MBOX_WAIT_COMPLETE mbox_wait_complete
|
||||
#define MBOX_NOTIFY_COMPLETE(isp) \
|
||||
wake_up(&isp->isp_osinfo.mboxwq); \
|
||||
isp->mboxcmd_done = 1
|
||||
#define MBOX_RELEASE(isp) up(&isp->isp_osinfo.mbox_sem)
|
||||
|
||||
#define FC_SCRATCH_ACQUIRE fc_scratch_acquire
|
||||
#define FC_SCRATCH_RELEASE(isp, chan) ISP_DATA(isp, chan)->scratch_busy = 0
|
||||
|
||||
|
||||
#ifndef SCSI_GOOD
|
||||
#define SCSI_GOOD 0x0
|
||||
#endif
|
||||
#ifndef SCSI_CHECK
|
||||
#define SCSI_CHECK 0x2
|
||||
#endif
|
||||
#ifndef SCSI_BUSY
|
||||
#define SCSI_BUSY 0x8
|
||||
#endif
|
||||
#ifndef SCSI_QFULL
|
||||
#define SCSI_QFULL 0x28
|
||||
#endif
|
||||
|
||||
#ifndef REPORT_LUNS
|
||||
#define REPORT_LUNS 0xa0
|
||||
#endif
|
||||
|
||||
#define XS_T Scsi_Cmnd
|
||||
#define XS_DMA_ADDR_T dma_addr_t
|
||||
#define XS_GET_DMA64_SEG isp_get_dma64_seg
|
||||
#define XS_GET_DMA_SEG isp_get_dma_seg
|
||||
#define XS_HOST(Cmnd) Cmnd->device->host
|
||||
#define XS_CHANNEL(Cmnd) (Cmnd)->device->channel
|
||||
#define XS_TGT(Cmnd) (Cmnd)->device->id
|
||||
#define XS_LUN(Cmnd) (Cmnd)->device->lun
|
||||
|
||||
#define SCSI_DATA_NONE DMA_NONE
|
||||
#define SCSI_DATA_READ DMA_FROM_DEVICE
|
||||
#define SCSI_DATA_WRITE DMA_TO_DEVICE
|
||||
#define scsi_to_pci_dma_dir(x) x
|
||||
|
||||
#define XS_ISP(Cmnd) ((ispsoftc_t *)XS_HOST(Cmnd)->hostdata)
|
||||
#define XS_CDBP(Cmnd) (Cmnd)->cmnd
|
||||
#define XS_CDBLEN(Cmnd) (Cmnd)->cmd_len
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25)
|
||||
#define XS_GET_RESID(Cmnd) (Cmnd)->SCp.this_residual
|
||||
#define XS_SET_RESID(Cmnd, resid) (Cmnd)->SCp.this_residual = resid
|
||||
#define XS_XFRLEN(Cmnd) (Cmnd)->request_bufflen
|
||||
#else
|
||||
#define XS_GET_RESID scsi_get_resid
|
||||
#define XS_SET_RESID scsi_set_resid
|
||||
#define XS_XFRLEN scsi_bufflen
|
||||
#endif
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
|
||||
#define XS_TIME(Cmnd) ((((Cmnd)->timeout_per_command) * HZ)*1000)
|
||||
#else
|
||||
#define XS_TIME(Cmnd) ((((Cmnd)->request->timeout) * HZ)*1000)
|
||||
#endif
|
||||
#define XS_STSP(Cmnd) (&(Cmnd)->SCp.Status)
|
||||
#define XS_SNSP(Cmnd) (Cmnd)->sense_buffer
|
||||
#define XS_SNSLEN(Cmnd) SCSI_SENSE_BUFFERSIZE
|
||||
#define XS_SNSKEY(Cmnd) (XS_SNSP(Cmnd)[2] & 0xf)
|
||||
#define XS_TAG_P(Cmnd) (Cmnd->device->tagged_supported != 0)
|
||||
#define XS_TAG_TYPE isplinux_tagtype
|
||||
|
||||
#define XS_SETERR(xs, v) \
|
||||
if ((v) == HBA_TGTBSY) { \
|
||||
(xs)->SCp.Status = SCSI_BUSY; \
|
||||
} else { \
|
||||
(xs)->result &= ~0xff0000; \
|
||||
(xs)->result |= ((v) << 16); \
|
||||
}
|
||||
|
||||
#define HBA_NOERROR DID_OK
|
||||
#define HBA_BOTCH DID_ERROR
|
||||
#define HBA_CMDTIMEOUT DID_TIME_OUT
|
||||
#define HBA_SELTIMEOUT DID_NO_CONNECT
|
||||
#define HBA_TGTBSY 123456 /* special handling */
|
||||
#define HBA_BUSRESET DID_RESET
|
||||
#define HBA_ABORTED DID_ABORT
|
||||
#define HBA_DATAOVR DID_ERROR
|
||||
#define HBA_ARQFAIL DID_ERROR
|
||||
|
||||
#define XS_ERR(xs) host_byte((xs)->result)
|
||||
|
||||
#define XS_NOERR(xs) host_byte((xs)->result) == DID_OK
|
||||
|
||||
#define XS_INITERR(xs) (xs)->result = 0, (xs)->SCp.Status = 0
|
||||
|
||||
#define XS_SAVE_SENSE(Cmnd, s, l) memcpy(XS_SNSP(Cmnd), s, min(XS_SNSLEN(Cmnd), l))
|
||||
|
||||
#define XS_SET_STATE_STAT(a, b, c)
|
||||
|
||||
#define GET_DEFAULT_ROLE isplinux_get_default_role
|
||||
#define SET_DEFAULT_ROLE isplinux_set_default_role
|
||||
#define DEFAULT_IID isplinux_get_default_id
|
||||
#define DEFAULT_LOOPID isplinux_get_default_id
|
||||
#define DEFAULT_FRAMESIZE(isp) isp->isp_osinfo.frame_size
|
||||
#define DEFAULT_EXEC_THROTTLE(isp) isp->isp_osinfo.exec_throttle
|
||||
#define DEFAULT_NODEWWN(isp, chan) isplinux_default_wwn(isp, chan, 0, 1)
|
||||
#define DEFAULT_PORTWWN(isp, chan) isplinux_default_wwn(isp, chan, 0, 0)
|
||||
#define ACTIVE_NODEWWN(isp, chan) isplinux_default_wwn(isp, chan, 1, 1)
|
||||
#define ACTIVE_PORTWWN(isp, chan) isplinux_default_wwn(isp, chan, 1, 0)
|
||||
|
||||
#define ISP_IOXPUT_8(isp, s, d) *(d) = s
|
||||
#define ISP_IOXPUT_16(isp, s, d) *(d) = cpu_to_le16(s)
|
||||
#define ISP_IOXPUT_32(isp, s, d) *(d) = cpu_to_le32(s)
|
||||
#define ISP_IOXGET_8(isp, s, d) d = *(s)
|
||||
#define ISP_IOXGET_16(isp, s, d) d = le16_to_cpu(*((uint16_t *)s))
|
||||
#define ISP_IOXGET_32(isp, s, d) d = le32_to_cpu(*((uint32_t *)s))
|
||||
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
#define ISP_IOX_8X2(isp, sptr, dptr, tag1, tag2) \
|
||||
dptr ## -> ## tag1 = sptr ## -> ## tag2; \
|
||||
dptr ## -> ## tag2 = sptr ## -> ## tag1
|
||||
#define ISP_IOZ_8X2(isp, sptr, dptr, tag1, tag2) \
|
||||
dptr ## -> ## tag1 = sptr ## -> ## tag1; \
|
||||
dptr ## -> ## tag2 = sptr ## -> ## tag2
|
||||
#else
|
||||
#define ISP_IOX_8X2(isp, sptr, dptr, tag1, tag2) \
|
||||
dptr ## -> ## tag1 = sptr ## -> ## tag1; \
|
||||
dptr ## -> ## tag2 = sptr ## -> ## tag2
|
||||
#define ISP_IOZ_8X2(isp, sptr, dptr, tag1, tag2) \
|
||||
dptr ## -> ## tag1 = sptr ## -> ## tag2; \
|
||||
dptr ## -> ## tag2 = sptr ## -> ## tag1
|
||||
#endif
|
||||
|
||||
#define ISP_IOZPUT_8 ISP_IOXPUT_8
|
||||
#define ISP_IOZPUT_16(isp, s, d) *(d) = cpu_to_be16(s)
|
||||
#define ISP_IOZPUT_32(isp, s, d) *(d) = cpu_to_be32(s)
|
||||
#define ISP_IOZGET_8 ISP_IOXGET_8
|
||||
#define ISP_IOZGET_16(isp, s, d) d = be16_to_cpu(*((uint16_t *)s))
|
||||
#define ISP_IOZGET_32(isp, s, d) d = be32_to_cpu(*((uint32_t *)s))
|
||||
|
||||
#define ISP_SWIZZLE_NVRAM_WORD(isp, rp) *rp = le16_to_cpu(*rp)
|
||||
#define ISP_SWIZZLE_NVRAM_LONG(isp, rp) *rp = le32_to_cpu(*rp)
|
||||
|
||||
#define ISP_SWAP16(isp, x) swab16(x)
|
||||
#define ISP_SWAP32(isp, x) swab32(x)
|
||||
|
||||
|
||||
/*
|
||||
* Includes of common header files
|
||||
*/
|
||||
#include "ispreg.h"
|
||||
#include "ispvar.h"
|
||||
|
||||
#if defined(__GNUC__) || defined(__INTEL_COMPILER)
|
||||
void isp_prt(ispsoftc_t *, int level, const char *, ...) __attribute__((__format__(__printf__, 3, 4)));
|
||||
#else
|
||||
void isp_prt(ispsoftc_t *, int level, const char *, ...);
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* isp_osinfo definitions, extensions and shorthand.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Parameter and platform per-channel storage.
|
||||
*/
|
||||
typedef struct {
|
||||
uint64_t def_wwnn;
|
||||
uint64_t def_wwpn;
|
||||
uint32_t
|
||||
tgts_tested : 16,
|
||||
: 11,
|
||||
scratch_busy : 1,
|
||||
blocked : 1,
|
||||
deadloop : 1,
|
||||
role : 2;
|
||||
unsigned long downcount, nextscan;
|
||||
unsigned int qfdelay;
|
||||
} isp_data;
|
||||
|
||||
#define ISP_DATA(isp, chan) (&((isp_data *)((isp)->isp_osinfo.storep))[chan])
|
||||
|
||||
#define isp_name isp_osinfo.hbaname
|
||||
#define isp_host isp_osinfo.host
|
||||
#define isp_unit isp_osinfo.host->unique_id
|
||||
|
||||
/*
|
||||
* Driver prototypes..
|
||||
*/
|
||||
void isplinux_timer(unsigned long);
|
||||
void isplinux_mbtimer(unsigned long);
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
|
||||
irqreturn_t isplinux_intr(int, void *, struct pt_regs *);
|
||||
#else
|
||||
irqreturn_t isplinux_intr(int, void *);
|
||||
#endif
|
||||
int isplinux_common_init(ispsoftc_t *);
|
||||
#ifdef CONFIG_PROC_FS
|
||||
void isplinux_init_proc(ispsoftc_t *);
|
||||
void isplinux_undo_proc(ispsoftc_t *);
|
||||
#endif
|
||||
int isplinux_reinit(ispsoftc_t *, int);
|
||||
void isplinux_sqd(struct Scsi_Host *, struct scsi_device *);
|
||||
|
||||
int isp_thread_event(ispsoftc_t *, int, void *, int, const char *, const int line);
|
||||
|
||||
static ISP_INLINE uint64_t _isp_microtime_sub(struct timeval *, struct timeval *);
|
||||
static ISP_INLINE void _isp_usec_delay(unsigned int);
|
||||
static ISP_INLINE unsigned long _usec_to_jiffies(unsigned int);
|
||||
static ISP_INLINE unsigned long _jiffies_to_usec(unsigned long);
|
||||
static ISP_INLINE int isplinux_tagtype(Scsi_Cmnd *);
|
||||
static ISP_INLINE void mbox_wait_complete(ispsoftc_t *, mbreg_t *);
|
||||
|
||||
int isplinux_proc_info(struct Scsi_Host *, char *, char **, off_t, int, int);
|
||||
const char *isplinux_info(struct Scsi_Host *);
|
||||
int isplinux_queuecommand(Scsi_Cmnd *, void (* done)(Scsi_Cmnd *));
|
||||
int isplinux_biosparam(struct scsi_device *, struct block_device *, sector_t, int[]);
|
||||
int isplinux_get_default_id(ispsoftc_t *, int);
|
||||
int isplinux_get_default_role(ispsoftc_t *, int);
|
||||
void isplinux_set_default_role(ispsoftc_t *, int, int);
|
||||
uint64_t isplinux_default_wwn(ispsoftc_t *, int, int, int);
|
||||
|
||||
|
||||
/*
|
||||
* Driver wide data...
|
||||
*/
|
||||
extern int isp_debug;
|
||||
extern int isp_unit_seed;
|
||||
extern int isp_disable;
|
||||
extern int isp_nofwreload;
|
||||
extern int isp_nonvram;
|
||||
extern int isp_fcduplex;
|
||||
extern int isp_maxsectors;
|
||||
extern struct scsi_host_template *isp_template;
|
||||
extern const char *class3_roles[4];
|
||||
extern int isp_vports;
|
||||
extern dev_t isp_dev;
|
||||
extern struct cdev isp_cdev;
|
||||
extern struct file_operations isp_ioctl_operations;
|
||||
extern ISP_CLASS *isp_class;
|
||||
|
||||
/*
|
||||
* This used to be considered bad form, but locking crap made it more attractive.
|
||||
*/
|
||||
#define MAX_ISP 32
|
||||
extern ispsoftc_t *isplist[MAX_ISP];
|
||||
extern ispsoftc_t *api_isp;
|
||||
extern int api_channel;
|
||||
|
||||
/*
|
||||
* Platform private flags
|
||||
*/
|
||||
#ifndef NULL
|
||||
#define NULL ((void *) 0)
|
||||
#endif
|
||||
|
||||
#define ISP_WATCH_TPS 10
|
||||
#define ISP_WATCH_TIME (HZ / ISP_WATCH_TPS)
|
||||
#define ISP_SCAN_TIMEOUT (2 * ISP_WATCH_TPS)
|
||||
#define ISP_RESCAN_TIMEOUT ISP_WATCH_TPS
|
||||
|
||||
#ifndef min
|
||||
#define min(a,b) (((a)<(b))?(a):(b))
|
||||
#endif
|
||||
#ifndef max
|
||||
#define max(a, b) (((a) > (b)) ? (a) : (b))
|
||||
#endif
|
||||
#ifndef roundup
|
||||
#define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Platform specific 'inline' or support functions
|
||||
*/
|
||||
|
||||
#ifdef __sparc__
|
||||
#define _SBSWAP(isp, b, c) \
|
||||
if (isp->isp_bustype == ISP_BT_SBUS) { \
|
||||
uint8_t tmp = b; \
|
||||
b = c; \
|
||||
c = tmp; \
|
||||
}
|
||||
#else
|
||||
#define _SBSWAP(a, b, c)
|
||||
#endif
|
||||
|
||||
static ISP_INLINE uint64_t
|
||||
_isp_microtime_sub(struct timeval *b, struct timeval *a)
|
||||
{
|
||||
uint64_t elapsed;
|
||||
struct timeval x = *b;
|
||||
x.tv_sec -= a->tv_sec;
|
||||
x.tv_usec -= a->tv_usec;
|
||||
if (x.tv_usec < 0) {
|
||||
x.tv_sec--;
|
||||
x.tv_usec += 1000000;
|
||||
}
|
||||
if (x.tv_usec >= 1000000) {
|
||||
x.tv_sec++;
|
||||
x.tv_usec -= 1000000;
|
||||
}
|
||||
elapsed = GET_NANOSEC(&x);
|
||||
if (elapsed == 0)
|
||||
elapsed++;
|
||||
if ((int64_t) elapsed < 0) /* !!!! */
|
||||
return (1000);
|
||||
return (elapsed * 1000);
|
||||
}
|
||||
|
||||
static ISP_INLINE void
|
||||
_isp_usec_delay(unsigned int usecs)
|
||||
{
|
||||
while (usecs > 1000) {
|
||||
mdelay(1);
|
||||
usecs -= 1000;
|
||||
}
|
||||
if (usecs)
|
||||
udelay(usecs);
|
||||
}
|
||||
|
||||
static ISP_INLINE unsigned long
|
||||
_usec_to_jiffies(unsigned int usecs)
|
||||
{
|
||||
struct timespec lt;
|
||||
if (usecs == 0)
|
||||
usecs++;
|
||||
lt.tv_sec = 0;
|
||||
lt.tv_nsec = usecs * 1000;
|
||||
return (timespec_to_jiffies(<));
|
||||
}
|
||||
|
||||
static ISP_INLINE unsigned long
|
||||
_jiffies_to_usec(unsigned long jiffies)
|
||||
{
|
||||
unsigned long usecs;
|
||||
struct timespec lt;
|
||||
jiffies++;
|
||||
jiffies_to_timespec((unsigned long) jiffies, <);
|
||||
usecs = (lt.tv_sec * 1000000L);
|
||||
usecs += (lt.tv_nsec * 1000);
|
||||
return (usecs);
|
||||
}
|
||||
|
||||
#ifndef MSG_SIMPLE_TAG
|
||||
#define MSG_SIMPLE_TAG 0x20
|
||||
#endif
|
||||
#ifndef MSG_HEAD_TAG
|
||||
#define MSG_HEAD_TAG 0x21
|
||||
#endif
|
||||
#ifndef MSG_ORDERED_TAG
|
||||
#define MSG_ORDERED_TAG 0x22
|
||||
#endif
|
||||
|
||||
static ISP_INLINE int
|
||||
isplinux_tagtype(Scsi_Cmnd *Cmnd)
|
||||
{
|
||||
switch (Cmnd->tag) {
|
||||
case MSG_ORDERED_TAG:
|
||||
return (REQFLAG_OTAG);
|
||||
case MSG_SIMPLE_TAG:
|
||||
return (REQFLAG_STAG);
|
||||
case MSG_HEAD_TAG:
|
||||
return (REQFLAG_HTAG);
|
||||
default:
|
||||
return (REQFLAG_STAG);
|
||||
}
|
||||
}
|
||||
|
||||
static ISP_INLINE void
|
||||
mbox_wait_complete(ispsoftc_t *isp, mbreg_t *mbp)
|
||||
{
|
||||
uint32_t lim = mbp->timeout;
|
||||
unsigned long et, tt = jiffies;
|
||||
|
||||
if (lim == 0) {
|
||||
lim = MBCMD_DEFAULT_TIMEOUT;
|
||||
}
|
||||
if (isp->isp_mbxwrk0) {
|
||||
lim *= isp->isp_mbxwrk0;
|
||||
}
|
||||
|
||||
isp->mboxcmd_done = 0;
|
||||
if (ISP_MUST_POLL(isp)) {
|
||||
int j;
|
||||
|
||||
for (j = 0; j < lim; j += 100) {
|
||||
uint32_t isr;
|
||||
uint16_t sema, mbox;
|
||||
if (isp->mboxcmd_done) {
|
||||
break;
|
||||
}
|
||||
if (ISP_READ_ISR(isp, &isr, &sema, &mbox)) {
|
||||
isp_intr(isp, isr, sema, mbox);
|
||||
if (isp->mboxcmd_done) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
ISP_ENABLE_INTS(isp);
|
||||
ISP_DROP_LK_SOFTC(isp);
|
||||
udelay(100);
|
||||
ISP_IGET_LK_SOFTC(isp);
|
||||
if (isp->mboxcmd_done) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isp->mboxcmd_done == 0) {
|
||||
isp_prt(isp, ISP_LOGWARN, "Polled Mailbox Command (0x%x) Timeout (%lu elapsed usec)", isp->isp_lastmbxcmd, _jiffies_to_usec(jiffies - tt));
|
||||
mbp->param[0] = MBOX_TIMEOUT;
|
||||
}
|
||||
} else {
|
||||
isp_prt(isp, ISP_LOGDEBUG1, "Start Interrupting Mailbox Command (%x)", isp->isp_lastmbxcmd);
|
||||
ISP_ENABLE_INTS(isp);
|
||||
ISP_DROP_LK_SOFTC(isp);
|
||||
et = wait_event_timeout(isp->isp_osinfo.mboxwq, isp->mboxcmd_done, usecs_to_jiffies(lim));
|
||||
ISP_IGET_LK_SOFTC(isp);
|
||||
if (et == 0) {
|
||||
isp_prt(isp, ISP_LOGWARN, "Interrupting Mailbox Command (0x%x) Timeout (elapsed time %lu usec)", isp->isp_lastmbxcmd, _jiffies_to_usec(jiffies - tt));
|
||||
mbp->param[0] = MBOX_TIMEOUT;
|
||||
} else {
|
||||
isp_prt(isp, ISP_LOGDEBUG1, "Interrupting Mailbox Command (0x%x) done (%lu usec)", isp->isp_lastmbxcmd, _jiffies_to_usec(et));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static ISP_INLINE int
|
||||
fc_scratch_acquire(ispsoftc_t *isp, int chan)
|
||||
{
|
||||
if (ISP_DATA(isp, chan)->scratch_busy) {
|
||||
return (-1);
|
||||
}
|
||||
ISP_DATA(isp, chan)->scratch_busy = 1;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Note that these allocators aren't interrupt safe
|
||||
*/
|
||||
static ISP_INLINE void * isp_kalloc(size_t, int);
|
||||
static ISP_INLINE void isp_kfree(void *, size_t);
|
||||
static ISP_INLINE void * isp_kzalloc(size_t, int);
|
||||
|
||||
static ISP_INLINE void *
|
||||
isp_kalloc(size_t size, int flags)
|
||||
{
|
||||
void *ptr;
|
||||
if (size >= PAGE_SIZE) {
|
||||
ptr = vmalloc(size);
|
||||
} else {
|
||||
ptr = kmalloc(size, flags);
|
||||
}
|
||||
return (ptr);
|
||||
}
|
||||
|
||||
static ISP_INLINE void
|
||||
isp_kfree(void *ptr, size_t size)
|
||||
{
|
||||
if (size >= PAGE_SIZE) {
|
||||
vfree(ptr);
|
||||
} else {
|
||||
kfree(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
static ISP_INLINE void *
|
||||
isp_kzalloc(size_t size, int flags)
|
||||
{
|
||||
void *ptr = isp_kalloc(size, flags);
|
||||
if (ptr != NULL){
|
||||
memset(ptr, 0, size);
|
||||
}
|
||||
return (ptr);
|
||||
}
|
||||
|
||||
#define COPYIN(uarg, karg, amt) copy_from_user(karg, uarg, amt)
|
||||
#define COPYOUT(karg, uarg, amt) copy_to_user(uarg, karg, amt)
|
||||
|
||||
static ISP_INLINE void
|
||||
isp_get_dma64_seg(ispds64_t *dsp, struct scatterlist *sg, uint32_t sgidx)
|
||||
{
|
||||
sg += sgidx;
|
||||
dsp->ds_base = DMA_LO32(sg_dma_address(sg));
|
||||
dsp->ds_basehi = DMA_HI32(sg_dma_address(sg));
|
||||
dsp->ds_count = sg_dma_len(sg);
|
||||
}
|
||||
|
||||
static ISP_INLINE void
|
||||
isp_get_dma_seg(ispds_t *dsp, struct scatterlist *sg, uint32_t sgidx)
|
||||
{
|
||||
sg += sgidx;
|
||||
dsp->ds_base = sg_dma_address(sg);
|
||||
dsp->ds_count = sg_dma_len(sg);
|
||||
}
|
||||
|
||||
/*
|
||||
* Common inline functions
|
||||
*/
|
||||
|
||||
#include "isp_library.h"
|
||||
|
||||
#ifdef ISP_TARGET_MODE
|
||||
#include "isp_tpublic.h"
|
||||
|
||||
int isp_init_target(ispsoftc_t *);
|
||||
void isp_attach_target(ispsoftc_t *);
|
||||
void isp_deinit_target(ispsoftc_t *);
|
||||
void isp_detach_target(ispsoftc_t *);
|
||||
int isp_target_async(ispsoftc_t *, int, int);
|
||||
int isp_target_notify(ispsoftc_t *, void *, uint32_t *);
|
||||
int isp_enable_lun(ispsoftc_t *, uint16_t, uint16_t);
|
||||
int isp_disable_lun(ispsoftc_t *, uint16_t, uint16_t);
|
||||
|
||||
struct notify {
|
||||
isp_notify_t notify;
|
||||
uint8_t qentry[QENTRY_LEN]; /* original immediate notify entry */
|
||||
uint8_t qevalid;
|
||||
uint8_t tmf_resp;
|
||||
};
|
||||
#endif
|
||||
/*
|
||||
* Config data
|
||||
*/
|
||||
|
||||
int isplinux_abort(Scsi_Cmnd *);
|
||||
int isplinux_bdr(Scsi_Cmnd *);
|
||||
int isplinux_sreset(Scsi_Cmnd *);
|
||||
int isplinux_hreset(Scsi_Cmnd *);
|
||||
#endif /* _ISP_LINUX_H */
|
||||
/*
|
||||
* vim:ts=4:sw=4:expandtab
|
||||
*/
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -5969,6 +5969,7 @@ ssize_t scst_readv(struct file *file, const struct iovec *vec,
|
||||
struct iovec *iov = iovstack;
|
||||
struct iov_iter iter;
|
||||
|
||||
set_fs(KERNEL_DS);
|
||||
WARN_ON_ONCE(scst_cmp_fs_ds() != 0);
|
||||
|
||||
result = import_iovec(READ, (const struct iovec __force __user *)vec,
|
||||
@@ -5981,11 +5982,13 @@ ssize_t scst_readv(struct file *file, const struct iovec *vec,
|
||||
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0) || \
|
||||
(defined(CONFIG_SUSE_KERNEL) && \
|
||||
LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
|
||||
set_fs(KERNEL_DS);
|
||||
WARN_ON_ONCE(scst_cmp_fs_ds() != 0);
|
||||
|
||||
result = vfs_readv(file, (const struct iovec __user *)vec, vlen, pos,
|
||||
0);
|
||||
#else
|
||||
set_fs(KERNEL_DS);
|
||||
WARN_ON_ONCE(scst_cmp_fs_ds() != 0);
|
||||
|
||||
result = vfs_readv(file, (const struct iovec __user *)vec, vlen, pos);
|
||||
@@ -6016,6 +6019,7 @@ ssize_t scst_writev(struct file *file, const struct iovec *vec,
|
||||
struct iovec *iov = iovstack;
|
||||
struct iov_iter iter;
|
||||
|
||||
set_fs(KERNEL_DS);
|
||||
WARN_ON_ONCE(scst_cmp_fs_ds() != 0);
|
||||
|
||||
result = import_iovec(WRITE, (const struct iovec __force __user *)vec,
|
||||
@@ -6030,9 +6034,13 @@ ssize_t scst_writev(struct file *file, const struct iovec *vec,
|
||||
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0) || \
|
||||
(defined(CONFIG_SUSE_KERNEL) && \
|
||||
LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
|
||||
set_fs(KERNEL_DS);
|
||||
WARN_ON_ONCE(scst_cmp_fs_ds() != 0);
|
||||
result = vfs_writev(file, (const struct iovec __user *)vec, vlen, pos,
|
||||
0);
|
||||
#else
|
||||
set_fs(KERNEL_DS);
|
||||
WARN_ON_ONCE(scst_cmp_fs_ds() != 0);
|
||||
result = vfs_writev(file, (const struct iovec __user *)vec, vlen, pos);
|
||||
#endif
|
||||
set_fs(old_fs);
|
||||
|
||||
Reference in New Issue
Block a user