mirror of
https://github.com/armbian/linux.git
synced 2026-01-06 10:13:00 -08:00
Merge master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-for-linus-2.6
This commit is contained in:
45
Documentation/scsi/LICENSE.qla2xxx
Normal file
45
Documentation/scsi/LICENSE.qla2xxx
Normal file
@@ -0,0 +1,45 @@
|
||||
Copyright (c) 2003-2005 QLogic Corporation
|
||||
QLogic Linux Fibre Channel HBA Driver
|
||||
|
||||
This program includes a device driver for Linux 2.6 that may be
|
||||
distributed with QLogic hardware specific firmware binary file.
|
||||
You may modify and redistribute the device driver code under the
|
||||
GNU General Public License as published by the Free Software
|
||||
Foundation (version 2 or a later version).
|
||||
|
||||
You may redistribute the hardware specific firmware binary file
|
||||
under the following terms:
|
||||
|
||||
1. Redistribution of source code (only if applicable),
|
||||
must retain the above copyright notice, this list of
|
||||
conditions and the following disclaimer.
|
||||
|
||||
2. Redistribution 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.
|
||||
|
||||
3. The name of QLogic Corporation may not be used to
|
||||
endorse or promote products derived from this software
|
||||
without specific prior written permission
|
||||
|
||||
REGARDLESS OF WHAT LICENSING MECHANISM IS USED OR APPLICABLE,
|
||||
THIS PROGRAM IS PROVIDED BY QLOGIC CORPORATION "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 THE AUTHOR
|
||||
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.
|
||||
|
||||
USER ACKNOWLEDGES AND AGREES THAT USE OF THIS PROGRAM WILL NOT
|
||||
CREATE OR GIVE GROUNDS FOR A LICENSE BY IMPLICATION, ESTOPPEL, OR
|
||||
OTHERWISE IN ANY INTELLECTUAL PROPERTY RIGHTS (PATENT, COPYRIGHT,
|
||||
TRADE SECRET, MASK WORK, OR OTHER PROPRIETARY RIGHT) EMBODIED IN
|
||||
ANY OTHER QLOGIC HARDWARE OR SOFTWARE EITHER SOLELY OR IN
|
||||
COMBINATION WITH THIS PROGRAM.
|
||||
@@ -77,8 +77,8 @@
|
||||
#define COPYRIGHT "Copyright (c) 1999-2005 " MODULEAUTHOR
|
||||
#endif
|
||||
|
||||
#define MPT_LINUX_VERSION_COMMON "3.03.03"
|
||||
#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.03.03"
|
||||
#define MPT_LINUX_VERSION_COMMON "3.03.04"
|
||||
#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.03.04"
|
||||
#define WHAT_MAGIC_STRING "@" "(" "#" ")"
|
||||
|
||||
#define show_mptmod_ver(s,ver) \
|
||||
@@ -421,6 +421,17 @@ typedef struct _MPT_IOCTL {
|
||||
struct semaphore sem_ioc;
|
||||
} MPT_IOCTL;
|
||||
|
||||
#define MPT_SAS_MGMT_STATUS_RF_VALID 0x02 /* The Reply Frame is VALID */
|
||||
#define MPT_SAS_MGMT_STATUS_COMMAND_GOOD 0x10 /* Command Status GOOD */
|
||||
#define MPT_SAS_MGMT_STATUS_TM_FAILED 0x40 /* User TM request failed */
|
||||
|
||||
typedef struct _MPT_SAS_MGMT {
|
||||
struct semaphore mutex;
|
||||
struct completion done;
|
||||
u8 reply[MPT_DEFAULT_FRAME_SIZE]; /* reply frame data */
|
||||
u8 status; /* current command status */
|
||||
}MPT_SAS_MGMT;
|
||||
|
||||
/*
|
||||
* Event Structure and define
|
||||
*/
|
||||
@@ -604,6 +615,7 @@ typedef struct _MPT_ADAPTER
|
||||
struct list_head list;
|
||||
struct net_device *netdev;
|
||||
struct list_head sas_topology;
|
||||
MPT_SAS_MGMT sas_mgmt;
|
||||
} MPT_ADAPTER;
|
||||
|
||||
/*
|
||||
|
||||
@@ -83,6 +83,7 @@ MODULE_PARM_DESC(mpt_pt_clear,
|
||||
static int mptsasDoneCtx = -1;
|
||||
static int mptsasTaskCtx = -1;
|
||||
static int mptsasInternalCtx = -1; /* Used only for internal commands */
|
||||
static int mptsasMgmtCtx = -1;
|
||||
|
||||
|
||||
/*
|
||||
@@ -123,6 +124,104 @@ struct mptsas_portinfo {
|
||||
struct mptsas_phyinfo *phy_info;
|
||||
};
|
||||
|
||||
|
||||
#ifdef SASDEBUG
|
||||
static void mptsas_print_phy_data(MPI_SAS_IO_UNIT0_PHY_DATA *phy_data)
|
||||
{
|
||||
printk("---- IO UNIT PAGE 0 ------------\n");
|
||||
printk("Handle=0x%X\n",
|
||||
le16_to_cpu(phy_data->AttachedDeviceHandle));
|
||||
printk("Controller Handle=0x%X\n",
|
||||
le16_to_cpu(phy_data->ControllerDevHandle));
|
||||
printk("Port=0x%X\n", phy_data->Port);
|
||||
printk("Port Flags=0x%X\n", phy_data->PortFlags);
|
||||
printk("PHY Flags=0x%X\n", phy_data->PhyFlags);
|
||||
printk("Negotiated Link Rate=0x%X\n", phy_data->NegotiatedLinkRate);
|
||||
printk("Controller PHY Device Info=0x%X\n",
|
||||
le32_to_cpu(phy_data->ControllerPhyDeviceInfo));
|
||||
printk("DiscoveryStatus=0x%X\n",
|
||||
le32_to_cpu(phy_data->DiscoveryStatus));
|
||||
printk("\n");
|
||||
}
|
||||
|
||||
static void mptsas_print_phy_pg0(SasPhyPage0_t *pg0)
|
||||
{
|
||||
__le64 sas_address;
|
||||
|
||||
memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
|
||||
|
||||
printk("---- SAS PHY PAGE 0 ------------\n");
|
||||
printk("Attached Device Handle=0x%X\n",
|
||||
le16_to_cpu(pg0->AttachedDevHandle));
|
||||
printk("SAS Address=0x%llX\n",
|
||||
(unsigned long long)le64_to_cpu(sas_address));
|
||||
printk("Attached PHY Identifier=0x%X\n", pg0->AttachedPhyIdentifier);
|
||||
printk("Attached Device Info=0x%X\n",
|
||||
le32_to_cpu(pg0->AttachedDeviceInfo));
|
||||
printk("Programmed Link Rate=0x%X\n", pg0->ProgrammedLinkRate);
|
||||
printk("Change Count=0x%X\n", pg0->ChangeCount);
|
||||
printk("PHY Info=0x%X\n", le32_to_cpu(pg0->PhyInfo));
|
||||
printk("\n");
|
||||
}
|
||||
|
||||
static void mptsas_print_phy_pg1(SasPhyPage1_t *pg1)
|
||||
{
|
||||
printk("---- SAS PHY PAGE 1 ------------\n");
|
||||
printk("Invalid Dword Count=0x%x\n", pg1->InvalidDwordCount);
|
||||
printk("Running Disparity Error Count=0x%x\n",
|
||||
pg1->RunningDisparityErrorCount);
|
||||
printk("Loss Dword Synch Count=0x%x\n", pg1->LossDwordSynchCount);
|
||||
printk("PHY Reset Problem Count=0x%x\n", pg1->PhyResetProblemCount);
|
||||
printk("\n");
|
||||
}
|
||||
|
||||
static void mptsas_print_device_pg0(SasDevicePage0_t *pg0)
|
||||
{
|
||||
__le64 sas_address;
|
||||
|
||||
memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
|
||||
|
||||
printk("---- SAS DEVICE PAGE 0 ---------\n");
|
||||
printk("Handle=0x%X\n" ,le16_to_cpu(pg0->DevHandle));
|
||||
printk("Enclosure Handle=0x%X\n", le16_to_cpu(pg0->EnclosureHandle));
|
||||
printk("Slot=0x%X\n", le16_to_cpu(pg0->Slot));
|
||||
printk("SAS Address=0x%llX\n", le64_to_cpu(sas_address));
|
||||
printk("Target ID=0x%X\n", pg0->TargetID);
|
||||
printk("Bus=0x%X\n", pg0->Bus);
|
||||
/* The PhyNum field specifies the PHY number of the parent
|
||||
* device this device is linked to
|
||||
*/
|
||||
printk("Parent Phy Num=0x%X\n", pg0->PhyNum);
|
||||
printk("Access Status=0x%X\n", le16_to_cpu(pg0->AccessStatus));
|
||||
printk("Device Info=0x%X\n", le32_to_cpu(pg0->DeviceInfo));
|
||||
printk("Flags=0x%X\n", le16_to_cpu(pg0->Flags));
|
||||
printk("Physical Port=0x%X\n", pg0->PhysicalPort);
|
||||
printk("\n");
|
||||
}
|
||||
|
||||
static void mptsas_print_expander_pg1(SasExpanderPage1_t *pg1)
|
||||
{
|
||||
printk("---- SAS EXPANDER PAGE 1 ------------\n");
|
||||
|
||||
printk("Physical Port=0x%X\n", pg1->PhysicalPort);
|
||||
printk("PHY Identifier=0x%X\n", pg1->PhyIdentifier);
|
||||
printk("Negotiated Link Rate=0x%X\n", pg1->NegotiatedLinkRate);
|
||||
printk("Programmed Link Rate=0x%X\n", pg1->ProgrammedLinkRate);
|
||||
printk("Hardware Link Rate=0x%X\n", pg1->HwLinkRate);
|
||||
printk("Owner Device Handle=0x%X\n",
|
||||
le16_to_cpu(pg1->OwnerDevHandle));
|
||||
printk("Attached Device Handle=0x%X\n",
|
||||
le16_to_cpu(pg1->AttachedDevHandle));
|
||||
}
|
||||
#else
|
||||
#define mptsas_print_phy_data(phy_data) do { } while (0)
|
||||
#define mptsas_print_phy_pg0(pg0) do { } while (0)
|
||||
#define mptsas_print_phy_pg1(pg1) do { } while (0)
|
||||
#define mptsas_print_device_pg0(pg0) do { } while (0)
|
||||
#define mptsas_print_expander_pg1(pg1) do { } while (0)
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* This is pretty ugly. We will be able to seriously clean it up
|
||||
* once the DV code in mptscsih goes away and we can properly
|
||||
@@ -200,92 +299,160 @@ static struct scsi_host_template mptsas_driver_template = {
|
||||
.use_clustering = ENABLE_CLUSTERING,
|
||||
};
|
||||
|
||||
static inline MPT_ADAPTER *phy_to_ioc(struct sas_phy *phy)
|
||||
{
|
||||
struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
|
||||
return ((MPT_SCSI_HOST *)shost->hostdata)->ioc;
|
||||
}
|
||||
|
||||
static int mptsas_get_linkerrors(struct sas_phy *phy)
|
||||
{
|
||||
MPT_ADAPTER *ioc = phy_to_ioc(phy);
|
||||
ConfigExtendedPageHeader_t hdr;
|
||||
CONFIGPARMS cfg;
|
||||
SasPhyPage1_t *buffer;
|
||||
dma_addr_t dma_handle;
|
||||
int error;
|
||||
|
||||
hdr.PageVersion = MPI_SASPHY1_PAGEVERSION;
|
||||
hdr.ExtPageLength = 0;
|
||||
hdr.PageNumber = 1 /* page number 1*/;
|
||||
hdr.Reserved1 = 0;
|
||||
hdr.Reserved2 = 0;
|
||||
hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
|
||||
hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
|
||||
|
||||
cfg.cfghdr.ehdr = &hdr;
|
||||
cfg.physAddr = -1;
|
||||
cfg.pageAddr = phy->identify.phy_identifier;
|
||||
cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
|
||||
cfg.dir = 0; /* read */
|
||||
cfg.timeout = 10;
|
||||
|
||||
error = mpt_config(ioc, &cfg);
|
||||
if (error)
|
||||
return error;
|
||||
if (!hdr.ExtPageLength)
|
||||
return -ENXIO;
|
||||
|
||||
buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
|
||||
&dma_handle);
|
||||
if (!buffer)
|
||||
return -ENOMEM;
|
||||
|
||||
cfg.physAddr = dma_handle;
|
||||
cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
|
||||
|
||||
error = mpt_config(ioc, &cfg);
|
||||
if (error)
|
||||
goto out_free_consistent;
|
||||
|
||||
mptsas_print_phy_pg1(buffer);
|
||||
|
||||
phy->invalid_dword_count = le32_to_cpu(buffer->InvalidDwordCount);
|
||||
phy->running_disparity_error_count =
|
||||
le32_to_cpu(buffer->RunningDisparityErrorCount);
|
||||
phy->loss_of_dword_sync_count =
|
||||
le32_to_cpu(buffer->LossDwordSynchCount);
|
||||
phy->phy_reset_problem_count =
|
||||
le32_to_cpu(buffer->PhyResetProblemCount);
|
||||
|
||||
out_free_consistent:
|
||||
pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
|
||||
buffer, dma_handle);
|
||||
return error;
|
||||
}
|
||||
|
||||
static int mptsas_mgmt_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
|
||||
MPT_FRAME_HDR *reply)
|
||||
{
|
||||
ioc->sas_mgmt.status |= MPT_SAS_MGMT_STATUS_COMMAND_GOOD;
|
||||
if (reply != NULL) {
|
||||
ioc->sas_mgmt.status |= MPT_SAS_MGMT_STATUS_RF_VALID;
|
||||
memcpy(ioc->sas_mgmt.reply, reply,
|
||||
min(ioc->reply_sz, 4 * reply->u.reply.MsgLength));
|
||||
}
|
||||
complete(&ioc->sas_mgmt.done);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int mptsas_phy_reset(struct sas_phy *phy, int hard_reset)
|
||||
{
|
||||
MPT_ADAPTER *ioc = phy_to_ioc(phy);
|
||||
SasIoUnitControlRequest_t *req;
|
||||
SasIoUnitControlReply_t *reply;
|
||||
MPT_FRAME_HDR *mf;
|
||||
MPIHeader_t *hdr;
|
||||
unsigned long timeleft;
|
||||
int error = -ERESTARTSYS;
|
||||
|
||||
/* not implemented for expanders */
|
||||
if (phy->identify.target_port_protocols & SAS_PROTOCOL_SMP)
|
||||
return -ENXIO;
|
||||
|
||||
if (down_interruptible(&ioc->sas_mgmt.mutex))
|
||||
goto out;
|
||||
|
||||
mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
|
||||
if (!mf) {
|
||||
error = -ENOMEM;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
hdr = (MPIHeader_t *) mf;
|
||||
req = (SasIoUnitControlRequest_t *)mf;
|
||||
memset(req, 0, sizeof(SasIoUnitControlRequest_t));
|
||||
req->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
|
||||
req->MsgContext = hdr->MsgContext;
|
||||
req->Operation = hard_reset ?
|
||||
MPI_SAS_OP_PHY_HARD_RESET : MPI_SAS_OP_PHY_LINK_RESET;
|
||||
req->PhyNum = phy->identify.phy_identifier;
|
||||
|
||||
mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
|
||||
|
||||
timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done,
|
||||
10 * HZ);
|
||||
if (!timeleft) {
|
||||
/* On timeout reset the board */
|
||||
mpt_free_msg_frame(ioc, mf);
|
||||
mpt_HardResetHandler(ioc, CAN_SLEEP);
|
||||
error = -ETIMEDOUT;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
/* a reply frame is expected */
|
||||
if ((ioc->sas_mgmt.status &
|
||||
MPT_IOCTL_STATUS_RF_VALID) == 0) {
|
||||
error = -ENXIO;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
/* process the completed Reply Message Frame */
|
||||
reply = (SasIoUnitControlReply_t *)ioc->sas_mgmt.reply;
|
||||
if (reply->IOCStatus != MPI_IOCSTATUS_SUCCESS) {
|
||||
printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
|
||||
__FUNCTION__,
|
||||
reply->IOCStatus,
|
||||
reply->IOCLogInfo);
|
||||
error = -ENXIO;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
error = 0;
|
||||
|
||||
out_unlock:
|
||||
up(&ioc->sas_mgmt.mutex);
|
||||
out:
|
||||
return error;
|
||||
}
|
||||
|
||||
static struct sas_function_template mptsas_transport_functions = {
|
||||
.get_linkerrors = mptsas_get_linkerrors,
|
||||
.phy_reset = mptsas_phy_reset,
|
||||
};
|
||||
|
||||
static struct scsi_transport_template *mptsas_transport_template;
|
||||
|
||||
#ifdef SASDEBUG
|
||||
static void mptsas_print_phy_data(MPI_SAS_IO_UNIT0_PHY_DATA *phy_data)
|
||||
{
|
||||
printk("---- IO UNIT PAGE 0 ------------\n");
|
||||
printk("Handle=0x%X\n",
|
||||
le16_to_cpu(phy_data->AttachedDeviceHandle));
|
||||
printk("Controller Handle=0x%X\n",
|
||||
le16_to_cpu(phy_data->ControllerDevHandle));
|
||||
printk("Port=0x%X\n", phy_data->Port);
|
||||
printk("Port Flags=0x%X\n", phy_data->PortFlags);
|
||||
printk("PHY Flags=0x%X\n", phy_data->PhyFlags);
|
||||
printk("Negotiated Link Rate=0x%X\n", phy_data->NegotiatedLinkRate);
|
||||
printk("Controller PHY Device Info=0x%X\n",
|
||||
le32_to_cpu(phy_data->ControllerPhyDeviceInfo));
|
||||
printk("DiscoveryStatus=0x%X\n",
|
||||
le32_to_cpu(phy_data->DiscoveryStatus));
|
||||
printk("\n");
|
||||
}
|
||||
|
||||
static void mptsas_print_phy_pg0(SasPhyPage0_t *pg0)
|
||||
{
|
||||
__le64 sas_address;
|
||||
|
||||
memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
|
||||
|
||||
printk("---- SAS PHY PAGE 0 ------------\n");
|
||||
printk("Attached Device Handle=0x%X\n",
|
||||
le16_to_cpu(pg0->AttachedDevHandle));
|
||||
printk("SAS Address=0x%llX\n",
|
||||
(unsigned long long)le64_to_cpu(sas_address));
|
||||
printk("Attached PHY Identifier=0x%X\n", pg0->AttachedPhyIdentifier);
|
||||
printk("Attached Device Info=0x%X\n",
|
||||
le32_to_cpu(pg0->AttachedDeviceInfo));
|
||||
printk("Programmed Link Rate=0x%X\n", pg0->ProgrammedLinkRate);
|
||||
printk("Change Count=0x%X\n", pg0->ChangeCount);
|
||||
printk("PHY Info=0x%X\n", le32_to_cpu(pg0->PhyInfo));
|
||||
printk("\n");
|
||||
}
|
||||
|
||||
static void mptsas_print_device_pg0(SasDevicePage0_t *pg0)
|
||||
{
|
||||
__le64 sas_address;
|
||||
|
||||
memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
|
||||
|
||||
printk("---- SAS DEVICE PAGE 0 ---------\n");
|
||||
printk("Handle=0x%X\n" ,le16_to_cpu(pg0->DevHandle));
|
||||
printk("Enclosure Handle=0x%X\n", le16_to_cpu(pg0->EnclosureHandle));
|
||||
printk("Slot=0x%X\n", le16_to_cpu(pg0->Slot));
|
||||
printk("SAS Address=0x%llX\n", le64_to_cpu(sas_address));
|
||||
printk("Target ID=0x%X\n", pg0->TargetID);
|
||||
printk("Bus=0x%X\n", pg0->Bus);
|
||||
printk("Parent Phy Num=0x%X\n", pg0->PhyNum);
|
||||
printk("Access Status=0x%X\n", le16_to_cpu(pg0->AccessStatus));
|
||||
printk("Device Info=0x%X\n", le32_to_cpu(pg0->DeviceInfo));
|
||||
printk("Flags=0x%X\n", le16_to_cpu(pg0->Flags));
|
||||
printk("Physical Port=0x%X\n", pg0->PhysicalPort);
|
||||
printk("\n");
|
||||
}
|
||||
|
||||
static void mptsas_print_expander_pg1(SasExpanderPage1_t *pg1)
|
||||
{
|
||||
printk("---- SAS EXPANDER PAGE 1 ------------\n");
|
||||
|
||||
printk("Physical Port=0x%X\n", pg1->PhysicalPort);
|
||||
printk("PHY Identifier=0x%X\n", pg1->PhyIdentifier);
|
||||
printk("Negotiated Link Rate=0x%X\n", pg1->NegotiatedLinkRate);
|
||||
printk("Programmed Link Rate=0x%X\n", pg1->ProgrammedLinkRate);
|
||||
printk("Hardware Link Rate=0x%X\n", pg1->HwLinkRate);
|
||||
printk("Owner Device Handle=0x%X\n",
|
||||
le16_to_cpu(pg1->OwnerDevHandle));
|
||||
printk("Attached Device Handle=0x%X\n",
|
||||
le16_to_cpu(pg1->AttachedDevHandle));
|
||||
}
|
||||
#else
|
||||
#define mptsas_print_phy_data(phy_data) do { } while (0)
|
||||
#define mptsas_print_phy_pg0(pg0) do { } while (0)
|
||||
#define mptsas_print_device_pg0(pg0) do { } while (0)
|
||||
#define mptsas_print_expander_pg1(pg1) do { } while (0)
|
||||
#endif
|
||||
|
||||
static int
|
||||
mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
|
||||
{
|
||||
@@ -680,7 +847,7 @@ mptsas_parse_device_info(struct sas_identify *identify,
|
||||
}
|
||||
|
||||
static int mptsas_probe_one_phy(struct device *dev,
|
||||
struct mptsas_phyinfo *phy_info, int index)
|
||||
struct mptsas_phyinfo *phy_info, int index, int local)
|
||||
{
|
||||
struct sas_phy *port;
|
||||
int error;
|
||||
@@ -773,6 +940,9 @@ static int mptsas_probe_one_phy(struct device *dev,
|
||||
break;
|
||||
}
|
||||
|
||||
if (local)
|
||||
port->local_attached = 1;
|
||||
|
||||
error = sas_phy_add(port);
|
||||
if (error) {
|
||||
sas_phy_free(port);
|
||||
@@ -838,7 +1008,7 @@ mptsas_probe_hba_phys(MPT_ADAPTER *ioc, int *index)
|
||||
}
|
||||
|
||||
mptsas_probe_one_phy(&ioc->sh->shost_gendev,
|
||||
&port_info->phy_info[i], *index);
|
||||
&port_info->phy_info[i], *index, 1);
|
||||
(*index)++;
|
||||
}
|
||||
|
||||
@@ -909,7 +1079,8 @@ mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle, int *index)
|
||||
}
|
||||
}
|
||||
|
||||
mptsas_probe_one_phy(parent, &port_info->phy_info[i], *index);
|
||||
mptsas_probe_one_phy(parent, &port_info->phy_info[i],
|
||||
*index, 0);
|
||||
(*index)++;
|
||||
}
|
||||
|
||||
@@ -1021,6 +1192,8 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
sh->unique_id = ioc->id;
|
||||
|
||||
INIT_LIST_HEAD(&ioc->sas_topology);
|
||||
init_MUTEX(&ioc->sas_mgmt.mutex);
|
||||
init_completion(&ioc->sas_mgmt.done);
|
||||
|
||||
/* Verify that we won't exceed the maximum
|
||||
* number of chain buffers
|
||||
@@ -1207,6 +1380,7 @@ mptsas_init(void)
|
||||
mptsasTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSAS_DRIVER);
|
||||
mptsasInternalCtx =
|
||||
mpt_register(mptscsih_scandv_complete, MPTSAS_DRIVER);
|
||||
mptsasMgmtCtx = mpt_register(mptsas_mgmt_done, MPTSAS_DRIVER);
|
||||
|
||||
if (mpt_event_register(mptsasDoneCtx, mptscsih_event_process) == 0) {
|
||||
devtprintk((KERN_INFO MYNAM
|
||||
@@ -1230,6 +1404,7 @@ mptsas_exit(void)
|
||||
mpt_reset_deregister(mptsasDoneCtx);
|
||||
mpt_event_deregister(mptsasDoneCtx);
|
||||
|
||||
mpt_deregister(mptsasMgmtCtx);
|
||||
mpt_deregister(mptsasInternalCtx);
|
||||
mpt_deregister(mptsasTaskCtx);
|
||||
mpt_deregister(mptsasDoneCtx);
|
||||
|
||||
@@ -1732,7 +1732,9 @@ static int twa_scsi_eh_reset(struct scsi_cmnd *SCpnt)
|
||||
|
||||
tw_dev->num_resets++;
|
||||
|
||||
printk(KERN_WARNING "3w-9xxx: scsi%d: WARNING: (0x%02X:0x%04X): Unit #%d: Command (0x%x) timed out, resetting card.\n", tw_dev->host->host_no, TW_DRIVER, 0x2c, SCpnt->device->id, SCpnt->cmnd[0]);
|
||||
sdev_printk(KERN_WARNING, SCpnt->device,
|
||||
"WARNING: (0x%02X:0x%04X): Command (0x%x) timed out, resetting card.\n",
|
||||
TW_DRIVER, 0x2c, SCpnt->cmnd[0]);
|
||||
|
||||
/* Now reset the card and some of the device extension data */
|
||||
if (twa_reset_device_extension(tw_dev, 0)) {
|
||||
|
||||
@@ -1432,7 +1432,9 @@ static int tw_scsi_eh_reset(struct scsi_cmnd *SCpnt)
|
||||
|
||||
tw_dev->num_resets++;
|
||||
|
||||
printk(KERN_WARNING "3w-xxxx: scsi%d: WARNING: Unit #%d: Command (0x%x) timed out, resetting card.\n", tw_dev->host->host_no, SCpnt->device->id, SCpnt->cmnd[0]);
|
||||
sdev_printk(KERN_WARNING, SCpnt->device,
|
||||
"WARNING: Command (0x%x) timed out, resetting card.\n",
|
||||
SCpnt->cmnd[0]);
|
||||
|
||||
/* Now reset the card and some of the device extension data */
|
||||
if (tw_reset_device_extension(tw_dev, 0)) {
|
||||
|
||||
@@ -128,6 +128,7 @@
|
||||
#include <linux/blkdev.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/device.h>
|
||||
#include <asm/dma.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/io.h>
|
||||
@@ -831,8 +832,8 @@ process_extended_message(struct Scsi_Host *host,
|
||||
|
||||
} else {
|
||||
/* SDTR message out of the blue, reject it */
|
||||
printk(KERN_WARNING "scsi%d Unexpected SDTR msg\n",
|
||||
host->host_no);
|
||||
shost_printk(KERN_WARNING, host,
|
||||
"Unexpected SDTR msg\n");
|
||||
hostdata->msgout[0] = A_REJECT_MSG;
|
||||
dma_cache_sync(hostdata->msgout, 1, DMA_TO_DEVICE);
|
||||
script_patch_16(hostdata->script, MessageCount, 1);
|
||||
@@ -906,15 +907,17 @@ process_message(struct Scsi_Host *host, struct NCR_700_Host_Parameters *hostdata
|
||||
NCR_700_clear_flag(SCp->device, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION);
|
||||
} else if(SCp != NULL && NCR_700_get_tag_neg_state(SCp->device) == NCR_700_DURING_TAG_NEGOTIATION) {
|
||||
/* rejected our first simple tag message */
|
||||
printk(KERN_WARNING "scsi%d (%d:%d) Rejected first tag queue attempt, turning off tag queueing\n", host->host_no, pun, lun);
|
||||
scmd_printk(KERN_WARNING, SCp,
|
||||
"Rejected first tag queue attempt, turning off tag queueing\n");
|
||||
/* we're done negotiating */
|
||||
NCR_700_set_tag_neg_state(SCp->device, NCR_700_FINISHED_TAG_NEGOTIATION);
|
||||
hostdata->tag_negotiated &= ~(1<<SCp->device->id);
|
||||
hostdata->tag_negotiated &= ~(1<<scmd_id(SCp));
|
||||
SCp->device->tagged_supported = 0;
|
||||
scsi_deactivate_tcq(SCp->device, host->cmd_per_lun);
|
||||
} else {
|
||||
printk(KERN_WARNING "scsi%d (%d:%d) Unexpected REJECT Message %s\n",
|
||||
host->host_no, pun, lun,
|
||||
shost_printk(KERN_WARNING, host,
|
||||
"(%d:%d) Unexpected REJECT Message %s\n",
|
||||
pun, lun,
|
||||
NCR_700_phase[(dsps & 0xf00) >> 8]);
|
||||
/* however, just ignore it */
|
||||
}
|
||||
@@ -983,7 +986,8 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp,
|
||||
if(SCp->cmnd[0] == REQUEST_SENSE) {
|
||||
/* OOPS: bad device, returning another
|
||||
* contingent allegiance condition */
|
||||
printk(KERN_ERR "scsi%d (%d:%d) broken device is looping in contingent allegiance: ignoring\n", host->host_no, pun, lun);
|
||||
scmd_printk(KERN_ERR, SCp,
|
||||
"broken device is looping in contingent allegiance: ignoring\n");
|
||||
NCR_700_scsi_done(hostdata, SCp, hostdata->status[0]);
|
||||
} else {
|
||||
#ifdef NCR_DEBUG
|
||||
@@ -1047,12 +1051,13 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp,
|
||||
// SCp->request_bufflen,
|
||||
// DMA_FROM_DEVICE);
|
||||
// if(((char *)SCp->request_buffer)[7] & 0x02) {
|
||||
// printk(KERN_INFO "scsi%d: (%d:%d) Enabling Tag Command Queuing\n", host->host_no, pun, lun);
|
||||
// hostdata->tag_negotiated |= (1<<SCp->device->id);
|
||||
// scmd_printk(KERN_INFO, SCp,
|
||||
// "Enabling Tag Command Queuing\n");
|
||||
// hostdata->tag_negotiated |= (1<<scmd_id(SCp));
|
||||
// NCR_700_set_flag(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING);
|
||||
// } else {
|
||||
// NCR_700_clear_flag(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING);
|
||||
// hostdata->tag_negotiated &= ~(1<<SCp->device->id);
|
||||
// hostdata->tag_negotiated &= ~(1<<scmd_id(SCp));
|
||||
// }
|
||||
//}
|
||||
NCR_700_scsi_done(hostdata, SCp, hostdata->status[0]);
|
||||
@@ -1060,11 +1065,11 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp,
|
||||
} else if((dsps & 0xfffff0f0) == A_UNEXPECTED_PHASE) {
|
||||
__u8 i = (dsps & 0xf00) >> 8;
|
||||
|
||||
printk(KERN_ERR "scsi%d: (%d:%d), UNEXPECTED PHASE %s (%s)\n",
|
||||
host->host_no, pun, lun,
|
||||
scmd_printk(KERN_ERR, SCp, "UNEXPECTED PHASE %s (%s)\n",
|
||||
NCR_700_phase[i],
|
||||
sbcl_to_string(NCR_700_readb(host, SBCL_REG)));
|
||||
printk(KERN_ERR " len = %d, cmd =", SCp->cmd_len);
|
||||
scmd_printk(KERN_ERR, SCp, " len = %d, cmd =",
|
||||
SCp->cmd_len);
|
||||
scsi_print_command(SCp);
|
||||
|
||||
NCR_700_internal_bus_reset(host);
|
||||
@@ -1115,14 +1120,14 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp,
|
||||
}
|
||||
|
||||
slot = (struct NCR_700_command_slot *)SCp->host_scribble;
|
||||
DEBUG(("53c700: %d:%d:%d, reselection is tag %d, slot %p(%d)\n",
|
||||
host->host_no, SDp->id, SDp->lun,
|
||||
hostdata->msgin[2], slot, slot->tag));
|
||||
DDEBUG(KERN_DEBUG, SDp,
|
||||
"reselection is tag %d, slot %p(%d)\n",
|
||||
hostdata->msgin[2], slot, slot->tag);
|
||||
} else {
|
||||
struct scsi_cmnd *SCp = scsi_find_tag(SDp, SCSI_NO_TAG);
|
||||
if(unlikely(SCp == NULL)) {
|
||||
printk(KERN_ERR "scsi%d: (%d:%d) no saved request for untagged cmd\n",
|
||||
host->host_no, reselection_id, lun);
|
||||
sdev_printk(KERN_ERR, SDp,
|
||||
"no saved request for untagged cmd\n");
|
||||
BUG();
|
||||
}
|
||||
slot = (struct NCR_700_command_slot *)SCp->host_scribble;
|
||||
@@ -1422,7 +1427,7 @@ NCR_700_start_command(struct scsi_cmnd *SCp)
|
||||
* If a contingent allegiance condition exists, the device
|
||||
* will refuse all tags, so send the request sense as untagged
|
||||
* */
|
||||
if((hostdata->tag_negotiated & (1<<SCp->device->id))
|
||||
if((hostdata->tag_negotiated & (1<<scmd_id(SCp)))
|
||||
&& (slot->tag != SCSI_NO_TAG && SCp->cmnd[0] != REQUEST_SENSE)) {
|
||||
count += scsi_populate_tag_msg(SCp, &hostdata->msgout[count]);
|
||||
}
|
||||
@@ -1441,7 +1446,7 @@ NCR_700_start_command(struct scsi_cmnd *SCp)
|
||||
|
||||
|
||||
script_patch_ID(hostdata->script,
|
||||
Device_ID, 1<<SCp->device->id);
|
||||
Device_ID, 1<<scmd_id(SCp));
|
||||
|
||||
script_patch_32_abs(hostdata->script, CommandAddress,
|
||||
slot->pCmd);
|
||||
@@ -1764,17 +1769,15 @@ NCR_700_queuecommand(struct scsi_cmnd *SCp, void (*done)(struct scsi_cmnd *))
|
||||
* - The blk layer sent and untagged command
|
||||
*/
|
||||
if(NCR_700_get_depth(SCp->device) != 0
|
||||
&& (!(hostdata->tag_negotiated & (1<<SCp->device->id))
|
||||
&& (!(hostdata->tag_negotiated & (1<<scmd_id(SCp)))
|
||||
|| !blk_rq_tagged(SCp->request))) {
|
||||
DEBUG((KERN_ERR "scsi%d (%d:%d) has non zero depth %d\n",
|
||||
SCp->device->host->host_no, SCp->device->id, SCp->device->lun,
|
||||
NCR_700_get_depth(SCp->device)));
|
||||
CDEBUG(KERN_ERR, SCp, "has non zero depth %d\n",
|
||||
NCR_700_get_depth(SCp->device));
|
||||
return SCSI_MLQUEUE_DEVICE_BUSY;
|
||||
}
|
||||
if(NCR_700_get_depth(SCp->device) >= SCp->device->queue_depth) {
|
||||
DEBUG((KERN_ERR "scsi%d (%d:%d) has max tag depth %d\n",
|
||||
SCp->device->host->host_no, SCp->device->id, SCp->device->lun,
|
||||
NCR_700_get_depth(SCp->device)));
|
||||
CDEBUG(KERN_ERR, SCp, "has max tag depth %d\n",
|
||||
NCR_700_get_depth(SCp->device));
|
||||
return SCSI_MLQUEUE_DEVICE_BUSY;
|
||||
}
|
||||
NCR_700_set_depth(SCp->device, NCR_700_get_depth(SCp->device) + 1);
|
||||
@@ -1796,10 +1799,10 @@ NCR_700_queuecommand(struct scsi_cmnd *SCp, void (*done)(struct scsi_cmnd *))
|
||||
scsi_print_command(SCp);
|
||||
#endif
|
||||
if(blk_rq_tagged(SCp->request)
|
||||
&& (hostdata->tag_negotiated &(1<<SCp->device->id)) == 0
|
||||
&& (hostdata->tag_negotiated &(1<<scmd_id(SCp))) == 0
|
||||
&& NCR_700_get_tag_neg_state(SCp->device) == NCR_700_START_TAG_NEGOTIATION) {
|
||||
printk(KERN_ERR "scsi%d: (%d:%d) Enabling Tag Command Queuing\n", SCp->device->host->host_no, SCp->device->id, SCp->device->lun);
|
||||
hostdata->tag_negotiated |= (1<<SCp->device->id);
|
||||
scmd_printk(KERN_ERR, SCp, "Enabling Tag Command Queuing\n");
|
||||
hostdata->tag_negotiated |= (1<<scmd_id(SCp));
|
||||
NCR_700_set_tag_neg_state(SCp->device, NCR_700_DURING_TAG_NEGOTIATION);
|
||||
}
|
||||
|
||||
@@ -1810,17 +1813,16 @@ NCR_700_queuecommand(struct scsi_cmnd *SCp, void (*done)(struct scsi_cmnd *))
|
||||
* FIXME: This will royally screw up on multiple LUN devices
|
||||
* */
|
||||
if(!blk_rq_tagged(SCp->request)
|
||||
&& (hostdata->tag_negotiated &(1<<SCp->device->id))) {
|
||||
printk(KERN_INFO "scsi%d: (%d:%d) Disabling Tag Command Queuing\n", SCp->device->host->host_no, SCp->device->id, SCp->device->lun);
|
||||
hostdata->tag_negotiated &= ~(1<<SCp->device->id);
|
||||
&& (hostdata->tag_negotiated &(1<<scmd_id(SCp)))) {
|
||||
scmd_printk(KERN_INFO, SCp, "Disabling Tag Command Queuing\n");
|
||||
hostdata->tag_negotiated &= ~(1<<scmd_id(SCp));
|
||||
}
|
||||
|
||||
if((hostdata->tag_negotiated &(1<<SCp->device->id))
|
||||
if((hostdata->tag_negotiated &(1<<scmd_id(SCp)))
|
||||
&& scsi_get_tag_type(SCp->device)) {
|
||||
slot->tag = SCp->request->tag;
|
||||
DEBUG(("53c700 %d:%d:%d, sending out tag %d, slot %p\n",
|
||||
SCp->device->host->host_no, SCp->device->id, SCp->device->lun, slot->tag,
|
||||
slot));
|
||||
CDEBUG(KERN_DEBUG, SCp, "sending out tag %d, slot %p\n",
|
||||
slot->tag, slot);
|
||||
} else {
|
||||
slot->tag = SCSI_NO_TAG;
|
||||
/* must populate current_cmnd for scsi_find_tag to work */
|
||||
@@ -1920,8 +1922,8 @@ NCR_700_abort(struct scsi_cmnd * SCp)
|
||||
{
|
||||
struct NCR_700_command_slot *slot;
|
||||
|
||||
printk(KERN_INFO "scsi%d (%d:%d) New error handler wants to abort command\n\t",
|
||||
SCp->device->host->host_no, SCp->device->id, SCp->device->lun);
|
||||
scmd_printk(KERN_INFO, SCp,
|
||||
"New error handler wants to abort command\n\t");
|
||||
scsi_print_command(SCp);
|
||||
|
||||
slot = (struct NCR_700_command_slot *)SCp->host_scribble;
|
||||
@@ -1954,8 +1956,8 @@ NCR_700_bus_reset(struct scsi_cmnd * SCp)
|
||||
struct NCR_700_Host_Parameters *hostdata =
|
||||
(struct NCR_700_Host_Parameters *)SCp->device->host->hostdata[0];
|
||||
|
||||
printk(KERN_INFO "scsi%d (%d:%d) New error handler wants BUS reset, cmd %p\n\t",
|
||||
SCp->device->host->host_no, SCp->device->id, SCp->device->lun, SCp);
|
||||
scmd_printk(KERN_INFO, SCp,
|
||||
"New error handler wants BUS reset, cmd %p\n\t", SCp);
|
||||
scsi_print_command(SCp);
|
||||
|
||||
/* In theory, eh_complete should always be null because the
|
||||
@@ -1987,8 +1989,7 @@ NCR_700_bus_reset(struct scsi_cmnd * SCp)
|
||||
STATIC int
|
||||
NCR_700_host_reset(struct scsi_cmnd * SCp)
|
||||
{
|
||||
printk(KERN_INFO "scsi%d (%d:%d) New error handler wants HOST reset\n\t",
|
||||
SCp->device->host->host_no, SCp->device->id, SCp->device->lun);
|
||||
scmd_printk(KERN_INFO, SCp, "New error handler wants HOST reset\n\t");
|
||||
scsi_print_command(SCp);
|
||||
|
||||
spin_lock_irq(SCp->device->host->host_lock);
|
||||
@@ -2110,7 +2111,7 @@ static int NCR_700_change_queue_type(struct scsi_device *SDp, int tag_type)
|
||||
/* shift back to the default unqueued number of commands
|
||||
* (the user can still raise this) */
|
||||
scsi_deactivate_tcq(SDp, SDp->host->cmd_per_lun);
|
||||
hostdata->tag_negotiated &= ~(1 << SDp->id);
|
||||
hostdata->tag_negotiated &= ~(1 << sdev_id(SDp));
|
||||
} else {
|
||||
/* Here, we cleared the negotiation flag above, so this
|
||||
* will force the driver to renegotiate */
|
||||
|
||||
@@ -22,8 +22,14 @@
|
||||
|
||||
#ifdef NCR_700_DEBUG
|
||||
#define DEBUG(x) printk x
|
||||
#define DDEBUG(prefix, sdev, fmt, a...) \
|
||||
sdev_printk(prefix, sdev, fmt, ##a)
|
||||
#define CDEBUG(prefix, scmd, fmt, a...) \
|
||||
scmd_printk(prefix, scmd, fmt, ##a)
|
||||
#else
|
||||
#define DEBUG(x)
|
||||
#define DEBUG(x) do {} while (0)
|
||||
#define DDEBUG(prefix, scmd, fmt, a...) do {} while (0)
|
||||
#define CDEBUG(prefix, scmd, fmt, a...) do {} while (0)
|
||||
#endif
|
||||
|
||||
/* The number of available command slots */
|
||||
|
||||
@@ -229,7 +229,7 @@ config SCSI_FC_ATTRS
|
||||
|
||||
config SCSI_ISCSI_ATTRS
|
||||
tristate "iSCSI Transport Attributes"
|
||||
depends on SCSI
|
||||
depends on SCSI && NET
|
||||
help
|
||||
If you wish to export transport-specific information about
|
||||
each attached iSCSI device to sysfs, say Y.
|
||||
@@ -247,6 +247,30 @@ endmenu
|
||||
menu "SCSI low-level drivers"
|
||||
depends on SCSI!=n
|
||||
|
||||
config ISCSI_TCP
|
||||
tristate "iSCSI Initiator over TCP/IP"
|
||||
depends on SCSI && INET
|
||||
select CRYPTO
|
||||
select CRYPTO_MD5
|
||||
select CRYPTO_CRC32C
|
||||
select SCSI_ISCSI_ATTRS
|
||||
help
|
||||
The iSCSI Driver provides a host with the ability to access storage
|
||||
through an IP network. The driver uses the iSCSI protocol to transport
|
||||
SCSI requests and responses over a TCP/IP network between the host
|
||||
(the "initiator") and "targets". Architecturally, the iSCSI driver
|
||||
combines with the host's TCP/IP stack, network drivers, and Network
|
||||
Interface Card (NIC) to provide the same functions as a SCSI or a
|
||||
Fibre Channel (FC) adapter driver with a Host Bus Adapter (HBA).
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called iscsi_tcp.
|
||||
|
||||
The userspace component needed to initialize the driver, documentation,
|
||||
and sample configuration files can be found here:
|
||||
|
||||
http://linux-iscsi.sf.net
|
||||
|
||||
config SGIWD93_SCSI
|
||||
tristate "SGI WD93C93 SCSI Driver"
|
||||
depends on SGI_IP22 && SCSI
|
||||
@@ -596,19 +620,6 @@ config SCSI_OMIT_FLASHPOINT
|
||||
substantial, so users of MultiMaster Host Adapters may wish to omit
|
||||
it.
|
||||
|
||||
#
|
||||
# This is marked broken because it uses over 4kB of stack in
|
||||
# just two routines:
|
||||
# 2076 CpqTsProcessIMQEntry
|
||||
# 2052 PeekIMQEntry
|
||||
#
|
||||
config SCSI_CPQFCTS
|
||||
tristate "Compaq Fibre Channel 64-bit/66Mhz HBA support"
|
||||
depends on PCI && SCSI && BROKEN
|
||||
help
|
||||
Say Y here to compile in support for the Compaq StorageWorks Fibre
|
||||
Channel 64-bit/66Mhz Host Bus Adapter.
|
||||
|
||||
config SCSI_DMX3191D
|
||||
tristate "DMX3191D SCSI support"
|
||||
depends on PCI && SCSI
|
||||
|
||||
@@ -33,6 +33,7 @@ obj-$(CONFIG_SCSI_FC_ATTRS) += scsi_transport_fc.o
|
||||
obj-$(CONFIG_SCSI_ISCSI_ATTRS) += scsi_transport_iscsi.o
|
||||
obj-$(CONFIG_SCSI_SAS_ATTRS) += scsi_transport_sas.o
|
||||
|
||||
obj-$(CONFIG_ISCSI_TCP) += iscsi_tcp.o
|
||||
obj-$(CONFIG_SCSI_AMIGA7XX) += amiga7xx.o 53c7xx.o
|
||||
obj-$(CONFIG_A3000_SCSI) += a3000.o wd33c93.o
|
||||
obj-$(CONFIG_A2091_SCSI) += a2091.o wd33c93.o
|
||||
@@ -119,7 +120,6 @@ obj-$(CONFIG_JAZZ_ESP) += NCR53C9x.o jazz_esp.o
|
||||
obj-$(CONFIG_SUN3X_ESP) += NCR53C9x.o sun3x_esp.o
|
||||
obj-$(CONFIG_SCSI_DEBUG) += scsi_debug.o
|
||||
obj-$(CONFIG_SCSI_FCAL) += fcal.o
|
||||
obj-$(CONFIG_SCSI_CPQFCTS) += cpqfc.o
|
||||
obj-$(CONFIG_SCSI_LASI700) += 53c700.o lasi700.o
|
||||
obj-$(CONFIG_SCSI_NSP32) += nsp32.o
|
||||
obj-$(CONFIG_SCSI_IPR) += ipr.o
|
||||
@@ -164,8 +164,6 @@ ncr53c8xx-flags-$(CONFIG_SCSI_ZALON) \
|
||||
CFLAGS_ncr53c8xx.o := $(ncr53c8xx-flags-y) $(ncr53c8xx-flags-m)
|
||||
zalon7xx-objs := zalon.o ncr53c8xx.o
|
||||
NCR_Q720_mod-objs := NCR_Q720.o ncr53c8xx.o
|
||||
cpqfc-objs := cpqfcTSinit.o cpqfcTScontrol.o cpqfcTSi2c.o \
|
||||
cpqfcTSworker.o cpqfcTStrigger.o
|
||||
libata-objs := libata-core.o libata-scsi.o
|
||||
|
||||
# Files generated that shall be removed upon make clean
|
||||
|
||||
@@ -1247,13 +1247,13 @@ static void collect_stats(struct NCR5380_hostdata *hostdata, Scsi_Cmnd * cmd)
|
||||
case WRITE:
|
||||
case WRITE_6:
|
||||
case WRITE_10:
|
||||
hostdata->time_write[cmd->device->id] += (jiffies - hostdata->timebase);
|
||||
hostdata->time_write[scmd_id(cmd)] += (jiffies - hostdata->timebase);
|
||||
hostdata->pendingw--;
|
||||
break;
|
||||
case READ:
|
||||
case READ_6:
|
||||
case READ_10:
|
||||
hostdata->time_read[cmd->device->id] += (jiffies - hostdata->timebase);
|
||||
hostdata->time_read[scmd_id(cmd)] += (jiffies - hostdata->timebase);
|
||||
hostdata->pendingr--;
|
||||
break;
|
||||
}
|
||||
@@ -1385,7 +1385,7 @@ static int NCR5380_select(struct Scsi_Host *instance, Scsi_Cmnd * cmd, int tag)
|
||||
* the host and target ID's on the SCSI bus.
|
||||
*/
|
||||
|
||||
NCR5380_write(OUTPUT_DATA_REG, (hostdata->id_mask | (1 << cmd->device->id)));
|
||||
NCR5380_write(OUTPUT_DATA_REG, (hostdata->id_mask | (1 << scmd_id(cmd))));
|
||||
|
||||
/*
|
||||
* Raise ATN while SEL is true before BSY goes false from arbitration,
|
||||
@@ -1430,7 +1430,7 @@ static int NCR5380_select(struct Scsi_Host *instance, Scsi_Cmnd * cmd, int tag)
|
||||
|
||||
udelay(1);
|
||||
|
||||
dprintk(NDEBUG_SELECTION, ("scsi%d : selecting target %d\n", instance->host_no, cmd->device->id));
|
||||
dprintk(NDEBUG_SELECTION, ("scsi%d : selecting target %d\n", instance->host_no, scmd_id(cmd)));
|
||||
|
||||
/*
|
||||
* The SCSI specification calls for a 250 ms timeout for the actual
|
||||
@@ -1483,7 +1483,7 @@ part2:
|
||||
|
||||
if (!(NCR5380_read(STATUS_REG) & SR_BSY)) {
|
||||
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
|
||||
if (hostdata->targets_present & (1 << cmd->device->id)) {
|
||||
if (hostdata->targets_present & (1 << scmd_id(cmd))) {
|
||||
printk(KERN_DEBUG "scsi%d : weirdness\n", instance->host_no);
|
||||
if (hostdata->restart_select)
|
||||
printk(KERN_DEBUG "\trestart select\n");
|
||||
@@ -1499,7 +1499,7 @@ part2:
|
||||
NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
|
||||
return 0;
|
||||
}
|
||||
hostdata->targets_present |= (1 << cmd->device->id);
|
||||
hostdata->targets_present |= (1 << scmd_id(cmd));
|
||||
|
||||
/*
|
||||
* Since we followed the SCSI spec, and raised ATN while SEL
|
||||
@@ -2190,7 +2190,8 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
|
||||
* If the watchdog timer fires, all future accesses to this
|
||||
* device will use the polled-IO.
|
||||
*/
|
||||
printk("scsi%d : switching target %d lun %d to slow handshake\n", instance->host_no, cmd->device->id, cmd->device->lun);
|
||||
scmd_printk(KERN_INFO, cmd,
|
||||
"switching to slow handshake\n");
|
||||
cmd->device->borken = 1;
|
||||
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
|
||||
sink = 1;
|
||||
@@ -2429,9 +2430,11 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
|
||||
scsi_print_msg(extended_msg);
|
||||
printk("\n");
|
||||
} else if (tmp != EXTENDED_MESSAGE)
|
||||
printk("scsi%d: rejecting unknown message %02x from target %d, lun %d\n", instance->host_no, tmp, cmd->device->id, cmd->device->lun);
|
||||
scmd_printk(KERN_INFO, cmd,
|
||||
"rejecting unknown message %02x\n",tmp);
|
||||
else
|
||||
printk("scsi%d: rejecting unknown extended message code %02x, length %d from target %d, lun %d\n", instance->host_no, extended_msg[1], extended_msg[0], cmd->device->id, cmd->device->lun);
|
||||
scmd_printk(KERN_INFO, cmd,
|
||||
"rejecting unknown extended message code %02x, length %d\n", extended_msg[1], extended_msg[0]);
|
||||
|
||||
msgout = MESSAGE_REJECT;
|
||||
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
|
||||
|
||||
@@ -936,7 +936,7 @@ static void esp_release_dmabufs(struct NCR_ESP *esp, Scsi_Cmnd *sp)
|
||||
|
||||
static void esp_restore_pointers(struct NCR_ESP *esp, Scsi_Cmnd *sp)
|
||||
{
|
||||
struct esp_pointers *ep = &esp->data_pointers[sp->device->id];
|
||||
struct esp_pointers *ep = &esp->data_pointers[scmd_id(sp)];
|
||||
|
||||
sp->SCp.ptr = ep->saved_ptr;
|
||||
sp->SCp.buffer = ep->saved_buffer;
|
||||
@@ -946,7 +946,7 @@ static void esp_restore_pointers(struct NCR_ESP *esp, Scsi_Cmnd *sp)
|
||||
|
||||
static void esp_save_pointers(struct NCR_ESP *esp, Scsi_Cmnd *sp)
|
||||
{
|
||||
struct esp_pointers *ep = &esp->data_pointers[sp->device->id];
|
||||
struct esp_pointers *ep = &esp->data_pointers[scmd_id(sp)];
|
||||
|
||||
ep->saved_ptr = sp->SCp.ptr;
|
||||
ep->saved_buffer = sp->SCp.buffer;
|
||||
@@ -1693,13 +1693,13 @@ static inline void esp_connect(struct NCR_ESP *esp, struct ESP_regs *eregs,
|
||||
if(esp->prev_soff != esp_dev->sync_max_offset ||
|
||||
esp->prev_stp != esp_dev->sync_min_period ||
|
||||
(esp->erev > esp100a &&
|
||||
esp->prev_cfg3 != esp->config3[sp->device->id])) {
|
||||
esp->prev_cfg3 != esp->config3[scmd_id(sp)])) {
|
||||
esp->prev_soff = esp_dev->sync_max_offset;
|
||||
esp_write(eregs->esp_soff, esp->prev_soff);
|
||||
esp->prev_stp = esp_dev->sync_min_period;
|
||||
esp_write(eregs->esp_stp, esp->prev_stp);
|
||||
if(esp->erev > esp100a) {
|
||||
esp->prev_cfg3 = esp->config3[sp->device->id];
|
||||
esp->prev_cfg3 = esp->config3[scmd_id(sp)];
|
||||
esp_write(eregs->esp_cfg3, esp->prev_cfg3);
|
||||
}
|
||||
}
|
||||
@@ -2205,7 +2205,7 @@ static int esp_do_freebus(struct NCR_ESP *esp, struct ESP_regs *eregs)
|
||||
|
||||
if(SCptr->SCp.Status != GOOD &&
|
||||
SCptr->SCp.Status != CONDITION_GOOD &&
|
||||
((1<<SCptr->device->id) & esp->targets_present) &&
|
||||
((1<<scmd_id(SCptr)) & esp->targets_present) &&
|
||||
esp_dev->sync && esp_dev->sync_max_offset) {
|
||||
/* SCSI standard says that the synchronous capabilities
|
||||
* should be renegotiated at this point. Most likely
|
||||
@@ -2597,7 +2597,7 @@ static int esp_select_complete(struct NCR_ESP *esp, struct ESP_regs *eregs)
|
||||
*/
|
||||
if(esp->ireg == (ESP_INTR_FDONE | ESP_INTR_BSERV)) {
|
||||
/* target speaks... */
|
||||
esp->targets_present |= (1<<SCptr->device->id);
|
||||
esp->targets_present |= (1<<scmd_id(SCptr));
|
||||
|
||||
/* What if the target ignores the sdtr? */
|
||||
if(esp->snip)
|
||||
@@ -3064,7 +3064,7 @@ static int check_multibyte_msg(struct NCR_ESP *esp,
|
||||
ESPSDTR(("soff=%2x stp=%2x cfg3=%2x\n",
|
||||
esp_dev->sync_max_offset,
|
||||
esp_dev->sync_min_period,
|
||||
esp->config3[SCptr->device->id]));
|
||||
esp->config3[scmd_id(SCptr)]));
|
||||
|
||||
esp->snip = 0;
|
||||
} else if(esp_dev->sync_max_offset) {
|
||||
@@ -3621,7 +3621,7 @@ void esp_slave_destroy(Scsi_Device *SDptr)
|
||||
{
|
||||
struct NCR_ESP *esp = (struct NCR_ESP *) SDptr->host->hostdata;
|
||||
|
||||
esp->targets_present &= ~(1 << SDptr->id);
|
||||
esp->targets_present &= ~(1 << sdev_id(SDptr));
|
||||
kfree(SDptr->hostdata);
|
||||
SDptr->hostdata = NULL;
|
||||
}
|
||||
|
||||
@@ -710,7 +710,7 @@ static int NCR53c406a_queue(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
|
||||
|
||||
/* We are locked here already by the mid layer */
|
||||
REG0;
|
||||
outb(SCpnt->device->id, DEST_ID); /* set destination */
|
||||
outb(scmd_id(SCpnt), DEST_ID); /* set destination */
|
||||
outb(FLUSH_FIFO, CMD_REG); /* reset the fifos */
|
||||
|
||||
for (i = 0; i < SCpnt->cmd_len; i++) {
|
||||
|
||||
@@ -923,7 +923,7 @@ static int inia100_device_reset(struct scsi_cmnd * SCpnt)
|
||||
{ /* I need Host Control Block Information */
|
||||
ORC_HCS *pHCB;
|
||||
pHCB = (ORC_HCS *) SCpnt->device->host->hostdata;
|
||||
return orc_device_reset(pHCB, SCpnt, SCpnt->device->id);
|
||||
return orc_device_reset(pHCB, SCpnt, scmd_id(SCpnt));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ Deanna Bonds (non-DASD support, PAE fibs and 64 bit,
|
||||
(fixed 64bit and 64G memory model, changed confusing naming convention
|
||||
where fibs that go to the hardware are consistently called hw_fibs and
|
||||
not just fibs like the name of the driver tracking structure)
|
||||
Mark Salyzyn <Mark_Salyzyn@adaptec.com> Fixed panic issues and added some new product ids for upcoming hbas.
|
||||
Mark Salyzyn <Mark_Salyzyn@adaptec.com> Fixed panic issues and added some new product ids for upcoming hbas. Performance tuning, card failover and bug mitigations.
|
||||
|
||||
Original Driver
|
||||
-------------------------
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
o Testing
|
||||
o More testing
|
||||
o Drop irq_mask, basically unused
|
||||
o I/O size increase
|
||||
|
||||
@@ -359,15 +359,6 @@ int aac_get_containers(struct aac_dev *dev)
|
||||
return status;
|
||||
}
|
||||
|
||||
static void aac_io_done(struct scsi_cmnd * scsicmd)
|
||||
{
|
||||
unsigned long cpu_flags;
|
||||
struct Scsi_Host *host = scsicmd->device->host;
|
||||
spin_lock_irqsave(host->host_lock, cpu_flags);
|
||||
scsicmd->scsi_done(scsicmd);
|
||||
spin_unlock_irqrestore(host->host_lock, cpu_flags);
|
||||
}
|
||||
|
||||
static void aac_internal_transfer(struct scsi_cmnd *scsicmd, void *data, unsigned int offset, unsigned int len)
|
||||
{
|
||||
void *buf;
|
||||
@@ -424,7 +415,7 @@ static void get_container_name_callback(void *context, struct fib * fibptr)
|
||||
|
||||
fib_complete(fibptr);
|
||||
fib_free(fibptr);
|
||||
aac_io_done(scsicmd);
|
||||
scsicmd->scsi_done(scsicmd);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -608,17 +599,43 @@ static char *container_types[] = {
|
||||
* files instead of in OS dependant driver source.
|
||||
*/
|
||||
|
||||
static void setinqstr(int devtype, void *data, int tindex)
|
||||
static void setinqstr(struct aac_dev *dev, void *data, int tindex)
|
||||
{
|
||||
struct scsi_inq *str;
|
||||
struct aac_driver_ident *mp;
|
||||
|
||||
mp = aac_get_driver_ident(devtype);
|
||||
|
||||
str = (struct scsi_inq *)(data); /* cast data to scsi inq block */
|
||||
memset(str, ' ', sizeof(*str));
|
||||
|
||||
inqstrcpy (mp->vname, str->vid);
|
||||
inqstrcpy (mp->model, str->pid); /* last six chars reserved for vol type */
|
||||
if (dev->supplement_adapter_info.AdapterTypeText[0]) {
|
||||
char * cp = dev->supplement_adapter_info.AdapterTypeText;
|
||||
int c = sizeof(str->vid);
|
||||
while (*cp && *cp != ' ' && --c)
|
||||
++cp;
|
||||
c = *cp;
|
||||
*cp = '\0';
|
||||
inqstrcpy (dev->supplement_adapter_info.AdapterTypeText,
|
||||
str->vid);
|
||||
*cp = c;
|
||||
while (*cp && *cp != ' ')
|
||||
++cp;
|
||||
while (*cp == ' ')
|
||||
++cp;
|
||||
/* last six chars reserved for vol type */
|
||||
c = 0;
|
||||
if (strlen(cp) > sizeof(str->pid)) {
|
||||
c = cp[sizeof(str->pid)];
|
||||
cp[sizeof(str->pid)] = '\0';
|
||||
}
|
||||
inqstrcpy (cp, str->pid);
|
||||
if (c)
|
||||
cp[sizeof(str->pid)] = c;
|
||||
} else {
|
||||
struct aac_driver_ident *mp = aac_get_driver_ident(dev->cardtype);
|
||||
|
||||
inqstrcpy (mp->vname, str->vid);
|
||||
/* last six chars reserved for vol type */
|
||||
inqstrcpy (mp->model, str->pid);
|
||||
}
|
||||
|
||||
if (tindex < (sizeof(container_types)/sizeof(char *))){
|
||||
char *findit = str->pid;
|
||||
@@ -627,7 +644,9 @@ static void setinqstr(int devtype, void *data, int tindex)
|
||||
/* RAID is superfluous in the context of a RAID device */
|
||||
if (memcmp(findit-4, "RAID", 4) == 0)
|
||||
*(findit -= 4) = ' ';
|
||||
inqstrcpy (container_types[tindex], findit + 1);
|
||||
if (((findit - str->pid) + strlen(container_types[tindex]))
|
||||
< (sizeof(str->pid) + sizeof(str->prl)))
|
||||
inqstrcpy (container_types[tindex], findit + 1);
|
||||
}
|
||||
inqstrcpy ("V1.0", str->prl);
|
||||
}
|
||||
@@ -822,12 +841,12 @@ int aac_get_adapter_info(struct aac_dev* dev)
|
||||
dev->dac_support = (dacmode!=0);
|
||||
}
|
||||
if(dev->dac_support != 0) {
|
||||
if (!pci_set_dma_mask(dev->pdev, 0xFFFFFFFFFFFFFFFFULL) &&
|
||||
!pci_set_consistent_dma_mask(dev->pdev, 0xFFFFFFFFFFFFFFFFULL)) {
|
||||
if (!pci_set_dma_mask(dev->pdev, DMA_64BIT_MASK) &&
|
||||
!pci_set_consistent_dma_mask(dev->pdev, DMA_64BIT_MASK)) {
|
||||
printk(KERN_INFO"%s%d: 64 Bit DAC enabled\n",
|
||||
dev->name, dev->id);
|
||||
} else if (!pci_set_dma_mask(dev->pdev, 0xFFFFFFFFULL) &&
|
||||
!pci_set_consistent_dma_mask(dev->pdev, 0xFFFFFFFFULL)) {
|
||||
} else if (!pci_set_dma_mask(dev->pdev, DMA_32BIT_MASK) &&
|
||||
!pci_set_consistent_dma_mask(dev->pdev, DMA_32BIT_MASK)) {
|
||||
printk(KERN_INFO"%s%d: DMA mask set failed, 64 Bit DAC disabled\n",
|
||||
dev->name, dev->id);
|
||||
dev->dac_support = 0;
|
||||
@@ -960,7 +979,7 @@ static void io_callback(void *context, struct fib * fibptr)
|
||||
fib_complete(fibptr);
|
||||
fib_free(fibptr);
|
||||
|
||||
aac_io_done(scsicmd);
|
||||
scsicmd->scsi_done(scsicmd);
|
||||
}
|
||||
|
||||
static int aac_read(struct scsi_cmnd * scsicmd, int cid)
|
||||
@@ -1139,7 +1158,7 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid)
|
||||
* For some reason, the Fib didn't queue, return QUEUE_FULL
|
||||
*/
|
||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_TASK_SET_FULL;
|
||||
aac_io_done(scsicmd);
|
||||
scsicmd->scsi_done(scsicmd);
|
||||
fib_complete(cmd_fibcontext);
|
||||
fib_free(cmd_fibcontext);
|
||||
return 0;
|
||||
@@ -1211,7 +1230,7 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid)
|
||||
*/
|
||||
if (!(cmd_fibcontext = fib_alloc(dev))) {
|
||||
scsicmd->result = DID_ERROR << 16;
|
||||
aac_io_done(scsicmd);
|
||||
scsicmd->scsi_done(scsicmd);
|
||||
return 0;
|
||||
}
|
||||
fib_init(cmd_fibcontext);
|
||||
@@ -1308,7 +1327,7 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid)
|
||||
* For some reason, the Fib didn't queue, return QUEUE_FULL
|
||||
*/
|
||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_TASK_SET_FULL;
|
||||
aac_io_done(scsicmd);
|
||||
scsicmd->scsi_done(scsicmd);
|
||||
|
||||
fib_complete(cmd_fibcontext);
|
||||
fib_free(cmd_fibcontext);
|
||||
@@ -1352,7 +1371,7 @@ static void synchronize_callback(void *context, struct fib *fibptr)
|
||||
|
||||
fib_complete(fibptr);
|
||||
fib_free(fibptr);
|
||||
aac_io_done(cmd);
|
||||
cmd->scsi_done(cmd);
|
||||
}
|
||||
|
||||
static int aac_synchronize(struct scsi_cmnd *scsicmd, int cid)
|
||||
@@ -1438,7 +1457,6 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
||||
struct Scsi_Host *host = scsicmd->device->host;
|
||||
struct aac_dev *dev = (struct aac_dev *)host->hostdata;
|
||||
struct fsa_dev_info *fsa_dev_ptr = dev->fsa_dev;
|
||||
int cardtype = dev->cardtype;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
@@ -1446,7 +1464,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
||||
* Test does not apply to ID 16, the pseudo id for the controller
|
||||
* itself.
|
||||
*/
|
||||
if (scsicmd->device->id != host->this_id) {
|
||||
if (scmd_id(scsicmd) != host->this_id) {
|
||||
if ((scsicmd->device->channel == 0) ){
|
||||
if( (scsicmd->device->id >= dev->maximum_num_containers) || (scsicmd->device->lun != 0)){
|
||||
scsicmd->result = DID_NO_CONNECT << 16;
|
||||
@@ -1541,15 +1559,15 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
||||
* Set the Vendor, Product, and Revision Level
|
||||
* see: <vendor>.c i.e. aac.c
|
||||
*/
|
||||
if (scsicmd->device->id == host->this_id) {
|
||||
setinqstr(cardtype, (void *) (inq_data.inqd_vid), (sizeof(container_types)/sizeof(char *)));
|
||||
if (scmd_id(scsicmd) == host->this_id) {
|
||||
setinqstr(dev, (void *) (inq_data.inqd_vid), (sizeof(container_types)/sizeof(char *)));
|
||||
inq_data.inqd_pdt = INQD_PDT_PROC; /* Processor device */
|
||||
aac_internal_transfer(scsicmd, &inq_data, 0, sizeof(inq_data));
|
||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
|
||||
scsicmd->scsi_done(scsicmd);
|
||||
return 0;
|
||||
}
|
||||
setinqstr(cardtype, (void *) (inq_data.inqd_vid), fsa_dev_ptr[cid].type);
|
||||
setinqstr(dev, (void *) (inq_data.inqd_vid), fsa_dev_ptr[cid].type);
|
||||
inq_data.inqd_pdt = INQD_PDT_DA; /* Direct/random access device */
|
||||
aac_internal_transfer(scsicmd, &inq_data, 0, sizeof(inq_data));
|
||||
return aac_get_container_name(scsicmd, cid);
|
||||
@@ -1931,7 +1949,7 @@ static void aac_srb_callback(void *context, struct fib * fibptr)
|
||||
* the channel is 2
|
||||
*/
|
||||
} else if ((dev->raid_scsi_mode) &&
|
||||
(scsicmd->device->channel == 2)) {
|
||||
(scmd_channel(scsicmd) == 2)) {
|
||||
scsicmd->result = DID_OK << 16 |
|
||||
COMMAND_COMPLETE << 8;
|
||||
} else {
|
||||
@@ -1975,7 +1993,7 @@ static void aac_srb_callback(void *context, struct fib * fibptr)
|
||||
* the channel is 2
|
||||
*/
|
||||
} else if ((dev->raid_scsi_mode) &&
|
||||
(scsicmd->device->channel == 2)) {
|
||||
(scmd_channel(scsicmd) == 2)) {
|
||||
scsicmd->result = DID_OK << 16 |
|
||||
COMMAND_COMPLETE << 8;
|
||||
} else {
|
||||
@@ -2070,7 +2088,7 @@ static void aac_srb_callback(void *context, struct fib * fibptr)
|
||||
|
||||
fib_complete(fibptr);
|
||||
fib_free(fibptr);
|
||||
aac_io_done(scsicmd);
|
||||
scsicmd->scsi_done(scsicmd);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -481,6 +481,7 @@ enum aac_log_level {
|
||||
#define FSAFS_NTC_FIB_CONTEXT 0x030c
|
||||
|
||||
struct aac_dev;
|
||||
struct fib;
|
||||
|
||||
struct adapter_ops
|
||||
{
|
||||
@@ -489,6 +490,7 @@ struct adapter_ops
|
||||
void (*adapter_disable_int)(struct aac_dev *dev);
|
||||
int (*adapter_sync_cmd)(struct aac_dev *dev, u32 command, u32 p1, u32 p2, u32 p3, u32 p4, u32 p5, u32 p6, u32 *status, u32 *r1, u32 *r2, u32 *r3, u32 *r4);
|
||||
int (*adapter_check_health)(struct aac_dev *dev);
|
||||
int (*adapter_send)(struct fib * fib);
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -659,6 +661,10 @@ struct rx_mu_registers {
|
||||
Status Register */
|
||||
__le32 OIMR; /* 1334h | 34h | Outbound Interrupt
|
||||
Mask Register */
|
||||
__le32 reserved2; /* 1338h | 38h | Reserved */
|
||||
__le32 reserved3; /* 133Ch | 3Ch | Reserved */
|
||||
__le32 InboundQueue;/* 1340h | 40h | Inbound Queue Port relative to firmware */
|
||||
__le32 OutboundQueue;/*1344h | 44h | Outbound Queue Port relative to firmware */
|
||||
/* * Must access through ATU Inbound
|
||||
Translation Window */
|
||||
};
|
||||
@@ -693,8 +699,8 @@ struct rx_inbound {
|
||||
#define OutboundDoorbellReg MUnit.ODR
|
||||
|
||||
struct rx_registers {
|
||||
struct rx_mu_registers MUnit; /* 1300h - 1334h */
|
||||
__le32 reserved1[6]; /* 1338h - 134ch */
|
||||
struct rx_mu_registers MUnit; /* 1300h - 1344h */
|
||||
__le32 reserved1[2]; /* 1348h - 134ch */
|
||||
struct rx_inbound IndexRegs;
|
||||
};
|
||||
|
||||
@@ -711,8 +717,8 @@ struct rx_registers {
|
||||
#define rkt_inbound rx_inbound
|
||||
|
||||
struct rkt_registers {
|
||||
struct rkt_mu_registers MUnit; /* 1300h - 1334h */
|
||||
__le32 reserved1[1010]; /* 1338h - 22fch */
|
||||
struct rkt_mu_registers MUnit; /* 1300h - 1344h */
|
||||
__le32 reserved1[1006]; /* 1348h - 22fch */
|
||||
struct rkt_inbound IndexRegs; /* 2300h - */
|
||||
};
|
||||
|
||||
@@ -721,8 +727,6 @@ struct rkt_registers {
|
||||
#define rkt_writeb(AEP, CSR, value) writeb(value, &((AEP)->regs.rkt->CSR))
|
||||
#define rkt_writel(AEP, CSR, value) writel(value, &((AEP)->regs.rkt->CSR))
|
||||
|
||||
struct fib;
|
||||
|
||||
typedef void (*fib_callback)(void *ctxt, struct fib *fibctx);
|
||||
|
||||
struct aac_fib_context {
|
||||
@@ -937,7 +941,6 @@ struct aac_dev
|
||||
const char *name;
|
||||
int id;
|
||||
|
||||
u16 irq_mask;
|
||||
/*
|
||||
* negotiated FIB settings
|
||||
*/
|
||||
@@ -972,6 +975,7 @@ struct aac_dev
|
||||
struct adapter_ops a_ops;
|
||||
unsigned long fsrev; /* Main driver's revision number */
|
||||
|
||||
unsigned base_size; /* Size of mapped in region */
|
||||
struct aac_init *init; /* Holds initialization info to communicate with adapter */
|
||||
dma_addr_t init_pa; /* Holds physical address of the init struct */
|
||||
|
||||
@@ -992,6 +996,9 @@ struct aac_dev
|
||||
/*
|
||||
* The following is the device specific extension.
|
||||
*/
|
||||
#if (!defined(AAC_MIN_FOOTPRINT_SIZE))
|
||||
# define AAC_MIN_FOOTPRINT_SIZE 8192
|
||||
#endif
|
||||
union
|
||||
{
|
||||
struct sa_registers __iomem *sa;
|
||||
@@ -1012,6 +1019,7 @@ struct aac_dev
|
||||
u8 nondasd_support;
|
||||
u8 dac_support;
|
||||
u8 raid_scsi_mode;
|
||||
u8 new_comm_interface;
|
||||
/* macro side-effects BEWARE */
|
||||
# define raw_io_interface \
|
||||
init->InitStructRevision==cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION_4)
|
||||
@@ -1034,6 +1042,8 @@ struct aac_dev
|
||||
#define aac_adapter_check_health(dev) \
|
||||
(dev)->a_ops.adapter_check_health(dev)
|
||||
|
||||
#define aac_adapter_send(fib) \
|
||||
((fib)->dev)->a_ops.adapter_send(fib)
|
||||
|
||||
#define FIB_CONTEXT_FLAG_TIMED_OUT (0x00000001)
|
||||
|
||||
@@ -1560,7 +1570,7 @@ struct fib_ioctl
|
||||
|
||||
struct revision
|
||||
{
|
||||
__le32 compat;
|
||||
u32 compat;
|
||||
__le32 version;
|
||||
__le32 build;
|
||||
};
|
||||
@@ -1779,6 +1789,7 @@ int aac_rkt_init(struct aac_dev *dev);
|
||||
int aac_sa_init(struct aac_dev *dev);
|
||||
unsigned int aac_response_normal(struct aac_queue * q);
|
||||
unsigned int aac_command_normal(struct aac_queue * q);
|
||||
unsigned int aac_intr_normal(struct aac_dev * dev, u32 Index);
|
||||
int aac_command_thread(struct aac_dev * dev);
|
||||
int aac_close_fib_context(struct aac_dev * dev, struct aac_fib_context *fibctx);
|
||||
int fib_adapter_complete(struct fib * fibptr, unsigned short size);
|
||||
|
||||
@@ -408,7 +408,7 @@ static int check_revision(struct aac_dev *dev, void __user *arg)
|
||||
char *driver_version = aac_driver_version;
|
||||
u32 version;
|
||||
|
||||
response.compat = cpu_to_le32(1);
|
||||
response.compat = 1;
|
||||
version = (simple_strtol(driver_version,
|
||||
&driver_version, 10) << 24) | 0x00000400;
|
||||
version += simple_strtol(driver_version + 1, &driver_version, 10) << 16;
|
||||
@@ -574,7 +574,7 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
|
||||
rcode = -ENOMEM;
|
||||
goto cleanup;
|
||||
}
|
||||
sg_user[i] = (void __user *)usg->sg[i].addr;
|
||||
sg_user[i] = (void __user *)(long)usg->sg[i].addr;
|
||||
sg_list[i] = p; // save so we can clean up later
|
||||
sg_indx = i;
|
||||
|
||||
@@ -624,7 +624,7 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
|
||||
rcode = -ENOMEM;
|
||||
goto cleanup;
|
||||
}
|
||||
sg_user[i] = (void __user *)upsg->sg[i].addr;
|
||||
sg_user[i] = (void __user *)(long)upsg->sg[i].addr;
|
||||
sg_list[i] = p; // save so we can clean up later
|
||||
sg_indx = i;
|
||||
|
||||
|
||||
@@ -116,6 +116,10 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co
|
||||
}
|
||||
|
||||
init->InitFlags = 0;
|
||||
if (dev->new_comm_interface) {
|
||||
init->InitFlags = cpu_to_le32(INITFLAGS_NEW_COMM_SUPPORTED);
|
||||
dprintk((KERN_WARNING"aacraid: New Comm Interface enabled\n"));
|
||||
}
|
||||
init->MaxIoCommands = cpu_to_le32(dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB);
|
||||
init->MaxIoSize = cpu_to_le32(dev->scsi_host_ptr->max_sectors << 9);
|
||||
init->MaxFibSize = cpu_to_le32(dev->max_fib_size);
|
||||
@@ -315,12 +319,33 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev)
|
||||
- sizeof(struct aac_fibhdr)
|
||||
- sizeof(struct aac_write) + sizeof(struct sgentry))
|
||||
/ sizeof(struct sgentry);
|
||||
dev->new_comm_interface = 0;
|
||||
dev->raw_io_64 = 0;
|
||||
if ((!aac_adapter_sync_cmd(dev, GET_ADAPTER_PROPERTIES,
|
||||
0, 0, 0, 0, 0, 0, status+0, status+1, status+2, NULL, NULL)) &&
|
||||
(status[0] == 0x00000001)) {
|
||||
if (status[1] & AAC_OPT_NEW_COMM_64)
|
||||
dev->raw_io_64 = 1;
|
||||
if (status[1] & AAC_OPT_NEW_COMM)
|
||||
dev->new_comm_interface = dev->a_ops.adapter_send != 0;
|
||||
if (dev->new_comm_interface && (status[2] > dev->base_size)) {
|
||||
iounmap(dev->regs.sa);
|
||||
dev->base_size = status[2];
|
||||
dprintk((KERN_DEBUG "ioremap(%lx,%d)\n",
|
||||
host->base, status[2]));
|
||||
dev->regs.sa = ioremap(host->base, status[2]);
|
||||
if (dev->regs.sa == NULL) {
|
||||
/* remap failed, go back ... */
|
||||
dev->new_comm_interface = 0;
|
||||
dev->regs.sa = ioremap(host->base,
|
||||
AAC_MIN_FOOTPRINT_SIZE);
|
||||
if (dev->regs.sa == NULL) {
|
||||
printk(KERN_WARNING
|
||||
"aacraid: unable to map adapter.\n");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((!aac_adapter_sync_cmd(dev, GET_COMM_PREFERRED_SETTINGS,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
|
||||
@@ -212,7 +212,7 @@ void fib_init(struct fib *fibptr)
|
||||
hw_fib->header.StructType = FIB_MAGIC;
|
||||
hw_fib->header.Size = cpu_to_le16(fibptr->dev->max_fib_size);
|
||||
hw_fib->header.XferState = cpu_to_le32(HostOwned | FibInitialized | FibEmpty | FastResponseCapable);
|
||||
hw_fib->header.SenderFibAddress = cpu_to_le32(fibptr->hw_fib_pa);
|
||||
hw_fib->header.SenderFibAddress = 0; /* Filled in later if needed */
|
||||
hw_fib->header.ReceiverFibAddress = cpu_to_le32(fibptr->hw_fib_pa);
|
||||
hw_fib->header.SenderSize = cpu_to_le16(fibptr->dev->max_fib_size);
|
||||
}
|
||||
@@ -380,9 +380,7 @@ static int aac_queue_get(struct aac_dev * dev, u32 * index, u32 qid, struct hw_f
|
||||
|
||||
int fib_send(u16 command, struct fib * fibptr, unsigned long size, int priority, int wait, int reply, fib_callback callback, void * callback_data)
|
||||
{
|
||||
u32 index;
|
||||
struct aac_dev * dev = fibptr->dev;
|
||||
unsigned long nointr = 0;
|
||||
struct hw_fib * hw_fib = fibptr->hw_fib;
|
||||
struct aac_queue * q;
|
||||
unsigned long flags = 0;
|
||||
@@ -417,7 +415,7 @@ int fib_send(u16 command, struct fib * fibptr, unsigned long size, int priority
|
||||
* Map the fib into 32bits by using the fib number
|
||||
*/
|
||||
|
||||
hw_fib->header.SenderFibAddress = cpu_to_le32(((u32)(fibptr-dev->fibs)) << 1);
|
||||
hw_fib->header.SenderFibAddress = cpu_to_le32(((u32)(fibptr - dev->fibs)) << 2);
|
||||
hw_fib->header.SenderData = (u32)(fibptr - dev->fibs);
|
||||
/*
|
||||
* Set FIB state to indicate where it came from and if we want a
|
||||
@@ -456,10 +454,10 @@ int fib_send(u16 command, struct fib * fibptr, unsigned long size, int priority
|
||||
|
||||
FIB_COUNTER_INCREMENT(aac_config.FibsSent);
|
||||
|
||||
dprintk((KERN_DEBUG "fib_send: inserting a queue entry at index %d.\n",index));
|
||||
dprintk((KERN_DEBUG "Fib contents:.\n"));
|
||||
dprintk((KERN_DEBUG " Command = %d.\n", hw_fib->header.Command));
|
||||
dprintk((KERN_DEBUG " XferState = %x.\n", hw_fib->header.XferState));
|
||||
dprintk((KERN_DEBUG " Command = %d.\n", le32_to_cpu(hw_fib->header.Command)));
|
||||
dprintk((KERN_DEBUG " SubCommand = %d.\n", le32_to_cpu(((struct aac_query_mount *)fib_data(fibptr))->command)));
|
||||
dprintk((KERN_DEBUG " XferState = %x.\n", le32_to_cpu(hw_fib->header.XferState)));
|
||||
dprintk((KERN_DEBUG " hw_fib va being sent=%p\n",fibptr->hw_fib));
|
||||
dprintk((KERN_DEBUG " hw_fib pa being sent=%lx\n",(ulong)fibptr->hw_fib_pa));
|
||||
dprintk((KERN_DEBUG " fib being sent=%p\n",fibptr));
|
||||
@@ -469,14 +467,37 @@ int fib_send(u16 command, struct fib * fibptr, unsigned long size, int priority
|
||||
if(wait)
|
||||
spin_lock_irqsave(&fibptr->event_lock, flags);
|
||||
spin_lock_irqsave(q->lock, qflags);
|
||||
aac_queue_get( dev, &index, AdapNormCmdQueue, hw_fib, 1, fibptr, &nointr);
|
||||
if (dev->new_comm_interface) {
|
||||
unsigned long count = 10000000L; /* 50 seconds */
|
||||
list_add_tail(&fibptr->queue, &q->pendingq);
|
||||
q->numpending++;
|
||||
spin_unlock_irqrestore(q->lock, qflags);
|
||||
while (aac_adapter_send(fibptr) != 0) {
|
||||
if (--count == 0) {
|
||||
if (wait)
|
||||
spin_unlock_irqrestore(&fibptr->event_lock, flags);
|
||||
spin_lock_irqsave(q->lock, qflags);
|
||||
q->numpending--;
|
||||
list_del(&fibptr->queue);
|
||||
spin_unlock_irqrestore(q->lock, qflags);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
udelay(5);
|
||||
}
|
||||
} else {
|
||||
u32 index;
|
||||
unsigned long nointr = 0;
|
||||
aac_queue_get( dev, &index, AdapNormCmdQueue, hw_fib, 1, fibptr, &nointr);
|
||||
|
||||
list_add_tail(&fibptr->queue, &q->pendingq);
|
||||
q->numpending++;
|
||||
*(q->headers.producer) = cpu_to_le32(index + 1);
|
||||
spin_unlock_irqrestore(q->lock, qflags);
|
||||
dprintk((KERN_DEBUG "fib_send: inserting a queue entry at index %d.\n",index));
|
||||
if (!(nointr & aac_config.irq_mod))
|
||||
aac_adapter_notify(dev, AdapNormCmdQueue);
|
||||
}
|
||||
|
||||
list_add_tail(&fibptr->queue, &q->pendingq);
|
||||
q->numpending++;
|
||||
*(q->headers.producer) = cpu_to_le32(index + 1);
|
||||
spin_unlock_irqrestore(q->lock, qflags);
|
||||
if (!(nointr & aac_config.irq_mod))
|
||||
aac_adapter_notify(dev, AdapNormCmdQueue);
|
||||
/*
|
||||
* If the caller wanted us to wait for response wait now.
|
||||
*/
|
||||
@@ -492,7 +513,6 @@ int fib_send(u16 command, struct fib * fibptr, unsigned long size, int priority
|
||||
* hardware failure has occurred.
|
||||
*/
|
||||
unsigned long count = 36000000L; /* 3 minutes */
|
||||
unsigned long qflags;
|
||||
while (down_trylock(&fibptr->event_wait)) {
|
||||
if (--count == 0) {
|
||||
spin_lock_irqsave(q->lock, qflags);
|
||||
@@ -621,12 +641,16 @@ int fib_adapter_complete(struct fib * fibptr, unsigned short size)
|
||||
unsigned long qflags;
|
||||
|
||||
if (hw_fib->header.XferState == 0) {
|
||||
if (dev->new_comm_interface)
|
||||
kfree (hw_fib);
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* If we plan to do anything check the structure type first.
|
||||
*/
|
||||
if ( hw_fib->header.StructType != FIB_MAGIC ) {
|
||||
if (dev->new_comm_interface)
|
||||
kfree (hw_fib);
|
||||
return -EINVAL;
|
||||
}
|
||||
/*
|
||||
@@ -637,21 +661,25 @@ int fib_adapter_complete(struct fib * fibptr, unsigned short size)
|
||||
* send the completed cdb to the adapter.
|
||||
*/
|
||||
if (hw_fib->header.XferState & cpu_to_le32(SentFromAdapter)) {
|
||||
u32 index;
|
||||
hw_fib->header.XferState |= cpu_to_le32(HostProcessed);
|
||||
if (size) {
|
||||
size += sizeof(struct aac_fibhdr);
|
||||
if (size > le16_to_cpu(hw_fib->header.SenderSize))
|
||||
return -EMSGSIZE;
|
||||
hw_fib->header.Size = cpu_to_le16(size);
|
||||
if (dev->new_comm_interface) {
|
||||
kfree (hw_fib);
|
||||
} else {
|
||||
u32 index;
|
||||
hw_fib->header.XferState |= cpu_to_le32(HostProcessed);
|
||||
if (size) {
|
||||
size += sizeof(struct aac_fibhdr);
|
||||
if (size > le16_to_cpu(hw_fib->header.SenderSize))
|
||||
return -EMSGSIZE;
|
||||
hw_fib->header.Size = cpu_to_le16(size);
|
||||
}
|
||||
q = &dev->queues->queue[AdapNormRespQueue];
|
||||
spin_lock_irqsave(q->lock, qflags);
|
||||
aac_queue_get(dev, &index, AdapNormRespQueue, hw_fib, 1, NULL, &nointr);
|
||||
*(q->headers.producer) = cpu_to_le32(index + 1);
|
||||
spin_unlock_irqrestore(q->lock, qflags);
|
||||
if (!(nointr & (int)aac_config.irq_mod))
|
||||
aac_adapter_notify(dev, AdapNormRespQueue);
|
||||
}
|
||||
q = &dev->queues->queue[AdapNormRespQueue];
|
||||
spin_lock_irqsave(q->lock, qflags);
|
||||
aac_queue_get(dev, &index, AdapNormRespQueue, hw_fib, 1, NULL, &nointr);
|
||||
*(q->headers.producer) = cpu_to_le32(index + 1);
|
||||
spin_unlock_irqrestore(q->lock, qflags);
|
||||
if (!(nointr & (int)aac_config.irq_mod))
|
||||
aac_adapter_notify(dev, AdapNormRespQueue);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user