Merge master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (138 commits) [SCSI] libata: implement minimal transport template for ->eh_timed_out [SCSI] eliminate rphy allocation in favour of expander/end device allocation [SCSI] convert mptsas over to end_device/expander allocations [SCSI] allow displaying and setting of cache type via sysfs [SCSI] add scsi_mode_select to scsi_lib.c [SCSI] 3ware 9000 add big endian support [SCSI] qla2xxx: update MAINTAINERS [SCSI] scsi: move target_destroy call [SCSI] fusion - bump version [SCSI] fusion - expander hotplug suport in mptsas module [SCSI] fusion - exposing raid components in mptsas [SCSI] fusion - memory leak, and initializing fields [SCSI] fusion - exclosure misspelled [SCSI] fusion - cleanup mptsas event handling functions [SCSI] fusion - removing target_id/bus_id from the VirtDevice structure [SCSI] fusion - static fix's [SCSI] fusion - move some debug firmware event debug msgs to verbose level [SCSI] fusion - loginfo header update [SCSI] add scsi_reprobe_device [SCSI] megaraid_sas: fix extended timeout handling ...
This commit is contained in:
Коммит
2152f85366
|
@ -2145,7 +2145,7 @@ S: Maintained
|
||||||
|
|
||||||
QLOGIC QLA2XXX FC-SCSI DRIVER
|
QLOGIC QLA2XXX FC-SCSI DRIVER
|
||||||
P: Andrew Vasquez
|
P: Andrew Vasquez
|
||||||
M: andrew.vasquez@qlogic.com
|
M: linux-driver@qlogic.com
|
||||||
L: linux-scsi@vger.kernel.org
|
L: linux-scsi@vger.kernel.org
|
||||||
S: Supported
|
S: Supported
|
||||||
|
|
||||||
|
|
|
@ -536,6 +536,28 @@ void bus_rescan_devices(struct bus_type * bus)
|
||||||
bus_for_each_dev(bus, NULL, NULL, bus_rescan_devices_helper);
|
bus_for_each_dev(bus, NULL, NULL, bus_rescan_devices_helper);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* device_reprobe - remove driver for a device and probe for a new driver
|
||||||
|
* @dev: the device to reprobe
|
||||||
|
*
|
||||||
|
* This function detaches the attached driver (if any) for the given
|
||||||
|
* device and restarts the driver probing process. It is intended
|
||||||
|
* to use if probing criteria changed during a devices lifetime and
|
||||||
|
* driver attachment should change accordingly.
|
||||||
|
*/
|
||||||
|
void device_reprobe(struct device *dev)
|
||||||
|
{
|
||||||
|
if (dev->driver) {
|
||||||
|
if (dev->parent) /* Needed for USB */
|
||||||
|
down(&dev->parent->sem);
|
||||||
|
device_release_driver(dev);
|
||||||
|
if (dev->parent)
|
||||||
|
up(&dev->parent->sem);
|
||||||
|
}
|
||||||
|
|
||||||
|
bus_rescan_devices_helper(dev, NULL);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(device_reprobe);
|
||||||
|
|
||||||
struct bus_type * get_bus(struct bus_type * bus)
|
struct bus_type * get_bus(struct bus_type * bus)
|
||||||
{
|
{
|
||||||
|
|
|
@ -3251,8 +3251,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
|
||||||
|
|
||||||
clean4:
|
clean4:
|
||||||
#ifdef CONFIG_CISS_SCSI_TAPE
|
#ifdef CONFIG_CISS_SCSI_TAPE
|
||||||
if(hba[i]->scsi_rejects.complete)
|
kfree(hba[i]->scsi_rejects.complete);
|
||||||
kfree(hba[i]->scsi_rejects.complete);
|
|
||||||
#endif
|
#endif
|
||||||
kfree(hba[i]->cmd_pool_bits);
|
kfree(hba[i]->cmd_pool_bits);
|
||||||
if(hba[i]->cmd_pool)
|
if(hba[i]->cmd_pool)
|
||||||
|
|
|
@ -9,6 +9,7 @@ config FUSION_SPI
|
||||||
tristate "Fusion MPT ScsiHost drivers for SPI"
|
tristate "Fusion MPT ScsiHost drivers for SPI"
|
||||||
depends on PCI && SCSI
|
depends on PCI && SCSI
|
||||||
select FUSION
|
select FUSION
|
||||||
|
select SCSI_SPI_ATTRS
|
||||||
---help---
|
---help---
|
||||||
SCSI HOST support for a parallel SCSI host adapters.
|
SCSI HOST support for a parallel SCSI host adapters.
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#EXTRA_CFLAGS += -DMPT_DEBUG_MSG_FRAME
|
#EXTRA_CFLAGS += -DMPT_DEBUG_MSG_FRAME
|
||||||
#EXTRA_CFLAGS += -DMPT_DEBUG_SG
|
#EXTRA_CFLAGS += -DMPT_DEBUG_SG
|
||||||
#EXTRA_CFLAGS += -DMPT_DEBUG_EVENTS
|
#EXTRA_CFLAGS += -DMPT_DEBUG_EVENTS
|
||||||
|
#EXTRA_CFLAGS += -DMPT_DEBUG_VERBOSE_EVENTS
|
||||||
#EXTRA_CFLAGS += -DMPT_DEBUG_INIT
|
#EXTRA_CFLAGS += -DMPT_DEBUG_INIT
|
||||||
#EXTRA_CFLAGS += -DMPT_DEBUG_EXIT
|
#EXTRA_CFLAGS += -DMPT_DEBUG_EXIT
|
||||||
#EXTRA_CFLAGS += -DMPT_DEBUG_FAIL
|
#EXTRA_CFLAGS += -DMPT_DEBUG_FAIL
|
||||||
|
|
|
@ -3,38 +3,11 @@
|
||||||
* *
|
* *
|
||||||
* Copyright 2003 LSI Logic Corporation. All rights reserved. *
|
* Copyright 2003 LSI Logic Corporation. All rights reserved. *
|
||||||
* *
|
* *
|
||||||
* This file is confidential and a trade secret of LSI Logic. The *
|
* Description *
|
||||||
* receipt of or possession of this file does not convey any rights to *
|
* ------------ *
|
||||||
* reproduce or disclose its contents or to manufacture, use, or sell *
|
* This include file contains SAS firmware interface IOC Log Info codes *
|
||||||
* anything it may describe, in whole, or in part, without the specific *
|
|
||||||
* written consent of LSI Logic Corporation. *
|
|
||||||
* *
|
* *
|
||||||
***************************************************************************
|
*-------------------------------------------------------------------------*
|
||||||
*
|
|
||||||
* Name: iopiIocLogInfo.h
|
|
||||||
* Title: SAS Firmware IOP Interface IOC Log Info Definitions
|
|
||||||
* Programmer: Guy Kendall
|
|
||||||
* Creation Date: September 24, 2003
|
|
||||||
*
|
|
||||||
* Version History
|
|
||||||
* ---------------
|
|
||||||
*
|
|
||||||
* Last Updated
|
|
||||||
* -------------
|
|
||||||
* Version %version: 22 %
|
|
||||||
* Date Updated %date_modified: %
|
|
||||||
* Programmer %created_by: nperucca %
|
|
||||||
*
|
|
||||||
* Date Who Description
|
|
||||||
* -------- --- -------------------------------------------------------
|
|
||||||
* 09/24/03 GWK Initial version
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* Description
|
|
||||||
* ------------
|
|
||||||
* This include file contains SAS firmware interface IOC Log Info codes
|
|
||||||
*
|
|
||||||
*-------------------------------------------------------------------------
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef IOPI_IOCLOGINFO_H_INCLUDED
|
#ifndef IOPI_IOCLOGINFO_H_INCLUDED
|
||||||
|
@ -57,6 +30,8 @@
|
||||||
#define IOC_LOGINFO_ORIGINATOR_PL (0x01000000)
|
#define IOC_LOGINFO_ORIGINATOR_PL (0x01000000)
|
||||||
#define IOC_LOGINFO_ORIGINATOR_IR (0x02000000)
|
#define IOC_LOGINFO_ORIGINATOR_IR (0x02000000)
|
||||||
|
|
||||||
|
#define IOC_LOGINFO_ORIGINATOR_MASK (0x0F000000)
|
||||||
|
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
/* LOGINFO_CODE defines */
|
/* LOGINFO_CODE defines */
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
|
@ -78,11 +53,27 @@
|
||||||
#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_DEFAULT (0x00030700) /* Default Page not found */
|
#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_DEFAULT (0x00030700) /* Default Page not found */
|
||||||
#define IOP_LOGINFO_CODE_TASK_TERMINATED (0x00050000)
|
#define IOP_LOGINFO_CODE_TASK_TERMINATED (0x00050000)
|
||||||
|
|
||||||
|
#define IOP_LOGINFO_CODE_ENCL_MGMT_READ_ACTION_ERR0R (0x00060001) /* Read Action not supported for SEP msg */
|
||||||
|
#define IOP_LOGINFO_CODE_ENCL_MGMT_INVALID_BUS_ID_ERR0R (0x00060002) /* Invalid Bus/ID in SEP msg */
|
||||||
|
|
||||||
|
#define IOP_LOGINFO_CODE_TARGET_ASSIST_TERMINATED (0x00070001)
|
||||||
|
#define IOP_LOGINFO_CODE_TARGET_STATUS_SEND_TERMINATED (0x00070002)
|
||||||
|
#define IOP_LOGINFO_CODE_TARGET_MODE_ABORT_ALL_IO (0x00070003)
|
||||||
|
#define IOP_LOGINFO_CODE_TARGET_MODE_ABORT_EXACT_IO (0x00070004)
|
||||||
|
#define IOP_LOGINFO_CODE_TARGET_MODE_ABORT_EXACT_IO_REQ (0x00070005)
|
||||||
|
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
/* PL LOGINFO_CODE defines, valid if IOC_LOGINFO_ORIGINATOR = PL */
|
/* PL LOGINFO_CODE defines, valid if IOC_LOGINFO_ORIGINATOR = PL */
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
#define PL_LOGINFO_CODE_OPEN_FAILURE (0x00010000)
|
#define PL_LOGINFO_CODE_OPEN_FAILURE (0x00010000)
|
||||||
|
#define PL_LOG_INFO_CODE_OPEN_FAILURE_NO_DEST_TIME_OUT (0x00010001)
|
||||||
|
#define PL_LOGINFO_CODE_OPEN_FAILURE_BAD_DESTINATION (0x00010011)
|
||||||
|
#define PL_LOGINFO_CODE_OPEN_FAILURE_PROTOCOL_NOT_SUPPORTED (0x00010013)
|
||||||
|
#define PL_LOGINFO_CODE_OPEN_FAILURE_STP_RESOURCES_BSY (0x00010018)
|
||||||
|
#define PL_LOGINFO_CODE_OPEN_FAILURE_WRONG_DESTINATION (0x00010019)
|
||||||
|
#define PL_LOGINFO_CODE_OPEN_FAILURE_ORR_TIMEOUT (0X0001001A)
|
||||||
|
#define PL_LOGINFO_CODE_OPEN_FAILURE_PATHWAY_BLOCKED (0x0001001B)
|
||||||
|
#define PL_LOGINFO_CODE_OPEN_FAILURE_AWT_MAXED (0x0001001C)
|
||||||
#define PL_LOGINFO_CODE_INVALID_SGL (0x00020000)
|
#define PL_LOGINFO_CODE_INVALID_SGL (0x00020000)
|
||||||
#define PL_LOGINFO_CODE_WRONG_REL_OFF_OR_FRAME_LENGTH (0x00030000)
|
#define PL_LOGINFO_CODE_WRONG_REL_OFF_OR_FRAME_LENGTH (0x00030000)
|
||||||
#define PL_LOGINFO_CODE_FRAME_XFER_ERROR (0x00040000)
|
#define PL_LOGINFO_CODE_FRAME_XFER_ERROR (0x00040000)
|
||||||
|
@ -97,6 +88,7 @@
|
||||||
#define PL_LOGINFO_CODE_SATA_LINK_DOWN (0x000D0000)
|
#define PL_LOGINFO_CODE_SATA_LINK_DOWN (0x000D0000)
|
||||||
#define PL_LOGINFO_CODE_DISCOVERY_SATA_INIT_W_IOS (0x000E0000)
|
#define PL_LOGINFO_CODE_DISCOVERY_SATA_INIT_W_IOS (0x000E0000)
|
||||||
#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE (0x000F0000)
|
#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE (0x000F0000)
|
||||||
|
#define PL_LOGINFO_CODE_CONFIG_PL_NOT_INITIALIZED (0x000F0001) /* PL not yet initialized, can't do config page req. */
|
||||||
#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_PT (0x000F0100) /* Invalid Page Type */
|
#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_PT (0x000F0100) /* Invalid Page Type */
|
||||||
#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_NUM_PHYS (0x000F0200) /* Invalid Number of Phys */
|
#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_NUM_PHYS (0x000F0200) /* Invalid Number of Phys */
|
||||||
#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_NOT_IMP (0x000F0300) /* Case Not Handled */
|
#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_NOT_IMP (0x000F0300) /* Case Not Handled */
|
||||||
|
@ -105,11 +97,23 @@
|
||||||
#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_PHY (0x000F0600) /* Invalid Phy */
|
#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_PHY (0x000F0600) /* Invalid Phy */
|
||||||
#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_NO_OWNER (0x000F0700) /* No Owner Found */
|
#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_NO_OWNER (0x000F0700) /* No Owner Found */
|
||||||
#define PL_LOGINFO_CODE_DSCVRY_SATA_INIT_TIMEOUT (0x00100000)
|
#define PL_LOGINFO_CODE_DSCVRY_SATA_INIT_TIMEOUT (0x00100000)
|
||||||
#define PL_LOGINFO_CODE_RESET (0x00110000)
|
#define PL_LOGINFO_CODE_RESET (0x00110000) /* See Sub-Codes below */
|
||||||
#define PL_LOGINFO_CODE_ABORT (0x00120000)
|
#define PL_LOGINFO_CODE_ABORT (0x00120000) /* See Sub-Codes below */
|
||||||
#define PL_LOGINFO_CODE_IO_NOT_YET_EXECUTED (0x00130000)
|
#define PL_LOGINFO_CODE_IO_NOT_YET_EXECUTED (0x00130000)
|
||||||
#define PL_LOGINFO_CODE_IO_EXECUTED (0x00140000)
|
#define PL_LOGINFO_CODE_IO_EXECUTED (0x00140000)
|
||||||
|
#define PL_LOGINFO_CODE_PERS_RESV_OUT_NOT_AFFIL_OWNER (0x00150000)
|
||||||
|
#define PL_LOGINFO_CODE_OPEN_TXDMA_ABORT (0x00160000)
|
||||||
#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE (0x00000100)
|
#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE (0x00000100)
|
||||||
|
#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_NO_DEST_TIMEOUT (0x00000101)
|
||||||
|
#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_ORR_TIMEOUT (0x0000011A) /* Open Reject (Retry) Timeout */
|
||||||
|
#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_PATHWAY_BLOCKED (0x0000011B)
|
||||||
|
#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_AWT_MAXED (0x0000011C) /* Arbitration Wait Timer Maxed */
|
||||||
|
|
||||||
|
#define PL_LOGINFO_SUB_CODE_TARGET_BUS_RESET (0x00000120)
|
||||||
|
#define PL_LOGINFO_SUB_CODE_TRANSPORT_LAYER (0x00000130) /* Leave lower nibble (1-f) reserved. */
|
||||||
|
#define PL_LOGINFO_SUB_CODE_PORT_LAYER (0x00000140) /* Leave lower nibble (1-f) reserved. */
|
||||||
|
|
||||||
|
|
||||||
#define PL_LOGINFO_SUB_CODE_INVALID_SGL (0x00000200)
|
#define PL_LOGINFO_SUB_CODE_INVALID_SGL (0x00000200)
|
||||||
#define PL_LOGINFO_SUB_CODE_WRONG_REL_OFF_OR_FRAME_LENGTH (0x00000300)
|
#define PL_LOGINFO_SUB_CODE_WRONG_REL_OFF_OR_FRAME_LENGTH (0x00000300)
|
||||||
#define PL_LOGINFO_SUB_CODE_FRAME_XFER_ERROR (0x00000400)
|
#define PL_LOGINFO_SUB_CODE_FRAME_XFER_ERROR (0x00000400)
|
||||||
|
@ -123,26 +127,39 @@
|
||||||
#define PL_LOGINFO_SUB_CODE_RX_FM_CURRENT_FRAME_ERROR (0x00000C00)
|
#define PL_LOGINFO_SUB_CODE_RX_FM_CURRENT_FRAME_ERROR (0x00000C00)
|
||||||
#define PL_LOGINFO_SUB_CODE_SATA_LINK_DOWN (0x00000D00)
|
#define PL_LOGINFO_SUB_CODE_SATA_LINK_DOWN (0x00000D00)
|
||||||
#define PL_LOGINFO_SUB_CODE_DISCOVERY_SATA_INIT_W_IOS (0x00000E00)
|
#define PL_LOGINFO_SUB_CODE_DISCOVERY_SATA_INIT_W_IOS (0x00000E00)
|
||||||
|
#define PL_LOGINFO_SUB_CODE_DISCOVERY_REMOTE_SEP_RESET (0x00000E01)
|
||||||
|
#define PL_LOGINFO_SUB_CODE_SECOND_OPEN (0x00000F00)
|
||||||
#define PL_LOGINFO_SUB_CODE_DSCVRY_SATA_INIT_TIMEOUT (0x00001000)
|
#define PL_LOGINFO_SUB_CODE_DSCVRY_SATA_INIT_TIMEOUT (0x00001000)
|
||||||
|
|
||||||
|
|
||||||
#define PL_LOGINFO_CODE_ENCL_MGMT_SMP_FRAME_FAILURE (0x00200000) /* Can't get SMP Frame */
|
#define PL_LOGINFO_CODE_ENCL_MGMT_SMP_FRAME_FAILURE (0x00200000) /* Can't get SMP Frame */
|
||||||
#define PL_LOGINFO_CODE_ENCL_MGMT_SMP_READ_ERROR (0x00200001) /* Error occured on SMP Read */
|
#define PL_LOGINFO_CODE_ENCL_MGMT_SMP_READ_ERROR (0x00200010) /* Error occured on SMP Read */
|
||||||
#define PL_LOGINFO_CODE_ENCL_MGMT_SMP_WRITE_ERROR (0x00200002) /* Error occured on SMP Write */
|
#define PL_LOGINFO_CODE_ENCL_MGMT_SMP_WRITE_ERROR (0x00200020) /* Error occured on SMP Write */
|
||||||
#define PL_LOGINFO_CODE_ENCL_MGMT_NOT_SUPPORTED_ON_ENCL (0x00200004) /* Encl Mgmt services not available for this WWID */
|
#define PL_LOGINFO_CODE_ENCL_MGMT_NOT_SUPPORTED_ON_ENCL (0x00200040) /* Encl Mgmt services not available for this WWID */
|
||||||
#define PL_LOGINFO_CODE_ENCL_MGMT_ADDR_MODE_NOT_SUPPORTED (0x00200005) /* Address Mode not suppored */
|
#define PL_LOGINFO_CODE_ENCL_MGMT_ADDR_MODE_NOT_SUPPORTED (0x00200050) /* Address Mode not suppored */
|
||||||
#define PL_LOGINFO_CODE_ENCL_MGMT_BAD_SLOT_NUM (0x00200006) /* Invalid Slot Number in SEP Msg */
|
#define PL_LOGINFO_CODE_ENCL_MGMT_BAD_SLOT_NUM (0x00200060) /* Invalid Slot Number in SEP Msg */
|
||||||
#define PL_LOGINFO_CODE_ENCL_MGMT_SGPIO_NOT_PRESENT (0x00200007) /* SGPIO not present/enabled */
|
#define PL_LOGINFO_CODE_ENCL_MGMT_SGPIO_NOT_PRESENT (0x00200070) /* SGPIO not present/enabled */
|
||||||
|
#define PL_LOGINFO_CODE_ENCL_MGMT_GPIO_NOT_CONFIGURED (0x00200080) /* GPIO not configured */
|
||||||
|
#define PL_LOGINFO_CODE_ENCL_MGMT_GPIO_FRAME_ERROR (0x00200090) /* GPIO can't allocate a frame */
|
||||||
|
#define PL_LOGINFO_CODE_ENCL_MGMT_GPIO_CONFIG_PAGE_ERROR (0x002000A0) /* GPIO failed config page request */
|
||||||
|
#define PL_LOGINFO_CODE_ENCL_MGMT_SES_FRAME_ALLOC_ERROR (0x002000B0) /* Can't get frame for SES command */
|
||||||
|
#define PL_LOGINFO_CODE_ENCL_MGMT_SES_IO_ERROR (0x002000C0) /* I/O execution error */
|
||||||
|
#define PL_LOGINFO_CODE_ENCL_MGMT_SES_RETRIES_EXHAUSTED (0x002000D0) /* SEP I/O retries exhausted */
|
||||||
|
#define PL_LOGINFO_CODE_ENCL_MGMT_SMP_FRAME_ALLOC_ERROR (0x002000E0) /* Can't get frame for SMP command */
|
||||||
|
|
||||||
#define PL_LOGINFO_DA_SEP_NOT_PRESENT (0x00200100) /* SEP not present when msg received */
|
#define PL_LOGINFO_DA_SEP_NOT_PRESENT (0x00200100) /* SEP not present when msg received */
|
||||||
#define PL_LOGINFO_DA_SEP_SINGLE_THREAD_ERROR (0x00200101) /* Can only accept 1 msg at a time */
|
#define PL_LOGINFO_DA_SEP_SINGLE_THREAD_ERROR (0x00200101) /* Can only accept 1 msg at a time */
|
||||||
#define PL_LOGINFO_DA_SEP_ISTWI_INTR_IN_IDLE_STATE (0x00200102) /* ISTWI interrupt recvd. while IDLE */
|
#define PL_LOGINFO_DA_SEP_ISTWI_INTR_IN_IDLE_STATE (0x00200102) /* ISTWI interrupt recvd. while IDLE */
|
||||||
#define PL_LOGINFO_DA_SEP_RECEIVED_NACK_FROM_SLAVE (0x00200103) /* SEP NACK'd, it is busy */
|
#define PL_LOGINFO_DA_SEP_RECEIVED_NACK_FROM_SLAVE (0x00200103) /* SEP NACK'd, it is busy */
|
||||||
#define PL_LOGINFO_DA_SEP_BAD_STATUS_HDR_CHKSUM (0x00200104) /* SEP stopped or sent bad chksum in Hdr */
|
#define PL_LOGINFO_DA_SEP_DID_NOT_RECEIVE_ACK (0x00200104) /* SEP didn't rcv. ACK (Last Rcvd Bit = 1) */
|
||||||
#define PL_LOGINFO_DA_SEP_UNSUPPORTED_SCSI_STATUS_1 (0x00200105) /* SEP returned unknown scsi status */
|
#define PL_LOGINFO_DA_SEP_BAD_STATUS_HDR_CHKSUM (0x00200105) /* SEP stopped or sent bad chksum in Hdr */
|
||||||
#define PL_LOGINFO_DA_SEP_UNSUPPORTED_SCSI_STATUS_2 (0x00200106) /* SEP returned unknown scsi status */
|
#define PL_LOGINFO_DA_SEP_STOP_ON_DATA (0x00200106) /* SEP stopped while transfering data */
|
||||||
#define PL_LOGINFO_DA_SEP_CHKSUM_ERROR_AFTER_STOP (0x00200107) /* SEP returned bad chksum after STOP */
|
#define PL_LOGINFO_DA_SEP_STOP_ON_SENSE_DATA (0x00200107) /* SEP stopped while transfering sense data */
|
||||||
#define PL_LOGINFO_DA_SEP_CHKSUM_ERROR_AFTER_STOP_GETDATA (0x00200108) /* SEP returned bad chksum after STOP while gettin data*/
|
#define PL_LOGINFO_DA_SEP_UNSUPPORTED_SCSI_STATUS_1 (0x00200108) /* SEP returned unknown scsi status */
|
||||||
|
#define PL_LOGINFO_DA_SEP_UNSUPPORTED_SCSI_STATUS_2 (0x00200109) /* SEP returned unknown scsi status */
|
||||||
|
#define PL_LOGINFO_DA_SEP_CHKSUM_ERROR_AFTER_STOP (0x0020010A) /* SEP returned bad chksum after STOP */
|
||||||
|
#define PL_LOGINFO_DA_SEP_CHKSUM_ERROR_AFTER_STOP_GETDATA (0x0020010B) /* SEP returned bad chksum after STOP while gettin data*/
|
||||||
|
#define PL_LOGINFO_DA_SEP_UNSUPPORTED_COMMAND (0x0020010C) /* SEP doesn't support CDB opcode */
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
|
|
|
@ -180,6 +180,7 @@ static void mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
|
||||||
static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info);
|
static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info);
|
||||||
static void mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info);
|
static void mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info);
|
||||||
static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info);
|
static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info);
|
||||||
|
static int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc);
|
||||||
|
|
||||||
/* module entry point */
|
/* module entry point */
|
||||||
static int __init fusion_init (void);
|
static int __init fusion_init (void);
|
||||||
|
@ -428,7 +429,7 @@ mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
|
||||||
results = ProcessEventNotification(ioc, pEvReply, &evHandlers);
|
results = ProcessEventNotification(ioc, pEvReply, &evHandlers);
|
||||||
if (results != evHandlers) {
|
if (results != evHandlers) {
|
||||||
/* CHECKME! Any special handling needed here? */
|
/* CHECKME! Any special handling needed here? */
|
||||||
devtprintk((MYIOC_s_WARN_FMT "Called %d event handlers, sum results = %d\n",
|
devtverboseprintk((MYIOC_s_WARN_FMT "Called %d event handlers, sum results = %d\n",
|
||||||
ioc->name, evHandlers, results));
|
ioc->name, evHandlers, results));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -438,10 +439,10 @@ mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
|
||||||
*/
|
*/
|
||||||
if (pEvReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY) {
|
if (pEvReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY) {
|
||||||
freereq = 0;
|
freereq = 0;
|
||||||
devtprintk((MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p does not return Request frame\n",
|
devtverboseprintk((MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p does not return Request frame\n",
|
||||||
ioc->name, pEvReply));
|
ioc->name, pEvReply));
|
||||||
} else {
|
} else {
|
||||||
devtprintk((MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p returns Request frame\n",
|
devtverboseprintk((MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p returns Request frame\n",
|
||||||
ioc->name, pEvReply));
|
ioc->name, pEvReply));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1120,65 +1121,6 @@ mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
mpt_alt_ioc_wait(MPT_ADAPTER *ioc)
|
|
||||||
{
|
|
||||||
int loop_count = 30 * 4; /* Wait 30 seconds */
|
|
||||||
int status = -1; /* -1 means failed to get board READY */
|
|
||||||
|
|
||||||
do {
|
|
||||||
spin_lock(&ioc->initializing_hba_lock);
|
|
||||||
if (ioc->initializing_hba_lock_flag == 0) {
|
|
||||||
ioc->initializing_hba_lock_flag=1;
|
|
||||||
spin_unlock(&ioc->initializing_hba_lock);
|
|
||||||
status = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
spin_unlock(&ioc->initializing_hba_lock);
|
|
||||||
set_current_state(TASK_INTERRUPTIBLE);
|
|
||||||
schedule_timeout(HZ/4);
|
|
||||||
} while (--loop_count);
|
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
|
||||||
/*
|
|
||||||
* mpt_bringup_adapter - This is a wrapper function for mpt_do_ioc_recovery
|
|
||||||
* @ioc: Pointer to MPT adapter structure
|
|
||||||
* @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
|
|
||||||
*
|
|
||||||
* This routine performs all the steps necessary to bring the IOC
|
|
||||||
* to a OPERATIONAL state.
|
|
||||||
*
|
|
||||||
* Special Note: This function was added with spin lock's so as to allow
|
|
||||||
* the dv(domain validation) work thread to succeed on the other channel
|
|
||||||
* that maybe occuring at the same time when this function is called.
|
|
||||||
* Without this lock, the dv would fail when message frames were
|
|
||||||
* requested during hba bringup on the alternate ioc.
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
mpt_bringup_adapter(MPT_ADAPTER *ioc, int sleepFlag)
|
|
||||||
{
|
|
||||||
int r;
|
|
||||||
|
|
||||||
if(ioc->alt_ioc) {
|
|
||||||
if((r=mpt_alt_ioc_wait(ioc->alt_ioc)!=0))
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
|
|
||||||
CAN_SLEEP);
|
|
||||||
|
|
||||||
if(ioc->alt_ioc) {
|
|
||||||
spin_lock(&ioc->alt_ioc->initializing_hba_lock);
|
|
||||||
ioc->alt_ioc->initializing_hba_lock_flag=0;
|
|
||||||
spin_unlock(&ioc->alt_ioc->initializing_hba_lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
||||||
/*
|
/*
|
||||||
* mpt_attach - Install a PCI intelligent MPT adapter.
|
* mpt_attach - Install a PCI intelligent MPT adapter.
|
||||||
|
@ -1482,7 +1424,8 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||||
*/
|
*/
|
||||||
mpt_detect_bound_ports(ioc, pdev);
|
mpt_detect_bound_ports(ioc, pdev);
|
||||||
|
|
||||||
if ((r = mpt_bringup_adapter(ioc, CAN_SLEEP)) != 0){
|
if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
|
||||||
|
CAN_SLEEP)) != 0){
|
||||||
printk(KERN_WARNING MYNAM
|
printk(KERN_WARNING MYNAM
|
||||||
": WARNING - %s did not initialize properly! (%d)\n",
|
": WARNING - %s did not initialize properly! (%d)\n",
|
||||||
ioc->name, r);
|
ioc->name, r);
|
||||||
|
@ -1629,7 +1572,6 @@ mpt_resume(struct pci_dev *pdev)
|
||||||
MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
|
MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
|
||||||
u32 device_state = pdev->current_state;
|
u32 device_state = pdev->current_state;
|
||||||
int recovery_state;
|
int recovery_state;
|
||||||
int ii;
|
|
||||||
|
|
||||||
printk(MYIOC_s_INFO_FMT
|
printk(MYIOC_s_INFO_FMT
|
||||||
"pci-resume: pdev=0x%p, slot=%s, Previous operating state [D%d]\n",
|
"pci-resume: pdev=0x%p, slot=%s, Previous operating state [D%d]\n",
|
||||||
|
@ -1643,14 +1585,6 @@ mpt_resume(struct pci_dev *pdev)
|
||||||
CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
|
CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
|
||||||
ioc->active = 1;
|
ioc->active = 1;
|
||||||
|
|
||||||
/* F/W not running */
|
|
||||||
if(!CHIPREG_READ32(&ioc->chip->Doorbell)) {
|
|
||||||
/* enable domain validation flags */
|
|
||||||
for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
|
|
||||||
ioc->spi_data.dvStatus[ii] |= MPT_SCSICFG_NEED_DV;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
printk(MYIOC_s_INFO_FMT
|
printk(MYIOC_s_INFO_FMT
|
||||||
"pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
|
"pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
|
||||||
ioc->name,
|
ioc->name,
|
||||||
|
@ -4938,7 +4872,7 @@ done_and_free:
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
static int
|
||||||
mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
|
mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
|
||||||
{
|
{
|
||||||
IOCPage3_t *pIoc3;
|
IOCPage3_t *pIoc3;
|
||||||
|
@ -5146,13 +5080,13 @@ SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch)
|
||||||
|
|
||||||
evnp = (EventNotification_t *) mpt_get_msg_frame(mpt_base_index, ioc);
|
evnp = (EventNotification_t *) mpt_get_msg_frame(mpt_base_index, ioc);
|
||||||
if (evnp == NULL) {
|
if (evnp == NULL) {
|
||||||
devtprintk((MYIOC_s_WARN_FMT "Unable to allocate event request frame!\n",
|
devtverboseprintk((MYIOC_s_WARN_FMT "Unable to allocate event request frame!\n",
|
||||||
ioc->name));
|
ioc->name));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
memset(evnp, 0, sizeof(*evnp));
|
memset(evnp, 0, sizeof(*evnp));
|
||||||
|
|
||||||
devtprintk((MYIOC_s_INFO_FMT "Sending EventNotification (%d) request %p\n", ioc->name, EvSwitch, evnp));
|
devtverboseprintk((MYIOC_s_INFO_FMT "Sending EventNotification (%d) request %p\n", ioc->name, EvSwitch, evnp));
|
||||||
|
|
||||||
evnp->Function = MPI_FUNCTION_EVENT_NOTIFICATION;
|
evnp->Function = MPI_FUNCTION_EVENT_NOTIFICATION;
|
||||||
evnp->ChainOffset = 0;
|
evnp->ChainOffset = 0;
|
||||||
|
@ -5907,24 +5841,27 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr)
|
||||||
break;
|
break;
|
||||||
case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
|
case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
|
||||||
{
|
{
|
||||||
|
char buf[50];
|
||||||
|
u8 id = (u8)(evData0);
|
||||||
u8 ReasonCode = (u8)(evData0 >> 16);
|
u8 ReasonCode = (u8)(evData0 >> 16);
|
||||||
switch (ReasonCode) {
|
switch (ReasonCode) {
|
||||||
case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
|
case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
|
||||||
ds = "SAS Device Status Change: Added";
|
sprintf(buf,"SAS Device Status Change: Added: id=%d", id);
|
||||||
break;
|
break;
|
||||||
case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
|
case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
|
||||||
ds = "SAS Device Status Change: Deleted";
|
sprintf(buf,"SAS Device Status Change: Deleted: id=%d", id);
|
||||||
break;
|
break;
|
||||||
case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
|
case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
|
||||||
ds = "SAS Device Status Change: SMART Data";
|
sprintf(buf,"SAS Device Status Change: SMART Data: id=%d", id);
|
||||||
break;
|
break;
|
||||||
case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
|
case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
|
||||||
ds = "SAS Device Status Change: No Persistancy Added";
|
sprintf(buf,"SAS Device Status Change: No Persistancy Added: id=%d", id);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ds = "SAS Device Status Change: Unknown";
|
sprintf(buf,"SAS Device Status Change: Unknown: id=%d", id);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
ds = buf;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MPI_EVENT_ON_BUS_TIMER_EXPIRED:
|
case MPI_EVENT_ON_BUS_TIMER_EXPIRED:
|
||||||
|
@ -5940,11 +5877,97 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr)
|
||||||
ds = "Persistent Table Full";
|
ds = "Persistent Table Full";
|
||||||
break;
|
break;
|
||||||
case MPI_EVENT_SAS_PHY_LINK_STATUS:
|
case MPI_EVENT_SAS_PHY_LINK_STATUS:
|
||||||
ds = "SAS PHY Link Status";
|
{
|
||||||
|
char buf[50];
|
||||||
|
u8 LinkRates = (u8)(evData0 >> 8);
|
||||||
|
u8 PhyNumber = (u8)(evData0);
|
||||||
|
LinkRates = (LinkRates & MPI_EVENT_SAS_PLS_LR_CURRENT_MASK) >>
|
||||||
|
MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT;
|
||||||
|
switch (LinkRates) {
|
||||||
|
case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN:
|
||||||
|
sprintf(buf,"SAS PHY Link Status: Phy=%d:"
|
||||||
|
" Rate Unknown",PhyNumber);
|
||||||
|
break;
|
||||||
|
case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED:
|
||||||
|
sprintf(buf,"SAS PHY Link Status: Phy=%d:"
|
||||||
|
" Phy Disabled",PhyNumber);
|
||||||
|
break;
|
||||||
|
case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION:
|
||||||
|
sprintf(buf,"SAS PHY Link Status: Phy=%d:"
|
||||||
|
" Failed Speed Nego",PhyNumber);
|
||||||
|
break;
|
||||||
|
case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE:
|
||||||
|
sprintf(buf,"SAS PHY Link Status: Phy=%d:"
|
||||||
|
" Sata OOB Completed",PhyNumber);
|
||||||
|
break;
|
||||||
|
case MPI_EVENT_SAS_PLS_LR_RATE_1_5:
|
||||||
|
sprintf(buf,"SAS PHY Link Status: Phy=%d:"
|
||||||
|
" Rate 1.5 Gbps",PhyNumber);
|
||||||
|
break;
|
||||||
|
case MPI_EVENT_SAS_PLS_LR_RATE_3_0:
|
||||||
|
sprintf(buf,"SAS PHY Link Status: Phy=%d:"
|
||||||
|
" Rate 3.0 Gpbs",PhyNumber);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
sprintf(buf,"SAS PHY Link Status: Phy=%d", PhyNumber);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ds = buf;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case MPI_EVENT_SAS_DISCOVERY_ERROR:
|
case MPI_EVENT_SAS_DISCOVERY_ERROR:
|
||||||
ds = "SAS Discovery Error";
|
ds = "SAS Discovery Error";
|
||||||
break;
|
break;
|
||||||
|
case MPI_EVENT_IR_RESYNC_UPDATE:
|
||||||
|
{
|
||||||
|
u8 resync_complete = (u8)(evData0 >> 16);
|
||||||
|
char buf[40];
|
||||||
|
sprintf(buf,"IR Resync Update: Complete = %d:",resync_complete);
|
||||||
|
ds = buf;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MPI_EVENT_IR2:
|
||||||
|
{
|
||||||
|
u8 ReasonCode = (u8)(evData0 >> 16);
|
||||||
|
switch (ReasonCode) {
|
||||||
|
case MPI_EVENT_IR2_RC_LD_STATE_CHANGED:
|
||||||
|
ds = "IR2: LD State Changed";
|
||||||
|
break;
|
||||||
|
case MPI_EVENT_IR2_RC_PD_STATE_CHANGED:
|
||||||
|
ds = "IR2: PD State Changed";
|
||||||
|
break;
|
||||||
|
case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL:
|
||||||
|
ds = "IR2: Bad Block Table Full";
|
||||||
|
break;
|
||||||
|
case MPI_EVENT_IR2_RC_PD_INSERTED:
|
||||||
|
ds = "IR2: PD Inserted";
|
||||||
|
break;
|
||||||
|
case MPI_EVENT_IR2_RC_PD_REMOVED:
|
||||||
|
ds = "IR2: PD Removed";
|
||||||
|
break;
|
||||||
|
case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED:
|
||||||
|
ds = "IR2: Foreign CFG Detected";
|
||||||
|
break;
|
||||||
|
case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR:
|
||||||
|
ds = "IR2: Rebuild Medium Error";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ds = "IR2";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MPI_EVENT_SAS_DISCOVERY:
|
||||||
|
{
|
||||||
|
if (evData0)
|
||||||
|
ds = "SAS Discovery: Start";
|
||||||
|
else
|
||||||
|
ds = "SAS Discovery: Stop";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MPI_EVENT_LOG_ENTRY_ADDED:
|
||||||
|
ds = "SAS Log Entry Added";
|
||||||
|
break;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MPT base "custom" events may be added here...
|
* MPT base "custom" events may be added here...
|
||||||
|
@ -5989,12 +6012,12 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply
|
||||||
}
|
}
|
||||||
|
|
||||||
EventDescriptionStr(event, evData0, evStr);
|
EventDescriptionStr(event, evData0, evStr);
|
||||||
devtprintk((MYIOC_s_INFO_FMT "MPT event (%s=%02Xh) detected!\n",
|
devtprintk((MYIOC_s_INFO_FMT "MPT event:(%02Xh) : %s\n",
|
||||||
ioc->name,
|
ioc->name,
|
||||||
evStr,
|
event,
|
||||||
event));
|
evStr));
|
||||||
|
|
||||||
#if defined(MPT_DEBUG) || defined(MPT_DEBUG_EVENTS)
|
#if defined(MPT_DEBUG) || defined(MPT_DEBUG_VERBOSE_EVENTS)
|
||||||
printk(KERN_INFO MYNAM ": Event data:\n" KERN_INFO);
|
printk(KERN_INFO MYNAM ": Event data:\n" KERN_INFO);
|
||||||
for (ii = 0; ii < evDataLen; ii++)
|
for (ii = 0; ii < evDataLen; ii++)
|
||||||
printk(" %08x", le32_to_cpu(pEventReply->Data[ii]));
|
printk(" %08x", le32_to_cpu(pEventReply->Data[ii]));
|
||||||
|
@ -6053,7 +6076,7 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply
|
||||||
*/
|
*/
|
||||||
for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
|
for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
|
||||||
if (MptEvHandlers[ii]) {
|
if (MptEvHandlers[ii]) {
|
||||||
devtprintk((MYIOC_s_INFO_FMT "Routing Event to event handler #%d\n",
|
devtverboseprintk((MYIOC_s_INFO_FMT "Routing Event to event handler #%d\n",
|
||||||
ioc->name, ii));
|
ioc->name, ii));
|
||||||
r += (*(MptEvHandlers[ii]))(ioc, pEventReply);
|
r += (*(MptEvHandlers[ii]))(ioc, pEventReply);
|
||||||
handlers++;
|
handlers++;
|
||||||
|
@ -6065,10 +6088,10 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply
|
||||||
* If needed, send (a single) EventAck.
|
* If needed, send (a single) EventAck.
|
||||||
*/
|
*/
|
||||||
if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) {
|
if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) {
|
||||||
devtprintk((MYIOC_s_WARN_FMT
|
devtverboseprintk((MYIOC_s_WARN_FMT
|
||||||
"EventAck required\n",ioc->name));
|
"EventAck required\n",ioc->name));
|
||||||
if ((ii = SendEventAck(ioc, pEventReply)) != 0) {
|
if ((ii = SendEventAck(ioc, pEventReply)) != 0) {
|
||||||
devtprintk((MYIOC_s_WARN_FMT "SendEventAck returned %d\n",
|
devtverboseprintk((MYIOC_s_WARN_FMT "SendEventAck returned %d\n",
|
||||||
ioc->name, ii));
|
ioc->name, ii));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6205,8 +6228,8 @@ mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
|
||||||
"Abort", /* 12h */
|
"Abort", /* 12h */
|
||||||
"IO Not Yet Executed", /* 13h */
|
"IO Not Yet Executed", /* 13h */
|
||||||
"IO Executed", /* 14h */
|
"IO Executed", /* 14h */
|
||||||
NULL, /* 15h */
|
"Persistant Reservation Out Not Affiliation Owner", /* 15h */
|
||||||
NULL, /* 16h */
|
"Open Transmit DMA Abort", /* 16h */
|
||||||
NULL, /* 17h */
|
NULL, /* 17h */
|
||||||
NULL, /* 18h */
|
NULL, /* 18h */
|
||||||
NULL, /* 19h */
|
NULL, /* 19h */
|
||||||
|
@ -6431,11 +6454,9 @@ EXPORT_SYMBOL(mpt_stm_index);
|
||||||
EXPORT_SYMBOL(mpt_HardResetHandler);
|
EXPORT_SYMBOL(mpt_HardResetHandler);
|
||||||
EXPORT_SYMBOL(mpt_config);
|
EXPORT_SYMBOL(mpt_config);
|
||||||
EXPORT_SYMBOL(mpt_findImVolumes);
|
EXPORT_SYMBOL(mpt_findImVolumes);
|
||||||
EXPORT_SYMBOL(mpt_read_ioc_pg_3);
|
|
||||||
EXPORT_SYMBOL(mpt_alloc_fw_memory);
|
EXPORT_SYMBOL(mpt_alloc_fw_memory);
|
||||||
EXPORT_SYMBOL(mpt_free_fw_memory);
|
EXPORT_SYMBOL(mpt_free_fw_memory);
|
||||||
EXPORT_SYMBOL(mptbase_sas_persist_operation);
|
EXPORT_SYMBOL(mptbase_sas_persist_operation);
|
||||||
EXPORT_SYMBOL(mpt_alt_ioc_wait);
|
|
||||||
EXPORT_SYMBOL(mptbase_GetFcPortPage0);
|
EXPORT_SYMBOL(mptbase_GetFcPortPage0);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -76,8 +76,8 @@
|
||||||
#define COPYRIGHT "Copyright (c) 1999-2005 " MODULEAUTHOR
|
#define COPYRIGHT "Copyright (c) 1999-2005 " MODULEAUTHOR
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define MPT_LINUX_VERSION_COMMON "3.03.07"
|
#define MPT_LINUX_VERSION_COMMON "3.03.08"
|
||||||
#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.03.07"
|
#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.03.08"
|
||||||
#define WHAT_MAGIC_STRING "@" "(" "#" ")"
|
#define WHAT_MAGIC_STRING "@" "(" "#" ")"
|
||||||
|
|
||||||
#define show_mptmod_ver(s,ver) \
|
#define show_mptmod_ver(s,ver) \
|
||||||
|
@ -331,6 +331,7 @@ typedef struct _SYSIF_REGS
|
||||||
* VirtDevice - FC LUN device or SCSI target device
|
* VirtDevice - FC LUN device or SCSI target device
|
||||||
*/
|
*/
|
||||||
typedef struct _VirtTarget {
|
typedef struct _VirtTarget {
|
||||||
|
struct scsi_target *starget;
|
||||||
u8 tflags;
|
u8 tflags;
|
||||||
u8 ioc_id;
|
u8 ioc_id;
|
||||||
u8 target_id;
|
u8 target_id;
|
||||||
|
@ -343,14 +344,10 @@ typedef struct _VirtTarget {
|
||||||
u8 type; /* byte 0 of Inquiry data */
|
u8 type; /* byte 0 of Inquiry data */
|
||||||
u32 num_luns;
|
u32 num_luns;
|
||||||
u32 luns[8]; /* Max LUNs is 256 */
|
u32 luns[8]; /* Max LUNs is 256 */
|
||||||
u8 inq_data[8];
|
|
||||||
} VirtTarget;
|
} VirtTarget;
|
||||||
|
|
||||||
typedef struct _VirtDevice {
|
typedef struct _VirtDevice {
|
||||||
VirtTarget *vtarget;
|
VirtTarget *vtarget;
|
||||||
u8 ioc_id;
|
|
||||||
u8 bus_id;
|
|
||||||
u8 target_id;
|
|
||||||
u8 configured_lun;
|
u8 configured_lun;
|
||||||
u32 lun;
|
u32 lun;
|
||||||
} VirtDevice;
|
} VirtDevice;
|
||||||
|
@ -364,6 +361,7 @@ typedef struct _VirtDevice {
|
||||||
#define MPT_TARGET_FLAGS_Q_YES 0x08
|
#define MPT_TARGET_FLAGS_Q_YES 0x08
|
||||||
#define MPT_TARGET_FLAGS_VALID_56 0x10
|
#define MPT_TARGET_FLAGS_VALID_56 0x10
|
||||||
#define MPT_TARGET_FLAGS_SAF_TE_ISSUED 0x20
|
#define MPT_TARGET_FLAGS_SAF_TE_ISSUED 0x20
|
||||||
|
#define MPT_TARGET_FLAGS_RAID_COMPONENT 0x40
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* /proc/mpt interface
|
* /proc/mpt interface
|
||||||
|
@ -447,13 +445,6 @@ typedef struct _mpt_ioctl_events {
|
||||||
* Substructure to store SCSI specific configuration page data
|
* Substructure to store SCSI specific configuration page data
|
||||||
*/
|
*/
|
||||||
/* dvStatus defines: */
|
/* dvStatus defines: */
|
||||||
#define MPT_SCSICFG_NEGOTIATE 0x01 /* Negotiate on next IO */
|
|
||||||
#define MPT_SCSICFG_NEED_DV 0x02 /* Schedule DV */
|
|
||||||
#define MPT_SCSICFG_DV_PENDING 0x04 /* DV on this physical id pending */
|
|
||||||
#define MPT_SCSICFG_DV_NOT_DONE 0x08 /* DV has not been performed */
|
|
||||||
#define MPT_SCSICFG_BLK_NEGO 0x10 /* WriteSDP1 with WDTR and SDTR disabled */
|
|
||||||
#define MPT_SCSICFG_RELOAD_IOC_PG3 0x20 /* IOC Pg 3 data is obsolete */
|
|
||||||
/* Args passed to writeSDP1: */
|
|
||||||
#define MPT_SCSICFG_USE_NVRAM 0x01 /* WriteSDP1 using NVRAM */
|
#define MPT_SCSICFG_USE_NVRAM 0x01 /* WriteSDP1 using NVRAM */
|
||||||
#define MPT_SCSICFG_ALL_IDS 0x02 /* WriteSDP1 to all IDS */
|
#define MPT_SCSICFG_ALL_IDS 0x02 /* WriteSDP1 to all IDS */
|
||||||
/* #define MPT_SCSICFG_BLK_NEGO 0x10 WriteSDP1 with WDTR and SDTR disabled */
|
/* #define MPT_SCSICFG_BLK_NEGO 0x10 WriteSDP1 with WDTR and SDTR disabled */
|
||||||
|
@ -464,7 +455,6 @@ typedef struct _SpiCfgData {
|
||||||
IOCPage4_t *pIocPg4; /* SEP devices addressing */
|
IOCPage4_t *pIocPg4; /* SEP devices addressing */
|
||||||
dma_addr_t IocPg4_dma; /* Phys Addr of IOCPage4 data */
|
dma_addr_t IocPg4_dma; /* Phys Addr of IOCPage4 data */
|
||||||
int IocPg4Sz; /* IOCPage4 size */
|
int IocPg4Sz; /* IOCPage4 size */
|
||||||
u8 dvStatus[MPT_MAX_SCSI_DEVICES];
|
|
||||||
u8 minSyncFactor; /* 0xFF if async */
|
u8 minSyncFactor; /* 0xFF if async */
|
||||||
u8 maxSyncOffset; /* 0 if async */
|
u8 maxSyncOffset; /* 0 if async */
|
||||||
u8 maxBusWidth; /* 0 if narrow, 1 if wide */
|
u8 maxBusWidth; /* 0 if narrow, 1 if wide */
|
||||||
|
@ -474,13 +464,11 @@ typedef struct _SpiCfgData {
|
||||||
u8 sdp0version; /* SDP0 version */
|
u8 sdp0version; /* SDP0 version */
|
||||||
u8 sdp0length; /* SDP0 length */
|
u8 sdp0length; /* SDP0 length */
|
||||||
u8 dvScheduled; /* 1 if scheduled */
|
u8 dvScheduled; /* 1 if scheduled */
|
||||||
u8 forceDv; /* 1 to force DV scheduling */
|
|
||||||
u8 noQas; /* Disable QAS for this adapter */
|
u8 noQas; /* Disable QAS for this adapter */
|
||||||
u8 Saf_Te; /* 1 to force all Processors as
|
u8 Saf_Te; /* 1 to force all Processors as
|
||||||
* SAF-TE if Inquiry data length
|
* SAF-TE if Inquiry data length
|
||||||
* is too short to check for SAF-TE
|
* is too short to check for SAF-TE
|
||||||
*/
|
*/
|
||||||
u8 mpt_dv; /* command line option: enhanced=1, basic=0 */
|
|
||||||
u8 bus_reset; /* 1 to allow bus reset */
|
u8 bus_reset; /* 1 to allow bus reset */
|
||||||
u8 rsvd[1];
|
u8 rsvd[1];
|
||||||
}SpiCfgData;
|
}SpiCfgData;
|
||||||
|
@ -631,6 +619,10 @@ typedef struct _MPT_ADAPTER
|
||||||
struct net_device *netdev;
|
struct net_device *netdev;
|
||||||
struct list_head sas_topology;
|
struct list_head sas_topology;
|
||||||
struct mutex sas_topology_mutex;
|
struct mutex sas_topology_mutex;
|
||||||
|
struct mutex sas_discovery_mutex;
|
||||||
|
u8 sas_discovery_runtime;
|
||||||
|
u8 sas_discovery_ignore_events;
|
||||||
|
int sas_index; /* index refrencing */
|
||||||
MPT_SAS_MGMT sas_mgmt;
|
MPT_SAS_MGMT sas_mgmt;
|
||||||
int num_ports;
|
int num_ports;
|
||||||
struct work_struct mptscsih_persistTask;
|
struct work_struct mptscsih_persistTask;
|
||||||
|
@ -728,12 +720,18 @@ typedef struct _mpt_sge {
|
||||||
#define dhsprintk(x)
|
#define dhsprintk(x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef MPT_DEBUG_EVENTS
|
#if defined(MPT_DEBUG_EVENTS) || defined(MPT_DEBUG_VERBOSE_EVENTS)
|
||||||
#define devtprintk(x) printk x
|
#define devtprintk(x) printk x
|
||||||
#else
|
#else
|
||||||
#define devtprintk(x)
|
#define devtprintk(x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef MPT_DEBUG_VERBOSE_EVENTS
|
||||||
|
#define devtverboseprintk(x) printk x
|
||||||
|
#else
|
||||||
|
#define devtverboseprintk(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef MPT_DEBUG_RESET
|
#ifdef MPT_DEBUG_RESET
|
||||||
#define drsprintk(x) printk x
|
#define drsprintk(x) printk x
|
||||||
#else
|
#else
|
||||||
|
@ -1030,10 +1028,8 @@ extern int mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *cfg);
|
||||||
extern void mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size);
|
extern void mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size);
|
||||||
extern void mpt_free_fw_memory(MPT_ADAPTER *ioc);
|
extern void mpt_free_fw_memory(MPT_ADAPTER *ioc);
|
||||||
extern int mpt_findImVolumes(MPT_ADAPTER *ioc);
|
extern int mpt_findImVolumes(MPT_ADAPTER *ioc);
|
||||||
extern int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc);
|
|
||||||
extern int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
|
extern int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
|
||||||
extern int mptbase_GetFcPortPage0(MPT_ADAPTER *ioc, int portnum);
|
extern int mptbase_GetFcPortPage0(MPT_ADAPTER *ioc, int portnum);
|
||||||
extern int mpt_alt_ioc_wait(MPT_ADAPTER *ioc);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Public data decl's...
|
* Public data decl's...
|
||||||
|
|
|
@ -140,7 +140,7 @@ static int mptctl_ioc_reset(MPT_ADAPTER *ioc, int reset_phase);
|
||||||
* Event Handler function
|
* Event Handler function
|
||||||
*/
|
*/
|
||||||
static int mptctl_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
|
static int mptctl_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
|
||||||
struct fasync_struct *async_queue=NULL;
|
static struct fasync_struct *async_queue=NULL;
|
||||||
|
|
||||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
||||||
/*
|
/*
|
||||||
|
@ -497,7 +497,7 @@ mptctl_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
|
||||||
if (event == 0x21 ) {
|
if (event == 0x21 ) {
|
||||||
ioc->aen_event_read_flag=1;
|
ioc->aen_event_read_flag=1;
|
||||||
dctlprintk(("Raised SIGIO to application\n"));
|
dctlprintk(("Raised SIGIO to application\n"));
|
||||||
devtprintk(("Raised SIGIO to application\n"));
|
devtverboseprintk(("Raised SIGIO to application\n"));
|
||||||
kill_fasync(&async_queue, SIGIO, POLL_IN);
|
kill_fasync(&async_queue, SIGIO, POLL_IN);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -515,7 +515,7 @@ mptctl_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
|
||||||
if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
|
if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
|
||||||
ioc->aen_event_read_flag=1;
|
ioc->aen_event_read_flag=1;
|
||||||
dctlprintk(("Raised SIGIO to application\n"));
|
dctlprintk(("Raised SIGIO to application\n"));
|
||||||
devtprintk(("Raised SIGIO to application\n"));
|
devtverboseprintk(("Raised SIGIO to application\n"));
|
||||||
kill_fasync(&async_queue, SIGIO, POLL_IN);
|
kill_fasync(&async_queue, SIGIO, POLL_IN);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -2968,7 +2968,7 @@ static int __init mptctl_init(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mpt_event_register(mptctl_id, mptctl_event_process) == 0) {
|
if (mpt_event_register(mptctl_id, mptctl_event_process) == 0) {
|
||||||
devtprintk((KERN_INFO MYNAM
|
devtverboseprintk((KERN_INFO MYNAM
|
||||||
": Registered for IOC event notifications\n"));
|
": Registered for IOC event notifications\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -154,7 +154,7 @@ MODULE_DEVICE_TABLE(pci, mptfc_pci_table);
|
||||||
|
|
||||||
static struct scsi_transport_template *mptfc_transport_template = NULL;
|
static struct scsi_transport_template *mptfc_transport_template = NULL;
|
||||||
|
|
||||||
struct fc_function_template mptfc_transport_functions = {
|
static struct fc_function_template mptfc_transport_functions = {
|
||||||
.dd_fcrport_size = 8,
|
.dd_fcrport_size = 8,
|
||||||
.show_host_node_name = 1,
|
.show_host_node_name = 1,
|
||||||
.show_host_port_name = 1,
|
.show_host_port_name = 1,
|
||||||
|
@ -348,24 +348,6 @@ mptfc_generate_rport_ids(FCDevicePage0_t *pg0, struct fc_rport_identifiers *rid)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
mptfc_remap_sdev(struct scsi_device *sdev, void *arg)
|
|
||||||
{
|
|
||||||
VirtDevice *vdev;
|
|
||||||
VirtTarget *vtarget;
|
|
||||||
struct scsi_target *starget;
|
|
||||||
|
|
||||||
starget = scsi_target(sdev);
|
|
||||||
if (starget->hostdata == arg) {
|
|
||||||
vtarget = arg;
|
|
||||||
vdev = sdev->hostdata;
|
|
||||||
if (vdev) {
|
|
||||||
vdev->bus_id = vtarget->bus_id;
|
|
||||||
vdev->target_id = vtarget->target_id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0)
|
mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0)
|
||||||
{
|
{
|
||||||
|
@ -423,8 +405,6 @@ mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0)
|
||||||
if (vtarget) {
|
if (vtarget) {
|
||||||
vtarget->target_id = pg0->CurrentTargetID;
|
vtarget->target_id = pg0->CurrentTargetID;
|
||||||
vtarget->bus_id = pg0->CurrentBus;
|
vtarget->bus_id = pg0->CurrentBus;
|
||||||
starget_for_each_device(ri->starget,
|
|
||||||
vtarget,mptfc_remap_sdev);
|
|
||||||
}
|
}
|
||||||
ri->remap_needed = 0;
|
ri->remap_needed = 0;
|
||||||
}
|
}
|
||||||
|
@ -432,7 +412,7 @@ mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0)
|
||||||
"mptfc_reg_dev.%d: %x, %llx / %llx, tid %d, "
|
"mptfc_reg_dev.%d: %x, %llx / %llx, tid %d, "
|
||||||
"rport tid %d, tmo %d\n",
|
"rport tid %d, tmo %d\n",
|
||||||
ioc->name,
|
ioc->name,
|
||||||
oc->sh->host_no,
|
ioc->sh->host_no,
|
||||||
pg0->PortIdentifier,
|
pg0->PortIdentifier,
|
||||||
pg0->WWNN,
|
pg0->WWNN,
|
||||||
pg0->WWPN,
|
pg0->WWPN,
|
||||||
|
@ -514,7 +494,7 @@ mptfc_target_alloc(struct scsi_target *starget)
|
||||||
* Return non-zero if allocation fails.
|
* Return non-zero if allocation fails.
|
||||||
* Init memory once per LUN.
|
* Init memory once per LUN.
|
||||||
*/
|
*/
|
||||||
int
|
static int
|
||||||
mptfc_slave_alloc(struct scsi_device *sdev)
|
mptfc_slave_alloc(struct scsi_device *sdev)
|
||||||
{
|
{
|
||||||
MPT_SCSI_HOST *hd;
|
MPT_SCSI_HOST *hd;
|
||||||
|
@ -553,23 +533,26 @@ mptfc_slave_alloc(struct scsi_device *sdev)
|
||||||
}
|
}
|
||||||
|
|
||||||
vdev->vtarget = vtarget;
|
vdev->vtarget = vtarget;
|
||||||
vdev->ioc_id = hd->ioc->id;
|
|
||||||
vdev->lun = sdev->lun;
|
vdev->lun = sdev->lun;
|
||||||
vdev->target_id = vtarget->target_id;
|
|
||||||
vdev->bus_id = vtarget->bus_id;
|
|
||||||
|
|
||||||
spin_unlock_irqrestore(&hd->ioc->fc_rport_lock,flags);
|
spin_unlock_irqrestore(&hd->ioc->fc_rport_lock,flags);
|
||||||
|
|
||||||
vtarget->num_luns++;
|
vtarget->num_luns++;
|
||||||
|
|
||||||
|
#ifdef DMPT_DEBUG_FC
|
||||||
|
{
|
||||||
|
struct mptfc_rport_info *ri;
|
||||||
|
ri = *((struct mptfc_rport_info **)rport->dd_data);
|
||||||
dfcprintk ((MYIOC_s_INFO_FMT
|
dfcprintk ((MYIOC_s_INFO_FMT
|
||||||
"mptfc_slv_alloc.%d: num_luns %d, sdev.id %d, "
|
"mptfc_slv_alloc.%d: num_luns %d, sdev.id %d, "
|
||||||
"CurrentTargetID %d, %x %llx %llx\n",
|
"CurrentTargetID %d, %x %llx %llx\n",
|
||||||
ioc->name,
|
hd->ioc->name,
|
||||||
sdev->host->host_no,
|
sdev->host->host_no,
|
||||||
vtarget->num_luns,
|
vtarget->num_luns,
|
||||||
sdev->id, ri->pg0.CurrentTargetID,
|
sdev->id, ri->pg0.CurrentTargetID,
|
||||||
ri->pg0.PortIdentifier, ri->pg0.WWPN, ri->pg0.WWNN));
|
ri->pg0.PortIdentifier, ri->pg0.WWPN, ri->pg0.WWNN));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -941,7 +924,7 @@ mptfc_init(void)
|
||||||
mptfcInternalCtx = mpt_register(mptscsih_scandv_complete, MPTFC_DRIVER);
|
mptfcInternalCtx = mpt_register(mptscsih_scandv_complete, MPTFC_DRIVER);
|
||||||
|
|
||||||
if (mpt_event_register(mptfcDoneCtx, mptscsih_event_process) == 0) {
|
if (mpt_event_register(mptfcDoneCtx, mptscsih_event_process) == 0) {
|
||||||
devtprintk((KERN_INFO MYNAM
|
devtverboseprintk((KERN_INFO MYNAM
|
||||||
": Registered for IOC event notifications\n"));
|
": Registered for IOC event notifications\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1152,10 +1152,7 @@ mpt_lan_receive_post_reply(struct net_device *dev,
|
||||||
priv->mpt_rxfidx_tail,
|
priv->mpt_rxfidx_tail,
|
||||||
MPT_LAN_MAX_BUCKETS_OUT);
|
MPT_LAN_MAX_BUCKETS_OUT);
|
||||||
|
|
||||||
panic("Damn it Jim! I'm a doctor, not a programmer! "
|
return -1;
|
||||||
"Oh, wait a sec, I am a programmer. "
|
|
||||||
"And, who's Jim?!?!\n"
|
|
||||||
"Arrgghh! We've done it again!\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (remaining == 0)
|
if (remaining == 0)
|
||||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -60,16 +60,6 @@
|
||||||
|
|
||||||
#define MPT_SCSI_MAX_SECTORS 8192
|
#define MPT_SCSI_MAX_SECTORS 8192
|
||||||
|
|
||||||
/* To disable domain validation, uncomment the
|
|
||||||
* following line. No effect for FC devices.
|
|
||||||
* For SCSI devices, driver will negotiate to
|
|
||||||
* NVRAM settings (if available) or to maximum adapter
|
|
||||||
* capabilities.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define MPTSCSIH_ENABLE_DOMAIN_VALIDATION
|
|
||||||
|
|
||||||
|
|
||||||
/* SCSI driver setup structure. Settings can be overridden
|
/* SCSI driver setup structure. Settings can be overridden
|
||||||
* by command line options.
|
* by command line options.
|
||||||
*/
|
*/
|
||||||
|
@ -109,3 +99,5 @@ extern int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
|
||||||
extern int mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth);
|
extern int mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth);
|
||||||
extern void mptscsih_timer_expired(unsigned long data);
|
extern void mptscsih_timer_expired(unsigned long data);
|
||||||
extern int mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout);
|
extern int mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout);
|
||||||
|
extern int mptscsih_raid_id_to_num(MPT_SCSI_HOST *hd, uint physdiskid);
|
||||||
|
extern int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id);
|
||||||
|
|
|
@ -56,12 +56,15 @@
|
||||||
#include <linux/reboot.h> /* notifier code */
|
#include <linux/reboot.h> /* notifier code */
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
#include <linux/workqueue.h>
|
#include <linux/workqueue.h>
|
||||||
|
#include <linux/raid_class.h>
|
||||||
|
|
||||||
#include <scsi/scsi.h>
|
#include <scsi/scsi.h>
|
||||||
#include <scsi/scsi_cmnd.h>
|
#include <scsi/scsi_cmnd.h>
|
||||||
#include <scsi/scsi_device.h>
|
#include <scsi/scsi_device.h>
|
||||||
#include <scsi/scsi_host.h>
|
#include <scsi/scsi_host.h>
|
||||||
#include <scsi/scsi_tcq.h>
|
#include <scsi/scsi_tcq.h>
|
||||||
|
#include <scsi/scsi_transport.h>
|
||||||
|
#include <scsi/scsi_transport_spi.h>
|
||||||
|
|
||||||
#include "mptbase.h"
|
#include "mptbase.h"
|
||||||
#include "mptscsih.h"
|
#include "mptscsih.h"
|
||||||
|
@ -76,20 +79,6 @@ MODULE_DESCRIPTION(my_NAME);
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
|
||||||
/* Command line args */
|
/* Command line args */
|
||||||
#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
|
|
||||||
static int mpt_dv = MPTSCSIH_DOMAIN_VALIDATION;
|
|
||||||
module_param(mpt_dv, int, 0);
|
|
||||||
MODULE_PARM_DESC(mpt_dv, " DV Algorithm: enhanced=1, basic=0 (default=MPTSCSIH_DOMAIN_VALIDATION=1)");
|
|
||||||
|
|
||||||
static int mpt_width = MPTSCSIH_MAX_WIDTH;
|
|
||||||
module_param(mpt_width, int, 0);
|
|
||||||
MODULE_PARM_DESC(mpt_width, " Max Bus Width: wide=1, narrow=0 (default=MPTSCSIH_MAX_WIDTH=1)");
|
|
||||||
|
|
||||||
static ushort mpt_factor = MPTSCSIH_MIN_SYNC;
|
|
||||||
module_param(mpt_factor, ushort, 0);
|
|
||||||
MODULE_PARM_DESC(mpt_factor, " Min Sync Factor (default=MPTSCSIH_MIN_SYNC=0x08)");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static int mpt_saf_te = MPTSCSIH_SAF_TE;
|
static int mpt_saf_te = MPTSCSIH_SAF_TE;
|
||||||
module_param(mpt_saf_te, int, 0);
|
module_param(mpt_saf_te, int, 0);
|
||||||
MODULE_PARM_DESC(mpt_saf_te, " Force enabling SEP Processor: enable=1 (default=MPTSCSIH_SAF_TE=0)");
|
MODULE_PARM_DESC(mpt_saf_te, " Force enabling SEP Processor: enable=1 (default=MPTSCSIH_SAF_TE=0)");
|
||||||
|
@ -98,10 +87,308 @@ static int mpt_pq_filter = 0;
|
||||||
module_param(mpt_pq_filter, int, 0);
|
module_param(mpt_pq_filter, int, 0);
|
||||||
MODULE_PARM_DESC(mpt_pq_filter, " Enable peripheral qualifier filter: enable=1 (default=0)");
|
MODULE_PARM_DESC(mpt_pq_filter, " Enable peripheral qualifier filter: enable=1 (default=0)");
|
||||||
|
|
||||||
|
static void mptspi_write_offset(struct scsi_target *, int);
|
||||||
|
static void mptspi_write_width(struct scsi_target *, int);
|
||||||
|
static int mptspi_write_spi_device_pg1(struct scsi_target *,
|
||||||
|
struct _CONFIG_PAGE_SCSI_DEVICE_1 *);
|
||||||
|
|
||||||
|
static struct scsi_transport_template *mptspi_transport_template = NULL;
|
||||||
|
|
||||||
static int mptspiDoneCtx = -1;
|
static int mptspiDoneCtx = -1;
|
||||||
static int mptspiTaskCtx = -1;
|
static int mptspiTaskCtx = -1;
|
||||||
static int mptspiInternalCtx = -1; /* Used only for internal commands */
|
static int mptspiInternalCtx = -1; /* Used only for internal commands */
|
||||||
|
|
||||||
|
static int mptspi_target_alloc(struct scsi_target *starget)
|
||||||
|
{
|
||||||
|
struct Scsi_Host *shost = dev_to_shost(&starget->dev);
|
||||||
|
struct _MPT_SCSI_HOST *hd = (struct _MPT_SCSI_HOST *)shost->hostdata;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (hd == NULL)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
ret = mptscsih_target_alloc(starget);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
/* if we're a device on virtual channel 1 and we're not part
|
||||||
|
* of an array, just return here (otherwise the setup below
|
||||||
|
* may actually affect a real physical device on channel 0 */
|
||||||
|
if (starget->channel == 1 &&
|
||||||
|
mptscsih_raid_id_to_num(hd, starget->id) < 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (hd->ioc->spi_data.nvram &&
|
||||||
|
hd->ioc->spi_data.nvram[starget->id] != MPT_HOST_NVRAM_INVALID) {
|
||||||
|
u32 nvram = hd->ioc->spi_data.nvram[starget->id];
|
||||||
|
spi_min_period(starget) = (nvram & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT;
|
||||||
|
spi_max_width(starget) = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
|
||||||
|
} else {
|
||||||
|
spi_min_period(starget) = hd->ioc->spi_data.minSyncFactor;
|
||||||
|
spi_max_width(starget) = hd->ioc->spi_data.maxBusWidth;
|
||||||
|
}
|
||||||
|
spi_max_offset(starget) = hd->ioc->spi_data.maxSyncOffset;
|
||||||
|
|
||||||
|
spi_offset(starget) = 0;
|
||||||
|
mptspi_write_width(starget, 0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mptspi_read_spi_device_pg0(struct scsi_target *starget,
|
||||||
|
struct _CONFIG_PAGE_SCSI_DEVICE_0 *pass_pg0)
|
||||||
|
{
|
||||||
|
struct Scsi_Host *shost = dev_to_shost(&starget->dev);
|
||||||
|
struct _MPT_SCSI_HOST *hd = (struct _MPT_SCSI_HOST *)shost->hostdata;
|
||||||
|
struct _MPT_ADAPTER *ioc = hd->ioc;
|
||||||
|
struct _CONFIG_PAGE_SCSI_DEVICE_0 *pg0;
|
||||||
|
dma_addr_t pg0_dma;
|
||||||
|
int size;
|
||||||
|
struct _x_config_parms cfg;
|
||||||
|
struct _CONFIG_PAGE_HEADER hdr;
|
||||||
|
int err = -EBUSY;
|
||||||
|
|
||||||
|
/* No SPI parameters for RAID devices */
|
||||||
|
if (starget->channel == 0 &&
|
||||||
|
(hd->ioc->raid_data.isRaid & (1 << starget->id)))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
size = ioc->spi_data.sdp0length * 4;
|
||||||
|
/*
|
||||||
|
if (ioc->spi_data.sdp0length & 1)
|
||||||
|
size += size + 4;
|
||||||
|
size += 2048;
|
||||||
|
*/
|
||||||
|
|
||||||
|
pg0 = dma_alloc_coherent(&ioc->pcidev->dev, size, &pg0_dma, GFP_KERNEL);
|
||||||
|
if (pg0 == NULL) {
|
||||||
|
starget_printk(KERN_ERR, starget, "dma_alloc_coherent for parameters failed\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&hdr, 0, sizeof(hdr));
|
||||||
|
|
||||||
|
hdr.PageVersion = ioc->spi_data.sdp0version;
|
||||||
|
hdr.PageLength = ioc->spi_data.sdp0length;
|
||||||
|
hdr.PageNumber = 0;
|
||||||
|
hdr.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
|
||||||
|
|
||||||
|
memset(&cfg, 0, sizeof(cfg));
|
||||||
|
|
||||||
|
cfg.cfghdr.hdr = &hdr;
|
||||||
|
cfg.physAddr = pg0_dma;
|
||||||
|
cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
|
||||||
|
cfg.dir = 0;
|
||||||
|
cfg.pageAddr = starget->id;
|
||||||
|
|
||||||
|
if (mpt_config(ioc, &cfg)) {
|
||||||
|
starget_printk(KERN_ERR, starget, "mpt_config failed\n");
|
||||||
|
goto out_free;
|
||||||
|
}
|
||||||
|
err = 0;
|
||||||
|
memcpy(pass_pg0, pg0, size);
|
||||||
|
|
||||||
|
out_free:
|
||||||
|
dma_free_coherent(&ioc->pcidev->dev, size, pg0, pg0_dma);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 mptspi_getRP(struct scsi_target *starget)
|
||||||
|
{
|
||||||
|
u32 nego = 0;
|
||||||
|
|
||||||
|
nego |= spi_iu(starget) ? MPI_SCSIDEVPAGE1_RP_IU : 0;
|
||||||
|
nego |= spi_dt(starget) ? MPI_SCSIDEVPAGE1_RP_DT : 0;
|
||||||
|
nego |= spi_qas(starget) ? MPI_SCSIDEVPAGE1_RP_QAS : 0;
|
||||||
|
nego |= spi_hold_mcs(starget) ? MPI_SCSIDEVPAGE1_RP_HOLD_MCS : 0;
|
||||||
|
nego |= spi_wr_flow(starget) ? MPI_SCSIDEVPAGE1_RP_WR_FLOW : 0;
|
||||||
|
nego |= spi_rd_strm(starget) ? MPI_SCSIDEVPAGE1_RP_RD_STRM : 0;
|
||||||
|
nego |= spi_rti(starget) ? MPI_SCSIDEVPAGE1_RP_RTI : 0;
|
||||||
|
nego |= spi_pcomp_en(starget) ? MPI_SCSIDEVPAGE1_RP_PCOMP_EN : 0;
|
||||||
|
|
||||||
|
nego |= (spi_period(starget) << MPI_SCSIDEVPAGE1_RP_SHIFT_MIN_SYNC_PERIOD) & MPI_SCSIDEVPAGE1_RP_MIN_SYNC_PERIOD_MASK;
|
||||||
|
nego |= (spi_offset(starget) << MPI_SCSIDEVPAGE1_RP_SHIFT_MAX_SYNC_OFFSET) & MPI_SCSIDEVPAGE1_RP_MAX_SYNC_OFFSET_MASK;
|
||||||
|
nego |= spi_width(starget) ? MPI_SCSIDEVPAGE1_RP_WIDE : 0;
|
||||||
|
|
||||||
|
return nego;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mptspi_read_parameters(struct scsi_target *starget)
|
||||||
|
{
|
||||||
|
int nego;
|
||||||
|
struct _CONFIG_PAGE_SCSI_DEVICE_0 pg0;
|
||||||
|
|
||||||
|
mptspi_read_spi_device_pg0(starget, &pg0);
|
||||||
|
|
||||||
|
nego = le32_to_cpu(pg0.NegotiatedParameters);
|
||||||
|
|
||||||
|
spi_iu(starget) = (nego & MPI_SCSIDEVPAGE0_NP_IU) ? 1 : 0;
|
||||||
|
spi_dt(starget) = (nego & MPI_SCSIDEVPAGE0_NP_DT) ? 1 : 0;
|
||||||
|
spi_qas(starget) = (nego & MPI_SCSIDEVPAGE0_NP_QAS) ? 1 : 0;
|
||||||
|
spi_wr_flow(starget) = (nego & MPI_SCSIDEVPAGE0_NP_WR_FLOW) ? 1 : 0;
|
||||||
|
spi_rd_strm(starget) = (nego & MPI_SCSIDEVPAGE0_NP_RD_STRM) ? 1 : 0;
|
||||||
|
spi_rti(starget) = (nego & MPI_SCSIDEVPAGE0_NP_RTI) ? 1 : 0;
|
||||||
|
spi_pcomp_en(starget) = (nego & MPI_SCSIDEVPAGE0_NP_PCOMP_EN) ? 1 : 0;
|
||||||
|
spi_hold_mcs(starget) = (nego & MPI_SCSIDEVPAGE0_NP_HOLD_MCS) ? 1 : 0;
|
||||||
|
spi_period(starget) = (nego & MPI_SCSIDEVPAGE0_NP_NEG_SYNC_PERIOD_MASK) >> MPI_SCSIDEVPAGE0_NP_SHIFT_SYNC_PERIOD;
|
||||||
|
spi_offset(starget) = (nego & MPI_SCSIDEVPAGE0_NP_NEG_SYNC_OFFSET_MASK) >> MPI_SCSIDEVPAGE0_NP_SHIFT_SYNC_OFFSET;
|
||||||
|
spi_width(starget) = (nego & MPI_SCSIDEVPAGE0_NP_WIDE) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
mptscsih_quiesce_raid(MPT_SCSI_HOST *hd, int quiesce, int disk)
|
||||||
|
{
|
||||||
|
MpiRaidActionRequest_t *pReq;
|
||||||
|
MPT_FRAME_HDR *mf;
|
||||||
|
|
||||||
|
/* Get and Populate a free Frame
|
||||||
|
*/
|
||||||
|
if ((mf = mpt_get_msg_frame(hd->ioc->InternalCtx, hd->ioc)) == NULL) {
|
||||||
|
ddvprintk((MYIOC_s_WARN_FMT "_do_raid: no msg frames!\n",
|
||||||
|
hd->ioc->name));
|
||||||
|
return -EAGAIN;
|
||||||
|
}
|
||||||
|
pReq = (MpiRaidActionRequest_t *)mf;
|
||||||
|
if (quiesce)
|
||||||
|
pReq->Action = MPI_RAID_ACTION_QUIESCE_PHYS_IO;
|
||||||
|
else
|
||||||
|
pReq->Action = MPI_RAID_ACTION_ENABLE_PHYS_IO;
|
||||||
|
pReq->Reserved1 = 0;
|
||||||
|
pReq->ChainOffset = 0;
|
||||||
|
pReq->Function = MPI_FUNCTION_RAID_ACTION;
|
||||||
|
pReq->VolumeID = disk;
|
||||||
|
pReq->VolumeBus = 0;
|
||||||
|
pReq->PhysDiskNum = 0;
|
||||||
|
pReq->MsgFlags = 0;
|
||||||
|
pReq->Reserved2 = 0;
|
||||||
|
pReq->ActionDataWord = 0; /* Reserved for this action */
|
||||||
|
|
||||||
|
mpt_add_sge((char *)&pReq->ActionDataSGE,
|
||||||
|
MPT_SGE_FLAGS_SSIMPLE_READ | 0, (dma_addr_t) -1);
|
||||||
|
|
||||||
|
ddvprintk((MYIOC_s_INFO_FMT "RAID Volume action %x id %d\n",
|
||||||
|
hd->ioc->name, action, io->id));
|
||||||
|
|
||||||
|
hd->pLocal = NULL;
|
||||||
|
hd->timer.expires = jiffies + HZ*10; /* 10 second timeout */
|
||||||
|
hd->scandv_wait_done = 0;
|
||||||
|
|
||||||
|
/* Save cmd pointer, for resource free if timeout or
|
||||||
|
* FW reload occurs
|
||||||
|
*/
|
||||||
|
hd->cmdPtr = mf;
|
||||||
|
|
||||||
|
add_timer(&hd->timer);
|
||||||
|
mpt_put_msg_frame(hd->ioc->InternalCtx, hd->ioc, mf);
|
||||||
|
wait_event(hd->scandv_waitq, hd->scandv_wait_done);
|
||||||
|
|
||||||
|
if ((hd->pLocal == NULL) || (hd->pLocal->completion != 0))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mptspi_dv_device(struct _MPT_SCSI_HOST *hd,
|
||||||
|
struct scsi_device *sdev)
|
||||||
|
{
|
||||||
|
VirtTarget *vtarget = scsi_target(sdev)->hostdata;
|
||||||
|
|
||||||
|
/* no DV on RAID devices */
|
||||||
|
if (sdev->channel == 0 &&
|
||||||
|
(hd->ioc->raid_data.isRaid & (1 << sdev->id)))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* If this is a piece of a RAID, then quiesce first */
|
||||||
|
if (sdev->channel == 1 &&
|
||||||
|
mptscsih_quiesce_raid(hd, 1, vtarget->target_id) < 0) {
|
||||||
|
starget_printk(KERN_ERR, scsi_target(sdev),
|
||||||
|
"Integrated RAID quiesce failed\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
spi_dv_device(sdev);
|
||||||
|
|
||||||
|
if (sdev->channel == 1 &&
|
||||||
|
mptscsih_quiesce_raid(hd, 0, vtarget->target_id) < 0)
|
||||||
|
starget_printk(KERN_ERR, scsi_target(sdev),
|
||||||
|
"Integrated RAID resume failed\n");
|
||||||
|
|
||||||
|
mptspi_read_parameters(sdev->sdev_target);
|
||||||
|
spi_display_xfer_agreement(sdev->sdev_target);
|
||||||
|
mptspi_read_parameters(sdev->sdev_target);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mptspi_slave_alloc(struct scsi_device *sdev)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sdev->host->hostdata;
|
||||||
|
/* gcc doesn't see that all uses of this variable occur within
|
||||||
|
* the if() statements, so stop it from whining */
|
||||||
|
int physdisknum = 0;
|
||||||
|
|
||||||
|
if (sdev->channel == 1) {
|
||||||
|
physdisknum = mptscsih_raid_id_to_num(hd, sdev->id);
|
||||||
|
|
||||||
|
if (physdisknum < 0)
|
||||||
|
return physdisknum;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = mptscsih_slave_alloc(sdev);
|
||||||
|
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if (sdev->channel == 1) {
|
||||||
|
VirtDevice *vdev = sdev->hostdata;
|
||||||
|
sdev->no_uld_attach = 1;
|
||||||
|
vdev->vtarget->tflags |= MPT_TARGET_FLAGS_RAID_COMPONENT;
|
||||||
|
/* The real channel for this device is zero */
|
||||||
|
vdev->vtarget->bus_id = 0;
|
||||||
|
/* The actual physdisknum (for RAID passthrough) */
|
||||||
|
vdev->vtarget->target_id = physdisknum;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mptspi_slave_configure(struct scsi_device *sdev)
|
||||||
|
{
|
||||||
|
int ret = mptscsih_slave_configure(sdev);
|
||||||
|
struct _MPT_SCSI_HOST *hd =
|
||||||
|
(struct _MPT_SCSI_HOST *)sdev->host->hostdata;
|
||||||
|
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if ((sdev->channel == 1 ||
|
||||||
|
!(hd->ioc->raid_data.isRaid & (1 << sdev->id))) &&
|
||||||
|
!spi_initial_dv(sdev->sdev_target))
|
||||||
|
mptspi_dv_device(hd, sdev);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mptspi_slave_destroy(struct scsi_device *sdev)
|
||||||
|
{
|
||||||
|
struct scsi_target *starget = scsi_target(sdev);
|
||||||
|
VirtTarget *vtarget = starget->hostdata;
|
||||||
|
VirtDevice *vdevice = sdev->hostdata;
|
||||||
|
|
||||||
|
/* Will this be the last lun on a non-raid device? */
|
||||||
|
if (vtarget->num_luns == 1 && vdevice->configured_lun) {
|
||||||
|
struct _CONFIG_PAGE_SCSI_DEVICE_1 pg1;
|
||||||
|
|
||||||
|
/* Async Narrow */
|
||||||
|
pg1.RequestedParameters = 0;
|
||||||
|
pg1.Reserved = 0;
|
||||||
|
pg1.Configuration = 0;
|
||||||
|
|
||||||
|
mptspi_write_spi_device_pg1(starget, &pg1);
|
||||||
|
}
|
||||||
|
|
||||||
|
mptscsih_slave_destroy(sdev);
|
||||||
|
}
|
||||||
|
|
||||||
static struct scsi_host_template mptspi_driver_template = {
|
static struct scsi_host_template mptspi_driver_template = {
|
||||||
.module = THIS_MODULE,
|
.module = THIS_MODULE,
|
||||||
.proc_name = "mptspi",
|
.proc_name = "mptspi",
|
||||||
|
@ -109,11 +396,11 @@ static struct scsi_host_template mptspi_driver_template = {
|
||||||
.name = "MPT SPI Host",
|
.name = "MPT SPI Host",
|
||||||
.info = mptscsih_info,
|
.info = mptscsih_info,
|
||||||
.queuecommand = mptscsih_qcmd,
|
.queuecommand = mptscsih_qcmd,
|
||||||
.target_alloc = mptscsih_target_alloc,
|
.target_alloc = mptspi_target_alloc,
|
||||||
.slave_alloc = mptscsih_slave_alloc,
|
.slave_alloc = mptspi_slave_alloc,
|
||||||
.slave_configure = mptscsih_slave_configure,
|
.slave_configure = mptspi_slave_configure,
|
||||||
.target_destroy = mptscsih_target_destroy,
|
.target_destroy = mptscsih_target_destroy,
|
||||||
.slave_destroy = mptscsih_slave_destroy,
|
.slave_destroy = mptspi_slave_destroy,
|
||||||
.change_queue_depth = mptscsih_change_queue_depth,
|
.change_queue_depth = mptscsih_change_queue_depth,
|
||||||
.eh_abort_handler = mptscsih_abort,
|
.eh_abort_handler = mptscsih_abort,
|
||||||
.eh_device_reset_handler = mptscsih_dev_reset,
|
.eh_device_reset_handler = mptscsih_dev_reset,
|
||||||
|
@ -128,6 +415,360 @@ static struct scsi_host_template mptspi_driver_template = {
|
||||||
.use_clustering = ENABLE_CLUSTERING,
|
.use_clustering = ENABLE_CLUSTERING,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int mptspi_write_spi_device_pg1(struct scsi_target *starget,
|
||||||
|
struct _CONFIG_PAGE_SCSI_DEVICE_1 *pass_pg1)
|
||||||
|
{
|
||||||
|
struct Scsi_Host *shost = dev_to_shost(&starget->dev);
|
||||||
|
struct _MPT_SCSI_HOST *hd = (struct _MPT_SCSI_HOST *)shost->hostdata;
|
||||||
|
struct _MPT_ADAPTER *ioc = hd->ioc;
|
||||||
|
struct _CONFIG_PAGE_SCSI_DEVICE_1 *pg1;
|
||||||
|
dma_addr_t pg1_dma;
|
||||||
|
int size;
|
||||||
|
struct _x_config_parms cfg;
|
||||||
|
struct _CONFIG_PAGE_HEADER hdr;
|
||||||
|
int err = -EBUSY;
|
||||||
|
|
||||||
|
/* don't allow updating nego parameters on RAID devices */
|
||||||
|
if (starget->channel == 0 &&
|
||||||
|
(hd->ioc->raid_data.isRaid & (1 << starget->id)))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
size = ioc->spi_data.sdp1length * 4;
|
||||||
|
|
||||||
|
pg1 = dma_alloc_coherent(&ioc->pcidev->dev, size, &pg1_dma, GFP_KERNEL);
|
||||||
|
if (pg1 == NULL) {
|
||||||
|
starget_printk(KERN_ERR, starget, "dma_alloc_coherent for parameters failed\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&hdr, 0, sizeof(hdr));
|
||||||
|
|
||||||
|
hdr.PageVersion = ioc->spi_data.sdp1version;
|
||||||
|
hdr.PageLength = ioc->spi_data.sdp1length;
|
||||||
|
hdr.PageNumber = 1;
|
||||||
|
hdr.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
|
||||||
|
|
||||||
|
memset(&cfg, 0, sizeof(cfg));
|
||||||
|
|
||||||
|
cfg.cfghdr.hdr = &hdr;
|
||||||
|
cfg.physAddr = pg1_dma;
|
||||||
|
cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
|
||||||
|
cfg.dir = 1;
|
||||||
|
cfg.pageAddr = starget->id;
|
||||||
|
|
||||||
|
memcpy(pg1, pass_pg1, size);
|
||||||
|
|
||||||
|
pg1->Header.PageVersion = hdr.PageVersion;
|
||||||
|
pg1->Header.PageLength = hdr.PageLength;
|
||||||
|
pg1->Header.PageNumber = hdr.PageNumber;
|
||||||
|
pg1->Header.PageType = hdr.PageType;
|
||||||
|
|
||||||
|
if (mpt_config(ioc, &cfg)) {
|
||||||
|
starget_printk(KERN_ERR, starget, "mpt_config failed\n");
|
||||||
|
goto out_free;
|
||||||
|
}
|
||||||
|
err = 0;
|
||||||
|
|
||||||
|
out_free:
|
||||||
|
dma_free_coherent(&ioc->pcidev->dev, size, pg1, pg1_dma);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mptspi_write_offset(struct scsi_target *starget, int offset)
|
||||||
|
{
|
||||||
|
struct _CONFIG_PAGE_SCSI_DEVICE_1 pg1;
|
||||||
|
u32 nego;
|
||||||
|
|
||||||
|
if (offset < 0)
|
||||||
|
offset = 0;
|
||||||
|
|
||||||
|
if (offset > 255)
|
||||||
|
offset = 255;
|
||||||
|
|
||||||
|
if (spi_offset(starget) == -1)
|
||||||
|
mptspi_read_parameters(starget);
|
||||||
|
|
||||||
|
spi_offset(starget) = offset;
|
||||||
|
|
||||||
|
nego = mptspi_getRP(starget);
|
||||||
|
|
||||||
|
pg1.RequestedParameters = cpu_to_le32(nego);
|
||||||
|
pg1.Reserved = 0;
|
||||||
|
pg1.Configuration = 0;
|
||||||
|
|
||||||
|
mptspi_write_spi_device_pg1(starget, &pg1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mptspi_write_period(struct scsi_target *starget, int period)
|
||||||
|
{
|
||||||
|
struct _CONFIG_PAGE_SCSI_DEVICE_1 pg1;
|
||||||
|
u32 nego;
|
||||||
|
|
||||||
|
if (period < 8)
|
||||||
|
period = 8;
|
||||||
|
|
||||||
|
if (period > 255)
|
||||||
|
period = 255;
|
||||||
|
|
||||||
|
if (spi_period(starget) == -1)
|
||||||
|
mptspi_read_parameters(starget);
|
||||||
|
|
||||||
|
if (period == 8) {
|
||||||
|
spi_iu(starget) = 1;
|
||||||
|
spi_dt(starget) = 1;
|
||||||
|
} else if (period == 9) {
|
||||||
|
spi_dt(starget) = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
spi_period(starget) = period;
|
||||||
|
|
||||||
|
nego = mptspi_getRP(starget);
|
||||||
|
|
||||||
|
pg1.RequestedParameters = cpu_to_le32(nego);
|
||||||
|
pg1.Reserved = 0;
|
||||||
|
pg1.Configuration = 0;
|
||||||
|
|
||||||
|
mptspi_write_spi_device_pg1(starget, &pg1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mptspi_write_dt(struct scsi_target *starget, int dt)
|
||||||
|
{
|
||||||
|
struct _CONFIG_PAGE_SCSI_DEVICE_1 pg1;
|
||||||
|
u32 nego;
|
||||||
|
|
||||||
|
if (spi_period(starget) == -1)
|
||||||
|
mptspi_read_parameters(starget);
|
||||||
|
|
||||||
|
if (!dt && spi_period(starget) < 10)
|
||||||
|
spi_period(starget) = 10;
|
||||||
|
|
||||||
|
spi_dt(starget) = dt;
|
||||||
|
|
||||||
|
nego = mptspi_getRP(starget);
|
||||||
|
|
||||||
|
|
||||||
|
pg1.RequestedParameters = cpu_to_le32(nego);
|
||||||
|
pg1.Reserved = 0;
|
||||||
|
pg1.Configuration = 0;
|
||||||
|
|
||||||
|
mptspi_write_spi_device_pg1(starget, &pg1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mptspi_write_iu(struct scsi_target *starget, int iu)
|
||||||
|
{
|
||||||
|
struct _CONFIG_PAGE_SCSI_DEVICE_1 pg1;
|
||||||
|
u32 nego;
|
||||||
|
|
||||||
|
if (spi_period(starget) == -1)
|
||||||
|
mptspi_read_parameters(starget);
|
||||||
|
|
||||||
|
if (!iu && spi_period(starget) < 9)
|
||||||
|
spi_period(starget) = 9;
|
||||||
|
|
||||||
|
spi_iu(starget) = iu;
|
||||||
|
|
||||||
|
nego = mptspi_getRP(starget);
|
||||||
|
|
||||||
|
pg1.RequestedParameters = cpu_to_le32(nego);
|
||||||
|
pg1.Reserved = 0;
|
||||||
|
pg1.Configuration = 0;
|
||||||
|
|
||||||
|
mptspi_write_spi_device_pg1(starget, &pg1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define MPTSPI_SIMPLE_TRANSPORT_PARM(parm) \
|
||||||
|
static void mptspi_write_##parm(struct scsi_target *starget, int parm)\
|
||||||
|
{ \
|
||||||
|
struct _CONFIG_PAGE_SCSI_DEVICE_1 pg1; \
|
||||||
|
u32 nego; \
|
||||||
|
\
|
||||||
|
spi_##parm(starget) = parm; \
|
||||||
|
\
|
||||||
|
nego = mptspi_getRP(starget); \
|
||||||
|
\
|
||||||
|
pg1.RequestedParameters = cpu_to_le32(nego); \
|
||||||
|
pg1.Reserved = 0; \
|
||||||
|
pg1.Configuration = 0; \
|
||||||
|
\
|
||||||
|
mptspi_write_spi_device_pg1(starget, &pg1); \
|
||||||
|
}
|
||||||
|
|
||||||
|
MPTSPI_SIMPLE_TRANSPORT_PARM(rd_strm)
|
||||||
|
MPTSPI_SIMPLE_TRANSPORT_PARM(wr_flow)
|
||||||
|
MPTSPI_SIMPLE_TRANSPORT_PARM(rti)
|
||||||
|
MPTSPI_SIMPLE_TRANSPORT_PARM(hold_mcs)
|
||||||
|
MPTSPI_SIMPLE_TRANSPORT_PARM(pcomp_en)
|
||||||
|
|
||||||
|
static void mptspi_write_qas(struct scsi_target *starget, int qas)
|
||||||
|
{
|
||||||
|
struct _CONFIG_PAGE_SCSI_DEVICE_1 pg1;
|
||||||
|
struct Scsi_Host *shost = dev_to_shost(&starget->dev);
|
||||||
|
struct _MPT_SCSI_HOST *hd = (struct _MPT_SCSI_HOST *)shost->hostdata;
|
||||||
|
VirtTarget *vtarget = starget->hostdata;
|
||||||
|
u32 nego;
|
||||||
|
|
||||||
|
if ((vtarget->negoFlags & MPT_TARGET_NO_NEGO_QAS) ||
|
||||||
|
hd->ioc->spi_data.noQas)
|
||||||
|
spi_qas(starget) = 0;
|
||||||
|
else
|
||||||
|
spi_qas(starget) = qas;
|
||||||
|
|
||||||
|
nego = mptspi_getRP(starget);
|
||||||
|
|
||||||
|
pg1.RequestedParameters = cpu_to_le32(nego);
|
||||||
|
pg1.Reserved = 0;
|
||||||
|
pg1.Configuration = 0;
|
||||||
|
|
||||||
|
mptspi_write_spi_device_pg1(starget, &pg1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mptspi_write_width(struct scsi_target *starget, int width)
|
||||||
|
{
|
||||||
|
struct _CONFIG_PAGE_SCSI_DEVICE_1 pg1;
|
||||||
|
u32 nego;
|
||||||
|
|
||||||
|
if (!width) {
|
||||||
|
spi_dt(starget) = 0;
|
||||||
|
if (spi_period(starget) < 10)
|
||||||
|
spi_period(starget) = 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
spi_width(starget) = width;
|
||||||
|
|
||||||
|
nego = mptspi_getRP(starget);
|
||||||
|
|
||||||
|
pg1.RequestedParameters = cpu_to_le32(nego);
|
||||||
|
pg1.Reserved = 0;
|
||||||
|
pg1.Configuration = 0;
|
||||||
|
|
||||||
|
mptspi_write_spi_device_pg1(starget, &pg1);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct work_queue_wrapper {
|
||||||
|
struct work_struct work;
|
||||||
|
struct _MPT_SCSI_HOST *hd;
|
||||||
|
int disk;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void mpt_work_wrapper(void *data)
|
||||||
|
{
|
||||||
|
struct work_queue_wrapper *wqw = (struct work_queue_wrapper *)data;
|
||||||
|
struct _MPT_SCSI_HOST *hd = wqw->hd;
|
||||||
|
struct Scsi_Host *shost = hd->ioc->sh;
|
||||||
|
struct scsi_device *sdev;
|
||||||
|
int disk = wqw->disk;
|
||||||
|
struct _CONFIG_PAGE_IOC_3 *pg3;
|
||||||
|
|
||||||
|
kfree(wqw);
|
||||||
|
|
||||||
|
mpt_findImVolumes(hd->ioc);
|
||||||
|
pg3 = hd->ioc->raid_data.pIocPg3;
|
||||||
|
if (!pg3)
|
||||||
|
return;
|
||||||
|
|
||||||
|
shost_for_each_device(sdev,shost) {
|
||||||
|
struct scsi_target *starget = scsi_target(sdev);
|
||||||
|
VirtTarget *vtarget = starget->hostdata;
|
||||||
|
|
||||||
|
/* only want to search RAID components */
|
||||||
|
if (sdev->channel != 1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* The target_id is the raid PhysDiskNum, even if
|
||||||
|
* starget->id is the actual target address */
|
||||||
|
if(vtarget->target_id != disk)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
starget_printk(KERN_INFO, vtarget->starget,
|
||||||
|
"Integrated RAID requests DV of new device\n");
|
||||||
|
mptspi_dv_device(hd, sdev);
|
||||||
|
}
|
||||||
|
shost_printk(KERN_INFO, shost,
|
||||||
|
"Integrated RAID detects new device %d\n", disk);
|
||||||
|
scsi_scan_target(&hd->ioc->sh->shost_gendev, 1, disk, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void mpt_dv_raid(struct _MPT_SCSI_HOST *hd, int disk)
|
||||||
|
{
|
||||||
|
struct work_queue_wrapper *wqw = kmalloc(sizeof(*wqw), GFP_ATOMIC);
|
||||||
|
|
||||||
|
if (!wqw) {
|
||||||
|
shost_printk(KERN_ERR, hd->ioc->sh,
|
||||||
|
"Failed to act on RAID event for physical disk %d\n",
|
||||||
|
disk);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
INIT_WORK(&wqw->work, mpt_work_wrapper, wqw);
|
||||||
|
wqw->hd = hd;
|
||||||
|
wqw->disk = disk;
|
||||||
|
|
||||||
|
schedule_work(&wqw->work);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
mptspi_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
|
||||||
|
{
|
||||||
|
u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
|
||||||
|
struct _MPT_SCSI_HOST *hd = (struct _MPT_SCSI_HOST *)ioc->sh->hostdata;
|
||||||
|
|
||||||
|
if (hd && event == MPI_EVENT_INTEGRATED_RAID) {
|
||||||
|
int reason
|
||||||
|
= (le32_to_cpu(pEvReply->Data[0]) & 0x00FF0000) >> 16;
|
||||||
|
|
||||||
|
if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
|
||||||
|
int disk = (le32_to_cpu(pEvReply->Data[0]) & 0xFF000000) >> 24;
|
||||||
|
mpt_dv_raid(hd, disk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return mptscsih_event_process(ioc, pEvReply);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
mptspi_deny_binding(struct scsi_target *starget)
|
||||||
|
{
|
||||||
|
struct _MPT_SCSI_HOST *hd =
|
||||||
|
(struct _MPT_SCSI_HOST *)dev_to_shost(starget->dev.parent)->hostdata;
|
||||||
|
return ((hd->ioc->raid_data.isRaid & (1 << starget->id)) &&
|
||||||
|
starget->channel == 0) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct spi_function_template mptspi_transport_functions = {
|
||||||
|
.get_offset = mptspi_read_parameters,
|
||||||
|
.set_offset = mptspi_write_offset,
|
||||||
|
.show_offset = 1,
|
||||||
|
.get_period = mptspi_read_parameters,
|
||||||
|
.set_period = mptspi_write_period,
|
||||||
|
.show_period = 1,
|
||||||
|
.get_width = mptspi_read_parameters,
|
||||||
|
.set_width = mptspi_write_width,
|
||||||
|
.show_width = 1,
|
||||||
|
.get_iu = mptspi_read_parameters,
|
||||||
|
.set_iu = mptspi_write_iu,
|
||||||
|
.show_iu = 1,
|
||||||
|
.get_dt = mptspi_read_parameters,
|
||||||
|
.set_dt = mptspi_write_dt,
|
||||||
|
.show_dt = 1,
|
||||||
|
.get_qas = mptspi_read_parameters,
|
||||||
|
.set_qas = mptspi_write_qas,
|
||||||
|
.show_qas = 1,
|
||||||
|
.get_wr_flow = mptspi_read_parameters,
|
||||||
|
.set_wr_flow = mptspi_write_wr_flow,
|
||||||
|
.show_wr_flow = 1,
|
||||||
|
.get_rd_strm = mptspi_read_parameters,
|
||||||
|
.set_rd_strm = mptspi_write_rd_strm,
|
||||||
|
.show_rd_strm = 1,
|
||||||
|
.get_rti = mptspi_read_parameters,
|
||||||
|
.set_rti = mptspi_write_rti,
|
||||||
|
.show_rti = 1,
|
||||||
|
.get_pcomp_en = mptspi_read_parameters,
|
||||||
|
.set_pcomp_en = mptspi_write_pcomp_en,
|
||||||
|
.show_pcomp_en = 1,
|
||||||
|
.get_hold_mcs = mptspi_read_parameters,
|
||||||
|
.set_hold_mcs = mptspi_write_hold_mcs,
|
||||||
|
.show_hold_mcs = 1,
|
||||||
|
.deny_binding = mptspi_deny_binding,
|
||||||
|
};
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Supported hardware
|
* Supported hardware
|
||||||
|
@ -242,7 +883,14 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||||
sh->max_id = MPT_MAX_SCSI_DEVICES;
|
sh->max_id = MPT_MAX_SCSI_DEVICES;
|
||||||
|
|
||||||
sh->max_lun = MPT_LAST_LUN + 1;
|
sh->max_lun = MPT_LAST_LUN + 1;
|
||||||
sh->max_channel = 0;
|
/*
|
||||||
|
* If RAID Firmware Detected, setup virtual channel
|
||||||
|
*/
|
||||||
|
if ((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
|
||||||
|
> MPI_FW_HEADER_PID_PROD_TARGET_SCSI)
|
||||||
|
sh->max_channel = 1;
|
||||||
|
else
|
||||||
|
sh->max_channel = 0;
|
||||||
sh->this_id = ioc->pfacts[0].PortSCSIID;
|
sh->this_id = ioc->pfacts[0].PortSCSIID;
|
||||||
|
|
||||||
/* Required entry.
|
/* Required entry.
|
||||||
|
@ -301,7 +949,8 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||||
* indicates a device exists.
|
* indicates a device exists.
|
||||||
* max_id = 1 + maximum id (hosts.h)
|
* max_id = 1 + maximum id (hosts.h)
|
||||||
*/
|
*/
|
||||||
hd->Targets = kcalloc(sh->max_id, sizeof(void *), GFP_ATOMIC);
|
hd->Targets = kcalloc(sh->max_id * (sh->max_channel + 1),
|
||||||
|
sizeof(void *), GFP_ATOMIC);
|
||||||
if (!hd->Targets) {
|
if (!hd->Targets) {
|
||||||
error = -ENOMEM;
|
error = -ENOMEM;
|
||||||
goto out_mptspi_probe;
|
goto out_mptspi_probe;
|
||||||
|
@ -334,49 +983,23 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||||
ioc->spi_data.Saf_Te = mpt_saf_te;
|
ioc->spi_data.Saf_Te = mpt_saf_te;
|
||||||
hd->mpt_pq_filter = mpt_pq_filter;
|
hd->mpt_pq_filter = mpt_pq_filter;
|
||||||
|
|
||||||
#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
|
|
||||||
if (ioc->spi_data.maxBusWidth > mpt_width)
|
|
||||||
ioc->spi_data.maxBusWidth = mpt_width;
|
|
||||||
if (ioc->spi_data.minSyncFactor < mpt_factor)
|
|
||||||
ioc->spi_data.minSyncFactor = mpt_factor;
|
|
||||||
if (ioc->spi_data.minSyncFactor == MPT_ASYNC) {
|
|
||||||
ioc->spi_data.maxSyncOffset = 0;
|
|
||||||
}
|
|
||||||
ioc->spi_data.mpt_dv = mpt_dv;
|
|
||||||
hd->negoNvram = 0;
|
|
||||||
|
|
||||||
ddvprintk((MYIOC_s_INFO_FMT
|
|
||||||
"dv %x width %x factor %x saf_te %x mpt_pq_filter %x\n",
|
|
||||||
ioc->name,
|
|
||||||
mpt_dv,
|
|
||||||
mpt_width,
|
|
||||||
mpt_factor,
|
|
||||||
mpt_saf_te,
|
|
||||||
mpt_pq_filter));
|
|
||||||
#else
|
|
||||||
hd->negoNvram = MPT_SCSICFG_USE_NVRAM;
|
hd->negoNvram = MPT_SCSICFG_USE_NVRAM;
|
||||||
ddvprintk((MYIOC_s_INFO_FMT
|
ddvprintk((MYIOC_s_INFO_FMT
|
||||||
"saf_te %x mpt_pq_filter %x\n",
|
"saf_te %x mpt_pq_filter %x\n",
|
||||||
ioc->name,
|
ioc->name,
|
||||||
mpt_saf_te,
|
mpt_saf_te,
|
||||||
mpt_pq_filter));
|
mpt_pq_filter));
|
||||||
#endif
|
|
||||||
|
|
||||||
ioc->spi_data.forceDv = 0;
|
|
||||||
ioc->spi_data.noQas = 0;
|
ioc->spi_data.noQas = 0;
|
||||||
|
|
||||||
for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++)
|
|
||||||
ioc->spi_data.dvStatus[ii] =
|
|
||||||
MPT_SCSICFG_NEGOTIATE;
|
|
||||||
|
|
||||||
for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++)
|
|
||||||
ioc->spi_data.dvStatus[ii] |=
|
|
||||||
MPT_SCSICFG_DV_NOT_DONE;
|
|
||||||
|
|
||||||
init_waitqueue_head(&hd->scandv_waitq);
|
init_waitqueue_head(&hd->scandv_waitq);
|
||||||
hd->scandv_wait_done = 0;
|
hd->scandv_wait_done = 0;
|
||||||
hd->last_queue_full = 0;
|
hd->last_queue_full = 0;
|
||||||
|
|
||||||
|
/* Some versions of the firmware don't support page 0; without
|
||||||
|
* that we can't get the parameters */
|
||||||
|
if (hd->ioc->spi_data.sdp0length != 0)
|
||||||
|
sh->transportt = mptspi_transport_template;
|
||||||
|
|
||||||
error = scsi_add_host (sh, &ioc->pcidev->dev);
|
error = scsi_add_host (sh, &ioc->pcidev->dev);
|
||||||
if(error) {
|
if(error) {
|
||||||
dprintk((KERN_ERR MYNAM
|
dprintk((KERN_ERR MYNAM
|
||||||
|
@ -423,15 +1046,18 @@ static struct pci_driver mptspi_driver = {
|
||||||
static int __init
|
static int __init
|
||||||
mptspi_init(void)
|
mptspi_init(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
show_mptmod_ver(my_NAME, my_VERSION);
|
show_mptmod_ver(my_NAME, my_VERSION);
|
||||||
|
|
||||||
|
mptspi_transport_template = spi_attach_transport(&mptspi_transport_functions);
|
||||||
|
if (!mptspi_transport_template)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
mptspiDoneCtx = mpt_register(mptscsih_io_done, MPTSPI_DRIVER);
|
mptspiDoneCtx = mpt_register(mptscsih_io_done, MPTSPI_DRIVER);
|
||||||
mptspiTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSPI_DRIVER);
|
mptspiTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSPI_DRIVER);
|
||||||
mptspiInternalCtx = mpt_register(mptscsih_scandv_complete, MPTSPI_DRIVER);
|
mptspiInternalCtx = mpt_register(mptscsih_scandv_complete, MPTSPI_DRIVER);
|
||||||
|
|
||||||
if (mpt_event_register(mptspiDoneCtx, mptscsih_event_process) == 0) {
|
if (mpt_event_register(mptspiDoneCtx, mptspi_event_process) == 0) {
|
||||||
devtprintk((KERN_INFO MYNAM
|
devtverboseprintk((KERN_INFO MYNAM
|
||||||
": Registered for IOC event notifications\n"));
|
": Registered for IOC event notifications\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -465,6 +1091,7 @@ mptspi_exit(void)
|
||||||
mpt_deregister(mptspiInternalCtx);
|
mpt_deregister(mptspiInternalCtx);
|
||||||
mpt_deregister(mptspiTaskCtx);
|
mpt_deregister(mptspiTaskCtx);
|
||||||
mpt_deregister(mptspiDoneCtx);
|
mpt_deregister(mptspiDoneCtx);
|
||||||
|
spi_release_transport(mptspi_transport_template);
|
||||||
}
|
}
|
||||||
|
|
||||||
module_init(mptspi_init);
|
module_init(mptspi_init);
|
||||||
|
|
|
@ -57,6 +57,13 @@ struct i2o_exec_wait {
|
||||||
struct list_head list; /* node in global wait list */
|
struct list_head list; /* node in global wait list */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Work struct needed to handle LCT NOTIFY replies */
|
||||||
|
struct i2o_exec_lct_notify_work {
|
||||||
|
struct work_struct work; /* work struct */
|
||||||
|
struct i2o_controller *c; /* controller on which the LCT NOTIFY
|
||||||
|
was received */
|
||||||
|
};
|
||||||
|
|
||||||
/* Exec OSM class handling definition */
|
/* Exec OSM class handling definition */
|
||||||
static struct i2o_class_id i2o_exec_class_id[] = {
|
static struct i2o_class_id i2o_exec_class_id[] = {
|
||||||
{I2O_CLASS_EXECUTIVE},
|
{I2O_CLASS_EXECUTIVE},
|
||||||
|
@ -355,9 +362,12 @@ static int i2o_exec_remove(struct device *dev)
|
||||||
* new LCT and if the buffer for the LCT was to small sends a LCT NOTIFY
|
* new LCT and if the buffer for the LCT was to small sends a LCT NOTIFY
|
||||||
* again, otherwise send LCT NOTIFY to get informed on next LCT change.
|
* again, otherwise send LCT NOTIFY to get informed on next LCT change.
|
||||||
*/
|
*/
|
||||||
static void i2o_exec_lct_modified(struct i2o_controller *c)
|
static void i2o_exec_lct_modified(struct i2o_exec_lct_notify_work *work)
|
||||||
{
|
{
|
||||||
u32 change_ind = 0;
|
u32 change_ind = 0;
|
||||||
|
struct i2o_controller *c = work->c;
|
||||||
|
|
||||||
|
kfree(work);
|
||||||
|
|
||||||
if (i2o_device_parse_lct(c) != -EAGAIN)
|
if (i2o_device_parse_lct(c) != -EAGAIN)
|
||||||
change_ind = c->lct->change_ind + 1;
|
change_ind = c->lct->change_ind + 1;
|
||||||
|
@ -410,7 +420,7 @@ static int i2o_exec_reply(struct i2o_controller *c, u32 m,
|
||||||
return i2o_msg_post_wait_complete(c, m, msg, context);
|
return i2o_msg_post_wait_complete(c, m, msg, context);
|
||||||
|
|
||||||
if ((le32_to_cpu(msg->u.head[1]) >> 24) == I2O_CMD_LCT_NOTIFY) {
|
if ((le32_to_cpu(msg->u.head[1]) >> 24) == I2O_CMD_LCT_NOTIFY) {
|
||||||
struct work_struct *work;
|
struct i2o_exec_lct_notify_work *work;
|
||||||
|
|
||||||
pr_debug("%s: LCT notify received\n", c->name);
|
pr_debug("%s: LCT notify received\n", c->name);
|
||||||
|
|
||||||
|
@ -418,8 +428,11 @@ static int i2o_exec_reply(struct i2o_controller *c, u32 m,
|
||||||
if (!work)
|
if (!work)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
INIT_WORK(work, (void (*)(void *))i2o_exec_lct_modified, c);
|
work->c = c;
|
||||||
queue_work(i2o_exec_driver.event_queue, work);
|
|
||||||
|
INIT_WORK(&work->work, (void (*)(void *))i2o_exec_lct_modified,
|
||||||
|
work);
|
||||||
|
queue_work(i2o_exec_driver.event_queue, &work->work);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,9 @@
|
||||||
3w-9xxx.c -- 3ware 9000 Storage Controller device driver for Linux.
|
3w-9xxx.c -- 3ware 9000 Storage Controller device driver for Linux.
|
||||||
|
|
||||||
Written By: Adam Radford <linuxraid@amcc.com>
|
Written By: Adam Radford <linuxraid@amcc.com>
|
||||||
|
Modifications By: Tom Couch <linuxraid@amcc.com>
|
||||||
|
|
||||||
Copyright (C) 2004-2005 Applied Micro Circuits Corporation.
|
Copyright (C) 2004-2006 Applied Micro Circuits Corporation.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -62,6 +63,8 @@
|
||||||
2.26.02.003 - Correctly handle single sgl's with use_sg=1.
|
2.26.02.003 - Correctly handle single sgl's with use_sg=1.
|
||||||
2.26.02.004 - Add support for 9550SX controllers.
|
2.26.02.004 - Add support for 9550SX controllers.
|
||||||
2.26.02.005 - Fix use_sg == 0 mapping on systems with 4GB or higher.
|
2.26.02.005 - Fix use_sg == 0 mapping on systems with 4GB or higher.
|
||||||
|
2.26.02.006 - Fix 9550SX pchip reset timeout.
|
||||||
|
Add big endian support.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
@ -85,7 +88,7 @@
|
||||||
#include "3w-9xxx.h"
|
#include "3w-9xxx.h"
|
||||||
|
|
||||||
/* Globals */
|
/* Globals */
|
||||||
#define TW_DRIVER_VERSION "2.26.02.005"
|
#define TW_DRIVER_VERSION "2.26.02.006"
|
||||||
static TW_Device_Extension *twa_device_extension_list[TW_MAX_SLOT];
|
static TW_Device_Extension *twa_device_extension_list[TW_MAX_SLOT];
|
||||||
static unsigned int twa_device_extension_count;
|
static unsigned int twa_device_extension_count;
|
||||||
static int twa_major = -1;
|
static int twa_major = -1;
|
||||||
|
@ -208,7 +211,7 @@ static int twa_aen_complete(TW_Device_Extension *tw_dev, int request_id)
|
||||||
|
|
||||||
header = (TW_Command_Apache_Header *)tw_dev->generic_buffer_virt[request_id];
|
header = (TW_Command_Apache_Header *)tw_dev->generic_buffer_virt[request_id];
|
||||||
tw_dev->posted_request_count--;
|
tw_dev->posted_request_count--;
|
||||||
aen = header->status_block.error;
|
aen = le16_to_cpu(header->status_block.error);
|
||||||
full_command_packet = tw_dev->command_packet_virt[request_id];
|
full_command_packet = tw_dev->command_packet_virt[request_id];
|
||||||
command_packet = &full_command_packet->command.oldcommand;
|
command_packet = &full_command_packet->command.oldcommand;
|
||||||
|
|
||||||
|
@ -305,7 +308,7 @@ static int twa_aen_drain_queue(TW_Device_Extension *tw_dev, int no_check_reset)
|
||||||
|
|
||||||
tw_dev->posted_request_count--;
|
tw_dev->posted_request_count--;
|
||||||
header = (TW_Command_Apache_Header *)tw_dev->generic_buffer_virt[request_id];
|
header = (TW_Command_Apache_Header *)tw_dev->generic_buffer_virt[request_id];
|
||||||
aen = header->status_block.error;
|
aen = le16_to_cpu(header->status_block.error);
|
||||||
queue = 0;
|
queue = 0;
|
||||||
count++;
|
count++;
|
||||||
|
|
||||||
|
@ -365,7 +368,7 @@ static void twa_aen_queue_event(TW_Device_Extension *tw_dev, TW_Command_Apache_H
|
||||||
tw_dev->aen_clobber = 1;
|
tw_dev->aen_clobber = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
aen = header->status_block.error;
|
aen = le16_to_cpu(header->status_block.error);
|
||||||
memset(event, 0, sizeof(TW_Event));
|
memset(event, 0, sizeof(TW_Event));
|
||||||
|
|
||||||
event->severity = TW_SEV_OUT(header->status_block.severity__reserved);
|
event->severity = TW_SEV_OUT(header->status_block.severity__reserved);
|
||||||
|
@ -382,7 +385,7 @@ static void twa_aen_queue_event(TW_Device_Extension *tw_dev, TW_Command_Apache_H
|
||||||
|
|
||||||
header->err_specific_desc[sizeof(header->err_specific_desc) - 1] = '\0';
|
header->err_specific_desc[sizeof(header->err_specific_desc) - 1] = '\0';
|
||||||
event->parameter_len = strlen(header->err_specific_desc);
|
event->parameter_len = strlen(header->err_specific_desc);
|
||||||
memcpy(event->parameter_data, header->err_specific_desc, event->parameter_len);
|
memcpy(event->parameter_data, header->err_specific_desc, event->parameter_len + (error_str[0] == '\0' ? 0 : (1 + strlen(error_str))));
|
||||||
if (event->severity != TW_AEN_SEVERITY_DEBUG)
|
if (event->severity != TW_AEN_SEVERITY_DEBUG)
|
||||||
printk(KERN_WARNING "3w-9xxx:%s AEN: %s (0x%02X:0x%04X): %s:%s.\n",
|
printk(KERN_WARNING "3w-9xxx:%s AEN: %s (0x%02X:0x%04X): %s:%s.\n",
|
||||||
host,
|
host,
|
||||||
|
@ -462,24 +465,24 @@ static void twa_aen_sync_time(TW_Device_Extension *tw_dev, int request_id)
|
||||||
command_packet = &full_command_packet->command.oldcommand;
|
command_packet = &full_command_packet->command.oldcommand;
|
||||||
command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_SET_PARAM);
|
command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_SET_PARAM);
|
||||||
command_packet->request_id = request_id;
|
command_packet->request_id = request_id;
|
||||||
command_packet->byte8_offset.param.sgl[0].address = tw_dev->generic_buffer_phys[request_id];
|
command_packet->byte8_offset.param.sgl[0].address = TW_CPU_TO_SGL(tw_dev->generic_buffer_phys[request_id]);
|
||||||
command_packet->byte8_offset.param.sgl[0].length = TW_SECTOR_SIZE;
|
command_packet->byte8_offset.param.sgl[0].length = cpu_to_le32(TW_SECTOR_SIZE);
|
||||||
command_packet->size = TW_COMMAND_SIZE;
|
command_packet->size = TW_COMMAND_SIZE;
|
||||||
command_packet->byte6_offset.parameter_count = 1;
|
command_packet->byte6_offset.parameter_count = cpu_to_le16(1);
|
||||||
|
|
||||||
/* Setup the param */
|
/* Setup the param */
|
||||||
param = (TW_Param_Apache *)tw_dev->generic_buffer_virt[request_id];
|
param = (TW_Param_Apache *)tw_dev->generic_buffer_virt[request_id];
|
||||||
memset(param, 0, TW_SECTOR_SIZE);
|
memset(param, 0, TW_SECTOR_SIZE);
|
||||||
param->table_id = TW_TIMEKEEP_TABLE | 0x8000; /* Controller time keep table */
|
param->table_id = cpu_to_le16(TW_TIMEKEEP_TABLE | 0x8000); /* Controller time keep table */
|
||||||
param->parameter_id = 0x3; /* SchedulerTime */
|
param->parameter_id = cpu_to_le16(0x3); /* SchedulerTime */
|
||||||
param->parameter_size_bytes = 4;
|
param->parameter_size_bytes = cpu_to_le16(4);
|
||||||
|
|
||||||
/* Convert system time in UTC to local time seconds since last
|
/* Convert system time in UTC to local time seconds since last
|
||||||
Sunday 12:00AM */
|
Sunday 12:00AM */
|
||||||
do_gettimeofday(&utc);
|
do_gettimeofday(&utc);
|
||||||
local_time = (u32)(utc.tv_sec - (sys_tz.tz_minuteswest * 60));
|
local_time = (u32)(utc.tv_sec - (sys_tz.tz_minuteswest * 60));
|
||||||
schedulertime = local_time - (3 * 86400);
|
schedulertime = local_time - (3 * 86400);
|
||||||
schedulertime = schedulertime % 604800;
|
schedulertime = cpu_to_le32(schedulertime % 604800);
|
||||||
|
|
||||||
memcpy(param->data, &schedulertime, sizeof(u32));
|
memcpy(param->data, &schedulertime, sizeof(u32));
|
||||||
|
|
||||||
|
@ -931,26 +934,19 @@ out:
|
||||||
/* This function will clear the pchip/response queue on 9550SX */
|
/* This function will clear the pchip/response queue on 9550SX */
|
||||||
static int twa_empty_response_queue_large(TW_Device_Extension *tw_dev)
|
static int twa_empty_response_queue_large(TW_Device_Extension *tw_dev)
|
||||||
{
|
{
|
||||||
u32 status_reg_value, response_que_value;
|
u32 response_que_value = 0;
|
||||||
int count = 0, retval = 1;
|
unsigned long before;
|
||||||
|
int retval = 1;
|
||||||
|
|
||||||
if (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9550SX) {
|
if (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9550SX) {
|
||||||
status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev));
|
before = jiffies;
|
||||||
|
while ((response_que_value & TW_9550SX_DRAIN_COMPLETED) != TW_9550SX_DRAIN_COMPLETED) {
|
||||||
while (((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) && (count < TW_MAX_RESPONSE_DRAIN)) {
|
|
||||||
response_que_value = readl(TW_RESPONSE_QUEUE_REG_ADDR_LARGE(tw_dev));
|
response_que_value = readl(TW_RESPONSE_QUEUE_REG_ADDR_LARGE(tw_dev));
|
||||||
if ((response_que_value & TW_9550SX_DRAIN_COMPLETED) == TW_9550SX_DRAIN_COMPLETED) {
|
if (time_after(jiffies, before + HZ * 30))
|
||||||
/* P-chip settle time */
|
|
||||||
msleep(500);
|
|
||||||
retval = 0;
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
|
||||||
status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev));
|
|
||||||
count++;
|
|
||||||
}
|
}
|
||||||
if (count == TW_MAX_RESPONSE_DRAIN)
|
/* P-chip settle time */
|
||||||
goto out;
|
msleep(500);
|
||||||
|
|
||||||
retval = 0;
|
retval = 0;
|
||||||
} else
|
} else
|
||||||
retval = 0;
|
retval = 0;
|
||||||
|
@ -972,7 +968,7 @@ static int twa_fill_sense(TW_Device_Extension *tw_dev, int request_id, int copy_
|
||||||
error_str = &(full_command_packet->header.err_specific_desc[strlen(full_command_packet->header.err_specific_desc) + 1]);
|
error_str = &(full_command_packet->header.err_specific_desc[strlen(full_command_packet->header.err_specific_desc) + 1]);
|
||||||
|
|
||||||
/* Don't print error for Logical unit not supported during rollcall */
|
/* Don't print error for Logical unit not supported during rollcall */
|
||||||
error = full_command_packet->header.status_block.error;
|
error = le16_to_cpu(full_command_packet->header.status_block.error);
|
||||||
if ((error != TW_ERROR_LOGICAL_UNIT_NOT_SUPPORTED) && (error != TW_ERROR_UNIT_OFFLINE)) {
|
if ((error != TW_ERROR_LOGICAL_UNIT_NOT_SUPPORTED) && (error != TW_ERROR_UNIT_OFFLINE)) {
|
||||||
if (print_host)
|
if (print_host)
|
||||||
printk(KERN_WARNING "3w-9xxx: scsi%d: ERROR: (0x%02X:0x%04X): %s:%s.\n",
|
printk(KERN_WARNING "3w-9xxx: scsi%d: ERROR: (0x%02X:0x%04X): %s:%s.\n",
|
||||||
|
@ -1047,18 +1043,18 @@ static void *twa_get_param(TW_Device_Extension *tw_dev, int request_id, int tabl
|
||||||
command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_GET_PARAM);
|
command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_GET_PARAM);
|
||||||
command_packet->size = TW_COMMAND_SIZE;
|
command_packet->size = TW_COMMAND_SIZE;
|
||||||
command_packet->request_id = request_id;
|
command_packet->request_id = request_id;
|
||||||
command_packet->byte6_offset.block_count = 1;
|
command_packet->byte6_offset.block_count = cpu_to_le16(1);
|
||||||
|
|
||||||
/* Now setup the param */
|
/* Now setup the param */
|
||||||
param = (TW_Param_Apache *)tw_dev->generic_buffer_virt[request_id];
|
param = (TW_Param_Apache *)tw_dev->generic_buffer_virt[request_id];
|
||||||
memset(param, 0, TW_SECTOR_SIZE);
|
memset(param, 0, TW_SECTOR_SIZE);
|
||||||
param->table_id = table_id | 0x8000;
|
param->table_id = cpu_to_le16(table_id | 0x8000);
|
||||||
param->parameter_id = parameter_id;
|
param->parameter_id = cpu_to_le16(parameter_id);
|
||||||
param->parameter_size_bytes = parameter_size_bytes;
|
param->parameter_size_bytes = cpu_to_le16(parameter_size_bytes);
|
||||||
param_value = tw_dev->generic_buffer_phys[request_id];
|
param_value = tw_dev->generic_buffer_phys[request_id];
|
||||||
|
|
||||||
command_packet->byte8_offset.param.sgl[0].address = param_value;
|
command_packet->byte8_offset.param.sgl[0].address = TW_CPU_TO_SGL(param_value);
|
||||||
command_packet->byte8_offset.param.sgl[0].length = TW_SECTOR_SIZE;
|
command_packet->byte8_offset.param.sgl[0].length = cpu_to_le32(TW_SECTOR_SIZE);
|
||||||
|
|
||||||
/* Post the command packet to the board */
|
/* Post the command packet to the board */
|
||||||
twa_post_command_packet(tw_dev, request_id, 1);
|
twa_post_command_packet(tw_dev, request_id, 1);
|
||||||
|
@ -1107,18 +1103,20 @@ static int twa_initconnection(TW_Device_Extension *tw_dev, int message_credits,
|
||||||
tw_initconnect = (TW_Initconnect *)&full_command_packet->command.oldcommand;
|
tw_initconnect = (TW_Initconnect *)&full_command_packet->command.oldcommand;
|
||||||
tw_initconnect->opcode__reserved = TW_OPRES_IN(0, TW_OP_INIT_CONNECTION);
|
tw_initconnect->opcode__reserved = TW_OPRES_IN(0, TW_OP_INIT_CONNECTION);
|
||||||
tw_initconnect->request_id = request_id;
|
tw_initconnect->request_id = request_id;
|
||||||
tw_initconnect->message_credits = message_credits;
|
tw_initconnect->message_credits = cpu_to_le16(message_credits);
|
||||||
tw_initconnect->features = set_features;
|
tw_initconnect->features = set_features;
|
||||||
|
|
||||||
/* Turn on 64-bit sgl support if we need to */
|
/* Turn on 64-bit sgl support if we need to */
|
||||||
tw_initconnect->features |= sizeof(dma_addr_t) > 4 ? 1 : 0;
|
tw_initconnect->features |= sizeof(dma_addr_t) > 4 ? 1 : 0;
|
||||||
|
|
||||||
|
tw_initconnect->features = cpu_to_le32(tw_initconnect->features);
|
||||||
|
|
||||||
if (set_features & TW_EXTENDED_INIT_CONNECT) {
|
if (set_features & TW_EXTENDED_INIT_CONNECT) {
|
||||||
tw_initconnect->size = TW_INIT_COMMAND_PACKET_SIZE_EXTENDED;
|
tw_initconnect->size = TW_INIT_COMMAND_PACKET_SIZE_EXTENDED;
|
||||||
tw_initconnect->fw_srl = current_fw_srl;
|
tw_initconnect->fw_srl = cpu_to_le16(current_fw_srl);
|
||||||
tw_initconnect->fw_arch_id = current_fw_arch_id;
|
tw_initconnect->fw_arch_id = cpu_to_le16(current_fw_arch_id);
|
||||||
tw_initconnect->fw_branch = current_fw_branch;
|
tw_initconnect->fw_branch = cpu_to_le16(current_fw_branch);
|
||||||
tw_initconnect->fw_build = current_fw_build;
|
tw_initconnect->fw_build = cpu_to_le16(current_fw_build);
|
||||||
} else
|
} else
|
||||||
tw_initconnect->size = TW_INIT_COMMAND_PACKET_SIZE;
|
tw_initconnect->size = TW_INIT_COMMAND_PACKET_SIZE;
|
||||||
|
|
||||||
|
@ -1130,11 +1128,11 @@ static int twa_initconnection(TW_Device_Extension *tw_dev, int message_credits,
|
||||||
TW_PRINTK(tw_dev->host, TW_DRIVER, 0x15, "No valid response during init connection");
|
TW_PRINTK(tw_dev->host, TW_DRIVER, 0x15, "No valid response during init connection");
|
||||||
} else {
|
} else {
|
||||||
if (set_features & TW_EXTENDED_INIT_CONNECT) {
|
if (set_features & TW_EXTENDED_INIT_CONNECT) {
|
||||||
*fw_on_ctlr_srl = tw_initconnect->fw_srl;
|
*fw_on_ctlr_srl = le16_to_cpu(tw_initconnect->fw_srl);
|
||||||
*fw_on_ctlr_arch_id = tw_initconnect->fw_arch_id;
|
*fw_on_ctlr_arch_id = le16_to_cpu(tw_initconnect->fw_arch_id);
|
||||||
*fw_on_ctlr_branch = tw_initconnect->fw_branch;
|
*fw_on_ctlr_branch = le16_to_cpu(tw_initconnect->fw_branch);
|
||||||
*fw_on_ctlr_build = tw_initconnect->fw_build;
|
*fw_on_ctlr_build = le16_to_cpu(tw_initconnect->fw_build);
|
||||||
*init_connect_result = tw_initconnect->result;
|
*init_connect_result = le32_to_cpu(tw_initconnect->result);
|
||||||
}
|
}
|
||||||
retval = 0;
|
retval = 0;
|
||||||
}
|
}
|
||||||
|
@ -1358,10 +1356,10 @@ static void twa_load_sgl(TW_Command_Full *full_command_packet, int request_id, d
|
||||||
newcommand = &full_command_packet->command.newcommand;
|
newcommand = &full_command_packet->command.newcommand;
|
||||||
newcommand->request_id__lunl =
|
newcommand->request_id__lunl =
|
||||||
TW_REQ_LUN_IN(TW_LUN_OUT(newcommand->request_id__lunl), request_id);
|
TW_REQ_LUN_IN(TW_LUN_OUT(newcommand->request_id__lunl), request_id);
|
||||||
newcommand->sg_list[0].address = dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1;
|
newcommand->sg_list[0].address = TW_CPU_TO_SGL(dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1);
|
||||||
newcommand->sg_list[0].length = length;
|
newcommand->sg_list[0].length = cpu_to_le32(length);
|
||||||
newcommand->sgl_entries__lunh =
|
newcommand->sgl_entries__lunh =
|
||||||
TW_REQ_LUN_IN(TW_LUN_OUT(newcommand->sgl_entries__lunh), 1);
|
cpu_to_le16(TW_REQ_LUN_IN(TW_LUN_OUT(newcommand->sgl_entries__lunh), 1));
|
||||||
} else {
|
} else {
|
||||||
oldcommand = &full_command_packet->command.oldcommand;
|
oldcommand = &full_command_packet->command.oldcommand;
|
||||||
oldcommand->request_id = request_id;
|
oldcommand->request_id = request_id;
|
||||||
|
@ -1369,8 +1367,8 @@ static void twa_load_sgl(TW_Command_Full *full_command_packet, int request_id, d
|
||||||
if (TW_SGL_OUT(oldcommand->opcode__sgloffset)) {
|
if (TW_SGL_OUT(oldcommand->opcode__sgloffset)) {
|
||||||
/* Load the sg list */
|
/* Load the sg list */
|
||||||
sgl = (TW_SG_Entry *)((u32 *)oldcommand+TW_SGL_OUT(oldcommand->opcode__sgloffset));
|
sgl = (TW_SG_Entry *)((u32 *)oldcommand+TW_SGL_OUT(oldcommand->opcode__sgloffset));
|
||||||
sgl->address = dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1;
|
sgl->address = TW_CPU_TO_SGL(dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1);
|
||||||
sgl->length = length;
|
sgl->length = cpu_to_le32(length);
|
||||||
|
|
||||||
if ((sizeof(long) < 8) && (sizeof(dma_addr_t) > 4))
|
if ((sizeof(long) < 8) && (sizeof(dma_addr_t) > 4))
|
||||||
oldcommand->size += 1;
|
oldcommand->size += 1;
|
||||||
|
@ -1828,10 +1826,10 @@ static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id,
|
||||||
if (srb) {
|
if (srb) {
|
||||||
command_packet->unit = srb->device->id;
|
command_packet->unit = srb->device->id;
|
||||||
command_packet->request_id__lunl =
|
command_packet->request_id__lunl =
|
||||||
TW_REQ_LUN_IN(srb->device->lun, request_id);
|
cpu_to_le16(TW_REQ_LUN_IN(srb->device->lun, request_id));
|
||||||
} else {
|
} else {
|
||||||
command_packet->request_id__lunl =
|
command_packet->request_id__lunl =
|
||||||
TW_REQ_LUN_IN(0, request_id);
|
cpu_to_le16(TW_REQ_LUN_IN(0, request_id));
|
||||||
command_packet->unit = 0;
|
command_packet->unit = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1841,8 +1839,8 @@ static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id,
|
||||||
/* Map sglist from scsi layer to cmd packet */
|
/* Map sglist from scsi layer to cmd packet */
|
||||||
if (tw_dev->srb[request_id]->use_sg == 0) {
|
if (tw_dev->srb[request_id]->use_sg == 0) {
|
||||||
if (tw_dev->srb[request_id]->request_bufflen < TW_MIN_SGL_LENGTH) {
|
if (tw_dev->srb[request_id]->request_bufflen < TW_MIN_SGL_LENGTH) {
|
||||||
command_packet->sg_list[0].address = tw_dev->generic_buffer_phys[request_id];
|
command_packet->sg_list[0].address = TW_CPU_TO_SGL(tw_dev->generic_buffer_phys[request_id]);
|
||||||
command_packet->sg_list[0].length = TW_MIN_SGL_LENGTH;
|
command_packet->sg_list[0].length = cpu_to_le32(TW_MIN_SGL_LENGTH);
|
||||||
if (tw_dev->srb[request_id]->sc_data_direction == DMA_TO_DEVICE || tw_dev->srb[request_id]->sc_data_direction == DMA_BIDIRECTIONAL)
|
if (tw_dev->srb[request_id]->sc_data_direction == DMA_TO_DEVICE || tw_dev->srb[request_id]->sc_data_direction == DMA_BIDIRECTIONAL)
|
||||||
memcpy(tw_dev->generic_buffer_virt[request_id], tw_dev->srb[request_id]->request_buffer, tw_dev->srb[request_id]->request_bufflen);
|
memcpy(tw_dev->generic_buffer_virt[request_id], tw_dev->srb[request_id]->request_buffer, tw_dev->srb[request_id]->request_bufflen);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1850,12 +1848,12 @@ static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id,
|
||||||
if (buffaddr == 0)
|
if (buffaddr == 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
command_packet->sg_list[0].address = buffaddr;
|
command_packet->sg_list[0].address = TW_CPU_TO_SGL(buffaddr);
|
||||||
command_packet->sg_list[0].length = tw_dev->srb[request_id]->request_bufflen;
|
command_packet->sg_list[0].length = cpu_to_le32(tw_dev->srb[request_id]->request_bufflen);
|
||||||
}
|
}
|
||||||
command_packet->sgl_entries__lunh = TW_REQ_LUN_IN((srb->device->lun >> 4), 1);
|
command_packet->sgl_entries__lunh = cpu_to_le16(TW_REQ_LUN_IN((srb->device->lun >> 4), 1));
|
||||||
|
|
||||||
if (command_packet->sg_list[0].address & TW_ALIGNMENT_9000_SGL) {
|
if (command_packet->sg_list[0].address & TW_CPU_TO_SGL(TW_ALIGNMENT_9000_SGL)) {
|
||||||
TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2d, "Found unaligned address during execute scsi");
|
TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2d, "Found unaligned address during execute scsi");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -1869,35 +1867,35 @@ static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id,
|
||||||
memcpy(tw_dev->generic_buffer_virt[request_id], buf, sg->length);
|
memcpy(tw_dev->generic_buffer_virt[request_id], buf, sg->length);
|
||||||
kunmap_atomic(buf - sg->offset, KM_IRQ0);
|
kunmap_atomic(buf - sg->offset, KM_IRQ0);
|
||||||
}
|
}
|
||||||
command_packet->sg_list[0].address = tw_dev->generic_buffer_phys[request_id];
|
command_packet->sg_list[0].address = TW_CPU_TO_SGL(tw_dev->generic_buffer_phys[request_id]);
|
||||||
command_packet->sg_list[0].length = TW_MIN_SGL_LENGTH;
|
command_packet->sg_list[0].length = cpu_to_le32(TW_MIN_SGL_LENGTH);
|
||||||
} else {
|
} else {
|
||||||
sg_count = twa_map_scsi_sg_data(tw_dev, request_id);
|
sg_count = twa_map_scsi_sg_data(tw_dev, request_id);
|
||||||
if (sg_count == 0)
|
if (sg_count == 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
for (i = 0; i < sg_count; i++) {
|
for (i = 0; i < sg_count; i++) {
|
||||||
command_packet->sg_list[i].address = sg_dma_address(&sglist[i]);
|
command_packet->sg_list[i].address = TW_CPU_TO_SGL(sg_dma_address(&sglist[i]));
|
||||||
command_packet->sg_list[i].length = sg_dma_len(&sglist[i]);
|
command_packet->sg_list[i].length = cpu_to_le32(sg_dma_len(&sglist[i]));
|
||||||
if (command_packet->sg_list[i].address & TW_ALIGNMENT_9000_SGL) {
|
if (command_packet->sg_list[i].address & TW_CPU_TO_SGL(TW_ALIGNMENT_9000_SGL)) {
|
||||||
TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2e, "Found unaligned sgl address during execute scsi");
|
TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2e, "Found unaligned sgl address during execute scsi");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
command_packet->sgl_entries__lunh = TW_REQ_LUN_IN((srb->device->lun >> 4), tw_dev->srb[request_id]->use_sg);
|
command_packet->sgl_entries__lunh = cpu_to_le16(TW_REQ_LUN_IN((srb->device->lun >> 4), tw_dev->srb[request_id]->use_sg));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Internal cdb post */
|
/* Internal cdb post */
|
||||||
for (i = 0; i < use_sg; i++) {
|
for (i = 0; i < use_sg; i++) {
|
||||||
command_packet->sg_list[i].address = sglistarg[i].address;
|
command_packet->sg_list[i].address = TW_CPU_TO_SGL(sglistarg[i].address);
|
||||||
command_packet->sg_list[i].length = sglistarg[i].length;
|
command_packet->sg_list[i].length = cpu_to_le32(sglistarg[i].length);
|
||||||
if (command_packet->sg_list[i].address & TW_ALIGNMENT_9000_SGL) {
|
if (command_packet->sg_list[i].address & TW_CPU_TO_SGL(TW_ALIGNMENT_9000_SGL)) {
|
||||||
TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2f, "Found unaligned sgl address during internal post");
|
TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2f, "Found unaligned sgl address during internal post");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
command_packet->sgl_entries__lunh = TW_REQ_LUN_IN(0, use_sg);
|
command_packet->sgl_entries__lunh = cpu_to_le16(TW_REQ_LUN_IN(0, use_sg));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (srb) {
|
if (srb) {
|
||||||
|
@ -2115,8 +2113,8 @@ static int __devinit twa_probe(struct pci_dev *pdev, const struct pci_device_id
|
||||||
TW_PARAM_FWVER, TW_PARAM_FWVER_LENGTH),
|
TW_PARAM_FWVER, TW_PARAM_FWVER_LENGTH),
|
||||||
(char *)twa_get_param(tw_dev, 1, TW_VERSION_TABLE,
|
(char *)twa_get_param(tw_dev, 1, TW_VERSION_TABLE,
|
||||||
TW_PARAM_BIOSVER, TW_PARAM_BIOSVER_LENGTH),
|
TW_PARAM_BIOSVER, TW_PARAM_BIOSVER_LENGTH),
|
||||||
*(int *)twa_get_param(tw_dev, 2, TW_INFORMATION_TABLE,
|
le32_to_cpu(*(int *)twa_get_param(tw_dev, 2, TW_INFORMATION_TABLE,
|
||||||
TW_PARAM_PORTCOUNT, TW_PARAM_PORTCOUNT_LENGTH));
|
TW_PARAM_PORTCOUNT, TW_PARAM_PORTCOUNT_LENGTH)));
|
||||||
|
|
||||||
/* Now setup the interrupt handler */
|
/* Now setup the interrupt handler */
|
||||||
retval = request_irq(pdev->irq, twa_interrupt, SA_SHIRQ, "3w-9xxx", tw_dev);
|
retval = request_irq(pdev->irq, twa_interrupt, SA_SHIRQ, "3w-9xxx", tw_dev);
|
||||||
|
|
|
@ -2,8 +2,9 @@
|
||||||
3w-9xxx.h -- 3ware 9000 Storage Controller device driver for Linux.
|
3w-9xxx.h -- 3ware 9000 Storage Controller device driver for Linux.
|
||||||
|
|
||||||
Written By: Adam Radford <linuxraid@amcc.com>
|
Written By: Adam Radford <linuxraid@amcc.com>
|
||||||
|
Modifications By: Tom Couch <linuxraid@amcc.com>
|
||||||
|
|
||||||
Copyright (C) 2004-2005 Applied Micro Circuits Corporation.
|
Copyright (C) 2004-2006 Applied Micro Circuits Corporation.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -287,9 +288,6 @@ static twa_message_type twa_error_table[] = {
|
||||||
#define TW_STATUS_UNEXPECTED_BITS 0x00F00000
|
#define TW_STATUS_UNEXPECTED_BITS 0x00F00000
|
||||||
#define TW_STATUS_VALID_INTERRUPT 0x00DF0000
|
#define TW_STATUS_VALID_INTERRUPT 0x00DF0000
|
||||||
|
|
||||||
/* RESPONSE QUEUE BIT DEFINITIONS */
|
|
||||||
#define TW_RESPONSE_ID_MASK 0x00000FF0
|
|
||||||
|
|
||||||
/* PCI related defines */
|
/* PCI related defines */
|
||||||
#define TW_NUMDEVICES 1
|
#define TW_NUMDEVICES 1
|
||||||
#define TW_PCI_CLEAR_PARITY_ERRORS 0xc100
|
#define TW_PCI_CLEAR_PARITY_ERRORS 0xc100
|
||||||
|
@ -471,6 +469,7 @@ printk(KERN_WARNING "3w-9xxx: ERROR: (0x%02X:0x%04X): %s.\n",a,b,c); \
|
||||||
#define TW_APACHE_MAX_SGL_LENGTH (sizeof(dma_addr_t) > 4 ? 72 : 109)
|
#define TW_APACHE_MAX_SGL_LENGTH (sizeof(dma_addr_t) > 4 ? 72 : 109)
|
||||||
#define TW_ESCALADE_MAX_SGL_LENGTH (sizeof(dma_addr_t) > 4 ? 41 : 62)
|
#define TW_ESCALADE_MAX_SGL_LENGTH (sizeof(dma_addr_t) > 4 ? 41 : 62)
|
||||||
#define TW_PADDING_LENGTH (sizeof(dma_addr_t) > 4 ? 8 : 0)
|
#define TW_PADDING_LENGTH (sizeof(dma_addr_t) > 4 ? 8 : 0)
|
||||||
|
#define TW_CPU_TO_SGL(x) (sizeof(dma_addr_t) > 4 ? cpu_to_le64(x) : cpu_to_le32(x))
|
||||||
|
|
||||||
#pragma pack(1)
|
#pragma pack(1)
|
||||||
|
|
||||||
|
@ -614,13 +613,6 @@ typedef union TAG_TW_Response_Queue {
|
||||||
u32 value;
|
u32 value;
|
||||||
} TW_Response_Queue;
|
} TW_Response_Queue;
|
||||||
|
|
||||||
typedef struct TAG_TW_Info {
|
|
||||||
char *buffer;
|
|
||||||
int length;
|
|
||||||
int offset;
|
|
||||||
int position;
|
|
||||||
} TW_Info;
|
|
||||||
|
|
||||||
/* Compatibility information structure */
|
/* Compatibility information structure */
|
||||||
typedef struct TAG_TW_Compatibility_Info
|
typedef struct TAG_TW_Compatibility_Info
|
||||||
{
|
{
|
||||||
|
@ -636,6 +628,8 @@ typedef struct TAG_TW_Compatibility_Info
|
||||||
unsigned short driver_build_low;
|
unsigned short driver_build_low;
|
||||||
} TW_Compatibility_Info;
|
} TW_Compatibility_Info;
|
||||||
|
|
||||||
|
#pragma pack()
|
||||||
|
|
||||||
typedef struct TAG_TW_Device_Extension {
|
typedef struct TAG_TW_Device_Extension {
|
||||||
u32 __iomem *base_addr;
|
u32 __iomem *base_addr;
|
||||||
unsigned long *generic_buffer_virt[TW_Q_LENGTH];
|
unsigned long *generic_buffer_virt[TW_Q_LENGTH];
|
||||||
|
@ -679,7 +673,5 @@ typedef struct TAG_TW_Device_Extension {
|
||||||
unsigned short working_build;
|
unsigned short working_build;
|
||||||
} TW_Device_Extension;
|
} TW_Device_Extension;
|
||||||
|
|
||||||
#pragma pack()
|
|
||||||
|
|
||||||
#endif /* _3W_9XXX_H */
|
#endif /* _3W_9XXX_H */
|
||||||
|
|
||||||
|
|
|
@ -238,14 +238,6 @@ static char *NCR_700_SBCL_to_phase[] = {
|
||||||
"MSG IN",
|
"MSG IN",
|
||||||
};
|
};
|
||||||
|
|
||||||
static __u8 NCR_700_SDTR_msg[] = {
|
|
||||||
0x01, /* Extended message */
|
|
||||||
0x03, /* Extended message Length */
|
|
||||||
0x01, /* SDTR Extended message */
|
|
||||||
NCR_700_MIN_PERIOD,
|
|
||||||
NCR_700_MAX_OFFSET
|
|
||||||
};
|
|
||||||
|
|
||||||
/* This translates the SDTR message offset and period to a value
|
/* This translates the SDTR message offset and period to a value
|
||||||
* which can be loaded into the SXFER_REG.
|
* which can be loaded into the SXFER_REG.
|
||||||
*
|
*
|
||||||
|
@ -266,7 +258,7 @@ NCR_700_offset_period_to_sxfer(struct NCR_700_Host_Parameters *hostdata,
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if(period < hostdata->min_period) {
|
if(period < hostdata->min_period) {
|
||||||
printk(KERN_WARNING "53c700: Period %dns is less than this chip's minimum, setting to %d\n", period*4, NCR_700_SDTR_msg[3]*4);
|
printk(KERN_WARNING "53c700: Period %dns is less than this chip's minimum, setting to %d\n", period*4, NCR_700_MIN_PERIOD*4);
|
||||||
period = hostdata->min_period;
|
period = hostdata->min_period;
|
||||||
}
|
}
|
||||||
XFERP = (period*4 * hostdata->sync_clock)/1000 - 4;
|
XFERP = (period*4 * hostdata->sync_clock)/1000 - 4;
|
||||||
|
@ -1434,11 +1426,9 @@ NCR_700_start_command(struct scsi_cmnd *SCp)
|
||||||
|
|
||||||
if(hostdata->fast &&
|
if(hostdata->fast &&
|
||||||
NCR_700_is_flag_clear(SCp->device, NCR_700_DEV_NEGOTIATED_SYNC)) {
|
NCR_700_is_flag_clear(SCp->device, NCR_700_DEV_NEGOTIATED_SYNC)) {
|
||||||
memcpy(&hostdata->msgout[count], NCR_700_SDTR_msg,
|
count += spi_populate_sync_msg(&hostdata->msgout[count],
|
||||||
sizeof(NCR_700_SDTR_msg));
|
spi_period(SCp->device->sdev_target),
|
||||||
hostdata->msgout[count+3] = spi_period(SCp->device->sdev_target);
|
spi_offset(SCp->device->sdev_target));
|
||||||
hostdata->msgout[count+4] = spi_offset(SCp->device->sdev_target);
|
|
||||||
count += sizeof(NCR_700_SDTR_msg);
|
|
||||||
NCR_700_set_flag(SCp->device, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION);
|
NCR_700_set_flag(SCp->device, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -218,7 +218,7 @@ NCR_D700_probe_one(struct NCR_D700_private *p, int siop, int irq,
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
detect_failed:
|
detect_failed:
|
||||||
release_region(host->base, 64);
|
release_region(region, 64);
|
||||||
region_failed:
|
region_failed:
|
||||||
kfree(hostdata);
|
kfree(hostdata);
|
||||||
|
|
||||||
|
|
|
@ -997,7 +997,7 @@ struct aac_dev
|
||||||
int maximum_num_physicals;
|
int maximum_num_physicals;
|
||||||
int maximum_num_channels;
|
int maximum_num_channels;
|
||||||
struct fsa_dev_info *fsa_dev;
|
struct fsa_dev_info *fsa_dev;
|
||||||
pid_t thread_pid;
|
struct task_struct *thread;
|
||||||
int cardtype;
|
int cardtype;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1017,7 +1017,6 @@ struct aac_dev
|
||||||
* AIF thread states
|
* AIF thread states
|
||||||
*/
|
*/
|
||||||
u32 aif_thread;
|
u32 aif_thread;
|
||||||
struct completion aif_completion;
|
|
||||||
struct aac_adapter_info adapter_info;
|
struct aac_adapter_info adapter_info;
|
||||||
struct aac_supplement_adapter_info supplement_adapter_info;
|
struct aac_supplement_adapter_info supplement_adapter_info;
|
||||||
/* These are in adapter info but they are in the io flow so
|
/* These are in adapter info but they are in the io flow so
|
||||||
|
@ -1797,7 +1796,7 @@ int aac_sa_init(struct aac_dev *dev);
|
||||||
unsigned int aac_response_normal(struct aac_queue * q);
|
unsigned int aac_response_normal(struct aac_queue * q);
|
||||||
unsigned int aac_command_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);
|
unsigned int aac_intr_normal(struct aac_dev * dev, u32 Index);
|
||||||
int aac_command_thread(struct aac_dev * dev);
|
int aac_command_thread(void *data);
|
||||||
int aac_close_fib_context(struct aac_dev * dev, struct aac_fib_context *fibctx);
|
int aac_close_fib_context(struct aac_dev * dev, struct aac_fib_context *fibctx);
|
||||||
int aac_fib_adapter_complete(struct fib * fibptr, unsigned short size);
|
int aac_fib_adapter_complete(struct fib * fibptr, unsigned short size);
|
||||||
struct aac_driver_ident* aac_get_driver_ident(int devtype);
|
struct aac_driver_ident* aac_get_driver_ident(int devtype);
|
||||||
|
|
|
@ -433,7 +433,6 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev)
|
||||||
}
|
}
|
||||||
|
|
||||||
INIT_LIST_HEAD(&dev->fib_list);
|
INIT_LIST_HEAD(&dev->fib_list);
|
||||||
init_completion(&dev->aif_completion);
|
|
||||||
|
|
||||||
return dev;
|
return dev;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
#include <linux/completion.h>
|
#include <linux/completion.h>
|
||||||
#include <linux/blkdev.h>
|
#include <linux/blkdev.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
|
#include <linux/kthread.h>
|
||||||
#include <scsi/scsi_host.h>
|
#include <scsi/scsi_host.h>
|
||||||
#include <scsi/scsi_device.h>
|
#include <scsi/scsi_device.h>
|
||||||
#include <asm/semaphore.h>
|
#include <asm/semaphore.h>
|
||||||
|
@ -1045,8 +1046,9 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
|
||||||
* more FIBs.
|
* more FIBs.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int aac_command_thread(struct aac_dev * dev)
|
int aac_command_thread(void *data)
|
||||||
{
|
{
|
||||||
|
struct aac_dev *dev = data;
|
||||||
struct hw_fib *hw_fib, *hw_newfib;
|
struct hw_fib *hw_fib, *hw_newfib;
|
||||||
struct fib *fib, *newfib;
|
struct fib *fib, *newfib;
|
||||||
struct aac_fib_context *fibctx;
|
struct aac_fib_context *fibctx;
|
||||||
|
@ -1058,12 +1060,7 @@ int aac_command_thread(struct aac_dev * dev)
|
||||||
*/
|
*/
|
||||||
if (dev->aif_thread)
|
if (dev->aif_thread)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
/*
|
|
||||||
* Set up the name that will appear in 'ps'
|
|
||||||
* stored in task_struct.comm[16].
|
|
||||||
*/
|
|
||||||
daemonize("aacraid");
|
|
||||||
allow_signal(SIGKILL);
|
|
||||||
/*
|
/*
|
||||||
* Let the DPC know it has a place to send the AIF's to.
|
* Let the DPC know it has a place to send the AIF's to.
|
||||||
*/
|
*/
|
||||||
|
@ -1266,13 +1263,12 @@ int aac_command_thread(struct aac_dev * dev)
|
||||||
spin_unlock_irqrestore(dev->queues->queue[HostNormCmdQueue].lock, flags);
|
spin_unlock_irqrestore(dev->queues->queue[HostNormCmdQueue].lock, flags);
|
||||||
schedule();
|
schedule();
|
||||||
|
|
||||||
if(signal_pending(current))
|
if (kthread_should_stop())
|
||||||
break;
|
break;
|
||||||
set_current_state(TASK_INTERRUPTIBLE);
|
set_current_state(TASK_INTERRUPTIBLE);
|
||||||
}
|
}
|
||||||
if (dev->queues)
|
if (dev->queues)
|
||||||
remove_wait_queue(&dev->queues->queue[HostNormCmdQueue].cmdready, &wait);
|
remove_wait_queue(&dev->queues->queue[HostNormCmdQueue].cmdready, &wait);
|
||||||
dev->aif_thread = 0;
|
dev->aif_thread = 0;
|
||||||
complete_and_exit(&dev->aif_completion, 0);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,7 @@
|
||||||
#include <linux/syscalls.h>
|
#include <linux/syscalls.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/smp_lock.h>
|
#include <linux/smp_lock.h>
|
||||||
|
#include <linux/kthread.h>
|
||||||
#include <asm/semaphore.h>
|
#include <asm/semaphore.h>
|
||||||
|
|
||||||
#include <scsi/scsi.h>
|
#include <scsi/scsi.h>
|
||||||
|
@ -850,10 +851,10 @@ static int __devinit aac_probe_one(struct pci_dev *pdev,
|
||||||
/*
|
/*
|
||||||
* Start any kernel threads needed
|
* Start any kernel threads needed
|
||||||
*/
|
*/
|
||||||
aac->thread_pid = kernel_thread((int (*)(void *))aac_command_thread,
|
aac->thread = kthread_run(aac_command_thread, aac, AAC_DRIVERNAME);
|
||||||
aac, 0);
|
if (IS_ERR(aac->thread)) {
|
||||||
if (aac->thread_pid < 0) {
|
|
||||||
printk(KERN_ERR "aacraid: Unable to create command thread.\n");
|
printk(KERN_ERR "aacraid: Unable to create command thread.\n");
|
||||||
|
error = PTR_ERR(aac->thread);
|
||||||
goto out_deinit;
|
goto out_deinit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -934,9 +935,7 @@ static int __devinit aac_probe_one(struct pci_dev *pdev,
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
out_deinit:
|
out_deinit:
|
||||||
kill_proc(aac->thread_pid, SIGKILL, 0);
|
kthread_stop(aac->thread);
|
||||||
wait_for_completion(&aac->aif_completion);
|
|
||||||
|
|
||||||
aac_send_shutdown(aac);
|
aac_send_shutdown(aac);
|
||||||
aac_adapter_disable_int(aac);
|
aac_adapter_disable_int(aac);
|
||||||
free_irq(pdev->irq, aac);
|
free_irq(pdev->irq, aac);
|
||||||
|
@ -970,8 +969,7 @@ static void __devexit aac_remove_one(struct pci_dev *pdev)
|
||||||
|
|
||||||
scsi_remove_host(shost);
|
scsi_remove_host(shost);
|
||||||
|
|
||||||
kill_proc(aac->thread_pid, SIGKILL, 0);
|
kthread_stop(aac->thread);
|
||||||
wait_for_completion(&aac->aif_completion);
|
|
||||||
|
|
||||||
aac_send_shutdown(aac);
|
aac_send_shutdown(aac);
|
||||||
aac_adapter_disable_int(aac);
|
aac_adapter_disable_int(aac);
|
||||||
|
|
|
@ -1716,12 +1716,7 @@ static void seldo_run(struct Scsi_Host *shpnt)
|
||||||
ADDMSGO(BUS_DEVICE_RESET);
|
ADDMSGO(BUS_DEVICE_RESET);
|
||||||
} else if (SYNCNEG==0 && SYNCHRONOUS) {
|
} else if (SYNCNEG==0 && SYNCHRONOUS) {
|
||||||
CURRENT_SC->SCp.phase |= syncneg;
|
CURRENT_SC->SCp.phase |= syncneg;
|
||||||
ADDMSGO(EXTENDED_MESSAGE);
|
MSGOLEN += spi_populate_sync_msg(&MSGO(MSGOLEN), 50, 8);
|
||||||
ADDMSGO(3);
|
|
||||||
ADDMSGO(EXTENDED_SDTR);
|
|
||||||
ADDMSGO(50); /* 200ns */
|
|
||||||
ADDMSGO(8); /* 8 byte req/ack offset */
|
|
||||||
|
|
||||||
SYNCNEG=1; /* negotiation in progress */
|
SYNCNEG=1; /* negotiation in progress */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -207,7 +207,6 @@ static struct scsi_host_template ahci_sht = {
|
||||||
.name = DRV_NAME,
|
.name = DRV_NAME,
|
||||||
.ioctl = ata_scsi_ioctl,
|
.ioctl = ata_scsi_ioctl,
|
||||||
.queuecommand = ata_scsi_queuecmd,
|
.queuecommand = ata_scsi_queuecmd,
|
||||||
.eh_timed_out = ata_scsi_timed_out,
|
|
||||||
.eh_strategy_handler = ata_scsi_error,
|
.eh_strategy_handler = ata_scsi_error,
|
||||||
.can_queue = ATA_DEF_QUEUE,
|
.can_queue = ATA_DEF_QUEUE,
|
||||||
.this_id = ATA_SHT_THIS_ID,
|
.this_id = ATA_SHT_THIS_ID,
|
||||||
|
|
|
@ -978,9 +978,13 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case INVALID_SEQINT:
|
case INVALID_SEQINT:
|
||||||
printf("%s: Invalid Sequencer interrupt occurred.\n",
|
printf("%s: Invalid Sequencer interrupt occurred, "
|
||||||
|
"resetting channel.\n",
|
||||||
ahd_name(ahd));
|
ahd_name(ahd));
|
||||||
ahd_dump_card_state(ahd);
|
#ifdef AHD_DEBUG
|
||||||
|
if ((ahd_debug & AHD_SHOW_RECOVERY) != 0)
|
||||||
|
ahd_dump_card_state(ahd);
|
||||||
|
#endif
|
||||||
ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE);
|
ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE);
|
||||||
break;
|
break;
|
||||||
case STATUS_OVERRUN:
|
case STATUS_OVERRUN:
|
||||||
|
@ -3762,11 +3766,8 @@ ahd_construct_sdtr(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
|
||||||
{
|
{
|
||||||
if (offset == 0)
|
if (offset == 0)
|
||||||
period = AHD_ASYNC_XFER_PERIOD;
|
period = AHD_ASYNC_XFER_PERIOD;
|
||||||
ahd->msgout_buf[ahd->msgout_index++] = MSG_EXTENDED;
|
ahd->msgout_index += spi_populate_sync_msg(
|
||||||
ahd->msgout_buf[ahd->msgout_index++] = MSG_EXT_SDTR_LEN;
|
ahd->msgout_buf + ahd->msgout_index, period, offset);
|
||||||
ahd->msgout_buf[ahd->msgout_index++] = MSG_EXT_SDTR;
|
|
||||||
ahd->msgout_buf[ahd->msgout_index++] = period;
|
|
||||||
ahd->msgout_buf[ahd->msgout_index++] = offset;
|
|
||||||
ahd->msgout_len += 5;
|
ahd->msgout_len += 5;
|
||||||
if (bootverbose) {
|
if (bootverbose) {
|
||||||
printf("(%s:%c:%d:%d): Sending SDTR period %x, offset %x\n",
|
printf("(%s:%c:%d:%d): Sending SDTR period %x, offset %x\n",
|
||||||
|
@ -3783,10 +3784,8 @@ static void
|
||||||
ahd_construct_wdtr(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
|
ahd_construct_wdtr(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
|
||||||
u_int bus_width)
|
u_int bus_width)
|
||||||
{
|
{
|
||||||
ahd->msgout_buf[ahd->msgout_index++] = MSG_EXTENDED;
|
ahd->msgout_index += spi_populate_width_msg(
|
||||||
ahd->msgout_buf[ahd->msgout_index++] = MSG_EXT_WDTR_LEN;
|
ahd->msgout_buf + ahd->msgout_index, bus_width);
|
||||||
ahd->msgout_buf[ahd->msgout_index++] = MSG_EXT_WDTR;
|
|
||||||
ahd->msgout_buf[ahd->msgout_index++] = bus_width;
|
|
||||||
ahd->msgout_len += 4;
|
ahd->msgout_len += 4;
|
||||||
if (bootverbose) {
|
if (bootverbose) {
|
||||||
printf("(%s:%c:%d:%d): Sending WDTR %x\n",
|
printf("(%s:%c:%d:%d): Sending WDTR %x\n",
|
||||||
|
@ -3813,14 +3812,9 @@ ahd_construct_ppr(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
|
||||||
ppr_options |= MSG_EXT_PPR_PCOMP_EN;
|
ppr_options |= MSG_EXT_PPR_PCOMP_EN;
|
||||||
if (offset == 0)
|
if (offset == 0)
|
||||||
period = AHD_ASYNC_XFER_PERIOD;
|
period = AHD_ASYNC_XFER_PERIOD;
|
||||||
ahd->msgout_buf[ahd->msgout_index++] = MSG_EXTENDED;
|
ahd->msgout_index += spi_populate_ppr_msg(
|
||||||
ahd->msgout_buf[ahd->msgout_index++] = MSG_EXT_PPR_LEN;
|
ahd->msgout_buf + ahd->msgout_index, period, offset,
|
||||||
ahd->msgout_buf[ahd->msgout_index++] = MSG_EXT_PPR;
|
bus_width, ppr_options);
|
||||||
ahd->msgout_buf[ahd->msgout_index++] = period;
|
|
||||||
ahd->msgout_buf[ahd->msgout_index++] = 0;
|
|
||||||
ahd->msgout_buf[ahd->msgout_index++] = offset;
|
|
||||||
ahd->msgout_buf[ahd->msgout_index++] = bus_width;
|
|
||||||
ahd->msgout_buf[ahd->msgout_index++] = ppr_options;
|
|
||||||
ahd->msgout_len += 8;
|
ahd->msgout_len += 8;
|
||||||
if (bootverbose) {
|
if (bootverbose) {
|
||||||
printf("(%s:%c:%d:%d): Sending PPR bus_width %x, period %x, "
|
printf("(%s:%c:%d:%d): Sending PPR bus_width %x, period %x, "
|
||||||
|
@ -7094,7 +7088,6 @@ ahd_pause_and_flushwork(struct ahd_softc *ahd)
|
||||||
|
|
||||||
ahd_flush_qoutfifo(ahd);
|
ahd_flush_qoutfifo(ahd);
|
||||||
|
|
||||||
ahd_platform_flushwork(ahd);
|
|
||||||
ahd->flags &= ~AHD_ALL_INTERRUPTS;
|
ahd->flags &= ~AHD_ALL_INTERRUPTS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -373,8 +373,7 @@ static void ahd_linux_handle_scsi_status(struct ahd_softc *,
|
||||||
struct scb *);
|
struct scb *);
|
||||||
static void ahd_linux_queue_cmd_complete(struct ahd_softc *ahd,
|
static void ahd_linux_queue_cmd_complete(struct ahd_softc *ahd,
|
||||||
struct scsi_cmnd *cmd);
|
struct scsi_cmnd *cmd);
|
||||||
static void ahd_linux_sem_timeout(u_long arg);
|
static int ahd_linux_queue_abort_cmd(struct scsi_cmnd *cmd);
|
||||||
static int ahd_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag);
|
|
||||||
static void ahd_linux_initialize_scsi_bus(struct ahd_softc *ahd);
|
static void ahd_linux_initialize_scsi_bus(struct ahd_softc *ahd);
|
||||||
static u_int ahd_linux_user_tagdepth(struct ahd_softc *ahd,
|
static u_int ahd_linux_user_tagdepth(struct ahd_softc *ahd,
|
||||||
struct ahd_devinfo *devinfo);
|
struct ahd_devinfo *devinfo);
|
||||||
|
@ -453,18 +452,13 @@ ahd_linux_queue(struct scsi_cmnd * cmd, void (*scsi_done) (struct scsi_cmnd *))
|
||||||
struct ahd_softc *ahd;
|
struct ahd_softc *ahd;
|
||||||
struct ahd_linux_device *dev = scsi_transport_device_data(cmd->device);
|
struct ahd_linux_device *dev = scsi_transport_device_data(cmd->device);
|
||||||
int rtn = SCSI_MLQUEUE_HOST_BUSY;
|
int rtn = SCSI_MLQUEUE_HOST_BUSY;
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
ahd = *(struct ahd_softc **)cmd->device->host->hostdata;
|
ahd = *(struct ahd_softc **)cmd->device->host->hostdata;
|
||||||
|
|
||||||
ahd_lock(ahd, &flags);
|
cmd->scsi_done = scsi_done;
|
||||||
if (ahd->platform_data->qfrozen == 0) {
|
cmd->result = CAM_REQ_INPROG << 16;
|
||||||
cmd->scsi_done = scsi_done;
|
rtn = ahd_linux_run_command(ahd, dev, cmd);
|
||||||
cmd->result = CAM_REQ_INPROG << 16;
|
|
||||||
rtn = ahd_linux_run_command(ahd, dev, cmd);
|
|
||||||
|
|
||||||
}
|
|
||||||
ahd_unlock(ahd, &flags);
|
|
||||||
return rtn;
|
return rtn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -487,6 +481,7 @@ ahd_linux_target_alloc(struct scsi_target *starget)
|
||||||
{
|
{
|
||||||
struct ahd_softc *ahd =
|
struct ahd_softc *ahd =
|
||||||
*((struct ahd_softc **)dev_to_shost(&starget->dev)->hostdata);
|
*((struct ahd_softc **)dev_to_shost(&starget->dev)->hostdata);
|
||||||
|
struct seeprom_config *sc = ahd->seep_config;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
struct scsi_target **ahd_targp = ahd_linux_target_in_softc(starget);
|
struct scsi_target **ahd_targp = ahd_linux_target_in_softc(starget);
|
||||||
struct ahd_linux_target *targ = scsi_transport_target_data(starget);
|
struct ahd_linux_target *targ = scsi_transport_target_data(starget);
|
||||||
|
@ -502,18 +497,38 @@ ahd_linux_target_alloc(struct scsi_target *starget)
|
||||||
*ahd_targp = starget;
|
*ahd_targp = starget;
|
||||||
memset(targ, 0, sizeof(*targ));
|
memset(targ, 0, sizeof(*targ));
|
||||||
|
|
||||||
|
if (sc) {
|
||||||
|
int flags = sc->device_flags[starget->id];
|
||||||
|
|
||||||
|
tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id,
|
||||||
|
starget->id, &tstate);
|
||||||
|
|
||||||
|
if ((flags & CFPACKETIZED) == 0) {
|
||||||
|
/* Do not negotiate packetized transfers */
|
||||||
|
spi_rd_strm(starget) = 0;
|
||||||
|
spi_pcomp_en(starget) = 0;
|
||||||
|
spi_rti(starget) = 0;
|
||||||
|
spi_wr_flow(starget) = 0;
|
||||||
|
spi_hold_mcs(starget) = 0;
|
||||||
|
} else {
|
||||||
|
if ((ahd->features & AHD_RTI) == 0)
|
||||||
|
spi_rti(starget) = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((flags & CFQAS) == 0)
|
||||||
|
spi_qas(starget) = 0;
|
||||||
|
|
||||||
|
/* Transinfo values have been set to BIOS settings */
|
||||||
|
spi_max_width(starget) = (flags & CFWIDEB) ? 1 : 0;
|
||||||
|
spi_min_period(starget) = tinfo->user.period;
|
||||||
|
spi_max_offset(starget) = tinfo->user.offset;
|
||||||
|
}
|
||||||
|
|
||||||
tinfo = ahd_fetch_transinfo(ahd, channel, ahd->our_id,
|
tinfo = ahd_fetch_transinfo(ahd, channel, ahd->our_id,
|
||||||
starget->id, &tstate);
|
starget->id, &tstate);
|
||||||
ahd_compile_devinfo(&devinfo, ahd->our_id, starget->id,
|
ahd_compile_devinfo(&devinfo, ahd->our_id, starget->id,
|
||||||
CAM_LUN_WILDCARD, channel,
|
CAM_LUN_WILDCARD, channel,
|
||||||
ROLE_INITIATOR);
|
ROLE_INITIATOR);
|
||||||
spi_min_period(starget) = AHD_SYNCRATE_MAX; /* We can do U320 */
|
|
||||||
if ((ahd->bugs & AHD_PACED_NEGTABLE_BUG) != 0)
|
|
||||||
spi_max_offset(starget) = MAX_OFFSET_PACED_BUG;
|
|
||||||
else
|
|
||||||
spi_max_offset(starget) = MAX_OFFSET_PACED;
|
|
||||||
spi_max_width(starget) = ahd->features & AHD_WIDE;
|
|
||||||
|
|
||||||
ahd_set_syncrate(ahd, &devinfo, 0, 0, 0,
|
ahd_set_syncrate(ahd, &devinfo, 0, 0, 0,
|
||||||
AHD_TRANS_GOAL, /*paused*/FALSE);
|
AHD_TRANS_GOAL, /*paused*/FALSE);
|
||||||
ahd_set_width(ahd, &devinfo, MSG_EXT_WDTR_BUS_8_BIT,
|
ahd_set_width(ahd, &devinfo, MSG_EXT_WDTR_BUS_8_BIT,
|
||||||
|
@ -654,10 +669,9 @@ static int
|
||||||
ahd_linux_abort(struct scsi_cmnd *cmd)
|
ahd_linux_abort(struct scsi_cmnd *cmd)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
|
error = ahd_linux_queue_abort_cmd(cmd);
|
||||||
|
|
||||||
error = ahd_linux_queue_recovery_cmd(cmd, SCB_ABORT);
|
|
||||||
if (error != 0)
|
|
||||||
printf("aic79xx_abort returns 0x%x\n", error);
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -667,12 +681,97 @@ ahd_linux_abort(struct scsi_cmnd *cmd)
|
||||||
static int
|
static int
|
||||||
ahd_linux_dev_reset(struct scsi_cmnd *cmd)
|
ahd_linux_dev_reset(struct scsi_cmnd *cmd)
|
||||||
{
|
{
|
||||||
int error;
|
struct ahd_softc *ahd;
|
||||||
|
struct ahd_linux_device *dev;
|
||||||
|
struct scb *reset_scb;
|
||||||
|
u_int cdb_byte;
|
||||||
|
int retval = SUCCESS;
|
||||||
|
int paused;
|
||||||
|
int wait;
|
||||||
|
struct ahd_initiator_tinfo *tinfo;
|
||||||
|
struct ahd_tmode_tstate *tstate;
|
||||||
|
unsigned long flags;
|
||||||
|
DECLARE_COMPLETION(done);
|
||||||
|
|
||||||
error = ahd_linux_queue_recovery_cmd(cmd, SCB_DEVICE_RESET);
|
reset_scb = NULL;
|
||||||
if (error != 0)
|
paused = FALSE;
|
||||||
printf("aic79xx_dev_reset returns 0x%x\n", error);
|
wait = FALSE;
|
||||||
return error;
|
ahd = *(struct ahd_softc **)cmd->device->host->hostdata;
|
||||||
|
|
||||||
|
scmd_printk(KERN_INFO, cmd,
|
||||||
|
"Attempting to queue a TARGET RESET message:");
|
||||||
|
|
||||||
|
printf("CDB:");
|
||||||
|
for (cdb_byte = 0; cdb_byte < cmd->cmd_len; cdb_byte++)
|
||||||
|
printf(" 0x%x", cmd->cmnd[cdb_byte]);
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Determine if we currently own this command.
|
||||||
|
*/
|
||||||
|
dev = scsi_transport_device_data(cmd->device);
|
||||||
|
|
||||||
|
if (dev == NULL) {
|
||||||
|
/*
|
||||||
|
* No target device for this command exists,
|
||||||
|
* so we must not still own the command.
|
||||||
|
*/
|
||||||
|
scmd_printk(KERN_INFO, cmd, "Is not an active device\n");
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Generate us a new SCB
|
||||||
|
*/
|
||||||
|
reset_scb = ahd_get_scb(ahd, AHD_NEVER_COL_IDX);
|
||||||
|
if (!reset_scb) {
|
||||||
|
scmd_printk(KERN_INFO, cmd, "No SCB available\n");
|
||||||
|
return FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id,
|
||||||
|
cmd->device->id, &tstate);
|
||||||
|
reset_scb->io_ctx = cmd;
|
||||||
|
reset_scb->platform_data->dev = dev;
|
||||||
|
reset_scb->sg_count = 0;
|
||||||
|
ahd_set_residual(reset_scb, 0);
|
||||||
|
ahd_set_sense_residual(reset_scb, 0);
|
||||||
|
reset_scb->platform_data->xfer_len = 0;
|
||||||
|
reset_scb->hscb->control = 0;
|
||||||
|
reset_scb->hscb->scsiid = BUILD_SCSIID(ahd,cmd);
|
||||||
|
reset_scb->hscb->lun = cmd->device->lun;
|
||||||
|
reset_scb->hscb->cdb_len = 0;
|
||||||
|
reset_scb->hscb->task_management = SIU_TASKMGMT_LUN_RESET;
|
||||||
|
reset_scb->flags |= SCB_DEVICE_RESET|SCB_RECOVERY_SCB|SCB_ACTIVE;
|
||||||
|
if ((tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ) != 0) {
|
||||||
|
reset_scb->flags |= SCB_PACKETIZED;
|
||||||
|
} else {
|
||||||
|
reset_scb->hscb->control |= MK_MESSAGE;
|
||||||
|
}
|
||||||
|
dev->openings--;
|
||||||
|
dev->active++;
|
||||||
|
dev->commands_issued++;
|
||||||
|
|
||||||
|
ahd_lock(ahd, &flags);
|
||||||
|
|
||||||
|
LIST_INSERT_HEAD(&ahd->pending_scbs, reset_scb, pending_links);
|
||||||
|
ahd_queue_scb(ahd, reset_scb);
|
||||||
|
|
||||||
|
ahd->platform_data->eh_done = &done;
|
||||||
|
ahd_unlock(ahd, &flags);
|
||||||
|
|
||||||
|
printf("%s: Device reset code sleeping\n", ahd_name(ahd));
|
||||||
|
if (!wait_for_completion_timeout(&done, 5 * HZ)) {
|
||||||
|
ahd_lock(ahd, &flags);
|
||||||
|
ahd->platform_data->eh_done = NULL;
|
||||||
|
ahd_unlock(ahd, &flags);
|
||||||
|
printf("%s: Device reset timer expired (active %d)\n",
|
||||||
|
ahd_name(ahd), dev->active);
|
||||||
|
retval = FAILED;
|
||||||
|
}
|
||||||
|
printf("%s: Device reset returning 0x%x\n", ahd_name(ahd), retval);
|
||||||
|
|
||||||
|
return (retval);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -682,7 +781,6 @@ static int
|
||||||
ahd_linux_bus_reset(struct scsi_cmnd *cmd)
|
ahd_linux_bus_reset(struct scsi_cmnd *cmd)
|
||||||
{
|
{
|
||||||
struct ahd_softc *ahd;
|
struct ahd_softc *ahd;
|
||||||
u_long s;
|
|
||||||
int found;
|
int found;
|
||||||
|
|
||||||
ahd = *(struct ahd_softc **)cmd->device->host->hostdata;
|
ahd = *(struct ahd_softc **)cmd->device->host->hostdata;
|
||||||
|
@ -691,10 +789,8 @@ ahd_linux_bus_reset(struct scsi_cmnd *cmd)
|
||||||
printf("%s: Bus reset called for cmd %p\n",
|
printf("%s: Bus reset called for cmd %p\n",
|
||||||
ahd_name(ahd), cmd);
|
ahd_name(ahd), cmd);
|
||||||
#endif
|
#endif
|
||||||
ahd_lock(ahd, &s);
|
|
||||||
found = ahd_reset_channel(ahd, scmd_channel(cmd) + 'A',
|
found = ahd_reset_channel(ahd, scmd_channel(cmd) + 'A',
|
||||||
/*initiate reset*/TRUE);
|
/*initiate reset*/TRUE);
|
||||||
ahd_unlock(ahd, &s);
|
|
||||||
|
|
||||||
if (bootverbose)
|
if (bootverbose)
|
||||||
printf("%s: SCSI bus reset delivered. "
|
printf("%s: SCSI bus reset delivered. "
|
||||||
|
@ -811,59 +907,6 @@ ahd_dmamap_unload(struct ahd_softc *ahd, bus_dma_tag_t dmat, bus_dmamap_t map)
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************* Platform Dependent Functions ***************************/
|
/********************* Platform Dependent Functions ***************************/
|
||||||
/*
|
|
||||||
* Compare "left hand" softc with "right hand" softc, returning:
|
|
||||||
* < 0 - lahd has a lower priority than rahd
|
|
||||||
* 0 - Softcs are equal
|
|
||||||
* > 0 - lahd has a higher priority than rahd
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
ahd_softc_comp(struct ahd_softc *lahd, struct ahd_softc *rahd)
|
|
||||||
{
|
|
||||||
int value;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Under Linux, cards are ordered as follows:
|
|
||||||
* 1) PCI devices that are marked as the boot controller.
|
|
||||||
* 2) PCI devices with BIOS enabled sorted by bus/slot/func.
|
|
||||||
* 3) All remaining PCI devices sorted by bus/slot/func.
|
|
||||||
*/
|
|
||||||
#if 0
|
|
||||||
value = (lahd->flags & AHD_BOOT_CHANNEL)
|
|
||||||
- (rahd->flags & AHD_BOOT_CHANNEL);
|
|
||||||
if (value != 0)
|
|
||||||
/* Controllers set for boot have a *higher* priority */
|
|
||||||
return (value);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
value = (lahd->flags & AHD_BIOS_ENABLED)
|
|
||||||
- (rahd->flags & AHD_BIOS_ENABLED);
|
|
||||||
if (value != 0)
|
|
||||||
/* Controllers with BIOS enabled have a *higher* priority */
|
|
||||||
return (value);
|
|
||||||
|
|
||||||
/* Still equal. Sort by bus/slot/func. */
|
|
||||||
if (aic79xx_reverse_scan != 0)
|
|
||||||
value = ahd_get_pci_bus(lahd->dev_softc)
|
|
||||||
- ahd_get_pci_bus(rahd->dev_softc);
|
|
||||||
else
|
|
||||||
value = ahd_get_pci_bus(rahd->dev_softc)
|
|
||||||
- ahd_get_pci_bus(lahd->dev_softc);
|
|
||||||
if (value != 0)
|
|
||||||
return (value);
|
|
||||||
if (aic79xx_reverse_scan != 0)
|
|
||||||
value = ahd_get_pci_slot(lahd->dev_softc)
|
|
||||||
- ahd_get_pci_slot(rahd->dev_softc);
|
|
||||||
else
|
|
||||||
value = ahd_get_pci_slot(rahd->dev_softc)
|
|
||||||
- ahd_get_pci_slot(lahd->dev_softc);
|
|
||||||
if (value != 0)
|
|
||||||
return (value);
|
|
||||||
|
|
||||||
value = rahd->channel - lahd->channel;
|
|
||||||
return (value);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ahd_linux_setup_iocell_info(u_long index, int instance, int targ, int32_t value)
|
ahd_linux_setup_iocell_info(u_long index, int instance, int targ, int32_t value)
|
||||||
{
|
{
|
||||||
|
@ -1194,7 +1237,6 @@ ahd_platform_alloc(struct ahd_softc *ahd, void *platform_arg)
|
||||||
memset(ahd->platform_data, 0, sizeof(struct ahd_platform_data));
|
memset(ahd->platform_data, 0, sizeof(struct ahd_platform_data));
|
||||||
ahd->platform_data->irq = AHD_LINUX_NOIRQ;
|
ahd->platform_data->irq = AHD_LINUX_NOIRQ;
|
||||||
ahd_lockinit(ahd);
|
ahd_lockinit(ahd);
|
||||||
init_MUTEX_LOCKED(&ahd->platform_data->eh_sem);
|
|
||||||
ahd->seltime = (aic79xx_seltime & 0x3) << 4;
|
ahd->seltime = (aic79xx_seltime & 0x3) << 4;
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
@ -1346,14 +1388,12 @@ ahd_platform_set_tags(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
|
||||||
|
|
||||||
switch ((dev->flags & (AHD_DEV_Q_BASIC|AHD_DEV_Q_TAGGED))) {
|
switch ((dev->flags & (AHD_DEV_Q_BASIC|AHD_DEV_Q_TAGGED))) {
|
||||||
case AHD_DEV_Q_BASIC:
|
case AHD_DEV_Q_BASIC:
|
||||||
scsi_adjust_queue_depth(sdev,
|
scsi_set_tag_type(sdev, MSG_SIMPLE_TASK);
|
||||||
MSG_SIMPLE_TASK,
|
scsi_activate_tcq(sdev, dev->openings + dev->active);
|
||||||
dev->openings + dev->active);
|
|
||||||
break;
|
break;
|
||||||
case AHD_DEV_Q_TAGGED:
|
case AHD_DEV_Q_TAGGED:
|
||||||
scsi_adjust_queue_depth(sdev,
|
scsi_set_tag_type(sdev, MSG_ORDERED_TASK);
|
||||||
MSG_ORDERED_TASK,
|
scsi_activate_tcq(sdev, dev->openings + dev->active);
|
||||||
dev->openings + dev->active);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/*
|
/*
|
||||||
|
@ -1362,9 +1402,7 @@ ahd_platform_set_tags(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
|
||||||
* serially on the controller/device. This should
|
* serially on the controller/device. This should
|
||||||
* remove some latency.
|
* remove some latency.
|
||||||
*/
|
*/
|
||||||
scsi_adjust_queue_depth(sdev,
|
scsi_deactivate_tcq(sdev, 1);
|
||||||
/*NON-TAGGED*/0,
|
|
||||||
/*queue depth*/2);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1443,6 +1481,9 @@ ahd_linux_run_command(struct ahd_softc *ahd, struct ahd_linux_device *dev,
|
||||||
struct ahd_tmode_tstate *tstate;
|
struct ahd_tmode_tstate *tstate;
|
||||||
u_int col_idx;
|
u_int col_idx;
|
||||||
uint16_t mask;
|
uint16_t mask;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
ahd_lock(ahd, &flags);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get an scb to use.
|
* Get an scb to use.
|
||||||
|
@ -1458,6 +1499,7 @@ ahd_linux_run_command(struct ahd_softc *ahd, struct ahd_linux_device *dev,
|
||||||
}
|
}
|
||||||
if ((scb = ahd_get_scb(ahd, col_idx)) == NULL) {
|
if ((scb = ahd_get_scb(ahd, col_idx)) == NULL) {
|
||||||
ahd->flags |= AHD_RESOURCE_SHORTAGE;
|
ahd->flags |= AHD_RESOURCE_SHORTAGE;
|
||||||
|
ahd_unlock(ahd, &flags);
|
||||||
return SCSI_MLQUEUE_HOST_BUSY;
|
return SCSI_MLQUEUE_HOST_BUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1484,30 +1526,6 @@ ahd_linux_run_command(struct ahd_softc *ahd, struct ahd_linux_device *dev,
|
||||||
if ((tstate->auto_negotiate & mask) != 0) {
|
if ((tstate->auto_negotiate & mask) != 0) {
|
||||||
scb->flags |= SCB_AUTO_NEGOTIATE;
|
scb->flags |= SCB_AUTO_NEGOTIATE;
|
||||||
scb->hscb->control |= MK_MESSAGE;
|
scb->hscb->control |= MK_MESSAGE;
|
||||||
} else if (cmd->cmnd[0] == INQUIRY
|
|
||||||
&& (tinfo->curr.offset != 0
|
|
||||||
|| tinfo->curr.width != MSG_EXT_WDTR_BUS_8_BIT
|
|
||||||
|| tinfo->curr.ppr_options != 0)
|
|
||||||
&& (tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ)==0) {
|
|
||||||
/*
|
|
||||||
* The SCSI spec requires inquiry
|
|
||||||
* commands to complete without
|
|
||||||
* reporting unit attention conditions.
|
|
||||||
* Because of this, an inquiry command
|
|
||||||
* that occurs just after a device is
|
|
||||||
* reset will result in a data phase
|
|
||||||
* with mismatched negotiated rates.
|
|
||||||
* The core already forces a renegotiation
|
|
||||||
* for reset events that are visible to
|
|
||||||
* our controller or that we initiate,
|
|
||||||
* but a third party device reset or a
|
|
||||||
* hot-plug insertion can still cause this
|
|
||||||
* issue. Therefore, we force a re-negotiation
|
|
||||||
* for every inquiry command unless we
|
|
||||||
* are async.
|
|
||||||
*/
|
|
||||||
scb->flags |= SCB_NEGOTIATE;
|
|
||||||
scb->hscb->control |= MK_MESSAGE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((dev->flags & (AHD_DEV_Q_TAGGED|AHD_DEV_Q_BASIC)) != 0) {
|
if ((dev->flags & (AHD_DEV_Q_TAGGED|AHD_DEV_Q_BASIC)) != 0) {
|
||||||
|
@ -1583,6 +1601,8 @@ ahd_linux_run_command(struct ahd_softc *ahd, struct ahd_linux_device *dev,
|
||||||
scb->flags |= SCB_ACTIVE;
|
scb->flags |= SCB_ACTIVE;
|
||||||
ahd_queue_scb(ahd, scb);
|
ahd_queue_scb(ahd, scb);
|
||||||
|
|
||||||
|
ahd_unlock(ahd, &flags);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1603,12 +1623,6 @@ ahd_linux_isr(int irq, void *dev_id, struct pt_regs * regs)
|
||||||
return IRQ_RETVAL(ours);
|
return IRQ_RETVAL(ours);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
ahd_platform_flushwork(struct ahd_softc *ahd)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ahd_send_async(struct ahd_softc *ahd, char channel,
|
ahd_send_async(struct ahd_softc *ahd, char channel,
|
||||||
u_int target, u_int lun, ac_code code, void *arg)
|
u_int target, u_int lun, ac_code code, void *arg)
|
||||||
|
@ -1618,7 +1632,6 @@ ahd_send_async(struct ahd_softc *ahd, char channel,
|
||||||
{
|
{
|
||||||
char buf[80];
|
char buf[80];
|
||||||
struct scsi_target *starget;
|
struct scsi_target *starget;
|
||||||
struct ahd_linux_target *targ;
|
|
||||||
struct info_str info;
|
struct info_str info;
|
||||||
struct ahd_initiator_tinfo *tinfo;
|
struct ahd_initiator_tinfo *tinfo;
|
||||||
struct ahd_tmode_tstate *tstate;
|
struct ahd_tmode_tstate *tstate;
|
||||||
|
@ -1651,7 +1664,6 @@ ahd_send_async(struct ahd_softc *ahd, char channel,
|
||||||
starget = ahd->platform_data->starget[target];
|
starget = ahd->platform_data->starget[target];
|
||||||
if (starget == NULL)
|
if (starget == NULL)
|
||||||
break;
|
break;
|
||||||
targ = scsi_transport_target_data(starget);
|
|
||||||
|
|
||||||
target_ppr_options =
|
target_ppr_options =
|
||||||
(spi_dt(starget) ? MSG_EXT_PPR_DT_REQ : 0)
|
(spi_dt(starget) ? MSG_EXT_PPR_DT_REQ : 0)
|
||||||
|
@ -1803,10 +1815,9 @@ ahd_done(struct ahd_softc *ahd, struct scb *scb)
|
||||||
if (ahd_get_transaction_status(scb) == CAM_BDR_SENT
|
if (ahd_get_transaction_status(scb) == CAM_BDR_SENT
|
||||||
|| ahd_get_transaction_status(scb) == CAM_REQ_ABORTED)
|
|| ahd_get_transaction_status(scb) == CAM_REQ_ABORTED)
|
||||||
ahd_set_transaction_status(scb, CAM_CMD_TIMEOUT);
|
ahd_set_transaction_status(scb, CAM_CMD_TIMEOUT);
|
||||||
if ((ahd->platform_data->flags & AHD_SCB_UP_EH_SEM) != 0) {
|
|
||||||
ahd->platform_data->flags &= ~AHD_SCB_UP_EH_SEM;
|
if (ahd->platform_data->eh_done)
|
||||||
up(&ahd->platform_data->eh_sem);
|
complete(ahd->platform_data->eh_done);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ahd_free_scb(ahd, scb);
|
ahd_free_scb(ahd, scb);
|
||||||
|
@ -1961,133 +1972,125 @@ ahd_linux_handle_scsi_status(struct ahd_softc *ahd,
|
||||||
static void
|
static void
|
||||||
ahd_linux_queue_cmd_complete(struct ahd_softc *ahd, struct scsi_cmnd *cmd)
|
ahd_linux_queue_cmd_complete(struct ahd_softc *ahd, struct scsi_cmnd *cmd)
|
||||||
{
|
{
|
||||||
|
int status;
|
||||||
|
int new_status = DID_OK;
|
||||||
|
int do_fallback = 0;
|
||||||
|
int scsi_status;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Map CAM error codes into Linux Error codes. We
|
* Map CAM error codes into Linux Error codes. We
|
||||||
* avoid the conversion so that the DV code has the
|
* avoid the conversion so that the DV code has the
|
||||||
* full error information available when making
|
* full error information available when making
|
||||||
* state change decisions.
|
* state change decisions.
|
||||||
*/
|
*/
|
||||||
{
|
|
||||||
uint32_t status;
|
|
||||||
u_int new_status;
|
|
||||||
|
|
||||||
status = ahd_cmd_get_transaction_status(cmd);
|
status = ahd_cmd_get_transaction_status(cmd);
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case CAM_REQ_INPROG:
|
case CAM_REQ_INPROG:
|
||||||
case CAM_REQ_CMP:
|
case CAM_REQ_CMP:
|
||||||
case CAM_SCSI_STATUS_ERROR:
|
new_status = DID_OK;
|
||||||
new_status = DID_OK;
|
break;
|
||||||
break;
|
case CAM_AUTOSENSE_FAIL:
|
||||||
case CAM_REQ_ABORTED:
|
new_status = DID_ERROR;
|
||||||
new_status = DID_ABORT;
|
/* Fallthrough */
|
||||||
break;
|
case CAM_SCSI_STATUS_ERROR:
|
||||||
case CAM_BUSY:
|
scsi_status = ahd_cmd_get_scsi_status(cmd);
|
||||||
new_status = DID_BUS_BUSY;
|
|
||||||
break;
|
switch(scsi_status) {
|
||||||
case CAM_REQ_INVALID:
|
case SCSI_STATUS_CMD_TERMINATED:
|
||||||
case CAM_PATH_INVALID:
|
case SCSI_STATUS_CHECK_COND:
|
||||||
new_status = DID_BAD_TARGET;
|
if ((cmd->result >> 24) != DRIVER_SENSE) {
|
||||||
break;
|
do_fallback = 1;
|
||||||
case CAM_SEL_TIMEOUT:
|
} else {
|
||||||
new_status = DID_NO_CONNECT;
|
struct scsi_sense_data *sense;
|
||||||
break;
|
|
||||||
case CAM_SCSI_BUS_RESET:
|
sense = (struct scsi_sense_data *)
|
||||||
case CAM_BDR_SENT:
|
&cmd->sense_buffer;
|
||||||
new_status = DID_RESET;
|
if (sense->extra_len >= 5 &&
|
||||||
break;
|
(sense->add_sense_code == 0x47
|
||||||
case CAM_UNCOR_PARITY:
|
|| sense->add_sense_code == 0x48))
|
||||||
new_status = DID_PARITY;
|
do_fallback = 1;
|
||||||
break;
|
}
|
||||||
case CAM_CMD_TIMEOUT:
|
|
||||||
new_status = DID_TIME_OUT;
|
|
||||||
break;
|
|
||||||
case CAM_UA_ABORT:
|
|
||||||
case CAM_REQ_CMP_ERR:
|
|
||||||
case CAM_AUTOSENSE_FAIL:
|
|
||||||
case CAM_NO_HBA:
|
|
||||||
case CAM_DATA_RUN_ERR:
|
|
||||||
case CAM_UNEXP_BUSFREE:
|
|
||||||
case CAM_SEQUENCE_FAIL:
|
|
||||||
case CAM_CCB_LEN_ERR:
|
|
||||||
case CAM_PROVIDE_FAIL:
|
|
||||||
case CAM_REQ_TERMIO:
|
|
||||||
case CAM_UNREC_HBA_ERROR:
|
|
||||||
case CAM_REQ_TOO_BIG:
|
|
||||||
new_status = DID_ERROR;
|
|
||||||
break;
|
|
||||||
case CAM_REQUEUE_REQ:
|
|
||||||
new_status = DID_REQUEUE;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* We should never get here */
|
|
||||||
new_status = DID_ERROR;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
ahd_cmd_set_transaction_status(cmd, new_status);
|
case CAM_REQ_ABORTED:
|
||||||
|
new_status = DID_ABORT;
|
||||||
|
break;
|
||||||
|
case CAM_BUSY:
|
||||||
|
new_status = DID_BUS_BUSY;
|
||||||
|
break;
|
||||||
|
case CAM_REQ_INVALID:
|
||||||
|
case CAM_PATH_INVALID:
|
||||||
|
new_status = DID_BAD_TARGET;
|
||||||
|
break;
|
||||||
|
case CAM_SEL_TIMEOUT:
|
||||||
|
new_status = DID_NO_CONNECT;
|
||||||
|
break;
|
||||||
|
case CAM_SCSI_BUS_RESET:
|
||||||
|
case CAM_BDR_SENT:
|
||||||
|
new_status = DID_RESET;
|
||||||
|
break;
|
||||||
|
case CAM_UNCOR_PARITY:
|
||||||
|
new_status = DID_PARITY;
|
||||||
|
do_fallback = 1;
|
||||||
|
break;
|
||||||
|
case CAM_CMD_TIMEOUT:
|
||||||
|
new_status = DID_TIME_OUT;
|
||||||
|
do_fallback = 1;
|
||||||
|
break;
|
||||||
|
case CAM_REQ_CMP_ERR:
|
||||||
|
case CAM_UNEXP_BUSFREE:
|
||||||
|
case CAM_DATA_RUN_ERR:
|
||||||
|
new_status = DID_ERROR;
|
||||||
|
do_fallback = 1;
|
||||||
|
break;
|
||||||
|
case CAM_UA_ABORT:
|
||||||
|
case CAM_NO_HBA:
|
||||||
|
case CAM_SEQUENCE_FAIL:
|
||||||
|
case CAM_CCB_LEN_ERR:
|
||||||
|
case CAM_PROVIDE_FAIL:
|
||||||
|
case CAM_REQ_TERMIO:
|
||||||
|
case CAM_UNREC_HBA_ERROR:
|
||||||
|
case CAM_REQ_TOO_BIG:
|
||||||
|
new_status = DID_ERROR;
|
||||||
|
break;
|
||||||
|
case CAM_REQUEUE_REQ:
|
||||||
|
new_status = DID_REQUEUE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* We should never get here */
|
||||||
|
new_status = DID_ERROR;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (do_fallback) {
|
||||||
|
printf("%s: device overrun (status %x) on %d:%d:%d\n",
|
||||||
|
ahd_name(ahd), status, cmd->device->channel,
|
||||||
|
cmd->device->id, cmd->device->lun);
|
||||||
|
}
|
||||||
|
|
||||||
|
ahd_cmd_set_transaction_status(cmd, new_status);
|
||||||
|
|
||||||
cmd->scsi_done(cmd);
|
cmd->scsi_done(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
ahd_linux_sem_timeout(u_long arg)
|
|
||||||
{
|
|
||||||
struct ahd_softc *ahd;
|
|
||||||
u_long s;
|
|
||||||
|
|
||||||
ahd = (struct ahd_softc *)arg;
|
|
||||||
|
|
||||||
ahd_lock(ahd, &s);
|
|
||||||
if ((ahd->platform_data->flags & AHD_SCB_UP_EH_SEM) != 0) {
|
|
||||||
ahd->platform_data->flags &= ~AHD_SCB_UP_EH_SEM;
|
|
||||||
up(&ahd->platform_data->eh_sem);
|
|
||||||
}
|
|
||||||
ahd_unlock(ahd, &s);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ahd_freeze_simq(struct ahd_softc *ahd)
|
ahd_freeze_simq(struct ahd_softc *ahd)
|
||||||
{
|
{
|
||||||
unsigned long s;
|
scsi_block_requests(ahd->platform_data->host);
|
||||||
|
|
||||||
ahd_lock(ahd, &s);
|
|
||||||
ahd->platform_data->qfrozen++;
|
|
||||||
if (ahd->platform_data->qfrozen == 1) {
|
|
||||||
scsi_block_requests(ahd->platform_data->host);
|
|
||||||
ahd_platform_abort_scbs(ahd, CAM_TARGET_WILDCARD, ALL_CHANNELS,
|
|
||||||
CAM_LUN_WILDCARD, SCB_LIST_NULL,
|
|
||||||
ROLE_INITIATOR, CAM_REQUEUE_REQ);
|
|
||||||
}
|
|
||||||
ahd_unlock(ahd, &s);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ahd_release_simq(struct ahd_softc *ahd)
|
ahd_release_simq(struct ahd_softc *ahd)
|
||||||
{
|
{
|
||||||
u_long s;
|
scsi_unblock_requests(ahd->platform_data->host);
|
||||||
int unblock_reqs;
|
|
||||||
|
|
||||||
unblock_reqs = 0;
|
|
||||||
ahd_lock(ahd, &s);
|
|
||||||
if (ahd->platform_data->qfrozen > 0)
|
|
||||||
ahd->platform_data->qfrozen--;
|
|
||||||
if (ahd->platform_data->qfrozen == 0) {
|
|
||||||
unblock_reqs = 1;
|
|
||||||
}
|
|
||||||
ahd_unlock(ahd, &s);
|
|
||||||
/*
|
|
||||||
* There is still a race here. The mid-layer
|
|
||||||
* should keep its own freeze count and use
|
|
||||||
* a bottom half handler to run the queues
|
|
||||||
* so we can unblock with our own lock held.
|
|
||||||
*/
|
|
||||||
if (unblock_reqs)
|
|
||||||
scsi_unblock_requests(ahd->platform_data->host);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ahd_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
|
ahd_linux_queue_abort_cmd(struct scsi_cmnd *cmd)
|
||||||
{
|
{
|
||||||
struct ahd_softc *ahd;
|
struct ahd_softc *ahd;
|
||||||
struct ahd_linux_device *dev;
|
struct ahd_linux_device *dev;
|
||||||
|
@ -2102,7 +2105,6 @@ ahd_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
|
||||||
int paused;
|
int paused;
|
||||||
int wait;
|
int wait;
|
||||||
int disconnected;
|
int disconnected;
|
||||||
int found;
|
|
||||||
ahd_mode_state saved_modes;
|
ahd_mode_state saved_modes;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
|
@ -2112,8 +2114,7 @@ ahd_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
|
||||||
ahd = *(struct ahd_softc **)cmd->device->host->hostdata;
|
ahd = *(struct ahd_softc **)cmd->device->host->hostdata;
|
||||||
|
|
||||||
scmd_printk(KERN_INFO, cmd,
|
scmd_printk(KERN_INFO, cmd,
|
||||||
"Attempting to queue a%s message:",
|
"Attempting to queue an ABORT message:");
|
||||||
flag == SCB_ABORT ? "n ABORT" : " TARGET RESET");
|
|
||||||
|
|
||||||
printf("CDB:");
|
printf("CDB:");
|
||||||
for (cdb_byte = 0; cdb_byte < cmd->cmd_len; cdb_byte++)
|
for (cdb_byte = 0; cdb_byte < cmd->cmd_len; cdb_byte++)
|
||||||
|
@ -2149,19 +2150,6 @@ ahd_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pending_scb == NULL && flag == SCB_DEVICE_RESET) {
|
|
||||||
|
|
||||||
/* Any SCB for this device will do for a target reset */
|
|
||||||
LIST_FOREACH(pending_scb, &ahd->pending_scbs, pending_links) {
|
|
||||||
if (ahd_match_scb(ahd, pending_scb,
|
|
||||||
scmd_id(cmd),
|
|
||||||
scmd_channel(cmd) + 'A',
|
|
||||||
CAM_LUN_WILDCARD,
|
|
||||||
SCB_LIST_NULL, ROLE_INITIATOR))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pending_scb == NULL) {
|
if (pending_scb == NULL) {
|
||||||
scmd_printk(KERN_INFO, cmd, "Command not found\n");
|
scmd_printk(KERN_INFO, cmd, "Command not found\n");
|
||||||
goto no_cmd;
|
goto no_cmd;
|
||||||
|
@ -2195,25 +2183,17 @@ ahd_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
|
||||||
ahd_dump_card_state(ahd);
|
ahd_dump_card_state(ahd);
|
||||||
|
|
||||||
disconnected = TRUE;
|
disconnected = TRUE;
|
||||||
if (flag == SCB_ABORT) {
|
if (ahd_search_qinfifo(ahd, cmd->device->id,
|
||||||
if (ahd_search_qinfifo(ahd, cmd->device->id,
|
cmd->device->channel + 'A',
|
||||||
cmd->device->channel + 'A',
|
cmd->device->lun,
|
||||||
cmd->device->lun,
|
pending_scb->hscb->tag,
|
||||||
pending_scb->hscb->tag,
|
ROLE_INITIATOR, CAM_REQ_ABORTED,
|
||||||
ROLE_INITIATOR, CAM_REQ_ABORTED,
|
SEARCH_COMPLETE) > 0) {
|
||||||
SEARCH_COMPLETE) > 0) {
|
printf("%s:%d:%d:%d: Cmd aborted from QINFIFO\n",
|
||||||
printf("%s:%d:%d:%d: Cmd aborted from QINFIFO\n",
|
ahd_name(ahd), cmd->device->channel,
|
||||||
ahd_name(ahd), cmd->device->channel,
|
cmd->device->id, cmd->device->lun);
|
||||||
cmd->device->id, cmd->device->lun);
|
retval = SUCCESS;
|
||||||
retval = SUCCESS;
|
goto done;
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
} else if (ahd_search_qinfifo(ahd, cmd->device->id,
|
|
||||||
cmd->device->channel + 'A',
|
|
||||||
cmd->device->lun, pending_scb->hscb->tag,
|
|
||||||
ROLE_INITIATOR, /*status*/0,
|
|
||||||
SEARCH_COUNT) > 0) {
|
|
||||||
disconnected = FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
saved_modes = ahd_save_modes(ahd);
|
saved_modes = ahd_save_modes(ahd);
|
||||||
|
@ -2221,17 +2201,12 @@ ahd_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
|
||||||
last_phase = ahd_inb(ahd, LASTPHASE);
|
last_phase = ahd_inb(ahd, LASTPHASE);
|
||||||
saved_scbptr = ahd_get_scbptr(ahd);
|
saved_scbptr = ahd_get_scbptr(ahd);
|
||||||
active_scbptr = saved_scbptr;
|
active_scbptr = saved_scbptr;
|
||||||
if (disconnected && ((last_phase != P_BUSFREE) ||
|
if (disconnected && (ahd_inb(ahd, SEQ_FLAGS) & NOT_IDENTIFIED) == 0) {
|
||||||
(ahd_inb(ahd, SEQ_FLAGS) & NOT_IDENTIFIED) == 0)) {
|
|
||||||
struct scb *bus_scb;
|
struct scb *bus_scb;
|
||||||
|
|
||||||
bus_scb = ahd_lookup_scb(ahd, active_scbptr);
|
bus_scb = ahd_lookup_scb(ahd, active_scbptr);
|
||||||
if (bus_scb == pending_scb)
|
if (bus_scb == pending_scb)
|
||||||
disconnected = FALSE;
|
disconnected = FALSE;
|
||||||
else if (flag != SCB_ABORT
|
|
||||||
&& ahd_inb(ahd, SAVED_SCSIID) == pending_scb->hscb->scsiid
|
|
||||||
&& ahd_inb(ahd, SAVED_LUN) == SCB_GET_LUN(pending_scb))
|
|
||||||
disconnected = FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2240,41 +2215,26 @@ ahd_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
|
||||||
* bus or is in the disconnected state.
|
* bus or is in the disconnected state.
|
||||||
*/
|
*/
|
||||||
saved_scsiid = ahd_inb(ahd, SAVED_SCSIID);
|
saved_scsiid = ahd_inb(ahd, SAVED_SCSIID);
|
||||||
if (SCB_GET_TAG(pending_scb) == active_scbptr
|
if (last_phase != P_BUSFREE
|
||||||
|| (flag == SCB_DEVICE_RESET
|
&& SCB_GET_TAG(pending_scb) == active_scbptr) {
|
||||||
&& SCSIID_TARGET(ahd, saved_scsiid) == scmd_id(cmd))) {
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We're active on the bus, so assert ATN
|
* We're active on the bus, so assert ATN
|
||||||
* and hope that the target responds.
|
* and hope that the target responds.
|
||||||
*/
|
*/
|
||||||
pending_scb = ahd_lookup_scb(ahd, active_scbptr);
|
pending_scb = ahd_lookup_scb(ahd, active_scbptr);
|
||||||
pending_scb->flags |= SCB_RECOVERY_SCB|SCB_DEVICE_RESET;
|
pending_scb->flags |= SCB_RECOVERY_SCB|SCB_ABORT;
|
||||||
ahd_outb(ahd, MSG_OUT, HOST_MSG);
|
ahd_outb(ahd, MSG_OUT, HOST_MSG);
|
||||||
ahd_outb(ahd, SCSISIGO, last_phase|ATNO);
|
ahd_outb(ahd, SCSISIGO, last_phase|ATNO);
|
||||||
scmd_printk(KERN_INFO, cmd, "BDR message in message buffer\n");
|
scmd_printk(KERN_INFO, cmd, "Device is active, asserting ATN\n");
|
||||||
wait = TRUE;
|
wait = TRUE;
|
||||||
} else if (last_phase != P_BUSFREE
|
|
||||||
&& ahd_inb(ahd, SCSIPHASE) == 0) {
|
|
||||||
/*
|
|
||||||
* SCB is not identified, there
|
|
||||||
* is no pending REQ, and the sequencer
|
|
||||||
* has not seen a busfree. Looks like
|
|
||||||
* a stuck connection waiting to
|
|
||||||
* go busfree. Reset the bus.
|
|
||||||
*/
|
|
||||||
found = ahd_reset_channel(ahd, cmd->device->channel + 'A',
|
|
||||||
/*Initiate Reset*/TRUE);
|
|
||||||
printf("%s: Issued Channel %c Bus Reset. "
|
|
||||||
"%d SCBs aborted\n", ahd_name(ahd),
|
|
||||||
cmd->device->channel + 'A', found);
|
|
||||||
} else if (disconnected) {
|
} else if (disconnected) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Actually re-queue this SCB in an attempt
|
* Actually re-queue this SCB in an attempt
|
||||||
* to select the device before it reconnects.
|
* to select the device before it reconnects.
|
||||||
*/
|
*/
|
||||||
pending_scb->flags |= SCB_RECOVERY_SCB|flag;
|
pending_scb->flags |= SCB_RECOVERY_SCB|SCB_ABORT;
|
||||||
ahd_set_scbptr(ahd, SCB_GET_TAG(pending_scb));
|
ahd_set_scbptr(ahd, SCB_GET_TAG(pending_scb));
|
||||||
pending_scb->hscb->cdb_len = 0;
|
pending_scb->hscb->cdb_len = 0;
|
||||||
pending_scb->hscb->task_attribute = 0;
|
pending_scb->hscb->task_attribute = 0;
|
||||||
|
@ -2344,30 +2304,29 @@ done:
|
||||||
if (paused)
|
if (paused)
|
||||||
ahd_unpause(ahd);
|
ahd_unpause(ahd);
|
||||||
if (wait) {
|
if (wait) {
|
||||||
struct timer_list timer;
|
DECLARE_COMPLETION(done);
|
||||||
int ret;
|
|
||||||
|
|
||||||
ahd->platform_data->flags |= AHD_SCB_UP_EH_SEM;
|
ahd->platform_data->eh_done = &done;
|
||||||
ahd_unlock(ahd, &flags);
|
ahd_unlock(ahd, &flags);
|
||||||
|
|
||||||
init_timer(&timer);
|
|
||||||
timer.data = (u_long)ahd;
|
|
||||||
timer.expires = jiffies + (5 * HZ);
|
|
||||||
timer.function = ahd_linux_sem_timeout;
|
|
||||||
add_timer(&timer);
|
|
||||||
printf("%s: Recovery code sleeping\n", ahd_name(ahd));
|
printf("%s: Recovery code sleeping\n", ahd_name(ahd));
|
||||||
down(&ahd->platform_data->eh_sem);
|
if (!wait_for_completion_timeout(&done, 5 * HZ)) {
|
||||||
printf("%s: Recovery code awake\n", ahd_name(ahd));
|
ahd_lock(ahd, &flags);
|
||||||
ret = del_timer_sync(&timer);
|
ahd->platform_data->eh_done = NULL;
|
||||||
if (ret == 0) {
|
ahd_unlock(ahd, &flags);
|
||||||
printf("%s: Timer Expired (active %d)\n",
|
printf("%s: Timer Expired (active %d)\n",
|
||||||
ahd_name(ahd), dev->active);
|
ahd_name(ahd), dev->active);
|
||||||
retval = FAILED;
|
retval = FAILED;
|
||||||
}
|
}
|
||||||
|
printf("Recovery code awake\n");
|
||||||
} else
|
} else
|
||||||
ahd_unlock(ahd, &flags);
|
ahd_unlock(ahd, &flags);
|
||||||
|
|
||||||
return (retval);
|
if (retval != SUCCESS)
|
||||||
|
printf("%s: Command abort returning 0x%x\n",
|
||||||
|
ahd_name(ahd), retval);
|
||||||
|
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ahd_linux_set_width(struct scsi_target *starget, int width)
|
static void ahd_linux_set_width(struct scsi_target *starget, int width)
|
||||||
|
|
|
@ -381,15 +381,12 @@ struct ahd_platform_data {
|
||||||
struct scsi_target *starget[AHD_NUM_TARGETS];
|
struct scsi_target *starget[AHD_NUM_TARGETS];
|
||||||
|
|
||||||
spinlock_t spin_lock;
|
spinlock_t spin_lock;
|
||||||
u_int qfrozen;
|
struct completion *eh_done;
|
||||||
struct semaphore eh_sem;
|
|
||||||
struct Scsi_Host *host; /* pointer to scsi host */
|
struct Scsi_Host *host; /* pointer to scsi host */
|
||||||
#define AHD_LINUX_NOIRQ ((uint32_t)~0)
|
#define AHD_LINUX_NOIRQ ((uint32_t)~0)
|
||||||
uint32_t irq; /* IRQ for this adapter */
|
uint32_t irq; /* IRQ for this adapter */
|
||||||
uint32_t bios_address;
|
uint32_t bios_address;
|
||||||
uint32_t mem_busaddr; /* Mem Base Addr */
|
uint32_t mem_busaddr; /* Mem Base Addr */
|
||||||
#define AHD_SCB_UP_EH_SEM 0x1
|
|
||||||
uint32_t flags;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/************************** OS Utility Wrappers *******************************/
|
/************************** OS Utility Wrappers *******************************/
|
||||||
|
@ -875,8 +872,6 @@ int ahd_platform_abort_scbs(struct ahd_softc *ahd, int target,
|
||||||
role_t role, uint32_t status);
|
role_t role, uint32_t status);
|
||||||
irqreturn_t
|
irqreturn_t
|
||||||
ahd_linux_isr(int irq, void *dev_id, struct pt_regs * regs);
|
ahd_linux_isr(int irq, void *dev_id, struct pt_regs * regs);
|
||||||
void ahd_platform_flushwork(struct ahd_softc *ahd);
|
|
||||||
int ahd_softc_comp(struct ahd_softc *, struct ahd_softc *);
|
|
||||||
void ahd_done(struct ahd_softc*, struct scb*);
|
void ahd_done(struct ahd_softc*, struct scb*);
|
||||||
void ahd_send_async(struct ahd_softc *, char channel,
|
void ahd_send_async(struct ahd_softc *, char channel,
|
||||||
u_int target, u_int lun, ac_code, void *);
|
u_int target, u_int lun, ac_code, void *);
|
||||||
|
|
|
@ -2461,11 +2461,8 @@ ahc_construct_sdtr(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
|
||||||
{
|
{
|
||||||
if (offset == 0)
|
if (offset == 0)
|
||||||
period = AHC_ASYNC_XFER_PERIOD;
|
period = AHC_ASYNC_XFER_PERIOD;
|
||||||
ahc->msgout_buf[ahc->msgout_index++] = MSG_EXTENDED;
|
ahc->msgout_index += spi_populate_sync_msg(
|
||||||
ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_SDTR_LEN;
|
ahc->msgout_buf + ahc->msgout_index, period, offset);
|
||||||
ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_SDTR;
|
|
||||||
ahc->msgout_buf[ahc->msgout_index++] = period;
|
|
||||||
ahc->msgout_buf[ahc->msgout_index++] = offset;
|
|
||||||
ahc->msgout_len += 5;
|
ahc->msgout_len += 5;
|
||||||
if (bootverbose) {
|
if (bootverbose) {
|
||||||
printf("(%s:%c:%d:%d): Sending SDTR period %x, offset %x\n",
|
printf("(%s:%c:%d:%d): Sending SDTR period %x, offset %x\n",
|
||||||
|
@ -2482,10 +2479,8 @@ static void
|
||||||
ahc_construct_wdtr(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
|
ahc_construct_wdtr(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
|
||||||
u_int bus_width)
|
u_int bus_width)
|
||||||
{
|
{
|
||||||
ahc->msgout_buf[ahc->msgout_index++] = MSG_EXTENDED;
|
ahc->msgout_index += spi_populate_width_msg(
|
||||||
ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_WDTR_LEN;
|
ahc->msgout_buf + ahc->msgout_index, bus_width);
|
||||||
ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_WDTR;
|
|
||||||
ahc->msgout_buf[ahc->msgout_index++] = bus_width;
|
|
||||||
ahc->msgout_len += 4;
|
ahc->msgout_len += 4;
|
||||||
if (bootverbose) {
|
if (bootverbose) {
|
||||||
printf("(%s:%c:%d:%d): Sending WDTR %x\n",
|
printf("(%s:%c:%d:%d): Sending WDTR %x\n",
|
||||||
|
@ -2505,14 +2500,9 @@ ahc_construct_ppr(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
|
||||||
{
|
{
|
||||||
if (offset == 0)
|
if (offset == 0)
|
||||||
period = AHC_ASYNC_XFER_PERIOD;
|
period = AHC_ASYNC_XFER_PERIOD;
|
||||||
ahc->msgout_buf[ahc->msgout_index++] = MSG_EXTENDED;
|
ahc->msgout_index += spi_populate_ppr_msg(
|
||||||
ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_PPR_LEN;
|
ahc->msgout_buf + ahc->msgout_index, period, offset,
|
||||||
ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_PPR;
|
bus_width, ppr_options);
|
||||||
ahc->msgout_buf[ahc->msgout_index++] = period;
|
|
||||||
ahc->msgout_buf[ahc->msgout_index++] = 0;
|
|
||||||
ahc->msgout_buf[ahc->msgout_index++] = offset;
|
|
||||||
ahc->msgout_buf[ahc->msgout_index++] = bus_width;
|
|
||||||
ahc->msgout_buf[ahc->msgout_index++] = ppr_options;
|
|
||||||
ahc->msgout_len += 8;
|
ahc->msgout_len += 8;
|
||||||
if (bootverbose) {
|
if (bootverbose) {
|
||||||
printf("(%s:%c:%d:%d): Sending PPR bus_width %x, period %x, "
|
printf("(%s:%c:%d:%d): Sending PPR bus_width %x, period %x, "
|
||||||
|
|
|
@ -373,7 +373,6 @@ static void ahc_linux_handle_scsi_status(struct ahc_softc *,
|
||||||
struct scb *);
|
struct scb *);
|
||||||
static void ahc_linux_queue_cmd_complete(struct ahc_softc *ahc,
|
static void ahc_linux_queue_cmd_complete(struct ahc_softc *ahc,
|
||||||
struct scsi_cmnd *cmd);
|
struct scsi_cmnd *cmd);
|
||||||
static void ahc_linux_sem_timeout(u_long arg);
|
|
||||||
static void ahc_linux_freeze_simq(struct ahc_softc *ahc);
|
static void ahc_linux_freeze_simq(struct ahc_softc *ahc);
|
||||||
static void ahc_linux_release_simq(struct ahc_softc *ahc);
|
static void ahc_linux_release_simq(struct ahc_softc *ahc);
|
||||||
static int ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag);
|
static int ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag);
|
||||||
|
@ -1193,7 +1192,6 @@ ahc_platform_alloc(struct ahc_softc *ahc, void *platform_arg)
|
||||||
memset(ahc->platform_data, 0, sizeof(struct ahc_platform_data));
|
memset(ahc->platform_data, 0, sizeof(struct ahc_platform_data));
|
||||||
ahc->platform_data->irq = AHC_LINUX_NOIRQ;
|
ahc->platform_data->irq = AHC_LINUX_NOIRQ;
|
||||||
ahc_lockinit(ahc);
|
ahc_lockinit(ahc);
|
||||||
init_MUTEX_LOCKED(&ahc->platform_data->eh_sem);
|
|
||||||
ahc->seltime = (aic7xxx_seltime & 0x3) << 4;
|
ahc->seltime = (aic7xxx_seltime & 0x3) << 4;
|
||||||
ahc->seltime_b = (aic7xxx_seltime & 0x3) << 4;
|
ahc->seltime_b = (aic7xxx_seltime & 0x3) << 4;
|
||||||
if (aic7xxx_pci_parity == 0)
|
if (aic7xxx_pci_parity == 0)
|
||||||
|
@ -1830,10 +1828,9 @@ ahc_done(struct ahc_softc *ahc, struct scb *scb)
|
||||||
if (ahc_get_transaction_status(scb) == CAM_BDR_SENT
|
if (ahc_get_transaction_status(scb) == CAM_BDR_SENT
|
||||||
|| ahc_get_transaction_status(scb) == CAM_REQ_ABORTED)
|
|| ahc_get_transaction_status(scb) == CAM_REQ_ABORTED)
|
||||||
ahc_set_transaction_status(scb, CAM_CMD_TIMEOUT);
|
ahc_set_transaction_status(scb, CAM_CMD_TIMEOUT);
|
||||||
if ((ahc->platform_data->flags & AHC_UP_EH_SEMAPHORE) != 0) {
|
|
||||||
ahc->platform_data->flags &= ~AHC_UP_EH_SEMAPHORE;
|
if (ahc->platform_data->eh_done)
|
||||||
up(&ahc->platform_data->eh_sem);
|
complete(ahc->platform_data->eh_done);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ahc_free_scb(ahc, scb);
|
ahc_free_scb(ahc, scb);
|
||||||
|
@ -2039,22 +2036,6 @@ ahc_linux_queue_cmd_complete(struct ahc_softc *ahc, struct scsi_cmnd *cmd)
|
||||||
cmd->scsi_done(cmd);
|
cmd->scsi_done(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
ahc_linux_sem_timeout(u_long arg)
|
|
||||||
{
|
|
||||||
struct ahc_softc *ahc;
|
|
||||||
u_long s;
|
|
||||||
|
|
||||||
ahc = (struct ahc_softc *)arg;
|
|
||||||
|
|
||||||
ahc_lock(ahc, &s);
|
|
||||||
if ((ahc->platform_data->flags & AHC_UP_EH_SEMAPHORE) != 0) {
|
|
||||||
ahc->platform_data->flags &= ~AHC_UP_EH_SEMAPHORE;
|
|
||||||
up(&ahc->platform_data->eh_sem);
|
|
||||||
}
|
|
||||||
ahc_unlock(ahc, &s);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ahc_linux_freeze_simq(struct ahc_softc *ahc)
|
ahc_linux_freeze_simq(struct ahc_softc *ahc)
|
||||||
{
|
{
|
||||||
|
@ -2355,25 +2336,21 @@ done:
|
||||||
if (paused)
|
if (paused)
|
||||||
ahc_unpause(ahc);
|
ahc_unpause(ahc);
|
||||||
if (wait) {
|
if (wait) {
|
||||||
struct timer_list timer;
|
DECLARE_COMPLETION(done);
|
||||||
int ret;
|
|
||||||
|
|
||||||
ahc->platform_data->flags |= AHC_UP_EH_SEMAPHORE;
|
ahc->platform_data->eh_done = &done;
|
||||||
ahc_unlock(ahc, &flags);
|
ahc_unlock(ahc, &flags);
|
||||||
|
|
||||||
init_timer(&timer);
|
|
||||||
timer.data = (u_long)ahc;
|
|
||||||
timer.expires = jiffies + (5 * HZ);
|
|
||||||
timer.function = ahc_linux_sem_timeout;
|
|
||||||
add_timer(&timer);
|
|
||||||
printf("Recovery code sleeping\n");
|
printf("Recovery code sleeping\n");
|
||||||
down(&ahc->platform_data->eh_sem);
|
if (!wait_for_completion_timeout(&done, 5 * HZ)) {
|
||||||
printf("Recovery code awake\n");
|
ahc_lock(ahc, &flags);
|
||||||
ret = del_timer_sync(&timer);
|
ahc->platform_data->eh_done = NULL;
|
||||||
if (ret == 0) {
|
ahc_unlock(ahc, &flags);
|
||||||
|
|
||||||
printf("Timer Expired\n");
|
printf("Timer Expired\n");
|
||||||
retval = FAILED;
|
retval = FAILED;
|
||||||
}
|
}
|
||||||
|
printf("Recovery code awake\n");
|
||||||
} else
|
} else
|
||||||
ahc_unlock(ahc, &flags);
|
ahc_unlock(ahc, &flags);
|
||||||
return (retval);
|
return (retval);
|
||||||
|
|
|
@ -369,15 +369,12 @@ struct ahc_platform_data {
|
||||||
|
|
||||||
spinlock_t spin_lock;
|
spinlock_t spin_lock;
|
||||||
u_int qfrozen;
|
u_int qfrozen;
|
||||||
struct semaphore eh_sem;
|
struct completion *eh_done;
|
||||||
struct Scsi_Host *host; /* pointer to scsi host */
|
struct Scsi_Host *host; /* pointer to scsi host */
|
||||||
#define AHC_LINUX_NOIRQ ((uint32_t)~0)
|
#define AHC_LINUX_NOIRQ ((uint32_t)~0)
|
||||||
uint32_t irq; /* IRQ for this adapter */
|
uint32_t irq; /* IRQ for this adapter */
|
||||||
uint32_t bios_address;
|
uint32_t bios_address;
|
||||||
uint32_t mem_busaddr; /* Mem Base Addr */
|
uint32_t mem_busaddr; /* Mem Base Addr */
|
||||||
|
|
||||||
#define AHC_UP_EH_SEMAPHORE 0x1
|
|
||||||
uint32_t flags;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/************************** OS Utility Wrappers *******************************/
|
/************************** OS Utility Wrappers *******************************/
|
||||||
|
|
|
@ -209,7 +209,6 @@ static struct scsi_host_template piix_sht = {
|
||||||
.name = DRV_NAME,
|
.name = DRV_NAME,
|
||||||
.ioctl = ata_scsi_ioctl,
|
.ioctl = ata_scsi_ioctl,
|
||||||
.queuecommand = ata_scsi_queuecmd,
|
.queuecommand = ata_scsi_queuecmd,
|
||||||
.eh_timed_out = ata_scsi_timed_out,
|
|
||||||
.eh_strategy_handler = ata_scsi_error,
|
.eh_strategy_handler = ata_scsi_error,
|
||||||
.can_queue = ATA_DEF_QUEUE,
|
.can_queue = ATA_DEF_QUEUE,
|
||||||
.this_id = ATA_SHT_THIS_ID,
|
.this_id = ATA_SHT_THIS_ID,
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
MODULE_DESCRIPTION("device driver for scsi media changer devices");
|
MODULE_DESCRIPTION("device driver for scsi media changer devices");
|
||||||
MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org>");
|
MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org>");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
MODULE_ALIAS_CHARDEV_MAJOR(SCSI_CHANGER_MAJOR);
|
||||||
|
|
||||||
static int init = 1;
|
static int init = 1;
|
||||||
module_param(init, int, 0444);
|
module_param(init, int, 0444);
|
||||||
|
|
|
@ -116,7 +116,7 @@ static int __devinit dmx3191d_probe_one(struct pci_dev *pdev,
|
||||||
out_free_irq:
|
out_free_irq:
|
||||||
free_irq(shost->irq, shost);
|
free_irq(shost->irq, shost);
|
||||||
out_release_region:
|
out_release_region:
|
||||||
release_region(shost->io_port, DMX3191D_REGION_LEN);
|
release_region(io, DMX3191D_REGION_LEN);
|
||||||
out_disable_device:
|
out_disable_device:
|
||||||
pci_disable_device(pdev);
|
pci_disable_device(pdev);
|
||||||
out:
|
out:
|
||||||
|
|
|
@ -306,10 +306,9 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
|
||||||
dump_stack();
|
dump_stack();
|
||||||
}
|
}
|
||||||
|
|
||||||
shost = kmalloc(sizeof(struct Scsi_Host) + privsize, gfp_mask);
|
shost = kzalloc(sizeof(struct Scsi_Host) + privsize, gfp_mask);
|
||||||
if (!shost)
|
if (!shost)
|
||||||
return NULL;
|
return NULL;
|
||||||
memset(shost, 0, sizeof(struct Scsi_Host) + privsize);
|
|
||||||
|
|
||||||
spin_lock_init(&shost->default_lock);
|
spin_lock_init(&shost->default_lock);
|
||||||
scsi_assign_lock(shost, &shost->default_lock);
|
scsi_assign_lock(shost, &shost->default_lock);
|
||||||
|
|
|
@ -2412,8 +2412,7 @@ static int ibmmca_proc_info(struct Scsi_Host *shpnt, char *buffer, char **start,
|
||||||
spin_lock_irqsave(hosts[i]->host_lock, flags); /* Check it */
|
spin_lock_irqsave(hosts[i]->host_lock, flags); /* Check it */
|
||||||
host_index = i;
|
host_index = i;
|
||||||
if (!shpnt) {
|
if (!shpnt) {
|
||||||
len += sprintf(buffer + len, "\nIBM MCA SCSI: Can't find adapter for host number %d\n",
|
len += sprintf(buffer + len, "\nIBM MCA SCSI: Can't find adapter");
|
||||||
shpnt->host_no);
|
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
max_pun = subsystem_maxid(host_index);
|
max_pun = subsystem_maxid(host_index);
|
||||||
|
|
|
@ -5830,6 +5830,109 @@ static void ipr_initiate_ioa_reset(struct ipr_ioa_cfg *ioa_cfg,
|
||||||
shutdown_type);
|
shutdown_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ipr_reset_freeze - Hold off all I/O activity
|
||||||
|
* @ipr_cmd: ipr command struct
|
||||||
|
*
|
||||||
|
* Description: If the PCI slot is frozen, hold off all I/O
|
||||||
|
* activity; then, as soon as the slot is available again,
|
||||||
|
* initiate an adapter reset.
|
||||||
|
*/
|
||||||
|
static int ipr_reset_freeze(struct ipr_cmnd *ipr_cmd)
|
||||||
|
{
|
||||||
|
/* Disallow new interrupts, avoid loop */
|
||||||
|
ipr_cmd->ioa_cfg->allow_interrupts = 0;
|
||||||
|
list_add_tail(&ipr_cmd->queue, &ipr_cmd->ioa_cfg->pending_q);
|
||||||
|
ipr_cmd->done = ipr_reset_ioa_job;
|
||||||
|
return IPR_RC_JOB_RETURN;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ipr_pci_frozen - Called when slot has experienced a PCI bus error.
|
||||||
|
* @pdev: PCI device struct
|
||||||
|
*
|
||||||
|
* Description: This routine is called to tell us that the PCI bus
|
||||||
|
* is down. Can't do anything here, except put the device driver
|
||||||
|
* into a holding pattern, waiting for the PCI bus to come back.
|
||||||
|
*/
|
||||||
|
static void ipr_pci_frozen(struct pci_dev *pdev)
|
||||||
|
{
|
||||||
|
unsigned long flags = 0;
|
||||||
|
struct ipr_ioa_cfg *ioa_cfg = pci_get_drvdata(pdev);
|
||||||
|
|
||||||
|
spin_lock_irqsave(ioa_cfg->host->host_lock, flags);
|
||||||
|
_ipr_initiate_ioa_reset(ioa_cfg, ipr_reset_freeze, IPR_SHUTDOWN_NONE);
|
||||||
|
spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ipr_pci_slot_reset - Called when PCI slot has been reset.
|
||||||
|
* @pdev: PCI device struct
|
||||||
|
*
|
||||||
|
* Description: This routine is called by the pci error recovery
|
||||||
|
* code after the PCI slot has been reset, just before we
|
||||||
|
* should resume normal operations.
|
||||||
|
*/
|
||||||
|
static pci_ers_result_t ipr_pci_slot_reset(struct pci_dev *pdev)
|
||||||
|
{
|
||||||
|
unsigned long flags = 0;
|
||||||
|
struct ipr_ioa_cfg *ioa_cfg = pci_get_drvdata(pdev);
|
||||||
|
|
||||||
|
spin_lock_irqsave(ioa_cfg->host->host_lock, flags);
|
||||||
|
_ipr_initiate_ioa_reset(ioa_cfg, ipr_reset_restore_cfg_space,
|
||||||
|
IPR_SHUTDOWN_NONE);
|
||||||
|
spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags);
|
||||||
|
return PCI_ERS_RESULT_RECOVERED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ipr_pci_perm_failure - Called when PCI slot is dead for good.
|
||||||
|
* @pdev: PCI device struct
|
||||||
|
*
|
||||||
|
* Description: This routine is called when the PCI bus has
|
||||||
|
* permanently failed.
|
||||||
|
*/
|
||||||
|
static void ipr_pci_perm_failure(struct pci_dev *pdev)
|
||||||
|
{
|
||||||
|
unsigned long flags = 0;
|
||||||
|
struct ipr_ioa_cfg *ioa_cfg = pci_get_drvdata(pdev);
|
||||||
|
|
||||||
|
spin_lock_irqsave(ioa_cfg->host->host_lock, flags);
|
||||||
|
if (ioa_cfg->sdt_state == WAIT_FOR_DUMP)
|
||||||
|
ioa_cfg->sdt_state = ABORT_DUMP;
|
||||||
|
ioa_cfg->reset_retries = IPR_NUM_RESET_RELOAD_RETRIES;
|
||||||
|
ioa_cfg->in_ioa_bringdown = 1;
|
||||||
|
ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NONE);
|
||||||
|
spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ipr_pci_error_detected - Called when a PCI error is detected.
|
||||||
|
* @pdev: PCI device struct
|
||||||
|
* @state: PCI channel state
|
||||||
|
*
|
||||||
|
* Description: Called when a PCI error is detected.
|
||||||
|
*
|
||||||
|
* Return value:
|
||||||
|
* PCI_ERS_RESULT_NEED_RESET or PCI_ERS_RESULT_DISCONNECT
|
||||||
|
*/
|
||||||
|
static pci_ers_result_t ipr_pci_error_detected(struct pci_dev *pdev,
|
||||||
|
pci_channel_state_t state)
|
||||||
|
{
|
||||||
|
switch (state) {
|
||||||
|
case pci_channel_io_frozen:
|
||||||
|
ipr_pci_frozen(pdev);
|
||||||
|
return PCI_ERS_RESULT_NEED_RESET;
|
||||||
|
case pci_channel_io_perm_failure:
|
||||||
|
ipr_pci_perm_failure(pdev);
|
||||||
|
return PCI_ERS_RESULT_DISCONNECT;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return PCI_ERS_RESULT_NEED_RESET;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ipr_probe_ioa_part2 - Initializes IOAs found in ipr_probe_ioa(..)
|
* ipr_probe_ioa_part2 - Initializes IOAs found in ipr_probe_ioa(..)
|
||||||
* @ioa_cfg: ioa cfg struct
|
* @ioa_cfg: ioa cfg struct
|
||||||
|
@ -6601,12 +6704,18 @@ static struct pci_device_id ipr_pci_table[] __devinitdata = {
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(pci, ipr_pci_table);
|
MODULE_DEVICE_TABLE(pci, ipr_pci_table);
|
||||||
|
|
||||||
|
static struct pci_error_handlers ipr_err_handler = {
|
||||||
|
.error_detected = ipr_pci_error_detected,
|
||||||
|
.slot_reset = ipr_pci_slot_reset,
|
||||||
|
};
|
||||||
|
|
||||||
static struct pci_driver ipr_driver = {
|
static struct pci_driver ipr_driver = {
|
||||||
.name = IPR_NAME,
|
.name = IPR_NAME,
|
||||||
.id_table = ipr_pci_table,
|
.id_table = ipr_pci_table,
|
||||||
.probe = ipr_probe,
|
.probe = ipr_probe,
|
||||||
.remove = ipr_remove,
|
.remove = ipr_remove,
|
||||||
.shutdown = ipr_shutdown,
|
.shutdown = ipr_shutdown,
|
||||||
|
.err_handler = &ipr_err_handler,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1146,7 +1146,7 @@ ips_queue(Scsi_Cmnd * SC, void (*done) (Scsi_Cmnd *))
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
ha->ioctl_reset = 1; /* This reset request is from an IOCTL */
|
ha->ioctl_reset = 1; /* This reset request is from an IOCTL */
|
||||||
ips_eh_reset(SC);
|
__ips_eh_reset(SC);
|
||||||
SC->result = DID_OK << 16;
|
SC->result = DID_OK << 16;
|
||||||
SC->scsi_done(SC);
|
SC->scsi_done(SC);
|
||||||
return (0);
|
return (0);
|
||||||
|
|
|
@ -52,7 +52,6 @@ static volatile unsigned char cmd_buffer[16];
|
||||||
* via PIO.
|
* via PIO.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int jazz_esp_detect(struct scsi_host_template *tpnt);
|
|
||||||
static int jazz_esp_release(struct Scsi_Host *shost)
|
static int jazz_esp_release(struct Scsi_Host *shost)
|
||||||
{
|
{
|
||||||
if (shost->irq)
|
if (shost->irq)
|
||||||
|
@ -75,7 +74,7 @@ static int jazz_esp_detect(struct scsi_host_template *tpnt)
|
||||||
* first assumption it is there:-)
|
* first assumption it is there:-)
|
||||||
*/
|
*/
|
||||||
if (1) {
|
if (1) {
|
||||||
esp_dev = 0;
|
esp_dev = NULL;
|
||||||
esp = esp_allocate(tpnt, (void *) esp_dev);
|
esp = esp_allocate(tpnt, (void *) esp_dev);
|
||||||
|
|
||||||
/* Do command transfer with programmed I/O */
|
/* Do command transfer with programmed I/O */
|
||||||
|
@ -94,13 +93,13 @@ static int jazz_esp_detect(struct scsi_host_template *tpnt)
|
||||||
esp->dma_setup = &dma_setup;
|
esp->dma_setup = &dma_setup;
|
||||||
|
|
||||||
/* Optional functions */
|
/* Optional functions */
|
||||||
esp->dma_barrier = 0;
|
esp->dma_barrier = NULL;
|
||||||
esp->dma_drain = 0;
|
esp->dma_drain = NULL;
|
||||||
esp->dma_invalidate = 0;
|
esp->dma_invalidate = NULL;
|
||||||
esp->dma_irq_entry = 0;
|
esp->dma_irq_entry = NULL;
|
||||||
esp->dma_irq_exit = 0;
|
esp->dma_irq_exit = NULL;
|
||||||
esp->dma_poll = 0;
|
esp->dma_poll = NULL;
|
||||||
esp->dma_reset = 0;
|
esp->dma_reset = NULL;
|
||||||
esp->dma_led_off = &dma_led_off;
|
esp->dma_led_off = &dma_led_off;
|
||||||
esp->dma_led_on = &dma_led_on;
|
esp->dma_led_on = &dma_led_on;
|
||||||
|
|
||||||
|
@ -120,7 +119,7 @@ static int jazz_esp_detect(struct scsi_host_template *tpnt)
|
||||||
* of DMA channel, so we can use the jazz DMA functions
|
* of DMA channel, so we can use the jazz DMA functions
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
esp->dregs = JAZZ_SCSI_DMA;
|
esp->dregs = (void *) JAZZ_SCSI_DMA;
|
||||||
|
|
||||||
/* ESP register base */
|
/* ESP register base */
|
||||||
esp->eregs = (struct ESP_regs *)(JAZZ_SCSI_BASE);
|
esp->eregs = (struct ESP_regs *)(JAZZ_SCSI_BASE);
|
||||||
|
|
|
@ -4653,6 +4653,8 @@ static struct ata_port * ata_host_add(const struct ata_probe_ent *ent,
|
||||||
if (!host)
|
if (!host)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
host->transportt = &ata_scsi_transport_template;
|
||||||
|
|
||||||
ap = (struct ata_port *) &host->hostdata[0];
|
ap = (struct ata_port *) &host->hostdata[0];
|
||||||
|
|
||||||
ata_host_init(ap, host, host_set, ent, port_no);
|
ata_host_init(ap, host, host_set, ent, port_no);
|
||||||
|
@ -5084,7 +5086,6 @@ EXPORT_SYMBOL_GPL(ata_busy_sleep);
|
||||||
EXPORT_SYMBOL_GPL(ata_port_queue_task);
|
EXPORT_SYMBOL_GPL(ata_port_queue_task);
|
||||||
EXPORT_SYMBOL_GPL(ata_scsi_ioctl);
|
EXPORT_SYMBOL_GPL(ata_scsi_ioctl);
|
||||||
EXPORT_SYMBOL_GPL(ata_scsi_queuecmd);
|
EXPORT_SYMBOL_GPL(ata_scsi_queuecmd);
|
||||||
EXPORT_SYMBOL_GPL(ata_scsi_timed_out);
|
|
||||||
EXPORT_SYMBOL_GPL(ata_scsi_error);
|
EXPORT_SYMBOL_GPL(ata_scsi_error);
|
||||||
EXPORT_SYMBOL_GPL(ata_scsi_slave_config);
|
EXPORT_SYMBOL_GPL(ata_scsi_slave_config);
|
||||||
EXPORT_SYMBOL_GPL(ata_scsi_release);
|
EXPORT_SYMBOL_GPL(ata_scsi_release);
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
#include <scsi/scsi_eh.h>
|
#include <scsi/scsi_eh.h>
|
||||||
#include <scsi/scsi_device.h>
|
#include <scsi/scsi_device.h>
|
||||||
#include <scsi/scsi_request.h>
|
#include <scsi/scsi_request.h>
|
||||||
|
#include <scsi/scsi_transport.h>
|
||||||
#include <linux/libata.h>
|
#include <linux/libata.h>
|
||||||
#include <linux/hdreg.h>
|
#include <linux/hdreg.h>
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
|
@ -52,6 +53,7 @@
|
||||||
typedef unsigned int (*ata_xlat_func_t)(struct ata_queued_cmd *qc, const u8 *scsicmd);
|
typedef unsigned int (*ata_xlat_func_t)(struct ata_queued_cmd *qc, const u8 *scsicmd);
|
||||||
static struct ata_device *
|
static struct ata_device *
|
||||||
ata_scsi_find_dev(struct ata_port *ap, const struct scsi_device *scsidev);
|
ata_scsi_find_dev(struct ata_port *ap, const struct scsi_device *scsidev);
|
||||||
|
enum scsi_eh_timer_return ata_scsi_timed_out(struct scsi_cmnd *cmd);
|
||||||
|
|
||||||
#define RW_RECOVERY_MPAGE 0x1
|
#define RW_RECOVERY_MPAGE 0x1
|
||||||
#define RW_RECOVERY_MPAGE_LEN 12
|
#define RW_RECOVERY_MPAGE_LEN 12
|
||||||
|
@ -92,6 +94,14 @@ static const u8 def_control_mpage[CONTROL_MPAGE_LEN] = {
|
||||||
0, 30 /* extended self test time, see 05-359r1 */
|
0, 30 /* extended self test time, see 05-359r1 */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* libata transport template. libata doesn't do real transport stuff.
|
||||||
|
* It just needs the eh_timed_out hook.
|
||||||
|
*/
|
||||||
|
struct scsi_transport_template ata_scsi_transport_template = {
|
||||||
|
.eh_timed_out = ata_scsi_timed_out,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
static void ata_scsi_invalid_field(struct scsi_cmnd *cmd,
|
static void ata_scsi_invalid_field(struct scsi_cmnd *cmd,
|
||||||
void (*done)(struct scsi_cmnd *))
|
void (*done)(struct scsi_cmnd *))
|
||||||
|
|
|
@ -57,6 +57,8 @@ extern int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg);
|
||||||
|
|
||||||
|
|
||||||
/* libata-scsi.c */
|
/* libata-scsi.c */
|
||||||
|
extern struct scsi_transport_template ata_scsi_transport_template;
|
||||||
|
|
||||||
extern void ata_scsi_scan_host(struct ata_port *ap);
|
extern void ata_scsi_scan_host(struct ata_port *ap);
|
||||||
extern int ata_scsi_error(struct Scsi_Host *host);
|
extern int ata_scsi_error(struct Scsi_Host *host);
|
||||||
extern unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf,
|
extern unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
* This file is part of the Emulex Linux Device Driver for *
|
* This file is part of the Emulex Linux Device Driver for *
|
||||||
* Fibre Channel Host Bus Adapters. *
|
* Fibre Channel Host Bus Adapters. *
|
||||||
* Copyright (C) 2004-2005 Emulex. All rights reserved. *
|
* Copyright (C) 2004-2006 Emulex. All rights reserved. *
|
||||||
* EMULEX and SLI are trademarks of Emulex. *
|
* EMULEX and SLI are trademarks of Emulex. *
|
||||||
* www.emulex.com *
|
* www.emulex.com *
|
||||||
* Portions Copyright (C) 2004-2005 Christoph Hellwig *
|
* Portions Copyright (C) 2004-2005 Christoph Hellwig *
|
||||||
|
@ -121,7 +121,9 @@ struct lpfc_stats {
|
||||||
uint32_t elsRcvLOGO;
|
uint32_t elsRcvLOGO;
|
||||||
uint32_t elsRcvPRLO;
|
uint32_t elsRcvPRLO;
|
||||||
uint32_t elsRcvPRLI;
|
uint32_t elsRcvPRLI;
|
||||||
uint32_t elsRcvRRQ;
|
uint32_t elsRcvLIRR;
|
||||||
|
uint32_t elsRcvRPS;
|
||||||
|
uint32_t elsRcvRPL;
|
||||||
uint32_t elsXmitFLOGI;
|
uint32_t elsXmitFLOGI;
|
||||||
uint32_t elsXmitPLOGI;
|
uint32_t elsXmitPLOGI;
|
||||||
uint32_t elsXmitPRLI;
|
uint32_t elsXmitPRLI;
|
||||||
|
@ -167,33 +169,35 @@ struct lpfc_sysfs_mbox {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct lpfc_hba {
|
struct lpfc_hba {
|
||||||
struct list_head hba_list; /* List of hbas/ports */
|
|
||||||
struct lpfc_sli sli;
|
struct lpfc_sli sli;
|
||||||
struct lpfc_sli2_slim *slim2p;
|
struct lpfc_sli2_slim *slim2p;
|
||||||
dma_addr_t slim2p_mapping;
|
dma_addr_t slim2p_mapping;
|
||||||
uint16_t pci_cfg_value;
|
uint16_t pci_cfg_value;
|
||||||
|
|
||||||
struct semaphore hba_can_block;
|
struct semaphore hba_can_block;
|
||||||
uint32_t hba_state;
|
int32_t hba_state;
|
||||||
|
|
||||||
#define LPFC_INIT_START 1 /* Initial state after board reset */
|
#define LPFC_STATE_UNKNOWN 0 /* HBA state is unknown */
|
||||||
#define LPFC_INIT_MBX_CMDS 2 /* Initialize HBA with mbox commands */
|
#define LPFC_WARM_START 1 /* HBA state after selective reset */
|
||||||
#define LPFC_LINK_DOWN 3 /* HBA initialized, link is down */
|
#define LPFC_INIT_START 2 /* Initial state after board reset */
|
||||||
#define LPFC_LINK_UP 4 /* Link is up - issue READ_LA */
|
#define LPFC_INIT_MBX_CMDS 3 /* Initialize HBA with mbox commands */
|
||||||
#define LPFC_LOCAL_CFG_LINK 5 /* local NPORT Id configured */
|
#define LPFC_LINK_DOWN 4 /* HBA initialized, link is down */
|
||||||
#define LPFC_FLOGI 6 /* FLOGI sent to Fabric */
|
#define LPFC_LINK_UP 5 /* Link is up - issue READ_LA */
|
||||||
#define LPFC_FABRIC_CFG_LINK 7 /* Fabric assigned NPORT Id
|
#define LPFC_LOCAL_CFG_LINK 6 /* local NPORT Id configured */
|
||||||
|
#define LPFC_FLOGI 7 /* FLOGI sent to Fabric */
|
||||||
|
#define LPFC_FABRIC_CFG_LINK 8 /* Fabric assigned NPORT Id
|
||||||
configured */
|
configured */
|
||||||
#define LPFC_NS_REG 8 /* Register with NameServer */
|
#define LPFC_NS_REG 9 /* Register with NameServer */
|
||||||
#define LPFC_NS_QRY 9 /* Query NameServer for NPort ID list */
|
#define LPFC_NS_QRY 10 /* Query NameServer for NPort ID list */
|
||||||
#define LPFC_BUILD_DISC_LIST 10 /* Build ADISC and PLOGI lists for
|
#define LPFC_BUILD_DISC_LIST 11 /* Build ADISC and PLOGI lists for
|
||||||
* device authentication / discovery */
|
* device authentication / discovery */
|
||||||
#define LPFC_DISC_AUTH 11 /* Processing ADISC list */
|
#define LPFC_DISC_AUTH 12 /* Processing ADISC list */
|
||||||
#define LPFC_CLEAR_LA 12 /* authentication cmplt - issue
|
#define LPFC_CLEAR_LA 13 /* authentication cmplt - issue
|
||||||
CLEAR_LA */
|
CLEAR_LA */
|
||||||
#define LPFC_HBA_READY 32
|
#define LPFC_HBA_READY 32
|
||||||
#define LPFC_HBA_ERROR 0xff
|
#define LPFC_HBA_ERROR -1
|
||||||
|
|
||||||
|
int32_t stopped; /* HBA has not been restarted since last ERATT */
|
||||||
uint8_t fc_linkspeed; /* Link speed after last READ_LA */
|
uint8_t fc_linkspeed; /* Link speed after last READ_LA */
|
||||||
|
|
||||||
uint32_t fc_eventTag; /* event tag for link attention */
|
uint32_t fc_eventTag; /* event tag for link attention */
|
||||||
|
@ -245,6 +249,7 @@ struct lpfc_hba {
|
||||||
#define FC_SCSI_SCAN_TMO 0x4000 /* scsi scan timer running */
|
#define FC_SCSI_SCAN_TMO 0x4000 /* scsi scan timer running */
|
||||||
#define FC_ABORT_DISCOVERY 0x8000 /* we want to abort discovery */
|
#define FC_ABORT_DISCOVERY 0x8000 /* we want to abort discovery */
|
||||||
#define FC_NDISC_ACTIVE 0x10000 /* NPort discovery active */
|
#define FC_NDISC_ACTIVE 0x10000 /* NPort discovery active */
|
||||||
|
#define FC_BYPASSED_MODE 0x20000 /* NPort is in bypassed mode */
|
||||||
|
|
||||||
uint32_t fc_topology; /* link topology, from LINK INIT */
|
uint32_t fc_topology; /* link topology, from LINK INIT */
|
||||||
|
|
||||||
|
@ -289,8 +294,8 @@ struct lpfc_hba {
|
||||||
uint32_t cfg_link_speed;
|
uint32_t cfg_link_speed;
|
||||||
uint32_t cfg_cr_delay;
|
uint32_t cfg_cr_delay;
|
||||||
uint32_t cfg_cr_count;
|
uint32_t cfg_cr_count;
|
||||||
|
uint32_t cfg_multi_ring_support;
|
||||||
uint32_t cfg_fdmi_on;
|
uint32_t cfg_fdmi_on;
|
||||||
uint32_t cfg_fcp_bind_method;
|
|
||||||
uint32_t cfg_discovery_threads;
|
uint32_t cfg_discovery_threads;
|
||||||
uint32_t cfg_max_luns;
|
uint32_t cfg_max_luns;
|
||||||
uint32_t cfg_poll;
|
uint32_t cfg_poll;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
* This file is part of the Emulex Linux Device Driver for *
|
* This file is part of the Emulex Linux Device Driver for *
|
||||||
* Fibre Channel Host Bus Adapters. *
|
* Fibre Channel Host Bus Adapters. *
|
||||||
* Copyright (C) 2004-2005 Emulex. All rights reserved. *
|
* Copyright (C) 2004-2006 Emulex. All rights reserved. *
|
||||||
* EMULEX and SLI are trademarks of Emulex. *
|
* EMULEX and SLI are trademarks of Emulex. *
|
||||||
* www.emulex.com *
|
* www.emulex.com *
|
||||||
* Portions Copyright (C) 2004-2005 Christoph Hellwig *
|
* Portions Copyright (C) 2004-2005 Christoph Hellwig *
|
||||||
|
@ -79,7 +79,7 @@ static ssize_t
|
||||||
lpfc_serialnum_show(struct class_device *cdev, char *buf)
|
lpfc_serialnum_show(struct class_device *cdev, char *buf)
|
||||||
{
|
{
|
||||||
struct Scsi_Host *host = class_to_shost(cdev);
|
struct Scsi_Host *host = class_to_shost(cdev);
|
||||||
struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
|
struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
|
||||||
return snprintf(buf, PAGE_SIZE, "%s\n",phba->SerialNumber);
|
return snprintf(buf, PAGE_SIZE, "%s\n",phba->SerialNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ static ssize_t
|
||||||
lpfc_modeldesc_show(struct class_device *cdev, char *buf)
|
lpfc_modeldesc_show(struct class_device *cdev, char *buf)
|
||||||
{
|
{
|
||||||
struct Scsi_Host *host = class_to_shost(cdev);
|
struct Scsi_Host *host = class_to_shost(cdev);
|
||||||
struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
|
struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
|
||||||
return snprintf(buf, PAGE_SIZE, "%s\n",phba->ModelDesc);
|
return snprintf(buf, PAGE_SIZE, "%s\n",phba->ModelDesc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@ static ssize_t
|
||||||
lpfc_modelname_show(struct class_device *cdev, char *buf)
|
lpfc_modelname_show(struct class_device *cdev, char *buf)
|
||||||
{
|
{
|
||||||
struct Scsi_Host *host = class_to_shost(cdev);
|
struct Scsi_Host *host = class_to_shost(cdev);
|
||||||
struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
|
struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
|
||||||
return snprintf(buf, PAGE_SIZE, "%s\n",phba->ModelName);
|
return snprintf(buf, PAGE_SIZE, "%s\n",phba->ModelName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,7 +103,7 @@ static ssize_t
|
||||||
lpfc_programtype_show(struct class_device *cdev, char *buf)
|
lpfc_programtype_show(struct class_device *cdev, char *buf)
|
||||||
{
|
{
|
||||||
struct Scsi_Host *host = class_to_shost(cdev);
|
struct Scsi_Host *host = class_to_shost(cdev);
|
||||||
struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
|
struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
|
||||||
return snprintf(buf, PAGE_SIZE, "%s\n",phba->ProgramType);
|
return snprintf(buf, PAGE_SIZE, "%s\n",phba->ProgramType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,7 +111,7 @@ static ssize_t
|
||||||
lpfc_portnum_show(struct class_device *cdev, char *buf)
|
lpfc_portnum_show(struct class_device *cdev, char *buf)
|
||||||
{
|
{
|
||||||
struct Scsi_Host *host = class_to_shost(cdev);
|
struct Scsi_Host *host = class_to_shost(cdev);
|
||||||
struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
|
struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
|
||||||
return snprintf(buf, PAGE_SIZE, "%s\n",phba->Port);
|
return snprintf(buf, PAGE_SIZE, "%s\n",phba->Port);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,7 +119,7 @@ static ssize_t
|
||||||
lpfc_fwrev_show(struct class_device *cdev, char *buf)
|
lpfc_fwrev_show(struct class_device *cdev, char *buf)
|
||||||
{
|
{
|
||||||
struct Scsi_Host *host = class_to_shost(cdev);
|
struct Scsi_Host *host = class_to_shost(cdev);
|
||||||
struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
|
struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
|
||||||
char fwrev[32];
|
char fwrev[32];
|
||||||
lpfc_decode_firmware_rev(phba, fwrev, 1);
|
lpfc_decode_firmware_rev(phba, fwrev, 1);
|
||||||
return snprintf(buf, PAGE_SIZE, "%s\n",fwrev);
|
return snprintf(buf, PAGE_SIZE, "%s\n",fwrev);
|
||||||
|
@ -130,7 +130,7 @@ lpfc_hdw_show(struct class_device *cdev, char *buf)
|
||||||
{
|
{
|
||||||
char hdw[9];
|
char hdw[9];
|
||||||
struct Scsi_Host *host = class_to_shost(cdev);
|
struct Scsi_Host *host = class_to_shost(cdev);
|
||||||
struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
|
struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
|
||||||
lpfc_vpd_t *vp = &phba->vpd;
|
lpfc_vpd_t *vp = &phba->vpd;
|
||||||
lpfc_jedec_to_ascii(vp->rev.biuRev, hdw);
|
lpfc_jedec_to_ascii(vp->rev.biuRev, hdw);
|
||||||
return snprintf(buf, PAGE_SIZE, "%s\n", hdw);
|
return snprintf(buf, PAGE_SIZE, "%s\n", hdw);
|
||||||
|
@ -139,16 +139,18 @@ static ssize_t
|
||||||
lpfc_option_rom_version_show(struct class_device *cdev, char *buf)
|
lpfc_option_rom_version_show(struct class_device *cdev, char *buf)
|
||||||
{
|
{
|
||||||
struct Scsi_Host *host = class_to_shost(cdev);
|
struct Scsi_Host *host = class_to_shost(cdev);
|
||||||
struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
|
struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
|
||||||
return snprintf(buf, PAGE_SIZE, "%s\n", phba->OptionROMVersion);
|
return snprintf(buf, PAGE_SIZE, "%s\n", phba->OptionROMVersion);
|
||||||
}
|
}
|
||||||
static ssize_t
|
static ssize_t
|
||||||
lpfc_state_show(struct class_device *cdev, char *buf)
|
lpfc_state_show(struct class_device *cdev, char *buf)
|
||||||
{
|
{
|
||||||
struct Scsi_Host *host = class_to_shost(cdev);
|
struct Scsi_Host *host = class_to_shost(cdev);
|
||||||
struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
|
struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
|
||||||
int len = 0;
|
int len = 0;
|
||||||
switch (phba->hba_state) {
|
switch (phba->hba_state) {
|
||||||
|
case LPFC_STATE_UNKNOWN:
|
||||||
|
case LPFC_WARM_START:
|
||||||
case LPFC_INIT_START:
|
case LPFC_INIT_START:
|
||||||
case LPFC_INIT_MBX_CMDS:
|
case LPFC_INIT_MBX_CMDS:
|
||||||
case LPFC_LINK_DOWN:
|
case LPFC_LINK_DOWN:
|
||||||
|
@ -194,7 +196,7 @@ static ssize_t
|
||||||
lpfc_num_discovered_ports_show(struct class_device *cdev, char *buf)
|
lpfc_num_discovered_ports_show(struct class_device *cdev, char *buf)
|
||||||
{
|
{
|
||||||
struct Scsi_Host *host = class_to_shost(cdev);
|
struct Scsi_Host *host = class_to_shost(cdev);
|
||||||
struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
|
struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
|
||||||
return snprintf(buf, PAGE_SIZE, "%d\n", phba->fc_map_cnt +
|
return snprintf(buf, PAGE_SIZE, "%d\n", phba->fc_map_cnt +
|
||||||
phba->fc_unmap_cnt);
|
phba->fc_unmap_cnt);
|
||||||
}
|
}
|
||||||
|
@ -203,7 +205,7 @@ lpfc_num_discovered_ports_show(struct class_device *cdev, char *buf)
|
||||||
static int
|
static int
|
||||||
lpfc_issue_lip(struct Scsi_Host *host)
|
lpfc_issue_lip(struct Scsi_Host *host)
|
||||||
{
|
{
|
||||||
struct lpfc_hba *phba = (struct lpfc_hba *) host->hostdata[0];
|
struct lpfc_hba *phba = (struct lpfc_hba *) host->hostdata;
|
||||||
LPFC_MBOXQ_t *pmboxq;
|
LPFC_MBOXQ_t *pmboxq;
|
||||||
int mbxstatus = MBXERR_ERROR;
|
int mbxstatus = MBXERR_ERROR;
|
||||||
|
|
||||||
|
@ -235,7 +237,7 @@ static ssize_t
|
||||||
lpfc_nport_evt_cnt_show(struct class_device *cdev, char *buf)
|
lpfc_nport_evt_cnt_show(struct class_device *cdev, char *buf)
|
||||||
{
|
{
|
||||||
struct Scsi_Host *host = class_to_shost(cdev);
|
struct Scsi_Host *host = class_to_shost(cdev);
|
||||||
struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
|
struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
|
||||||
return snprintf(buf, PAGE_SIZE, "%d\n", phba->nport_event_cnt);
|
return snprintf(buf, PAGE_SIZE, "%d\n", phba->nport_event_cnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -243,7 +245,7 @@ static ssize_t
|
||||||
lpfc_board_online_show(struct class_device *cdev, char *buf)
|
lpfc_board_online_show(struct class_device *cdev, char *buf)
|
||||||
{
|
{
|
||||||
struct Scsi_Host *host = class_to_shost(cdev);
|
struct Scsi_Host *host = class_to_shost(cdev);
|
||||||
struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
|
struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
|
||||||
|
|
||||||
if (phba->fc_flag & FC_OFFLINE_MODE)
|
if (phba->fc_flag & FC_OFFLINE_MODE)
|
||||||
return snprintf(buf, PAGE_SIZE, "0\n");
|
return snprintf(buf, PAGE_SIZE, "0\n");
|
||||||
|
@ -256,7 +258,7 @@ lpfc_board_online_store(struct class_device *cdev, const char *buf,
|
||||||
size_t count)
|
size_t count)
|
||||||
{
|
{
|
||||||
struct Scsi_Host *host = class_to_shost(cdev);
|
struct Scsi_Host *host = class_to_shost(cdev);
|
||||||
struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
|
struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
|
||||||
struct completion online_compl;
|
struct completion online_compl;
|
||||||
int val=0, status=0;
|
int val=0, status=0;
|
||||||
|
|
||||||
|
@ -278,11 +280,63 @@ lpfc_board_online_store(struct class_device *cdev, const char *buf,
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ssize_t
|
||||||
|
lpfc_board_mode_show(struct class_device *cdev, char *buf)
|
||||||
|
{
|
||||||
|
struct Scsi_Host *host = class_to_shost(cdev);
|
||||||
|
struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
|
||||||
|
char * state;
|
||||||
|
|
||||||
|
if (phba->hba_state == LPFC_HBA_ERROR)
|
||||||
|
state = "error";
|
||||||
|
else if (phba->hba_state == LPFC_WARM_START)
|
||||||
|
state = "warm start";
|
||||||
|
else if (phba->hba_state == LPFC_INIT_START)
|
||||||
|
state = "offline";
|
||||||
|
else
|
||||||
|
state = "online";
|
||||||
|
|
||||||
|
return snprintf(buf, PAGE_SIZE, "%s\n", state);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t
|
||||||
|
lpfc_board_mode_store(struct class_device *cdev, const char *buf, size_t count)
|
||||||
|
{
|
||||||
|
struct Scsi_Host *host = class_to_shost(cdev);
|
||||||
|
struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
|
||||||
|
struct completion online_compl;
|
||||||
|
int status=0;
|
||||||
|
|
||||||
|
init_completion(&online_compl);
|
||||||
|
|
||||||
|
if(strncmp(buf, "online", sizeof("online") - 1) == 0)
|
||||||
|
lpfc_workq_post_event(phba, &status, &online_compl,
|
||||||
|
LPFC_EVT_ONLINE);
|
||||||
|
else if (strncmp(buf, "offline", sizeof("offline") - 1) == 0)
|
||||||
|
lpfc_workq_post_event(phba, &status, &online_compl,
|
||||||
|
LPFC_EVT_OFFLINE);
|
||||||
|
else if (strncmp(buf, "warm", sizeof("warm") - 1) == 0)
|
||||||
|
lpfc_workq_post_event(phba, &status, &online_compl,
|
||||||
|
LPFC_EVT_WARM_START);
|
||||||
|
else if (strncmp(buf, "error", sizeof("error") - 1) == 0)
|
||||||
|
lpfc_workq_post_event(phba, &status, &online_compl,
|
||||||
|
LPFC_EVT_KILL);
|
||||||
|
else
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
wait_for_completion(&online_compl);
|
||||||
|
|
||||||
|
if (!status)
|
||||||
|
return strlen(buf);
|
||||||
|
else
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
static ssize_t
|
static ssize_t
|
||||||
lpfc_poll_show(struct class_device *cdev, char *buf)
|
lpfc_poll_show(struct class_device *cdev, char *buf)
|
||||||
{
|
{
|
||||||
struct Scsi_Host *host = class_to_shost(cdev);
|
struct Scsi_Host *host = class_to_shost(cdev);
|
||||||
struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
|
struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
|
||||||
|
|
||||||
return snprintf(buf, PAGE_SIZE, "%#x\n", phba->cfg_poll);
|
return snprintf(buf, PAGE_SIZE, "%#x\n", phba->cfg_poll);
|
||||||
}
|
}
|
||||||
|
@ -292,7 +346,7 @@ lpfc_poll_store(struct class_device *cdev, const char *buf,
|
||||||
size_t count)
|
size_t count)
|
||||||
{
|
{
|
||||||
struct Scsi_Host *host = class_to_shost(cdev);
|
struct Scsi_Host *host = class_to_shost(cdev);
|
||||||
struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
|
struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
|
||||||
uint32_t creg_val;
|
uint32_t creg_val;
|
||||||
uint32_t old_val;
|
uint32_t old_val;
|
||||||
int val=0;
|
int val=0;
|
||||||
|
@ -349,7 +403,7 @@ static ssize_t \
|
||||||
lpfc_##attr##_show(struct class_device *cdev, char *buf) \
|
lpfc_##attr##_show(struct class_device *cdev, char *buf) \
|
||||||
{ \
|
{ \
|
||||||
struct Scsi_Host *host = class_to_shost(cdev);\
|
struct Scsi_Host *host = class_to_shost(cdev);\
|
||||||
struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];\
|
struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;\
|
||||||
int val = 0;\
|
int val = 0;\
|
||||||
val = phba->cfg_##attr;\
|
val = phba->cfg_##attr;\
|
||||||
return snprintf(buf, PAGE_SIZE, "%d\n",\
|
return snprintf(buf, PAGE_SIZE, "%d\n",\
|
||||||
|
@ -361,7 +415,7 @@ static ssize_t \
|
||||||
lpfc_##attr##_show(struct class_device *cdev, char *buf) \
|
lpfc_##attr##_show(struct class_device *cdev, char *buf) \
|
||||||
{ \
|
{ \
|
||||||
struct Scsi_Host *host = class_to_shost(cdev);\
|
struct Scsi_Host *host = class_to_shost(cdev);\
|
||||||
struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];\
|
struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;\
|
||||||
int val = 0;\
|
int val = 0;\
|
||||||
val = phba->cfg_##attr;\
|
val = phba->cfg_##attr;\
|
||||||
return snprintf(buf, PAGE_SIZE, "%#x\n",\
|
return snprintf(buf, PAGE_SIZE, "%#x\n",\
|
||||||
|
@ -404,7 +458,7 @@ static ssize_t \
|
||||||
lpfc_##attr##_store(struct class_device *cdev, const char *buf, size_t count) \
|
lpfc_##attr##_store(struct class_device *cdev, const char *buf, size_t count) \
|
||||||
{ \
|
{ \
|
||||||
struct Scsi_Host *host = class_to_shost(cdev);\
|
struct Scsi_Host *host = class_to_shost(cdev);\
|
||||||
struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];\
|
struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;\
|
||||||
int val=0;\
|
int val=0;\
|
||||||
if (!isdigit(buf[0]))\
|
if (!isdigit(buf[0]))\
|
||||||
return -EINVAL;\
|
return -EINVAL;\
|
||||||
|
@ -480,6 +534,8 @@ static CLASS_DEVICE_ATTR(management_version, S_IRUGO, management_version_show,
|
||||||
NULL);
|
NULL);
|
||||||
static CLASS_DEVICE_ATTR(board_online, S_IRUGO | S_IWUSR,
|
static CLASS_DEVICE_ATTR(board_online, S_IRUGO | S_IWUSR,
|
||||||
lpfc_board_online_show, lpfc_board_online_store);
|
lpfc_board_online_show, lpfc_board_online_store);
|
||||||
|
static CLASS_DEVICE_ATTR(board_mode, S_IRUGO | S_IWUSR,
|
||||||
|
lpfc_board_mode_show, lpfc_board_mode_store);
|
||||||
|
|
||||||
static int lpfc_poll = 0;
|
static int lpfc_poll = 0;
|
||||||
module_param(lpfc_poll, int, 0);
|
module_param(lpfc_poll, int, 0);
|
||||||
|
@ -519,6 +575,16 @@ LPFC_ATTR_HEX_RW(log_verbose, 0x0, 0x0, 0xffff, "Verbose logging bit-mask");
|
||||||
LPFC_ATTR_R(lun_queue_depth, 30, 1, 128,
|
LPFC_ATTR_R(lun_queue_depth, 30, 1, 128,
|
||||||
"Max number of FCP commands we can queue to a specific LUN");
|
"Max number of FCP commands we can queue to a specific LUN");
|
||||||
|
|
||||||
|
/*
|
||||||
|
# hba_queue_depth: This parameter is used to limit the number of outstanding
|
||||||
|
# commands per lpfc HBA. Value range is [32,8192]. If this parameter
|
||||||
|
# value is greater than the maximum number of exchanges supported by the HBA,
|
||||||
|
# then maximum number of exchanges supported by the HBA is used to determine
|
||||||
|
# the hba_queue_depth.
|
||||||
|
*/
|
||||||
|
LPFC_ATTR_R(hba_queue_depth, 8192, 32, 8192,
|
||||||
|
"Max number of FCP commands we can queue to a lpfc HBA");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
# Some disk devices have a "select ID" or "select Target" capability.
|
# Some disk devices have a "select ID" or "select Target" capability.
|
||||||
# From a protocol standpoint "select ID" usually means select the
|
# From a protocol standpoint "select ID" usually means select the
|
||||||
|
@ -550,6 +616,7 @@ LPFC_ATTR_RW(nodev_tmo, 30, 0, 255,
|
||||||
/*
|
/*
|
||||||
# lpfc_topology: link topology for init link
|
# lpfc_topology: link topology for init link
|
||||||
# 0x0 = attempt loop mode then point-to-point
|
# 0x0 = attempt loop mode then point-to-point
|
||||||
|
# 0x01 = internal loopback mode
|
||||||
# 0x02 = attempt point-to-point mode only
|
# 0x02 = attempt point-to-point mode only
|
||||||
# 0x04 = attempt loop mode only
|
# 0x04 = attempt loop mode only
|
||||||
# 0x06 = attempt point-to-point mode then loop
|
# 0x06 = attempt point-to-point mode then loop
|
||||||
|
@ -557,7 +624,7 @@ LPFC_ATTR_RW(nodev_tmo, 30, 0, 255,
|
||||||
# Set loop mode if you want to run as an NL_Port. Value range is [0,0x6].
|
# Set loop mode if you want to run as an NL_Port. Value range is [0,0x6].
|
||||||
# Default value is 0.
|
# Default value is 0.
|
||||||
*/
|
*/
|
||||||
LPFC_ATTR_R(topology, 0, 0, 6, "Select Fibre Channel topology");
|
LPFC_ATTR_RW(topology, 0, 0, 6, "Select Fibre Channel topology");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
# lpfc_link_speed: Link speed selection for initializing the Fibre Channel
|
# lpfc_link_speed: Link speed selection for initializing the Fibre Channel
|
||||||
|
@ -597,12 +664,20 @@ LPFC_ATTR_R(ack0, 0, 0, 1, "Enable ACK0 support");
|
||||||
# is 0. Default value of cr_count is 1. The cr_count feature is disabled if
|
# is 0. Default value of cr_count is 1. The cr_count feature is disabled if
|
||||||
# cr_delay is set to 0.
|
# cr_delay is set to 0.
|
||||||
*/
|
*/
|
||||||
LPFC_ATTR_RW(cr_delay, 0, 0, 63, "A count of milliseconds after which an"
|
LPFC_ATTR_RW(cr_delay, 0, 0, 63, "A count of milliseconds after which an "
|
||||||
"interrupt response is generated");
|
"interrupt response is generated");
|
||||||
|
|
||||||
LPFC_ATTR_RW(cr_count, 1, 1, 255, "A count of I/O completions after which an"
|
LPFC_ATTR_RW(cr_count, 1, 1, 255, "A count of I/O completions after which an "
|
||||||
"interrupt response is generated");
|
"interrupt response is generated");
|
||||||
|
|
||||||
|
/*
|
||||||
|
# lpfc_multi_ring_support: Determines how many rings to spread available
|
||||||
|
# cmd/rsp IOCB entries across.
|
||||||
|
# Value range is [1,2]. Default value is 1.
|
||||||
|
*/
|
||||||
|
LPFC_ATTR_R(multi_ring_support, 1, 1, 2, "Determines number of primary "
|
||||||
|
"SLI rings to spread IOCB entries across");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
# lpfc_fdmi_on: controls FDMI support.
|
# lpfc_fdmi_on: controls FDMI support.
|
||||||
# 0 = no FDMI support
|
# 0 = no FDMI support
|
||||||
|
@ -616,7 +691,7 @@ LPFC_ATTR_RW(fdmi_on, 0, 0, 2, "Enable FDMI support");
|
||||||
# Specifies the maximum number of ELS cmds we can have outstanding (for
|
# Specifies the maximum number of ELS cmds we can have outstanding (for
|
||||||
# discovery). Value range is [1,64]. Default value = 32.
|
# discovery). Value range is [1,64]. Default value = 32.
|
||||||
*/
|
*/
|
||||||
LPFC_ATTR(discovery_threads, 32, 1, 64, "Maximum number of ELS commands"
|
LPFC_ATTR(discovery_threads, 32, 1, 64, "Maximum number of ELS commands "
|
||||||
"during discovery");
|
"during discovery");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -649,6 +724,7 @@ struct class_device_attribute *lpfc_host_attrs[] = {
|
||||||
&class_device_attr_lpfc_drvr_version,
|
&class_device_attr_lpfc_drvr_version,
|
||||||
&class_device_attr_lpfc_log_verbose,
|
&class_device_attr_lpfc_log_verbose,
|
||||||
&class_device_attr_lpfc_lun_queue_depth,
|
&class_device_attr_lpfc_lun_queue_depth,
|
||||||
|
&class_device_attr_lpfc_hba_queue_depth,
|
||||||
&class_device_attr_lpfc_nodev_tmo,
|
&class_device_attr_lpfc_nodev_tmo,
|
||||||
&class_device_attr_lpfc_fcp_class,
|
&class_device_attr_lpfc_fcp_class,
|
||||||
&class_device_attr_lpfc_use_adisc,
|
&class_device_attr_lpfc_use_adisc,
|
||||||
|
@ -658,11 +734,13 @@ struct class_device_attribute *lpfc_host_attrs[] = {
|
||||||
&class_device_attr_lpfc_link_speed,
|
&class_device_attr_lpfc_link_speed,
|
||||||
&class_device_attr_lpfc_cr_delay,
|
&class_device_attr_lpfc_cr_delay,
|
||||||
&class_device_attr_lpfc_cr_count,
|
&class_device_attr_lpfc_cr_count,
|
||||||
|
&class_device_attr_lpfc_multi_ring_support,
|
||||||
&class_device_attr_lpfc_fdmi_on,
|
&class_device_attr_lpfc_fdmi_on,
|
||||||
&class_device_attr_lpfc_max_luns,
|
&class_device_attr_lpfc_max_luns,
|
||||||
&class_device_attr_nport_evt_cnt,
|
&class_device_attr_nport_evt_cnt,
|
||||||
&class_device_attr_management_version,
|
&class_device_attr_management_version,
|
||||||
&class_device_attr_board_online,
|
&class_device_attr_board_online,
|
||||||
|
&class_device_attr_board_mode,
|
||||||
&class_device_attr_lpfc_poll,
|
&class_device_attr_lpfc_poll,
|
||||||
&class_device_attr_lpfc_poll_tmo,
|
&class_device_attr_lpfc_poll_tmo,
|
||||||
NULL,
|
NULL,
|
||||||
|
@ -674,7 +752,7 @@ sysfs_ctlreg_write(struct kobject *kobj, char *buf, loff_t off, size_t count)
|
||||||
size_t buf_off;
|
size_t buf_off;
|
||||||
struct Scsi_Host *host = class_to_shost(container_of(kobj,
|
struct Scsi_Host *host = class_to_shost(container_of(kobj,
|
||||||
struct class_device, kobj));
|
struct class_device, kobj));
|
||||||
struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
|
struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
|
||||||
|
|
||||||
if ((off + count) > FF_REG_AREA_SIZE)
|
if ((off + count) > FF_REG_AREA_SIZE)
|
||||||
return -ERANGE;
|
return -ERANGE;
|
||||||
|
@ -707,7 +785,7 @@ sysfs_ctlreg_read(struct kobject *kobj, char *buf, loff_t off, size_t count)
|
||||||
uint32_t * tmp_ptr;
|
uint32_t * tmp_ptr;
|
||||||
struct Scsi_Host *host = class_to_shost(container_of(kobj,
|
struct Scsi_Host *host = class_to_shost(container_of(kobj,
|
||||||
struct class_device, kobj));
|
struct class_device, kobj));
|
||||||
struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
|
struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
|
||||||
|
|
||||||
if (off > FF_REG_AREA_SIZE)
|
if (off > FF_REG_AREA_SIZE)
|
||||||
return -ERANGE;
|
return -ERANGE;
|
||||||
|
@ -762,7 +840,7 @@ sysfs_mbox_write(struct kobject *kobj, char *buf, loff_t off, size_t count)
|
||||||
{
|
{
|
||||||
struct Scsi_Host * host =
|
struct Scsi_Host * host =
|
||||||
class_to_shost(container_of(kobj, struct class_device, kobj));
|
class_to_shost(container_of(kobj, struct class_device, kobj));
|
||||||
struct lpfc_hba * phba = (struct lpfc_hba*)host->hostdata[0];
|
struct lpfc_hba * phba = (struct lpfc_hba*)host->hostdata;
|
||||||
struct lpfcMboxq * mbox = NULL;
|
struct lpfcMboxq * mbox = NULL;
|
||||||
|
|
||||||
if ((count + off) > MAILBOX_CMD_SIZE)
|
if ((count + off) > MAILBOX_CMD_SIZE)
|
||||||
|
@ -778,7 +856,7 @@ sysfs_mbox_write(struct kobject *kobj, char *buf, loff_t off, size_t count)
|
||||||
mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
|
mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
|
||||||
if (!mbox)
|
if (!mbox)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
memset(mbox, 0, sizeof (LPFC_MBOXQ_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_lock_irq(host->host_lock);
|
spin_lock_irq(host->host_lock);
|
||||||
|
@ -815,7 +893,7 @@ sysfs_mbox_read(struct kobject *kobj, char *buf, loff_t off, size_t count)
|
||||||
struct Scsi_Host *host =
|
struct Scsi_Host *host =
|
||||||
class_to_shost(container_of(kobj, struct class_device,
|
class_to_shost(container_of(kobj, struct class_device,
|
||||||
kobj));
|
kobj));
|
||||||
struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
|
struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (off > sizeof(MAILBOX_t))
|
if (off > sizeof(MAILBOX_t))
|
||||||
|
@ -872,8 +950,11 @@ sysfs_mbox_read(struct kobject *kobj, char *buf, loff_t off, size_t count)
|
||||||
case MBX_DUMP_MEMORY:
|
case MBX_DUMP_MEMORY:
|
||||||
case MBX_DOWN_LOAD:
|
case MBX_DOWN_LOAD:
|
||||||
case MBX_UPDATE_CFG:
|
case MBX_UPDATE_CFG:
|
||||||
|
case MBX_KILL_BOARD:
|
||||||
case MBX_LOAD_AREA:
|
case MBX_LOAD_AREA:
|
||||||
case MBX_LOAD_EXP_ROM:
|
case MBX_LOAD_EXP_ROM:
|
||||||
|
case MBX_BEACON:
|
||||||
|
case MBX_DEL_LD_ENTRY:
|
||||||
break;
|
break;
|
||||||
case MBX_READ_SPARM64:
|
case MBX_READ_SPARM64:
|
||||||
case MBX_READ_LA:
|
case MBX_READ_LA:
|
||||||
|
@ -990,7 +1071,7 @@ lpfc_free_sysfs_attr(struct lpfc_hba *phba)
|
||||||
static void
|
static void
|
||||||
lpfc_get_host_port_id(struct Scsi_Host *shost)
|
lpfc_get_host_port_id(struct Scsi_Host *shost)
|
||||||
{
|
{
|
||||||
struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata[0];
|
struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata;
|
||||||
/* note: fc_myDID already in cpu endianness */
|
/* note: fc_myDID already in cpu endianness */
|
||||||
fc_host_port_id(shost) = phba->fc_myDID;
|
fc_host_port_id(shost) = phba->fc_myDID;
|
||||||
}
|
}
|
||||||
|
@ -998,7 +1079,7 @@ lpfc_get_host_port_id(struct Scsi_Host *shost)
|
||||||
static void
|
static void
|
||||||
lpfc_get_host_port_type(struct Scsi_Host *shost)
|
lpfc_get_host_port_type(struct Scsi_Host *shost)
|
||||||
{
|
{
|
||||||
struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata[0];
|
struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata;
|
||||||
|
|
||||||
spin_lock_irq(shost->host_lock);
|
spin_lock_irq(shost->host_lock);
|
||||||
|
|
||||||
|
@ -1023,7 +1104,7 @@ lpfc_get_host_port_type(struct Scsi_Host *shost)
|
||||||
static void
|
static void
|
||||||
lpfc_get_host_port_state(struct Scsi_Host *shost)
|
lpfc_get_host_port_state(struct Scsi_Host *shost)
|
||||||
{
|
{
|
||||||
struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata[0];
|
struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata;
|
||||||
|
|
||||||
spin_lock_irq(shost->host_lock);
|
spin_lock_irq(shost->host_lock);
|
||||||
|
|
||||||
|
@ -1031,6 +1112,8 @@ lpfc_get_host_port_state(struct Scsi_Host *shost)
|
||||||
fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE;
|
fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE;
|
||||||
else {
|
else {
|
||||||
switch (phba->hba_state) {
|
switch (phba->hba_state) {
|
||||||
|
case LPFC_STATE_UNKNOWN:
|
||||||
|
case LPFC_WARM_START:
|
||||||
case LPFC_INIT_START:
|
case LPFC_INIT_START:
|
||||||
case LPFC_INIT_MBX_CMDS:
|
case LPFC_INIT_MBX_CMDS:
|
||||||
case LPFC_LINK_DOWN:
|
case LPFC_LINK_DOWN:
|
||||||
|
@ -1064,7 +1147,7 @@ lpfc_get_host_port_state(struct Scsi_Host *shost)
|
||||||
static void
|
static void
|
||||||
lpfc_get_host_speed(struct Scsi_Host *shost)
|
lpfc_get_host_speed(struct Scsi_Host *shost)
|
||||||
{
|
{
|
||||||
struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata[0];
|
struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata;
|
||||||
|
|
||||||
spin_lock_irq(shost->host_lock);
|
spin_lock_irq(shost->host_lock);
|
||||||
|
|
||||||
|
@ -1091,7 +1174,7 @@ lpfc_get_host_speed(struct Scsi_Host *shost)
|
||||||
static void
|
static void
|
||||||
lpfc_get_host_fabric_name (struct Scsi_Host *shost)
|
lpfc_get_host_fabric_name (struct Scsi_Host *shost)
|
||||||
{
|
{
|
||||||
struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata[0];
|
struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata;
|
||||||
u64 node_name;
|
u64 node_name;
|
||||||
|
|
||||||
spin_lock_irq(shost->host_lock);
|
spin_lock_irq(shost->host_lock);
|
||||||
|
@ -1113,7 +1196,7 @@ lpfc_get_host_fabric_name (struct Scsi_Host *shost)
|
||||||
static struct fc_host_statistics *
|
static struct fc_host_statistics *
|
||||||
lpfc_get_stats(struct Scsi_Host *shost)
|
lpfc_get_stats(struct Scsi_Host *shost)
|
||||||
{
|
{
|
||||||
struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata[0];
|
struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata;
|
||||||
struct lpfc_sli *psli = &phba->sli;
|
struct lpfc_sli *psli = &phba->sli;
|
||||||
struct fc_host_statistics *hs = &phba->link_stats;
|
struct fc_host_statistics *hs = &phba->link_stats;
|
||||||
LPFC_MBOXQ_t *pmboxq;
|
LPFC_MBOXQ_t *pmboxq;
|
||||||
|
@ -1203,7 +1286,7 @@ static void
|
||||||
lpfc_get_starget_port_id(struct scsi_target *starget)
|
lpfc_get_starget_port_id(struct scsi_target *starget)
|
||||||
{
|
{
|
||||||
struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
|
struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
|
||||||
struct lpfc_hba *phba = (struct lpfc_hba *) shost->hostdata[0];
|
struct lpfc_hba *phba = (struct lpfc_hba *) shost->hostdata;
|
||||||
uint32_t did = -1;
|
uint32_t did = -1;
|
||||||
struct lpfc_nodelist *ndlp = NULL;
|
struct lpfc_nodelist *ndlp = NULL;
|
||||||
|
|
||||||
|
@ -1224,7 +1307,7 @@ static void
|
||||||
lpfc_get_starget_node_name(struct scsi_target *starget)
|
lpfc_get_starget_node_name(struct scsi_target *starget)
|
||||||
{
|
{
|
||||||
struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
|
struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
|
||||||
struct lpfc_hba *phba = (struct lpfc_hba *) shost->hostdata[0];
|
struct lpfc_hba *phba = (struct lpfc_hba *) shost->hostdata;
|
||||||
u64 node_name = 0;
|
u64 node_name = 0;
|
||||||
struct lpfc_nodelist *ndlp = NULL;
|
struct lpfc_nodelist *ndlp = NULL;
|
||||||
|
|
||||||
|
@ -1245,7 +1328,7 @@ static void
|
||||||
lpfc_get_starget_port_name(struct scsi_target *starget)
|
lpfc_get_starget_port_name(struct scsi_target *starget)
|
||||||
{
|
{
|
||||||
struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
|
struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
|
||||||
struct lpfc_hba *phba = (struct lpfc_hba *) shost->hostdata[0];
|
struct lpfc_hba *phba = (struct lpfc_hba *) shost->hostdata;
|
||||||
u64 port_name = 0;
|
u64 port_name = 0;
|
||||||
struct lpfc_nodelist *ndlp = NULL;
|
struct lpfc_nodelist *ndlp = NULL;
|
||||||
|
|
||||||
|
@ -1366,6 +1449,7 @@ lpfc_get_cfgparam(struct lpfc_hba *phba)
|
||||||
lpfc_log_verbose_init(phba, lpfc_log_verbose);
|
lpfc_log_verbose_init(phba, lpfc_log_verbose);
|
||||||
lpfc_cr_delay_init(phba, lpfc_cr_delay);
|
lpfc_cr_delay_init(phba, lpfc_cr_delay);
|
||||||
lpfc_cr_count_init(phba, lpfc_cr_count);
|
lpfc_cr_count_init(phba, lpfc_cr_count);
|
||||||
|
lpfc_multi_ring_support_init(phba, lpfc_multi_ring_support);
|
||||||
lpfc_lun_queue_depth_init(phba, lpfc_lun_queue_depth);
|
lpfc_lun_queue_depth_init(phba, lpfc_lun_queue_depth);
|
||||||
lpfc_fcp_class_init(phba, lpfc_fcp_class);
|
lpfc_fcp_class_init(phba, lpfc_fcp_class);
|
||||||
lpfc_use_adisc_init(phba, lpfc_use_adisc);
|
lpfc_use_adisc_init(phba, lpfc_use_adisc);
|
||||||
|
@ -1411,5 +1495,9 @@ lpfc_get_cfgparam(struct lpfc_hba *phba)
|
||||||
default:
|
default:
|
||||||
phba->cfg_hba_queue_depth = LPFC_DFT_HBA_Q_DEPTH;
|
phba->cfg_hba_queue_depth = LPFC_DFT_HBA_Q_DEPTH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (phba->cfg_hba_queue_depth > lpfc_hba_queue_depth)
|
||||||
|
lpfc_hba_queue_depth_init(phba, lpfc_hba_queue_depth);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
* This file is part of the Emulex Linux Device Driver for *
|
* This file is part of the Emulex Linux Device Driver for *
|
||||||
* Fibre Channel Host Bus Adapters. *
|
* Fibre Channel Host Bus Adapters. *
|
||||||
* Copyright (C) 2004-2005 Emulex. All rights reserved. *
|
* Copyright (C) 2004-2006 Emulex. All rights reserved. *
|
||||||
* EMULEX and SLI are trademarks of Emulex. *
|
* EMULEX and SLI are trademarks of Emulex. *
|
||||||
* www.emulex.com *
|
* www.emulex.com *
|
||||||
* *
|
* *
|
||||||
|
@ -26,6 +26,7 @@ void lpfc_clear_la(struct lpfc_hba *, LPFC_MBOXQ_t *);
|
||||||
void lpfc_config_link(struct lpfc_hba *, LPFC_MBOXQ_t *);
|
void lpfc_config_link(struct lpfc_hba *, LPFC_MBOXQ_t *);
|
||||||
int lpfc_read_sparam(struct lpfc_hba *, LPFC_MBOXQ_t *);
|
int lpfc_read_sparam(struct lpfc_hba *, LPFC_MBOXQ_t *);
|
||||||
void lpfc_read_config(struct lpfc_hba *, LPFC_MBOXQ_t *);
|
void lpfc_read_config(struct lpfc_hba *, LPFC_MBOXQ_t *);
|
||||||
|
void lpfc_read_lnk_stat(struct lpfc_hba *, LPFC_MBOXQ_t *);
|
||||||
void lpfc_set_slim(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t, uint32_t);
|
void lpfc_set_slim(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t, uint32_t);
|
||||||
int lpfc_reg_login(struct lpfc_hba *, uint32_t, uint8_t *, LPFC_MBOXQ_t *,
|
int lpfc_reg_login(struct lpfc_hba *, uint32_t, uint8_t *, LPFC_MBOXQ_t *,
|
||||||
uint32_t);
|
uint32_t);
|
||||||
|
@ -42,9 +43,6 @@ void lpfc_mbx_cmpl_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *);
|
||||||
void lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *);
|
void lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *);
|
||||||
void lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *);
|
void lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *);
|
||||||
void lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *);
|
void lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *);
|
||||||
int lpfc_nlp_plogi(struct lpfc_hba *, struct lpfc_nodelist *);
|
|
||||||
int lpfc_nlp_adisc(struct lpfc_hba *, struct lpfc_nodelist *);
|
|
||||||
int lpfc_nlp_unmapped(struct lpfc_hba *, struct lpfc_nodelist *);
|
|
||||||
int lpfc_nlp_list(struct lpfc_hba *, struct lpfc_nodelist *, int);
|
int lpfc_nlp_list(struct lpfc_hba *, struct lpfc_nodelist *, int);
|
||||||
void lpfc_set_disctmo(struct lpfc_hba *);
|
void lpfc_set_disctmo(struct lpfc_hba *);
|
||||||
int lpfc_can_disctmo(struct lpfc_hba *);
|
int lpfc_can_disctmo(struct lpfc_hba *);
|
||||||
|
@ -54,12 +52,10 @@ int lpfc_check_sli_ndlp(struct lpfc_hba *, struct lpfc_sli_ring *,
|
||||||
int lpfc_nlp_remove(struct lpfc_hba *, struct lpfc_nodelist *);
|
int lpfc_nlp_remove(struct lpfc_hba *, struct lpfc_nodelist *);
|
||||||
void lpfc_nlp_init(struct lpfc_hba *, struct lpfc_nodelist *, uint32_t);
|
void lpfc_nlp_init(struct lpfc_hba *, struct lpfc_nodelist *, uint32_t);
|
||||||
struct lpfc_nodelist *lpfc_setup_disc_node(struct lpfc_hba *, uint32_t);
|
struct lpfc_nodelist *lpfc_setup_disc_node(struct lpfc_hba *, uint32_t);
|
||||||
struct lpfc_nodelist *lpfc_setup_rscn_node(struct lpfc_hba *, uint32_t);
|
|
||||||
void lpfc_disc_list_loopmap(struct lpfc_hba *);
|
void lpfc_disc_list_loopmap(struct lpfc_hba *);
|
||||||
void lpfc_disc_start(struct lpfc_hba *);
|
void lpfc_disc_start(struct lpfc_hba *);
|
||||||
void lpfc_disc_flush_list(struct lpfc_hba *);
|
void lpfc_disc_flush_list(struct lpfc_hba *);
|
||||||
void lpfc_disc_timeout(unsigned long);
|
void lpfc_disc_timeout(unsigned long);
|
||||||
void lpfc_scan_timeout(unsigned long);
|
|
||||||
|
|
||||||
struct lpfc_nodelist *lpfc_findnode_rpi(struct lpfc_hba * phba, uint16_t rpi);
|
struct lpfc_nodelist *lpfc_findnode_rpi(struct lpfc_hba * phba, uint16_t rpi);
|
||||||
|
|
||||||
|
@ -68,19 +64,13 @@ int lpfc_do_work(void *);
|
||||||
int lpfc_disc_state_machine(struct lpfc_hba *, struct lpfc_nodelist *, void *,
|
int lpfc_disc_state_machine(struct lpfc_hba *, struct lpfc_nodelist *, void *,
|
||||||
uint32_t);
|
uint32_t);
|
||||||
|
|
||||||
uint32_t lpfc_cmpl_prli_reglogin_issue(struct lpfc_hba *,
|
|
||||||
struct lpfc_nodelist *, void *,
|
|
||||||
uint32_t);
|
|
||||||
uint32_t lpfc_cmpl_plogi_prli_issue(struct lpfc_hba *, struct lpfc_nodelist *,
|
|
||||||
void *, uint32_t);
|
|
||||||
|
|
||||||
int lpfc_check_sparm(struct lpfc_hba *, struct lpfc_nodelist *,
|
int lpfc_check_sparm(struct lpfc_hba *, struct lpfc_nodelist *,
|
||||||
struct serv_parm *, uint32_t);
|
struct serv_parm *, uint32_t);
|
||||||
int lpfc_els_abort(struct lpfc_hba *, struct lpfc_nodelist * ndlp,
|
int lpfc_els_abort(struct lpfc_hba *, struct lpfc_nodelist * ndlp,
|
||||||
int);
|
int);
|
||||||
int lpfc_els_abort_flogi(struct lpfc_hba *);
|
int lpfc_els_abort_flogi(struct lpfc_hba *);
|
||||||
int lpfc_initial_flogi(struct lpfc_hba *);
|
int lpfc_initial_flogi(struct lpfc_hba *);
|
||||||
int lpfc_issue_els_plogi(struct lpfc_hba *, struct lpfc_nodelist *, uint8_t);
|
int lpfc_issue_els_plogi(struct lpfc_hba *, uint32_t, uint8_t);
|
||||||
int lpfc_issue_els_prli(struct lpfc_hba *, struct lpfc_nodelist *, uint8_t);
|
int lpfc_issue_els_prli(struct lpfc_hba *, struct lpfc_nodelist *, uint8_t);
|
||||||
int lpfc_issue_els_adisc(struct lpfc_hba *, struct lpfc_nodelist *, uint8_t);
|
int lpfc_issue_els_adisc(struct lpfc_hba *, struct lpfc_nodelist *, uint8_t);
|
||||||
int lpfc_issue_els_logo(struct lpfc_hba *, struct lpfc_nodelist *, uint8_t);
|
int lpfc_issue_els_logo(struct lpfc_hba *, struct lpfc_nodelist *, uint8_t);
|
||||||
|
@ -94,6 +84,7 @@ int lpfc_els_rsp_adisc_acc(struct lpfc_hba *, struct lpfc_iocbq *,
|
||||||
struct lpfc_nodelist *);
|
struct lpfc_nodelist *);
|
||||||
int lpfc_els_rsp_prli_acc(struct lpfc_hba *, struct lpfc_iocbq *,
|
int lpfc_els_rsp_prli_acc(struct lpfc_hba *, struct lpfc_iocbq *,
|
||||||
struct lpfc_nodelist *);
|
struct lpfc_nodelist *);
|
||||||
|
void lpfc_cancel_retry_delay_tmo(struct lpfc_hba *, struct lpfc_nodelist *);
|
||||||
void lpfc_els_retry_delay(unsigned long);
|
void lpfc_els_retry_delay(unsigned long);
|
||||||
void lpfc_els_retry_delay_handler(struct lpfc_nodelist *);
|
void lpfc_els_retry_delay_handler(struct lpfc_nodelist *);
|
||||||
void lpfc_els_unsol_event(struct lpfc_hba *, struct lpfc_sli_ring *,
|
void lpfc_els_unsol_event(struct lpfc_hba *, struct lpfc_sli_ring *,
|
||||||
|
@ -117,18 +108,15 @@ void lpfc_fdmi_tmo_handler(struct lpfc_hba *);
|
||||||
int lpfc_config_port_prep(struct lpfc_hba *);
|
int lpfc_config_port_prep(struct lpfc_hba *);
|
||||||
int lpfc_config_port_post(struct lpfc_hba *);
|
int lpfc_config_port_post(struct lpfc_hba *);
|
||||||
int lpfc_hba_down_prep(struct lpfc_hba *);
|
int lpfc_hba_down_prep(struct lpfc_hba *);
|
||||||
|
int lpfc_hba_down_post(struct lpfc_hba *);
|
||||||
void lpfc_hba_init(struct lpfc_hba *, uint32_t *);
|
void lpfc_hba_init(struct lpfc_hba *, uint32_t *);
|
||||||
int lpfc_post_buffer(struct lpfc_hba *, struct lpfc_sli_ring *, int, int);
|
int lpfc_post_buffer(struct lpfc_hba *, struct lpfc_sli_ring *, int, int);
|
||||||
void lpfc_decode_firmware_rev(struct lpfc_hba *, char *, int);
|
void lpfc_decode_firmware_rev(struct lpfc_hba *, char *, int);
|
||||||
uint8_t *lpfc_get_lpfchba_info(struct lpfc_hba *, uint8_t *);
|
|
||||||
int lpfc_fcp_abort(struct lpfc_hba *, int, int, int);
|
|
||||||
int lpfc_online(struct lpfc_hba *);
|
int lpfc_online(struct lpfc_hba *);
|
||||||
int lpfc_offline(struct lpfc_hba *);
|
int lpfc_offline(struct lpfc_hba *);
|
||||||
|
|
||||||
|
|
||||||
int lpfc_sli_setup(struct lpfc_hba *);
|
int lpfc_sli_setup(struct lpfc_hba *);
|
||||||
int lpfc_sli_queue_setup(struct lpfc_hba *);
|
int lpfc_sli_queue_setup(struct lpfc_hba *);
|
||||||
void lpfc_slim_access(struct lpfc_hba *);
|
|
||||||
|
|
||||||
void lpfc_handle_eratt(struct lpfc_hba *);
|
void lpfc_handle_eratt(struct lpfc_hba *);
|
||||||
void lpfc_handle_latt(struct lpfc_hba *);
|
void lpfc_handle_latt(struct lpfc_hba *);
|
||||||
|
@ -137,6 +125,7 @@ irqreturn_t lpfc_intr_handler(int, void *, struct pt_regs *);
|
||||||
void lpfc_read_rev(struct lpfc_hba *, LPFC_MBOXQ_t *);
|
void lpfc_read_rev(struct lpfc_hba *, LPFC_MBOXQ_t *);
|
||||||
void lpfc_config_ring(struct lpfc_hba *, int, LPFC_MBOXQ_t *);
|
void lpfc_config_ring(struct lpfc_hba *, int, LPFC_MBOXQ_t *);
|
||||||
void lpfc_config_port(struct lpfc_hba *, LPFC_MBOXQ_t *);
|
void lpfc_config_port(struct lpfc_hba *, LPFC_MBOXQ_t *);
|
||||||
|
void lpfc_kill_board(struct lpfc_hba *, LPFC_MBOXQ_t *);
|
||||||
void lpfc_mbox_put(struct lpfc_hba *, LPFC_MBOXQ_t *);
|
void lpfc_mbox_put(struct lpfc_hba *, LPFC_MBOXQ_t *);
|
||||||
LPFC_MBOXQ_t *lpfc_mbox_get(struct lpfc_hba *);
|
LPFC_MBOXQ_t *lpfc_mbox_get(struct lpfc_hba *);
|
||||||
|
|
||||||
|
@ -149,6 +138,12 @@ void lpfc_sli_poll_fcp_ring(struct lpfc_hba * hba);
|
||||||
struct lpfc_iocbq * lpfc_sli_get_iocbq(struct lpfc_hba *);
|
struct lpfc_iocbq * lpfc_sli_get_iocbq(struct lpfc_hba *);
|
||||||
void lpfc_sli_release_iocbq(struct lpfc_hba * phba, struct lpfc_iocbq * iocb);
|
void lpfc_sli_release_iocbq(struct lpfc_hba * phba, struct lpfc_iocbq * iocb);
|
||||||
uint16_t lpfc_sli_next_iotag(struct lpfc_hba * phba, struct lpfc_iocbq * iocb);
|
uint16_t lpfc_sli_next_iotag(struct lpfc_hba * phba, struct lpfc_iocbq * iocb);
|
||||||
|
|
||||||
|
void lpfc_reset_barrier(struct lpfc_hba * phba);
|
||||||
|
int lpfc_sli_brdready(struct lpfc_hba *, uint32_t);
|
||||||
|
int lpfc_sli_brdkill(struct lpfc_hba *);
|
||||||
|
int lpfc_sli_brdreset(struct lpfc_hba *);
|
||||||
|
int lpfc_sli_brdrestart(struct lpfc_hba *);
|
||||||
int lpfc_sli_hba_setup(struct lpfc_hba *);
|
int lpfc_sli_hba_setup(struct lpfc_hba *);
|
||||||
int lpfc_sli_hba_down(struct lpfc_hba *);
|
int lpfc_sli_hba_down(struct lpfc_hba *);
|
||||||
int lpfc_sli_issue_mbox(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t);
|
int lpfc_sli_issue_mbox(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t);
|
||||||
|
@ -174,12 +169,10 @@ int lpfc_sli_abort_iocb(struct lpfc_hba *, struct lpfc_sli_ring *, uint16_t,
|
||||||
|
|
||||||
void lpfc_mbox_timeout(unsigned long);
|
void lpfc_mbox_timeout(unsigned long);
|
||||||
void lpfc_mbox_timeout_handler(struct lpfc_hba *);
|
void lpfc_mbox_timeout_handler(struct lpfc_hba *);
|
||||||
void lpfc_map_fcp_cmnd_to_bpl(struct lpfc_hba *, struct lpfc_scsi_buf *);
|
|
||||||
void lpfc_free_scsi_cmd(struct lpfc_scsi_buf *);
|
|
||||||
uint32_t lpfc_os_timeout_transform(struct lpfc_hba *, uint32_t);
|
|
||||||
|
|
||||||
struct lpfc_nodelist *lpfc_findnode_did(struct lpfc_hba * phba, uint32_t order,
|
struct lpfc_nodelist *lpfc_findnode_did(struct lpfc_hba *, uint32_t, uint32_t);
|
||||||
uint32_t did);
|
struct lpfc_nodelist *lpfc_findnode_wwpn(struct lpfc_hba *, uint32_t,
|
||||||
|
struct lpfc_name *);
|
||||||
|
|
||||||
int lpfc_sli_issue_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq,
|
int lpfc_sli_issue_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq,
|
||||||
uint32_t timeout);
|
uint32_t timeout);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
* This file is part of the Emulex Linux Device Driver for *
|
* This file is part of the Emulex Linux Device Driver for *
|
||||||
* Fibre Channel Host Bus Adapters. *
|
* Fibre Channel Host Bus Adapters. *
|
||||||
* Copyright (C) 2004-2005 Emulex. All rights reserved. *
|
* Copyright (C) 2004-2006 Emulex. All rights reserved. *
|
||||||
* EMULEX and SLI are trademarks of Emulex. *
|
* EMULEX and SLI are trademarks of Emulex. *
|
||||||
* www.emulex.com *
|
* www.emulex.com *
|
||||||
* *
|
* *
|
||||||
|
@ -260,8 +260,10 @@ lpfc_gen_req(struct lpfc_hba *phba, struct lpfc_dmabuf *bmp,
|
||||||
icmd->un.genreq64.w5.hcsw.Rctl = FC_UNSOL_CTL;
|
icmd->un.genreq64.w5.hcsw.Rctl = FC_UNSOL_CTL;
|
||||||
icmd->un.genreq64.w5.hcsw.Type = FC_COMMON_TRANSPORT_ULP;
|
icmd->un.genreq64.w5.hcsw.Type = FC_COMMON_TRANSPORT_ULP;
|
||||||
|
|
||||||
if (!tmo)
|
if (!tmo) {
|
||||||
tmo = (2 * phba->fc_ratov) + 1;
|
/* FC spec states we need 3 * ratov for CT requests */
|
||||||
|
tmo = (3 * phba->fc_ratov);
|
||||||
|
}
|
||||||
icmd->ulpTimeout = tmo;
|
icmd->ulpTimeout = tmo;
|
||||||
icmd->ulpBdeCount = 1;
|
icmd->ulpBdeCount = 1;
|
||||||
icmd->ulpLe = 1;
|
icmd->ulpLe = 1;
|
||||||
|
@ -321,6 +323,7 @@ lpfc_ns_rsp(struct lpfc_hba * phba, struct lpfc_dmabuf * mp, uint32_t Size)
|
||||||
struct lpfc_sli_ct_request *Response =
|
struct lpfc_sli_ct_request *Response =
|
||||||
(struct lpfc_sli_ct_request *) mp->virt;
|
(struct lpfc_sli_ct_request *) mp->virt;
|
||||||
struct lpfc_nodelist *ndlp = NULL;
|
struct lpfc_nodelist *ndlp = NULL;
|
||||||
|
struct lpfc_nodelist *next_ndlp;
|
||||||
struct lpfc_dmabuf *mlast, *next_mp;
|
struct lpfc_dmabuf *mlast, *next_mp;
|
||||||
uint32_t *ctptr = (uint32_t *) & Response->un.gid.PortType;
|
uint32_t *ctptr = (uint32_t *) & Response->un.gid.PortType;
|
||||||
uint32_t Did;
|
uint32_t Did;
|
||||||
|
@ -389,8 +392,36 @@ lpfc_ns_rsp(struct lpfc_hba * phba, struct lpfc_dmabuf * mp, uint32_t Size)
|
||||||
nsout1:
|
nsout1:
|
||||||
list_del(&head);
|
list_del(&head);
|
||||||
|
|
||||||
/* Here we are finished in the case RSCN */
|
/*
|
||||||
|
* The driver has cycled through all Nports in the RSCN payload.
|
||||||
|
* Complete the handling by cleaning up and marking the
|
||||||
|
* current driver state.
|
||||||
|
*/
|
||||||
if (phba->hba_state == LPFC_HBA_READY) {
|
if (phba->hba_state == LPFC_HBA_READY) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Switch ports that connect a loop of multiple targets need
|
||||||
|
* special consideration. The driver wants to unregister the
|
||||||
|
* rpi only on the target that was pulled from the loop. On
|
||||||
|
* RSCN, the driver wants to rediscover an NPort only if the
|
||||||
|
* driver flagged it as NLP_NPR_2B_DISC. Provided adisc is
|
||||||
|
* not enabled and the NPort is not capable of retransmissions
|
||||||
|
* (FC Tape) prevent timing races with the scsi error handler by
|
||||||
|
* unregistering the Nport's RPI. This action causes all
|
||||||
|
* outstanding IO to flush back to the midlayer.
|
||||||
|
*/
|
||||||
|
list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_npr_list,
|
||||||
|
nlp_listp) {
|
||||||
|
if (!(ndlp->nlp_flag & NLP_NPR_2B_DISC) &&
|
||||||
|
(lpfc_rscn_payload_check(phba, ndlp->nlp_DID))) {
|
||||||
|
if ((phba->cfg_use_adisc == 0) &&
|
||||||
|
!(ndlp->nlp_fcp_info &
|
||||||
|
NLP_FCP_2_DEVICE)) {
|
||||||
|
lpfc_unreg_rpi(phba, ndlp);
|
||||||
|
ndlp->nlp_flag &= ~NLP_NPR_ADISC;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
lpfc_els_flush_rscn(phba);
|
lpfc_els_flush_rscn(phba);
|
||||||
spin_lock_irq(phba->host->host_lock);
|
spin_lock_irq(phba->host->host_lock);
|
||||||
phba->fc_flag |= FC_RSCN_MODE; /* we are still in RSCN mode */
|
phba->fc_flag |= FC_RSCN_MODE; /* we are still in RSCN mode */
|
||||||
|
@ -449,6 +480,11 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
|
||||||
CTrsp = (struct lpfc_sli_ct_request *) outp->virt;
|
CTrsp = (struct lpfc_sli_ct_request *) outp->virt;
|
||||||
if (CTrsp->CommandResponse.bits.CmdRsp ==
|
if (CTrsp->CommandResponse.bits.CmdRsp ==
|
||||||
be16_to_cpu(SLI_CT_RESPONSE_FS_ACC)) {
|
be16_to_cpu(SLI_CT_RESPONSE_FS_ACC)) {
|
||||||
|
lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
|
||||||
|
"%d:0239 NameServer Rsp "
|
||||||
|
"Data: x%x\n",
|
||||||
|
phba->brd_no,
|
||||||
|
phba->fc_flag);
|
||||||
lpfc_ns_rsp(phba, outp,
|
lpfc_ns_rsp(phba, outp,
|
||||||
(uint32_t) (irsp->un.genreq64.bdl.bdeSize));
|
(uint32_t) (irsp->un.genreq64.bdl.bdeSize));
|
||||||
} else if (CTrsp->CommandResponse.bits.CmdRsp ==
|
} else if (CTrsp->CommandResponse.bits.CmdRsp ==
|
||||||
|
@ -978,19 +1014,19 @@ lpfc_fdmi_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode)
|
||||||
ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) pab + size);
|
ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) pab + size);
|
||||||
ae->ad.bits.AttrType = be16_to_cpu(SUPPORTED_SPEED);
|
ae->ad.bits.AttrType = be16_to_cpu(SUPPORTED_SPEED);
|
||||||
ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + 4);
|
ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + 4);
|
||||||
if (FC_JEDEC_ID(vp->rev.biuRev) == VIPER_JEDEC_ID)
|
|
||||||
|
ae->un.SupportSpeed = 0;
|
||||||
|
if (phba->lmt & LMT_10Gb)
|
||||||
ae->un.SupportSpeed = HBA_PORTSPEED_10GBIT;
|
ae->un.SupportSpeed = HBA_PORTSPEED_10GBIT;
|
||||||
else if (FC_JEDEC_ID(vp->rev.biuRev) == HELIOS_JEDEC_ID)
|
if (phba->lmt & LMT_8Gb)
|
||||||
ae->un.SupportSpeed = HBA_PORTSPEED_4GBIT;
|
ae->un.SupportSpeed |= HBA_PORTSPEED_8GBIT;
|
||||||
else if ((FC_JEDEC_ID(vp->rev.biuRev) ==
|
if (phba->lmt & LMT_4Gb)
|
||||||
CENTAUR_2G_JEDEC_ID)
|
ae->un.SupportSpeed |= HBA_PORTSPEED_4GBIT;
|
||||||
|| (FC_JEDEC_ID(vp->rev.biuRev) ==
|
if (phba->lmt & LMT_2Gb)
|
||||||
PEGASUS_JEDEC_ID)
|
ae->un.SupportSpeed |= HBA_PORTSPEED_2GBIT;
|
||||||
|| (FC_JEDEC_ID(vp->rev.biuRev) ==
|
if (phba->lmt & LMT_1Gb)
|
||||||
THOR_JEDEC_ID))
|
ae->un.SupportSpeed |= HBA_PORTSPEED_1GBIT;
|
||||||
ae->un.SupportSpeed = HBA_PORTSPEED_2GBIT;
|
|
||||||
else
|
|
||||||
ae->un.SupportSpeed = HBA_PORTSPEED_1GBIT;
|
|
||||||
pab->ab.EntryCnt++;
|
pab->ab.EntryCnt++;
|
||||||
size += FOURBYTES + 4;
|
size += FOURBYTES + 4;
|
||||||
|
|
||||||
|
@ -1130,11 +1166,6 @@ lpfc_fdmi_tmo_handler(struct lpfc_hba *phba)
|
||||||
{
|
{
|
||||||
struct lpfc_nodelist *ndlp;
|
struct lpfc_nodelist *ndlp;
|
||||||
|
|
||||||
spin_lock_irq(phba->host->host_lock);
|
|
||||||
if (!(phba->work_hba_events & WORKER_FDMI_TMO)) {
|
|
||||||
spin_unlock_irq(phba->host->host_lock);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, FDMI_DID);
|
ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, FDMI_DID);
|
||||||
if (ndlp) {
|
if (ndlp) {
|
||||||
if (system_utsname.nodename[0] != '\0') {
|
if (system_utsname.nodename[0] != '\0') {
|
||||||
|
@ -1143,7 +1174,6 @@ lpfc_fdmi_tmo_handler(struct lpfc_hba *phba)
|
||||||
mod_timer(&phba->fc_fdmitmo, jiffies + HZ * 60);
|
mod_timer(&phba->fc_fdmitmo, jiffies + HZ * 60);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
spin_unlock_irq(phba->host->host_lock);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
* This file is part of the Emulex Linux Device Driver for *
|
* This file is part of the Emulex Linux Device Driver for *
|
||||||
* Fibre Channel Host Bus Adapters. *
|
* Fibre Channel Host Bus Adapters. *
|
||||||
* Copyright (C) 2004-2005 Emulex. All rights reserved. *
|
* Copyright (C) 2004-2006 Emulex. All rights reserved. *
|
||||||
* EMULEX and SLI are trademarks of Emulex. *
|
* EMULEX and SLI are trademarks of Emulex. *
|
||||||
* www.emulex.com *
|
* www.emulex.com *
|
||||||
* *
|
* *
|
||||||
|
@ -28,18 +28,24 @@
|
||||||
* This is used by Fibre Channel protocol to support FCP.
|
* This is used by Fibre Channel protocol to support FCP.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* worker thread events */
|
||||||
|
enum lpfc_work_type {
|
||||||
|
LPFC_EVT_NODEV_TMO,
|
||||||
|
LPFC_EVT_ONLINE,
|
||||||
|
LPFC_EVT_OFFLINE,
|
||||||
|
LPFC_EVT_WARM_START,
|
||||||
|
LPFC_EVT_KILL,
|
||||||
|
LPFC_EVT_ELS_RETRY,
|
||||||
|
};
|
||||||
|
|
||||||
/* structure used to queue event to the discovery tasklet */
|
/* structure used to queue event to the discovery tasklet */
|
||||||
struct lpfc_work_evt {
|
struct lpfc_work_evt {
|
||||||
struct list_head evt_listp;
|
struct list_head evt_listp;
|
||||||
void * evt_arg1;
|
void * evt_arg1;
|
||||||
void * evt_arg2;
|
void * evt_arg2;
|
||||||
uint32_t evt;
|
enum lpfc_work_type evt;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define LPFC_EVT_NODEV_TMO 0x1
|
|
||||||
#define LPFC_EVT_ONLINE 0x2
|
|
||||||
#define LPFC_EVT_OFFLINE 0x3
|
|
||||||
#define LPFC_EVT_ELS_RETRY 0x4
|
|
||||||
|
|
||||||
struct lpfc_nodelist {
|
struct lpfc_nodelist {
|
||||||
struct list_head nlp_listp;
|
struct list_head nlp_listp;
|
||||||
|
@ -56,6 +62,7 @@ struct lpfc_nodelist {
|
||||||
|
|
||||||
uint16_t nlp_rpi;
|
uint16_t nlp_rpi;
|
||||||
uint16_t nlp_state; /* state transition indicator */
|
uint16_t nlp_state; /* state transition indicator */
|
||||||
|
uint16_t nlp_prev_state; /* state transition indicator */
|
||||||
uint16_t nlp_xri; /* output exchange id for RPI */
|
uint16_t nlp_xri; /* output exchange id for RPI */
|
||||||
uint16_t nlp_sid; /* scsi id */
|
uint16_t nlp_sid; /* scsi id */
|
||||||
#define NLP_NO_SID 0xffff
|
#define NLP_NO_SID 0xffff
|
||||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,7 +1,7 @@
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
* This file is part of the Emulex Linux Device Driver for *
|
* This file is part of the Emulex Linux Device Driver for *
|
||||||
* Fibre Channel Host Bus Adapters. *
|
* Fibre Channel Host Bus Adapters. *
|
||||||
* Copyright (C) 2004-2005 Emulex. All rights reserved. *
|
* Copyright (C) 2004-2006 Emulex. All rights reserved. *
|
||||||
* EMULEX and SLI are trademarks of Emulex. *
|
* EMULEX and SLI are trademarks of Emulex. *
|
||||||
* www.emulex.com *
|
* www.emulex.com *
|
||||||
* *
|
* *
|
||||||
|
@ -454,10 +454,13 @@ struct serv_parm { /* Structure is in Big Endian format */
|
||||||
#define ELS_CMD_ADISC 0x52000000
|
#define ELS_CMD_ADISC 0x52000000
|
||||||
#define ELS_CMD_FARP 0x54000000
|
#define ELS_CMD_FARP 0x54000000
|
||||||
#define ELS_CMD_FARPR 0x55000000
|
#define ELS_CMD_FARPR 0x55000000
|
||||||
|
#define ELS_CMD_RPS 0x56000000
|
||||||
|
#define ELS_CMD_RPL 0x57000000
|
||||||
#define ELS_CMD_FAN 0x60000000
|
#define ELS_CMD_FAN 0x60000000
|
||||||
#define ELS_CMD_RSCN 0x61040000
|
#define ELS_CMD_RSCN 0x61040000
|
||||||
#define ELS_CMD_SCR 0x62000000
|
#define ELS_CMD_SCR 0x62000000
|
||||||
#define ELS_CMD_RNID 0x78000000
|
#define ELS_CMD_RNID 0x78000000
|
||||||
|
#define ELS_CMD_LIRR 0x7A000000
|
||||||
#else /* __LITTLE_ENDIAN_BITFIELD */
|
#else /* __LITTLE_ENDIAN_BITFIELD */
|
||||||
#define ELS_CMD_MASK 0xffff
|
#define ELS_CMD_MASK 0xffff
|
||||||
#define ELS_RSP_MASK 0xff
|
#define ELS_RSP_MASK 0xff
|
||||||
|
@ -486,10 +489,13 @@ struct serv_parm { /* Structure is in Big Endian format */
|
||||||
#define ELS_CMD_ADISC 0x52
|
#define ELS_CMD_ADISC 0x52
|
||||||
#define ELS_CMD_FARP 0x54
|
#define ELS_CMD_FARP 0x54
|
||||||
#define ELS_CMD_FARPR 0x55
|
#define ELS_CMD_FARPR 0x55
|
||||||
|
#define ELS_CMD_RPS 0x56
|
||||||
|
#define ELS_CMD_RPL 0x57
|
||||||
#define ELS_CMD_FAN 0x60
|
#define ELS_CMD_FAN 0x60
|
||||||
#define ELS_CMD_RSCN 0x0461
|
#define ELS_CMD_RSCN 0x0461
|
||||||
#define ELS_CMD_SCR 0x62
|
#define ELS_CMD_SCR 0x62
|
||||||
#define ELS_CMD_RNID 0x78
|
#define ELS_CMD_RNID 0x78
|
||||||
|
#define ELS_CMD_LIRR 0x7A
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -758,12 +764,40 @@ typedef struct _RNID { /* Structure is in Big Endian format */
|
||||||
} un;
|
} un;
|
||||||
} RNID;
|
} RNID;
|
||||||
|
|
||||||
typedef struct _RRQ { /* Structure is in Big Endian format */
|
typedef struct _RPS { /* Structure is in Big Endian format */
|
||||||
uint32_t SID;
|
union {
|
||||||
uint16_t Oxid;
|
uint32_t portNum;
|
||||||
uint16_t Rxid;
|
struct lpfc_name portName;
|
||||||
uint8_t resv[32]; /* optional association hdr */
|
} un;
|
||||||
} RRQ;
|
} RPS;
|
||||||
|
|
||||||
|
typedef struct _RPS_RSP { /* Structure is in Big Endian format */
|
||||||
|
uint16_t rsvd1;
|
||||||
|
uint16_t portStatus;
|
||||||
|
uint32_t linkFailureCnt;
|
||||||
|
uint32_t lossSyncCnt;
|
||||||
|
uint32_t lossSignalCnt;
|
||||||
|
uint32_t primSeqErrCnt;
|
||||||
|
uint32_t invalidXmitWord;
|
||||||
|
uint32_t crcCnt;
|
||||||
|
} RPS_RSP;
|
||||||
|
|
||||||
|
typedef struct _RPL { /* Structure is in Big Endian format */
|
||||||
|
uint32_t maxsize;
|
||||||
|
uint32_t index;
|
||||||
|
} RPL;
|
||||||
|
|
||||||
|
typedef struct _PORT_NUM_BLK {
|
||||||
|
uint32_t portNum;
|
||||||
|
uint32_t portID;
|
||||||
|
struct lpfc_name portName;
|
||||||
|
} PORT_NUM_BLK;
|
||||||
|
|
||||||
|
typedef struct _RPL_RSP { /* Structure is in Big Endian format */
|
||||||
|
uint32_t listLen;
|
||||||
|
uint32_t index;
|
||||||
|
PORT_NUM_BLK port_num_blk;
|
||||||
|
} RPL_RSP;
|
||||||
|
|
||||||
/* This is used for RSCN command */
|
/* This is used for RSCN command */
|
||||||
typedef struct _D_ID { /* Structure is in Big Endian format */
|
typedef struct _D_ID { /* Structure is in Big Endian format */
|
||||||
|
@ -804,7 +838,6 @@ typedef struct _ELS_PKT { /* Structure is in Big Endian format */
|
||||||
FARP farp; /* Payload for FARP/ACC */
|
FARP farp; /* Payload for FARP/ACC */
|
||||||
FAN fan; /* Payload for FAN */
|
FAN fan; /* Payload for FAN */
|
||||||
SCR scr; /* Payload for SCR/ACC */
|
SCR scr; /* Payload for SCR/ACC */
|
||||||
RRQ rrq; /* Payload for RRQ */
|
|
||||||
RNID rnid; /* Payload for RNID */
|
RNID rnid; /* Payload for RNID */
|
||||||
uint8_t pad[128 - 4]; /* Pad out to payload of 128 bytes */
|
uint8_t pad[128 - 4]; /* Pad out to payload of 128 bytes */
|
||||||
} un;
|
} un;
|
||||||
|
@ -1200,7 +1233,9 @@ typedef struct { /* FireFly BIU registers */
|
||||||
#define MBX_SET_MASK 0x20
|
#define MBX_SET_MASK 0x20
|
||||||
#define MBX_SET_SLIM 0x21
|
#define MBX_SET_SLIM 0x21
|
||||||
#define MBX_UNREG_D_ID 0x23
|
#define MBX_UNREG_D_ID 0x23
|
||||||
|
#define MBX_KILL_BOARD 0x24
|
||||||
#define MBX_CONFIG_FARP 0x25
|
#define MBX_CONFIG_FARP 0x25
|
||||||
|
#define MBX_BEACON 0x2A
|
||||||
|
|
||||||
#define MBX_LOAD_AREA 0x81
|
#define MBX_LOAD_AREA 0x81
|
||||||
#define MBX_RUN_BIU_DIAG64 0x84
|
#define MBX_RUN_BIU_DIAG64 0x84
|
||||||
|
@ -1676,13 +1711,13 @@ typedef struct {
|
||||||
uint32_t rttov;
|
uint32_t rttov;
|
||||||
uint32_t altov;
|
uint32_t altov;
|
||||||
uint32_t lmt;
|
uint32_t lmt;
|
||||||
#define LMT_RESERVED 0x0 /* Not used */
|
#define LMT_RESERVED 0x000 /* Not used */
|
||||||
#define LMT_266_10bit 0x1 /* 265.625 Mbaud 10 bit iface */
|
#define LMT_1Gb 0x004
|
||||||
#define LMT_532_10bit 0x2 /* 531.25 Mbaud 10 bit iface */
|
#define LMT_2Gb 0x008
|
||||||
#define LMT_1063_20bit 0x3 /* 1062.5 Mbaud 20 bit iface */
|
#define LMT_4Gb 0x040
|
||||||
#define LMT_1063_10bit 0x4 /* 1062.5 Mbaud 10 bit iface */
|
#define LMT_8Gb 0x080
|
||||||
#define LMT_2125_10bit 0x8 /* 2125 Mbaud 10 bit iface */
|
#define LMT_10Gb 0x100
|
||||||
#define LMT_4250_10bit 0x40 /* 4250 Mbaud 10 bit iface */
|
|
||||||
|
|
||||||
uint32_t rsvd2;
|
uint32_t rsvd2;
|
||||||
uint32_t rsvd3;
|
uint32_t rsvd3;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
* This file is part of the Emulex Linux Device Driver for *
|
* This file is part of the Emulex Linux Device Driver for *
|
||||||
* Fibre Channel Host Bus Adapters. *
|
* Fibre Channel Host Bus Adapters. *
|
||||||
* Copyright (C) 2004-2005 Emulex. All rights reserved. *
|
* Copyright (C) 2004-2006 Emulex. All rights reserved. *
|
||||||
* EMULEX and SLI are trademarks of Emulex. *
|
* EMULEX and SLI are trademarks of Emulex. *
|
||||||
* www.emulex.com *
|
* www.emulex.com *
|
||||||
* Portions Copyright (C) 2004-2005 Christoph Hellwig *
|
* Portions Copyright (C) 2004-2005 Christoph Hellwig *
|
||||||
|
@ -42,7 +42,7 @@
|
||||||
#include "lpfc_crtn.h"
|
#include "lpfc_crtn.h"
|
||||||
#include "lpfc_version.h"
|
#include "lpfc_version.h"
|
||||||
|
|
||||||
static int lpfc_parse_vpd(struct lpfc_hba *, uint8_t *);
|
static int lpfc_parse_vpd(struct lpfc_hba *, uint8_t *, int);
|
||||||
static void lpfc_get_hba_model_desc(struct lpfc_hba *, uint8_t *, uint8_t *);
|
static void lpfc_get_hba_model_desc(struct lpfc_hba *, uint8_t *, uint8_t *);
|
||||||
static int lpfc_post_rcv_buf(struct lpfc_hba *);
|
static int lpfc_post_rcv_buf(struct lpfc_hba *);
|
||||||
|
|
||||||
|
@ -161,9 +161,6 @@ lpfc_config_port_prep(struct lpfc_hba * phba)
|
||||||
memcpy(phba->RandomData, (char *)&mb->un.varWords[24],
|
memcpy(phba->RandomData, (char *)&mb->un.varWords[24],
|
||||||
sizeof (phba->RandomData));
|
sizeof (phba->RandomData));
|
||||||
|
|
||||||
/* Get the default values for Model Name and Description */
|
|
||||||
lpfc_get_hba_model_desc(phba, phba->ModelName, phba->ModelDesc);
|
|
||||||
|
|
||||||
/* Get adapter VPD information */
|
/* Get adapter VPD information */
|
||||||
pmb->context2 = kmalloc(DMP_RSP_SIZE, GFP_KERNEL);
|
pmb->context2 = kmalloc(DMP_RSP_SIZE, GFP_KERNEL);
|
||||||
if (!pmb->context2)
|
if (!pmb->context2)
|
||||||
|
@ -182,16 +179,15 @@ lpfc_config_port_prep(struct lpfc_hba * phba)
|
||||||
"mbxCmd x%x DUMP VPD, mbxStatus x%x\n",
|
"mbxCmd x%x DUMP VPD, mbxStatus x%x\n",
|
||||||
phba->brd_no,
|
phba->brd_no,
|
||||||
mb->mbxCommand, mb->mbxStatus);
|
mb->mbxCommand, mb->mbxStatus);
|
||||||
kfree(lpfc_vpd_data);
|
mb->un.varDmp.word_cnt = 0;
|
||||||
lpfc_vpd_data = NULL;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
if (mb->un.varDmp.word_cnt > DMP_VPD_SIZE - offset)
|
||||||
|
mb->un.varDmp.word_cnt = DMP_VPD_SIZE - offset;
|
||||||
lpfc_sli_pcimem_bcopy(pmb->context2, lpfc_vpd_data + offset,
|
lpfc_sli_pcimem_bcopy(pmb->context2, lpfc_vpd_data + offset,
|
||||||
mb->un.varDmp.word_cnt);
|
mb->un.varDmp.word_cnt);
|
||||||
offset += mb->un.varDmp.word_cnt;
|
offset += mb->un.varDmp.word_cnt;
|
||||||
} while (mb->un.varDmp.word_cnt);
|
} while (mb->un.varDmp.word_cnt && offset < DMP_VPD_SIZE);
|
||||||
lpfc_parse_vpd(phba, lpfc_vpd_data);
|
lpfc_parse_vpd(phba, lpfc_vpd_data, offset);
|
||||||
|
|
||||||
kfree(lpfc_vpd_data);
|
kfree(lpfc_vpd_data);
|
||||||
out_free_context2:
|
out_free_context2:
|
||||||
|
@ -327,13 +323,22 @@ lpfc_config_port_post(struct lpfc_hba * phba)
|
||||||
mb->un.varRdConfig.max_xri + 1;
|
mb->un.varRdConfig.max_xri + 1;
|
||||||
|
|
||||||
phba->lmt = mb->un.varRdConfig.lmt;
|
phba->lmt = mb->un.varRdConfig.lmt;
|
||||||
/* HBA is not 4GB capable, or HBA is not 2GB capable,
|
|
||||||
don't let link speed ask for it */
|
/* Get the default values for Model Name and Description */
|
||||||
if ((((phba->lmt & LMT_4250_10bit) != LMT_4250_10bit) &&
|
lpfc_get_hba_model_desc(phba, phba->ModelName, phba->ModelDesc);
|
||||||
(phba->cfg_link_speed > LINK_SPEED_2G)) ||
|
|
||||||
(((phba->lmt & LMT_2125_10bit) != LMT_2125_10bit) &&
|
if ((phba->cfg_link_speed > LINK_SPEED_10G)
|
||||||
(phba->cfg_link_speed > LINK_SPEED_1G))) {
|
|| ((phba->cfg_link_speed == LINK_SPEED_1G)
|
||||||
/* Reset link speed to auto. 1G/2GB HBA cfg'd for 4G */
|
&& !(phba->lmt & LMT_1Gb))
|
||||||
|
|| ((phba->cfg_link_speed == LINK_SPEED_2G)
|
||||||
|
&& !(phba->lmt & LMT_2Gb))
|
||||||
|
|| ((phba->cfg_link_speed == LINK_SPEED_4G)
|
||||||
|
&& !(phba->lmt & LMT_4Gb))
|
||||||
|
|| ((phba->cfg_link_speed == LINK_SPEED_8G)
|
||||||
|
&& !(phba->lmt & LMT_8Gb))
|
||||||
|
|| ((phba->cfg_link_speed == LINK_SPEED_10G)
|
||||||
|
&& !(phba->lmt & LMT_10Gb))) {
|
||||||
|
/* Reset link speed to auto */
|
||||||
lpfc_printf_log(phba,
|
lpfc_printf_log(phba,
|
||||||
KERN_WARNING,
|
KERN_WARNING,
|
||||||
LOG_LINK_EVENT,
|
LOG_LINK_EVENT,
|
||||||
|
@ -462,6 +467,40 @@ lpfc_hba_down_prep(struct lpfc_hba * phba)
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/************************************************************************/
|
||||||
|
/* */
|
||||||
|
/* lpfc_hba_down_post */
|
||||||
|
/* This routine will do uninitialization after the HBA is reset */
|
||||||
|
/* when bringing down the SLI Layer. */
|
||||||
|
/* This routine returns 0 on success. Any other return value */
|
||||||
|
/* indicates an error. */
|
||||||
|
/* */
|
||||||
|
/************************************************************************/
|
||||||
|
int
|
||||||
|
lpfc_hba_down_post(struct lpfc_hba * phba)
|
||||||
|
{
|
||||||
|
struct lpfc_sli *psli = &phba->sli;
|
||||||
|
struct lpfc_sli_ring *pring;
|
||||||
|
struct lpfc_dmabuf *mp, *next_mp;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Cleanup preposted buffers on the ELS ring */
|
||||||
|
pring = &psli->ring[LPFC_ELS_RING];
|
||||||
|
list_for_each_entry_safe(mp, next_mp, &pring->postbufq, list) {
|
||||||
|
list_del(&mp->list);
|
||||||
|
pring->postbufq_cnt--;
|
||||||
|
lpfc_mbuf_free(phba, mp->virt, mp->phys);
|
||||||
|
kfree(mp);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < psli->num_rings; i++) {
|
||||||
|
pring = &psli->ring[i];
|
||||||
|
lpfc_sli_abort_iocb_ring(phba, pring);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
/* */
|
/* */
|
||||||
/* lpfc_handle_eratt */
|
/* lpfc_handle_eratt */
|
||||||
|
@ -476,20 +515,6 @@ lpfc_handle_eratt(struct lpfc_hba * phba)
|
||||||
struct lpfc_sli *psli = &phba->sli;
|
struct lpfc_sli *psli = &phba->sli;
|
||||||
struct lpfc_sli_ring *pring;
|
struct lpfc_sli_ring *pring;
|
||||||
|
|
||||||
/*
|
|
||||||
* If a reset is sent to the HBA restore PCI configuration registers.
|
|
||||||
*/
|
|
||||||
if ( phba->hba_state == LPFC_INIT_START ) {
|
|
||||||
mdelay(1);
|
|
||||||
readl(phba->HCregaddr); /* flush */
|
|
||||||
writel(0, phba->HCregaddr);
|
|
||||||
readl(phba->HCregaddr); /* flush */
|
|
||||||
|
|
||||||
/* Restore PCI cmd register */
|
|
||||||
pci_write_config_word(phba->pcidev,
|
|
||||||
PCI_COMMAND, phba->pci_cfg_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (phba->work_hs & HS_FFER6) {
|
if (phba->work_hs & HS_FFER6) {
|
||||||
/* Re-establishing Link */
|
/* Re-establishing Link */
|
||||||
lpfc_printf_log(phba, KERN_INFO, LOG_LINK_EVENT,
|
lpfc_printf_log(phba, KERN_INFO, LOG_LINK_EVENT,
|
||||||
|
@ -499,6 +524,7 @@ lpfc_handle_eratt(struct lpfc_hba * phba)
|
||||||
phba->work_status[0], phba->work_status[1]);
|
phba->work_status[0], phba->work_status[1]);
|
||||||
spin_lock_irq(phba->host->host_lock);
|
spin_lock_irq(phba->host->host_lock);
|
||||||
phba->fc_flag |= FC_ESTABLISH_LINK;
|
phba->fc_flag |= FC_ESTABLISH_LINK;
|
||||||
|
psli->sli_flag &= ~LPFC_SLI2_ACTIVE;
|
||||||
spin_unlock_irq(phba->host->host_lock);
|
spin_unlock_irq(phba->host->host_lock);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -516,6 +542,7 @@ lpfc_handle_eratt(struct lpfc_hba * phba)
|
||||||
* attempt to restart it.
|
* attempt to restart it.
|
||||||
*/
|
*/
|
||||||
lpfc_offline(phba);
|
lpfc_offline(phba);
|
||||||
|
lpfc_sli_brdrestart(phba);
|
||||||
if (lpfc_online(phba) == 0) { /* Initialize the HBA */
|
if (lpfc_online(phba) == 0) { /* Initialize the HBA */
|
||||||
mod_timer(&phba->fc_estabtmo, jiffies + HZ * 60);
|
mod_timer(&phba->fc_estabtmo, jiffies + HZ * 60);
|
||||||
return;
|
return;
|
||||||
|
@ -531,8 +558,10 @@ lpfc_handle_eratt(struct lpfc_hba * phba)
|
||||||
phba->brd_no, phba->work_hs,
|
phba->brd_no, phba->work_hs,
|
||||||
phba->work_status[0], phba->work_status[1]);
|
phba->work_status[0], phba->work_status[1]);
|
||||||
|
|
||||||
|
psli->sli_flag &= ~LPFC_SLI2_ACTIVE;
|
||||||
lpfc_offline(phba);
|
lpfc_offline(phba);
|
||||||
|
phba->hba_state = LPFC_HBA_ERROR;
|
||||||
|
lpfc_hba_down_post(phba);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -623,7 +652,7 @@ lpfc_handle_latt_err_exit:
|
||||||
/* */
|
/* */
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
static int
|
static int
|
||||||
lpfc_parse_vpd(struct lpfc_hba * phba, uint8_t * vpd)
|
lpfc_parse_vpd(struct lpfc_hba * phba, uint8_t * vpd, int len)
|
||||||
{
|
{
|
||||||
uint8_t lenlo, lenhi;
|
uint8_t lenlo, lenhi;
|
||||||
uint32_t Length;
|
uint32_t Length;
|
||||||
|
@ -642,9 +671,10 @@ lpfc_parse_vpd(struct lpfc_hba * phba, uint8_t * vpd)
|
||||||
phba->brd_no,
|
phba->brd_no,
|
||||||
(uint32_t) vpd[0], (uint32_t) vpd[1], (uint32_t) vpd[2],
|
(uint32_t) vpd[0], (uint32_t) vpd[1], (uint32_t) vpd[2],
|
||||||
(uint32_t) vpd[3]);
|
(uint32_t) vpd[3]);
|
||||||
do {
|
while (!finished && (index < (len - 4))) {
|
||||||
switch (vpd[index]) {
|
switch (vpd[index]) {
|
||||||
case 0x82:
|
case 0x82:
|
||||||
|
case 0x91:
|
||||||
index += 1;
|
index += 1;
|
||||||
lenlo = vpd[index];
|
lenlo = vpd[index];
|
||||||
index += 1;
|
index += 1;
|
||||||
|
@ -660,7 +690,8 @@ lpfc_parse_vpd(struct lpfc_hba * phba, uint8_t * vpd)
|
||||||
lenhi = vpd[index];
|
lenhi = vpd[index];
|
||||||
index += 1;
|
index += 1;
|
||||||
Length = ((((unsigned short)lenhi) << 8) + lenlo);
|
Length = ((((unsigned short)lenhi) << 8) + lenlo);
|
||||||
|
if (Length > len - index)
|
||||||
|
Length = len - index;
|
||||||
while (Length > 0) {
|
while (Length > 0) {
|
||||||
/* Look for Serial Number */
|
/* Look for Serial Number */
|
||||||
if ((vpd[index] == 'S') && (vpd[index+1] == 'N')) {
|
if ((vpd[index] == 'S') && (vpd[index+1] == 'N')) {
|
||||||
|
@ -754,7 +785,7 @@ lpfc_parse_vpd(struct lpfc_hba * phba, uint8_t * vpd)
|
||||||
index ++;
|
index ++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} while (!finished && (index < 108));
|
}
|
||||||
|
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
@ -765,137 +796,173 @@ lpfc_get_hba_model_desc(struct lpfc_hba * phba, uint8_t * mdp, uint8_t * descp)
|
||||||
lpfc_vpd_t *vp;
|
lpfc_vpd_t *vp;
|
||||||
uint16_t dev_id = phba->pcidev->device;
|
uint16_t dev_id = phba->pcidev->device;
|
||||||
uint16_t dev_subid = phba->pcidev->subsystem_device;
|
uint16_t dev_subid = phba->pcidev->subsystem_device;
|
||||||
uint8_t hdrtype = phba->pcidev->hdr_type;
|
uint8_t hdrtype;
|
||||||
char *model_str = "";
|
int max_speed;
|
||||||
|
char * ports;
|
||||||
|
struct {
|
||||||
|
char * name;
|
||||||
|
int max_speed;
|
||||||
|
char * ports;
|
||||||
|
char * bus;
|
||||||
|
} m;
|
||||||
|
|
||||||
|
pci_read_config_byte(phba->pcidev, PCI_HEADER_TYPE, &hdrtype);
|
||||||
|
ports = (hdrtype == 0x80) ? "2-port " : "";
|
||||||
|
if (mdp && mdp[0] != '\0'
|
||||||
|
&& descp && descp[0] != '\0')
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (phba->lmt & LMT_10Gb)
|
||||||
|
max_speed = 10;
|
||||||
|
else if (phba->lmt & LMT_8Gb)
|
||||||
|
max_speed = 8;
|
||||||
|
else if (phba->lmt & LMT_4Gb)
|
||||||
|
max_speed = 4;
|
||||||
|
else if (phba->lmt & LMT_2Gb)
|
||||||
|
max_speed = 2;
|
||||||
|
else
|
||||||
|
max_speed = 1;
|
||||||
|
|
||||||
vp = &phba->vpd;
|
vp = &phba->vpd;
|
||||||
|
|
||||||
switch (dev_id) {
|
switch (dev_id) {
|
||||||
case PCI_DEVICE_ID_FIREFLY:
|
case PCI_DEVICE_ID_FIREFLY:
|
||||||
model_str = "LP6000 1Gb PCI";
|
m = (typeof(m)){"LP6000", max_speed, "", "PCI"};
|
||||||
break;
|
break;
|
||||||
case PCI_DEVICE_ID_SUPERFLY:
|
case PCI_DEVICE_ID_SUPERFLY:
|
||||||
if (vp->rev.biuRev >= 1 && vp->rev.biuRev <= 3)
|
if (vp->rev.biuRev >= 1 && vp->rev.biuRev <= 3)
|
||||||
model_str = "LP7000 1Gb PCI";
|
m = (typeof(m)){"LP7000", max_speed, "", "PCI"};
|
||||||
else
|
else
|
||||||
model_str = "LP7000E 1Gb PCI";
|
m = (typeof(m)){"LP7000E", max_speed, "", "PCI"};
|
||||||
break;
|
break;
|
||||||
case PCI_DEVICE_ID_DRAGONFLY:
|
case PCI_DEVICE_ID_DRAGONFLY:
|
||||||
model_str = "LP8000 1Gb PCI";
|
m = (typeof(m)){"LP8000", max_speed, "", "PCI"};
|
||||||
break;
|
break;
|
||||||
case PCI_DEVICE_ID_CENTAUR:
|
case PCI_DEVICE_ID_CENTAUR:
|
||||||
if (FC_JEDEC_ID(vp->rev.biuRev) == CENTAUR_2G_JEDEC_ID)
|
if (FC_JEDEC_ID(vp->rev.biuRev) == CENTAUR_2G_JEDEC_ID)
|
||||||
model_str = "LP9002 2Gb PCI";
|
m = (typeof(m)){"LP9002", max_speed, "", "PCI"};
|
||||||
else
|
else
|
||||||
model_str = "LP9000 1Gb PCI";
|
m = (typeof(m)){"LP9000", max_speed, "", "PCI"};
|
||||||
break;
|
break;
|
||||||
case PCI_DEVICE_ID_RFLY:
|
case PCI_DEVICE_ID_RFLY:
|
||||||
model_str = "LP952 2Gb PCI";
|
m = (typeof(m)){"LP952", max_speed, "", "PCI"};
|
||||||
break;
|
break;
|
||||||
case PCI_DEVICE_ID_PEGASUS:
|
case PCI_DEVICE_ID_PEGASUS:
|
||||||
model_str = "LP9802 2Gb PCI-X";
|
m = (typeof(m)){"LP9802", max_speed, "", "PCI-X"};
|
||||||
break;
|
break;
|
||||||
case PCI_DEVICE_ID_THOR:
|
case PCI_DEVICE_ID_THOR:
|
||||||
if (hdrtype == 0x80)
|
if (hdrtype == 0x80)
|
||||||
model_str = "LP10000DC 2Gb 2-port PCI-X";
|
m = (typeof(m)){"LP10000DC",
|
||||||
|
max_speed, ports, "PCI-X"};
|
||||||
else
|
else
|
||||||
model_str = "LP10000 2Gb PCI-X";
|
m = (typeof(m)){"LP10000",
|
||||||
|
max_speed, ports, "PCI-X"};
|
||||||
break;
|
break;
|
||||||
case PCI_DEVICE_ID_VIPER:
|
case PCI_DEVICE_ID_VIPER:
|
||||||
model_str = "LPX1000 10Gb PCI-X";
|
m = (typeof(m)){"LPX1000", max_speed, "", "PCI-X"};
|
||||||
break;
|
break;
|
||||||
case PCI_DEVICE_ID_PFLY:
|
case PCI_DEVICE_ID_PFLY:
|
||||||
model_str = "LP982 2Gb PCI-X";
|
m = (typeof(m)){"LP982", max_speed, "", "PCI-X"};
|
||||||
break;
|
break;
|
||||||
case PCI_DEVICE_ID_TFLY:
|
case PCI_DEVICE_ID_TFLY:
|
||||||
if (hdrtype == 0x80)
|
if (hdrtype == 0x80)
|
||||||
model_str = "LP1050DC 2Gb 2-port PCI-X";
|
m = (typeof(m)){"LP1050DC", max_speed, ports, "PCI-X"};
|
||||||
else
|
else
|
||||||
model_str = "LP1050 2Gb PCI-X";
|
m = (typeof(m)){"LP1050", max_speed, ports, "PCI-X"};
|
||||||
break;
|
break;
|
||||||
case PCI_DEVICE_ID_HELIOS:
|
case PCI_DEVICE_ID_HELIOS:
|
||||||
if (hdrtype == 0x80)
|
if (hdrtype == 0x80)
|
||||||
model_str = "LP11002 4Gb 2-port PCI-X2";
|
m = (typeof(m)){"LP11002", max_speed, ports, "PCI-X2"};
|
||||||
else
|
else
|
||||||
model_str = "LP11000 4Gb PCI-X2";
|
m = (typeof(m)){"LP11000", max_speed, ports, "PCI-X2"};
|
||||||
break;
|
break;
|
||||||
case PCI_DEVICE_ID_HELIOS_SCSP:
|
case PCI_DEVICE_ID_HELIOS_SCSP:
|
||||||
model_str = "LP11000-SP 4Gb PCI-X2";
|
m = (typeof(m)){"LP11000-SP", max_speed, ports, "PCI-X2"};
|
||||||
break;
|
break;
|
||||||
case PCI_DEVICE_ID_HELIOS_DCSP:
|
case PCI_DEVICE_ID_HELIOS_DCSP:
|
||||||
model_str = "LP11002-SP 4Gb 2-port PCI-X2";
|
m = (typeof(m)){"LP11002-SP", max_speed, ports, "PCI-X2"};
|
||||||
break;
|
break;
|
||||||
case PCI_DEVICE_ID_NEPTUNE:
|
case PCI_DEVICE_ID_NEPTUNE:
|
||||||
if (hdrtype == 0x80)
|
if (hdrtype == 0x80)
|
||||||
model_str = "LPe1002 4Gb 2-port";
|
m = (typeof(m)){"LPe1002", max_speed, ports, "PCIe"};
|
||||||
else
|
else
|
||||||
model_str = "LPe1000 4Gb PCIe";
|
m = (typeof(m)){"LPe1000", max_speed, ports, "PCIe"};
|
||||||
break;
|
break;
|
||||||
case PCI_DEVICE_ID_NEPTUNE_SCSP:
|
case PCI_DEVICE_ID_NEPTUNE_SCSP:
|
||||||
model_str = "LPe1000-SP 4Gb PCIe";
|
m = (typeof(m)){"LPe1000-SP", max_speed, ports, "PCIe"};
|
||||||
break;
|
break;
|
||||||
case PCI_DEVICE_ID_NEPTUNE_DCSP:
|
case PCI_DEVICE_ID_NEPTUNE_DCSP:
|
||||||
model_str = "LPe1002-SP 4Gb 2-port PCIe";
|
m = (typeof(m)){"LPe1002-SP", max_speed, ports, "PCIe"};
|
||||||
break;
|
break;
|
||||||
case PCI_DEVICE_ID_BMID:
|
case PCI_DEVICE_ID_BMID:
|
||||||
model_str = "LP1150 4Gb PCI-X2";
|
m = (typeof(m)){"LP1150", max_speed, ports, "PCI-X2"};
|
||||||
break;
|
break;
|
||||||
case PCI_DEVICE_ID_BSMB:
|
case PCI_DEVICE_ID_BSMB:
|
||||||
model_str = "LP111 4Gb PCI-X2";
|
m = (typeof(m)){"LP111", max_speed, ports, "PCI-X2"};
|
||||||
break;
|
break;
|
||||||
case PCI_DEVICE_ID_ZEPHYR:
|
case PCI_DEVICE_ID_ZEPHYR:
|
||||||
if (hdrtype == 0x80)
|
if (hdrtype == 0x80)
|
||||||
model_str = "LPe11002 4Gb 2-port PCIe";
|
m = (typeof(m)){"LPe11002", max_speed, ports, "PCIe"};
|
||||||
else
|
else
|
||||||
model_str = "LPe11000 4Gb PCIe";
|
m = (typeof(m)){"LPe11000", max_speed, ports, "PCIe"};
|
||||||
break;
|
break;
|
||||||
case PCI_DEVICE_ID_ZEPHYR_SCSP:
|
case PCI_DEVICE_ID_ZEPHYR_SCSP:
|
||||||
model_str = "LPe11000-SP 4Gb PCIe";
|
m = (typeof(m)){"LPe11000", max_speed, ports, "PCIe"};
|
||||||
break;
|
break;
|
||||||
case PCI_DEVICE_ID_ZEPHYR_DCSP:
|
case PCI_DEVICE_ID_ZEPHYR_DCSP:
|
||||||
model_str = "LPe11002-SP 4Gb 2-port PCIe";
|
m = (typeof(m)){"LPe11002-SP", max_speed, ports, "PCIe"};
|
||||||
break;
|
break;
|
||||||
case PCI_DEVICE_ID_ZMID:
|
case PCI_DEVICE_ID_ZMID:
|
||||||
model_str = "LPe1150 4Gb PCIe";
|
m = (typeof(m)){"LPe1150", max_speed, ports, "PCIe"};
|
||||||
break;
|
break;
|
||||||
case PCI_DEVICE_ID_ZSMB:
|
case PCI_DEVICE_ID_ZSMB:
|
||||||
model_str = "LPe111 4Gb PCIe";
|
m = (typeof(m)){"LPe111", max_speed, ports, "PCIe"};
|
||||||
break;
|
break;
|
||||||
case PCI_DEVICE_ID_LP101:
|
case PCI_DEVICE_ID_LP101:
|
||||||
model_str = "LP101 2Gb PCI-X";
|
m = (typeof(m)){"LP101", max_speed, ports, "PCI-X"};
|
||||||
break;
|
break;
|
||||||
case PCI_DEVICE_ID_LP10000S:
|
case PCI_DEVICE_ID_LP10000S:
|
||||||
model_str = "LP10000-S 2Gb PCI";
|
m = (typeof(m)){"LP10000-S", max_speed, ports, "PCI"};
|
||||||
break;
|
break;
|
||||||
case PCI_DEVICE_ID_LP11000S:
|
case PCI_DEVICE_ID_LP11000S:
|
||||||
case PCI_DEVICE_ID_LPE11000S:
|
case PCI_DEVICE_ID_LPE11000S:
|
||||||
switch (dev_subid) {
|
switch (dev_subid) {
|
||||||
case PCI_SUBSYSTEM_ID_LP11000S:
|
case PCI_SUBSYSTEM_ID_LP11000S:
|
||||||
model_str = "LP11002-S 4Gb PCI-X2";
|
m = (typeof(m)){"LP11000-S", max_speed,
|
||||||
|
ports, "PCI-X2"};
|
||||||
break;
|
break;
|
||||||
case PCI_SUBSYSTEM_ID_LP11002S:
|
case PCI_SUBSYSTEM_ID_LP11002S:
|
||||||
model_str = "LP11000-S 4Gb 2-port PCI-X2";
|
m = (typeof(m)){"LP11002-S", max_speed,
|
||||||
|
ports, "PCI-X2"};
|
||||||
break;
|
break;
|
||||||
case PCI_SUBSYSTEM_ID_LPE11000S:
|
case PCI_SUBSYSTEM_ID_LPE11000S:
|
||||||
model_str = "LPe11002-S 4Gb PCIe";
|
m = (typeof(m)){"LPe11000-S", max_speed,
|
||||||
|
ports, "PCIe"};
|
||||||
break;
|
break;
|
||||||
case PCI_SUBSYSTEM_ID_LPE11002S:
|
case PCI_SUBSYSTEM_ID_LPE11002S:
|
||||||
model_str = "LPe11002-S 4Gb 2-port PCIe";
|
m = (typeof(m)){"LPe11002-S", max_speed,
|
||||||
|
ports, "PCIe"};
|
||||||
break;
|
break;
|
||||||
case PCI_SUBSYSTEM_ID_LPE11010S:
|
case PCI_SUBSYSTEM_ID_LPE11010S:
|
||||||
model_str = "LPe11010-S 4Gb 10-port PCIe";
|
m = (typeof(m)){"LPe11010-S", max_speed,
|
||||||
|
"10-port ", "PCIe"};
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
m = (typeof(m)){ 0 };
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
m = (typeof(m)){ 0 };
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (mdp)
|
|
||||||
sscanf(model_str, "%s", mdp);
|
if (mdp && mdp[0] == '\0')
|
||||||
if (descp)
|
snprintf(mdp, 79,"%s", m.name);
|
||||||
sprintf(descp, "Emulex %s Fibre Channel Adapter", model_str);
|
if (descp && descp[0] == '\0')
|
||||||
|
snprintf(descp, 255,
|
||||||
|
"Emulex %s %dGb %s%s Fibre Channel Adapter",
|
||||||
|
m.name, m.max_speed, m.ports, m.bus);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************/
|
/**************************************************/
|
||||||
|
@ -1462,9 +1529,23 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
|
||||||
phba->pci_bar2_map = pci_resource_start(phba->pcidev, 2);
|
phba->pci_bar2_map = pci_resource_start(phba->pcidev, 2);
|
||||||
bar2map_len = pci_resource_len(phba->pcidev, 2);
|
bar2map_len = pci_resource_len(phba->pcidev, 2);
|
||||||
|
|
||||||
/* Map HBA SLIM and Control Registers to a kernel virtual address. */
|
/* Map HBA SLIM to a kernel virtual address. */
|
||||||
phba->slim_memmap_p = ioremap(phba->pci_bar0_map, bar0map_len);
|
phba->slim_memmap_p = ioremap(phba->pci_bar0_map, bar0map_len);
|
||||||
|
if (!phba->slim_memmap_p) {
|
||||||
|
error = -ENODEV;
|
||||||
|
dev_printk(KERN_ERR, &pdev->dev,
|
||||||
|
"ioremap failed for SLIM memory.\n");
|
||||||
|
goto out_idr_remove;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Map HBA Control Registers to a kernel virtual address. */
|
||||||
phba->ctrl_regs_memmap_p = ioremap(phba->pci_bar2_map, bar2map_len);
|
phba->ctrl_regs_memmap_p = ioremap(phba->pci_bar2_map, bar2map_len);
|
||||||
|
if (!phba->ctrl_regs_memmap_p) {
|
||||||
|
error = -ENODEV;
|
||||||
|
dev_printk(KERN_ERR, &pdev->dev,
|
||||||
|
"ioremap failed for HBA control registers.\n");
|
||||||
|
goto out_iounmap_slim;
|
||||||
|
}
|
||||||
|
|
||||||
/* Allocate memory for SLI-2 structures */
|
/* Allocate memory for SLI-2 structures */
|
||||||
phba->slim2p = dma_alloc_coherent(&phba->pcidev->dev, SLI2_SLIM_SIZE,
|
phba->slim2p = dma_alloc_coherent(&phba->pcidev->dev, SLI2_SLIM_SIZE,
|
||||||
|
@ -1539,7 +1620,6 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
|
||||||
INIT_LIST_HEAD(&phba->lpfc_scsi_buf_list);
|
INIT_LIST_HEAD(&phba->lpfc_scsi_buf_list);
|
||||||
|
|
||||||
host->transportt = lpfc_transport_template;
|
host->transportt = lpfc_transport_template;
|
||||||
host->hostdata[0] = (unsigned long)phba;
|
|
||||||
pci_set_drvdata(pdev, host);
|
pci_set_drvdata(pdev, host);
|
||||||
error = scsi_add_host(host, &pdev->dev);
|
error = scsi_add_host(host, &pdev->dev);
|
||||||
if (error)
|
if (error)
|
||||||
|
@ -1590,21 +1670,14 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
|
||||||
lpfc_get_hba_sym_node_name(phba, fc_host_symbolic_name(host));
|
lpfc_get_hba_sym_node_name(phba, fc_host_symbolic_name(host));
|
||||||
|
|
||||||
fc_host_supported_speeds(host) = 0;
|
fc_host_supported_speeds(host) = 0;
|
||||||
switch (FC_JEDEC_ID(phba->vpd.rev.biuRev)) {
|
if (phba->lmt & LMT_10Gb)
|
||||||
case VIPER_JEDEC_ID:
|
|
||||||
fc_host_supported_speeds(host) |= FC_PORTSPEED_10GBIT;
|
fc_host_supported_speeds(host) |= FC_PORTSPEED_10GBIT;
|
||||||
break;
|
if (phba->lmt & LMT_4Gb)
|
||||||
case HELIOS_JEDEC_ID:
|
|
||||||
fc_host_supported_speeds(host) |= FC_PORTSPEED_4GBIT;
|
fc_host_supported_speeds(host) |= FC_PORTSPEED_4GBIT;
|
||||||
/* Fall through */
|
if (phba->lmt & LMT_2Gb)
|
||||||
case CENTAUR_2G_JEDEC_ID:
|
|
||||||
case PEGASUS_JEDEC_ID:
|
|
||||||
case THOR_JEDEC_ID:
|
|
||||||
fc_host_supported_speeds(host) |= FC_PORTSPEED_2GBIT;
|
fc_host_supported_speeds(host) |= FC_PORTSPEED_2GBIT;
|
||||||
/* Fall through */
|
if (phba->lmt & LMT_1Gb)
|
||||||
default:
|
fc_host_supported_speeds(host) |= FC_PORTSPEED_1GBIT;
|
||||||
fc_host_supported_speeds(host) = FC_PORTSPEED_1GBIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
fc_host_maxframe_size(host) =
|
fc_host_maxframe_size(host) =
|
||||||
((((uint32_t) phba->fc_sparam.cmn.bbRcvSizeMsb & 0x0F) << 8) |
|
((((uint32_t) phba->fc_sparam.cmn.bbRcvSizeMsb & 0x0F) << 8) |
|
||||||
|
@ -1643,6 +1716,7 @@ out_free_slim:
|
||||||
phba->slim2p_mapping);
|
phba->slim2p_mapping);
|
||||||
out_iounmap:
|
out_iounmap:
|
||||||
iounmap(phba->ctrl_regs_memmap_p);
|
iounmap(phba->ctrl_regs_memmap_p);
|
||||||
|
out_iounmap_slim:
|
||||||
iounmap(phba->slim_memmap_p);
|
iounmap(phba->slim_memmap_p);
|
||||||
out_idr_remove:
|
out_idr_remove:
|
||||||
idr_remove(&lpfc_hba_index, phba->brd_no);
|
idr_remove(&lpfc_hba_index, phba->brd_no);
|
||||||
|
@ -1660,7 +1734,7 @@ static void __devexit
|
||||||
lpfc_pci_remove_one(struct pci_dev *pdev)
|
lpfc_pci_remove_one(struct pci_dev *pdev)
|
||||||
{
|
{
|
||||||
struct Scsi_Host *host = pci_get_drvdata(pdev);
|
struct Scsi_Host *host = pci_get_drvdata(pdev);
|
||||||
struct lpfc_hba *phba = (struct lpfc_hba *)host->hostdata[0];
|
struct lpfc_hba *phba = (struct lpfc_hba *)host->hostdata;
|
||||||
unsigned long iflag;
|
unsigned long iflag;
|
||||||
|
|
||||||
lpfc_free_sysfs_attr(phba);
|
lpfc_free_sysfs_attr(phba);
|
||||||
|
@ -1681,6 +1755,7 @@ lpfc_pci_remove_one(struct pci_dev *pdev)
|
||||||
* the HBA.
|
* the HBA.
|
||||||
*/
|
*/
|
||||||
lpfc_sli_hba_down(phba);
|
lpfc_sli_hba_down(phba);
|
||||||
|
lpfc_sli_brdrestart(phba);
|
||||||
|
|
||||||
/* Release the irq reservation */
|
/* Release the irq reservation */
|
||||||
free_irq(phba->pcidev->irq, phba);
|
free_irq(phba->pcidev->irq, phba);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
* This file is part of the Emulex Linux Device Driver for *
|
* This file is part of the Emulex Linux Device Driver for *
|
||||||
* Fibre Channel Host Bus Adapters. *
|
* Fibre Channel Host Bus Adapters. *
|
||||||
* Copyright (C) 2004-2005 Emulex. All rights reserved. *
|
* Copyright (C) 2004-2006 Emulex. All rights reserved. *
|
||||||
* EMULEX and SLI are trademarks of Emulex. *
|
* EMULEX and SLI are trademarks of Emulex. *
|
||||||
* www.emulex.com *
|
* www.emulex.com *
|
||||||
* Portions Copyright (C) 2004-2005 Christoph Hellwig *
|
* Portions Copyright (C) 2004-2005 Christoph Hellwig *
|
||||||
|
@ -195,6 +195,9 @@ lpfc_init_link(struct lpfc_hba * phba,
|
||||||
mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_PT_PT;
|
mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_PT_PT;
|
||||||
mb->un.varInitLnk.link_flags |= FLAGS_TOPOLOGY_FAILOVER;
|
mb->un.varInitLnk.link_flags |= FLAGS_TOPOLOGY_FAILOVER;
|
||||||
break;
|
break;
|
||||||
|
case FLAGS_LOCAL_LB:
|
||||||
|
mb->un.varInitLnk.link_flags = FLAGS_LOCAL_LB;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* NEW_FEATURE
|
/* NEW_FEATURE
|
||||||
|
@ -336,6 +339,23 @@ lpfc_read_config(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*************************************************/
|
||||||
|
/* lpfc_read_lnk_stat Issue a READ LINK STATUS */
|
||||||
|
/* mailbox command */
|
||||||
|
/*************************************************/
|
||||||
|
void
|
||||||
|
lpfc_read_lnk_stat(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
|
||||||
|
{
|
||||||
|
MAILBOX_t *mb;
|
||||||
|
|
||||||
|
mb = &pmb->mb;
|
||||||
|
memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
|
||||||
|
|
||||||
|
mb->mbxCommand = MBX_READ_LNK_STAT;
|
||||||
|
mb->mbxOwner = OWN_HOST;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/********************************************/
|
/********************************************/
|
||||||
/* lpfc_reg_login Issue a REG_LOGIN */
|
/* lpfc_reg_login Issue a REG_LOGIN */
|
||||||
/* mailbox command */
|
/* mailbox command */
|
||||||
|
@ -619,6 +639,17 @@ lpfc_config_port(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
|
||||||
phba->brd_no);
|
phba->brd_no);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
lpfc_kill_board(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
|
||||||
|
{
|
||||||
|
MAILBOX_t *mb = &pmb->mb;
|
||||||
|
|
||||||
|
memset(pmb, 0, sizeof(LPFC_MBOXQ_t));
|
||||||
|
mb->mbxCommand = MBX_KILL_BOARD;
|
||||||
|
mb->mbxOwner = OWN_HOST;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
lpfc_mbox_put(struct lpfc_hba * phba, LPFC_MBOXQ_t * mbq)
|
lpfc_mbox_put(struct lpfc_hba * phba, LPFC_MBOXQ_t * mbq)
|
||||||
{
|
{
|
||||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,7 +1,7 @@
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
* This file is part of the Emulex Linux Device Driver for *
|
* This file is part of the Emulex Linux Device Driver for *
|
||||||
* Fibre Channel Host Bus Adapters. *
|
* Fibre Channel Host Bus Adapters. *
|
||||||
* Copyright (C) 2004-2005 Emulex. All rights reserved. *
|
* Copyright (C) 2004-2006 Emulex. All rights reserved. *
|
||||||
* EMULEX and SLI are trademarks of Emulex. *
|
* EMULEX and SLI are trademarks of Emulex. *
|
||||||
* www.emulex.com *
|
* www.emulex.com *
|
||||||
* Portions Copyright (C) 2004-2005 Christoph Hellwig *
|
* Portions Copyright (C) 2004-2005 Christoph Hellwig *
|
||||||
|
@ -467,7 +467,12 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
|
||||||
sdev = cmd->device;
|
sdev = cmd->device;
|
||||||
cmd->scsi_done(cmd);
|
cmd->scsi_done(cmd);
|
||||||
|
|
||||||
if (!result &&
|
if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) {
|
||||||
|
lpfc_release_scsi_buf(phba, lpfc_cmd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!result && pnode != NULL &&
|
||||||
((jiffies - pnode->last_ramp_up_time) >
|
((jiffies - pnode->last_ramp_up_time) >
|
||||||
LPFC_Q_RAMP_UP_INTERVAL * HZ) &&
|
LPFC_Q_RAMP_UP_INTERVAL * HZ) &&
|
||||||
((jiffies - pnode->last_q_full_time) >
|
((jiffies - pnode->last_q_full_time) >
|
||||||
|
@ -495,7 +500,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
|
||||||
* Check for queue full. If the lun is reporting queue full, then
|
* Check for queue full. If the lun is reporting queue full, then
|
||||||
* back off the lun queue depth to prevent target overloads.
|
* back off the lun queue depth to prevent target overloads.
|
||||||
*/
|
*/
|
||||||
if (result == SAM_STAT_TASK_SET_FULL) {
|
if (result == SAM_STAT_TASK_SET_FULL && pnode != NULL) {
|
||||||
pnode->last_q_full_time = jiffies;
|
pnode->last_q_full_time = jiffies;
|
||||||
|
|
||||||
shost_for_each_device(tmp_sdev, sdev->host) {
|
shost_for_each_device(tmp_sdev, sdev->host) {
|
||||||
|
@ -743,7 +748,7 @@ lpfc_scsi_tgt_reset(struct lpfc_scsi_buf * lpfc_cmd, struct lpfc_hba * phba)
|
||||||
const char *
|
const char *
|
||||||
lpfc_info(struct Scsi_Host *host)
|
lpfc_info(struct Scsi_Host *host)
|
||||||
{
|
{
|
||||||
struct lpfc_hba *phba = (struct lpfc_hba *) host->hostdata[0];
|
struct lpfc_hba *phba = (struct lpfc_hba *) host->hostdata;
|
||||||
int len;
|
int len;
|
||||||
static char lpfcinfobuf[384];
|
static char lpfcinfobuf[384];
|
||||||
|
|
||||||
|
@ -803,7 +808,7 @@ static int
|
||||||
lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
|
lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
|
||||||
{
|
{
|
||||||
struct lpfc_hba *phba =
|
struct lpfc_hba *phba =
|
||||||
(struct lpfc_hba *) cmnd->device->host->hostdata[0];
|
(struct lpfc_hba *) cmnd->device->host->hostdata;
|
||||||
struct lpfc_sli *psli = &phba->sli;
|
struct lpfc_sli *psli = &phba->sli;
|
||||||
struct lpfc_rport_data *rdata = cmnd->device->hostdata;
|
struct lpfc_rport_data *rdata = cmnd->device->hostdata;
|
||||||
struct lpfc_nodelist *ndlp = rdata->pnode;
|
struct lpfc_nodelist *ndlp = rdata->pnode;
|
||||||
|
@ -877,7 +882,7 @@ static int
|
||||||
lpfc_abort_handler(struct scsi_cmnd *cmnd)
|
lpfc_abort_handler(struct scsi_cmnd *cmnd)
|
||||||
{
|
{
|
||||||
struct Scsi_Host *shost = cmnd->device->host;
|
struct Scsi_Host *shost = cmnd->device->host;
|
||||||
struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata[0];
|
struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata;
|
||||||
struct lpfc_sli_ring *pring = &phba->sli.ring[phba->sli.fcp_ring];
|
struct lpfc_sli_ring *pring = &phba->sli.ring[phba->sli.fcp_ring];
|
||||||
struct lpfc_iocbq *iocb;
|
struct lpfc_iocbq *iocb;
|
||||||
struct lpfc_iocbq *abtsiocb;
|
struct lpfc_iocbq *abtsiocb;
|
||||||
|
@ -981,7 +986,7 @@ static int
|
||||||
lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
|
lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
|
||||||
{
|
{
|
||||||
struct Scsi_Host *shost = cmnd->device->host;
|
struct Scsi_Host *shost = cmnd->device->host;
|
||||||
struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata[0];
|
struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata;
|
||||||
struct lpfc_scsi_buf *lpfc_cmd;
|
struct lpfc_scsi_buf *lpfc_cmd;
|
||||||
struct lpfc_iocbq *iocbq, *iocbqrsp;
|
struct lpfc_iocbq *iocbq, *iocbqrsp;
|
||||||
struct lpfc_rport_data *rdata = cmnd->device->hostdata;
|
struct lpfc_rport_data *rdata = cmnd->device->hostdata;
|
||||||
|
@ -1094,7 +1099,7 @@ static int
|
||||||
lpfc_reset_bus_handler(struct scsi_cmnd *cmnd)
|
lpfc_reset_bus_handler(struct scsi_cmnd *cmnd)
|
||||||
{
|
{
|
||||||
struct Scsi_Host *shost = cmnd->device->host;
|
struct Scsi_Host *shost = cmnd->device->host;
|
||||||
struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata[0];
|
struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata;
|
||||||
struct lpfc_nodelist *ndlp = NULL;
|
struct lpfc_nodelist *ndlp = NULL;
|
||||||
int match;
|
int match;
|
||||||
int ret = FAILED, i, err_count = 0;
|
int ret = FAILED, i, err_count = 0;
|
||||||
|
@ -1195,7 +1200,7 @@ out:
|
||||||
static int
|
static int
|
||||||
lpfc_slave_alloc(struct scsi_device *sdev)
|
lpfc_slave_alloc(struct scsi_device *sdev)
|
||||||
{
|
{
|
||||||
struct lpfc_hba *phba = (struct lpfc_hba *)sdev->host->hostdata[0];
|
struct lpfc_hba *phba = (struct lpfc_hba *)sdev->host->hostdata;
|
||||||
struct lpfc_scsi_buf *scsi_buf = NULL;
|
struct lpfc_scsi_buf *scsi_buf = NULL;
|
||||||
struct fc_rport *rport = starget_to_rport(scsi_target(sdev));
|
struct fc_rport *rport = starget_to_rport(scsi_target(sdev));
|
||||||
uint32_t total = 0, i;
|
uint32_t total = 0, i;
|
||||||
|
@ -1251,7 +1256,7 @@ lpfc_slave_alloc(struct scsi_device *sdev)
|
||||||
static int
|
static int
|
||||||
lpfc_slave_configure(struct scsi_device *sdev)
|
lpfc_slave_configure(struct scsi_device *sdev)
|
||||||
{
|
{
|
||||||
struct lpfc_hba *phba = (struct lpfc_hba *) sdev->host->hostdata[0];
|
struct lpfc_hba *phba = (struct lpfc_hba *) sdev->host->hostdata;
|
||||||
struct fc_rport *rport = starget_to_rport(sdev->sdev_target);
|
struct fc_rport *rport = starget_to_rport(sdev->sdev_target);
|
||||||
|
|
||||||
if (sdev->tagged_supported)
|
if (sdev->tagged_supported)
|
||||||
|
|
|
@ -23,10 +23,13 @@
|
||||||
struct lpfc_hba;
|
struct lpfc_hba;
|
||||||
|
|
||||||
#define list_remove_head(list, entry, type, member) \
|
#define list_remove_head(list, entry, type, member) \
|
||||||
|
do { \
|
||||||
|
entry = NULL; \
|
||||||
if (!list_empty(list)) { \
|
if (!list_empty(list)) { \
|
||||||
entry = list_entry((list)->next, type, member); \
|
entry = list_entry((list)->next, type, member); \
|
||||||
list_del_init(&entry->member); \
|
list_del_init(&entry->member); \
|
||||||
}
|
} \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
#define list_get_first(list, type, member) \
|
#define list_get_first(list, type, member) \
|
||||||
(list_empty(list)) ? NULL : \
|
(list_empty(list)) ? NULL : \
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
* This file is part of the Emulex Linux Device Driver for *
|
* This file is part of the Emulex Linux Device Driver for *
|
||||||
* Fibre Channel Host Bus Adapters. *
|
* Fibre Channel Host Bus Adapters. *
|
||||||
* Copyright (C) 2004-2005 Emulex. All rights reserved. *
|
* Copyright (C) 2004-2006 Emulex. All rights reserved. *
|
||||||
* EMULEX and SLI are trademarks of Emulex. *
|
* EMULEX and SLI are trademarks of Emulex. *
|
||||||
* www.emulex.com *
|
* www.emulex.com *
|
||||||
* Portions Copyright (C) 2004-2005 Christoph Hellwig *
|
* Portions Copyright (C) 2004-2005 Christoph Hellwig *
|
||||||
|
@ -513,7 +513,9 @@ lpfc_sli_chk_mbx_command(uint8_t mbxCommand)
|
||||||
case MBX_SET_MASK:
|
case MBX_SET_MASK:
|
||||||
case MBX_SET_SLIM:
|
case MBX_SET_SLIM:
|
||||||
case MBX_UNREG_D_ID:
|
case MBX_UNREG_D_ID:
|
||||||
|
case MBX_KILL_BOARD:
|
||||||
case MBX_CONFIG_FARP:
|
case MBX_CONFIG_FARP:
|
||||||
|
case MBX_BEACON:
|
||||||
case MBX_LOAD_AREA:
|
case MBX_LOAD_AREA:
|
||||||
case MBX_RUN_BIU_DIAG64:
|
case MBX_RUN_BIU_DIAG64:
|
||||||
case MBX_CONFIG_PORT:
|
case MBX_CONFIG_PORT:
|
||||||
|
@ -764,7 +766,9 @@ lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
|
||||||
}
|
}
|
||||||
/* unSolicited Responses */
|
/* unSolicited Responses */
|
||||||
if (pring->prt[0].profile) {
|
if (pring->prt[0].profile) {
|
||||||
(pring->prt[0].lpfc_sli_rcv_unsol_event) (phba, pring, saveq);
|
if (pring->prt[0].lpfc_sli_rcv_unsol_event)
|
||||||
|
(pring->prt[0].lpfc_sli_rcv_unsol_event) (phba, pring,
|
||||||
|
saveq);
|
||||||
match = 1;
|
match = 1;
|
||||||
} else {
|
} else {
|
||||||
/* We must search, based on rctl / type
|
/* We must search, based on rctl / type
|
||||||
|
@ -775,8 +779,9 @@ lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
|
||||||
Rctl)
|
Rctl)
|
||||||
&& (pring->prt[i].
|
&& (pring->prt[i].
|
||||||
type == Type)) {
|
type == Type)) {
|
||||||
(pring->prt[i].lpfc_sli_rcv_unsol_event)
|
if (pring->prt[i].lpfc_sli_rcv_unsol_event)
|
||||||
(phba, pring, saveq);
|
(pring->prt[i].lpfc_sli_rcv_unsol_event)
|
||||||
|
(phba, pring, saveq);
|
||||||
match = 1;
|
match = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1149,12 +1154,17 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba * phba,
|
||||||
cmdiocbq = lpfc_sli_iocbq_lookup(phba, pring,
|
cmdiocbq = lpfc_sli_iocbq_lookup(phba, pring,
|
||||||
&rspiocbq);
|
&rspiocbq);
|
||||||
if ((cmdiocbq) && (cmdiocbq->iocb_cmpl)) {
|
if ((cmdiocbq) && (cmdiocbq->iocb_cmpl)) {
|
||||||
spin_unlock_irqrestore(
|
if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) {
|
||||||
phba->host->host_lock, iflag);
|
(cmdiocbq->iocb_cmpl)(phba, cmdiocbq,
|
||||||
(cmdiocbq->iocb_cmpl)(phba, cmdiocbq,
|
&rspiocbq);
|
||||||
&rspiocbq);
|
} else {
|
||||||
spin_lock_irqsave(phba->host->host_lock,
|
spin_unlock_irqrestore(
|
||||||
iflag);
|
phba->host->host_lock, iflag);
|
||||||
|
(cmdiocbq->iocb_cmpl)(phba, cmdiocbq,
|
||||||
|
&rspiocbq);
|
||||||
|
spin_lock_irqsave(phba->host->host_lock,
|
||||||
|
iflag);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -1512,98 +1522,240 @@ lpfc_sli_abort_iocb_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
|
||||||
return errcnt;
|
return errcnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
int
|
||||||
* lpfc_sli_send_reset
|
lpfc_sli_brdready(struct lpfc_hba * phba, uint32_t mask)
|
||||||
*
|
|
||||||
* Note: After returning from this function, the HBA cannot be accessed for
|
|
||||||
* 1 ms. Since we do not wish to delay in interrupt context, it is the
|
|
||||||
* responsibility of the caller to perform the mdelay(1) and flush via readl().
|
|
||||||
******************************************************************************/
|
|
||||||
static int
|
|
||||||
lpfc_sli_send_reset(struct lpfc_hba * phba, uint16_t skip_post)
|
|
||||||
{
|
{
|
||||||
MAILBOX_t *swpmb;
|
uint32_t status;
|
||||||
volatile uint32_t word0;
|
int i = 0;
|
||||||
void __iomem *to_slim;
|
int retval = 0;
|
||||||
unsigned long flags = 0;
|
|
||||||
|
|
||||||
spin_lock_irqsave(phba->host->host_lock, flags);
|
/* Read the HBA Host Status Register */
|
||||||
|
status = readl(phba->HSregaddr);
|
||||||
|
|
||||||
/* A board reset must use REAL SLIM. */
|
/*
|
||||||
phba->sli.sli_flag &= ~LPFC_SLI2_ACTIVE;
|
* Check status register every 100ms for 5 retries, then every
|
||||||
|
* 500ms for 5, then every 2.5 sec for 5, then reset board and
|
||||||
|
* every 2.5 sec for 4.
|
||||||
|
* Break our of the loop if errors occurred during init.
|
||||||
|
*/
|
||||||
|
while (((status & mask) != mask) &&
|
||||||
|
!(status & HS_FFERM) &&
|
||||||
|
i++ < 20) {
|
||||||
|
|
||||||
word0 = 0;
|
if (i <= 5)
|
||||||
swpmb = (MAILBOX_t *) & word0;
|
msleep(10);
|
||||||
swpmb->mbxCommand = MBX_RESTART;
|
else if (i <= 10)
|
||||||
swpmb->mbxHc = 1;
|
msleep(500);
|
||||||
|
else
|
||||||
|
msleep(2500);
|
||||||
|
|
||||||
to_slim = phba->MBslimaddr;
|
if (i == 15) {
|
||||||
writel(*(uint32_t *) swpmb, to_slim);
|
phba->hba_state = LPFC_STATE_UNKNOWN; /* Do post */
|
||||||
readl(to_slim); /* flush */
|
lpfc_sli_brdrestart(phba);
|
||||||
|
}
|
||||||
/* Only skip post after fc_ffinit is completed */
|
/* Read the HBA Host Status Register */
|
||||||
if (skip_post) {
|
status = readl(phba->HSregaddr);
|
||||||
word0 = 1; /* This is really setting up word1 */
|
|
||||||
} else {
|
|
||||||
word0 = 0; /* This is really setting up word1 */
|
|
||||||
}
|
}
|
||||||
to_slim = phba->MBslimaddr + sizeof (uint32_t);
|
|
||||||
writel(*(uint32_t *) swpmb, to_slim);
|
|
||||||
readl(to_slim); /* flush */
|
|
||||||
|
|
||||||
/* Turn off parity checking and serr during the physical reset */
|
/* Check to see if any errors occurred during init */
|
||||||
pci_read_config_word(phba->pcidev, PCI_COMMAND, &phba->pci_cfg_value);
|
if ((status & HS_FFERM) || (i >= 20)) {
|
||||||
pci_write_config_word(phba->pcidev, PCI_COMMAND,
|
phba->hba_state = LPFC_HBA_ERROR;
|
||||||
(phba->pci_cfg_value &
|
retval = 1;
|
||||||
~(PCI_COMMAND_PARITY | PCI_COMMAND_SERR)));
|
}
|
||||||
|
|
||||||
writel(HC_INITFF, phba->HCregaddr);
|
return retval;
|
||||||
|
|
||||||
phba->hba_state = LPFC_INIT_START;
|
|
||||||
spin_unlock_irqrestore(phba->host->host_lock, flags);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
#define BARRIER_TEST_PATTERN (0xdeadbeef)
|
||||||
lpfc_sli_brdreset(struct lpfc_hba * phba, uint16_t skip_post)
|
|
||||||
|
void lpfc_reset_barrier(struct lpfc_hba * phba)
|
||||||
{
|
{
|
||||||
|
uint32_t * resp_buf;
|
||||||
|
uint32_t * mbox_buf;
|
||||||
|
volatile uint32_t mbox;
|
||||||
|
uint32_t hc_copy;
|
||||||
|
int i;
|
||||||
|
uint8_t hdrtype;
|
||||||
|
|
||||||
|
pci_read_config_byte(phba->pcidev, PCI_HEADER_TYPE, &hdrtype);
|
||||||
|
if (hdrtype != 0x80 ||
|
||||||
|
(FC_JEDEC_ID(phba->vpd.rev.biuRev) != HELIOS_JEDEC_ID &&
|
||||||
|
FC_JEDEC_ID(phba->vpd.rev.biuRev) != THOR_JEDEC_ID))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tell the other part of the chip to suspend temporarily all
|
||||||
|
* its DMA activity.
|
||||||
|
*/
|
||||||
|
resp_buf = (uint32_t *)phba->MBslimaddr;
|
||||||
|
|
||||||
|
/* Disable the error attention */
|
||||||
|
hc_copy = readl(phba->HCregaddr);
|
||||||
|
writel((hc_copy & ~HC_ERINT_ENA), phba->HCregaddr);
|
||||||
|
readl(phba->HCregaddr); /* flush */
|
||||||
|
|
||||||
|
if (readl(phba->HAregaddr) & HA_ERATT) {
|
||||||
|
/* Clear Chip error bit */
|
||||||
|
writel(HA_ERATT, phba->HAregaddr);
|
||||||
|
phba->stopped = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
mbox = 0;
|
||||||
|
((MAILBOX_t *)&mbox)->mbxCommand = MBX_KILL_BOARD;
|
||||||
|
((MAILBOX_t *)&mbox)->mbxOwner = OWN_CHIP;
|
||||||
|
|
||||||
|
writel(BARRIER_TEST_PATTERN, (resp_buf + 1));
|
||||||
|
mbox_buf = (uint32_t *)phba->MBslimaddr;
|
||||||
|
writel(mbox, mbox_buf);
|
||||||
|
|
||||||
|
for (i = 0;
|
||||||
|
readl(resp_buf + 1) != ~(BARRIER_TEST_PATTERN) && i < 50; i++)
|
||||||
|
mdelay(1);
|
||||||
|
|
||||||
|
if (readl(resp_buf + 1) != ~(BARRIER_TEST_PATTERN)) {
|
||||||
|
if (phba->sli.sli_flag & LPFC_SLI2_ACTIVE ||
|
||||||
|
phba->stopped)
|
||||||
|
goto restore_hc;
|
||||||
|
else
|
||||||
|
goto clear_errat;
|
||||||
|
}
|
||||||
|
|
||||||
|
((MAILBOX_t *)&mbox)->mbxOwner = OWN_HOST;
|
||||||
|
for (i = 0; readl(resp_buf) != mbox && i < 500; i++)
|
||||||
|
mdelay(1);
|
||||||
|
|
||||||
|
clear_errat:
|
||||||
|
|
||||||
|
while (!(readl(phba->HAregaddr) & HA_ERATT) && ++i < 500)
|
||||||
|
mdelay(1);
|
||||||
|
|
||||||
|
if (readl(phba->HAregaddr) & HA_ERATT) {
|
||||||
|
writel(HA_ERATT, phba->HAregaddr);
|
||||||
|
phba->stopped = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
restore_hc:
|
||||||
|
writel(hc_copy, phba->HCregaddr);
|
||||||
|
readl(phba->HCregaddr); /* flush */
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
lpfc_sli_brdkill(struct lpfc_hba * phba)
|
||||||
|
{
|
||||||
|
struct lpfc_sli *psli;
|
||||||
|
LPFC_MBOXQ_t *pmb;
|
||||||
|
uint32_t status;
|
||||||
|
uint32_t ha_copy;
|
||||||
|
int retval;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
psli = &phba->sli;
|
||||||
|
|
||||||
|
/* Kill HBA */
|
||||||
|
lpfc_printf_log(phba,
|
||||||
|
KERN_INFO,
|
||||||
|
LOG_SLI,
|
||||||
|
"%d:0329 Kill HBA Data: x%x x%x\n",
|
||||||
|
phba->brd_no,
|
||||||
|
phba->hba_state,
|
||||||
|
psli->sli_flag);
|
||||||
|
|
||||||
|
if ((pmb = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool,
|
||||||
|
GFP_KERNEL)) == 0)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/* Disable the error attention */
|
||||||
|
spin_lock_irq(phba->host->host_lock);
|
||||||
|
status = readl(phba->HCregaddr);
|
||||||
|
status &= ~HC_ERINT_ENA;
|
||||||
|
writel(status, phba->HCregaddr);
|
||||||
|
readl(phba->HCregaddr); /* flush */
|
||||||
|
spin_unlock_irq(phba->host->host_lock);
|
||||||
|
|
||||||
|
lpfc_kill_board(phba, pmb);
|
||||||
|
pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
|
||||||
|
retval = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT);
|
||||||
|
|
||||||
|
if (retval != MBX_SUCCESS) {
|
||||||
|
if (retval != MBX_BUSY)
|
||||||
|
mempool_free(pmb, phba->mbox_mem_pool);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
psli->sli_flag &= ~LPFC_SLI2_ACTIVE;
|
||||||
|
|
||||||
|
mempool_free(pmb, phba->mbox_mem_pool);
|
||||||
|
|
||||||
|
/* There is no completion for a KILL_BOARD mbox cmd. Check for an error
|
||||||
|
* attention every 100ms for 3 seconds. If we don't get ERATT after
|
||||||
|
* 3 seconds we still set HBA_ERROR state because the status of the
|
||||||
|
* board is now undefined.
|
||||||
|
*/
|
||||||
|
ha_copy = readl(phba->HAregaddr);
|
||||||
|
|
||||||
|
while ((i++ < 30) && !(ha_copy & HA_ERATT)) {
|
||||||
|
mdelay(100);
|
||||||
|
ha_copy = readl(phba->HAregaddr);
|
||||||
|
}
|
||||||
|
|
||||||
|
del_timer_sync(&psli->mbox_tmo);
|
||||||
|
if (ha_copy & HA_ERATT) {
|
||||||
|
writel(HA_ERATT, phba->HAregaddr);
|
||||||
|
phba->stopped = 1;
|
||||||
|
}
|
||||||
|
spin_lock_irq(phba->host->host_lock);
|
||||||
|
psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE;
|
||||||
|
spin_unlock_irq(phba->host->host_lock);
|
||||||
|
|
||||||
|
psli->mbox_active = NULL;
|
||||||
|
lpfc_hba_down_post(phba);
|
||||||
|
phba->hba_state = LPFC_HBA_ERROR;
|
||||||
|
|
||||||
|
return (ha_copy & HA_ERATT ? 0 : 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
lpfc_sli_brdreset(struct lpfc_hba * phba)
|
||||||
|
{
|
||||||
|
struct lpfc_sli *psli;
|
||||||
struct lpfc_sli_ring *pring;
|
struct lpfc_sli_ring *pring;
|
||||||
|
uint16_t cfg_value;
|
||||||
int i;
|
int i;
|
||||||
struct lpfc_dmabuf *mp, *next_mp;
|
|
||||||
unsigned long flags = 0;
|
|
||||||
|
|
||||||
lpfc_sli_send_reset(phba, skip_post);
|
psli = &phba->sli;
|
||||||
mdelay(1);
|
|
||||||
|
|
||||||
spin_lock_irqsave(phba->host->host_lock, flags);
|
/* Reset HBA */
|
||||||
/* Risk the write on flush case ie no delay after the readl */
|
lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
|
||||||
readl(phba->HCregaddr); /* flush */
|
"%d:0325 Reset HBA Data: x%x x%x\n", phba->brd_no,
|
||||||
/* Now toggle INITFF bit set by lpfc_sli_send_reset */
|
phba->hba_state, psli->sli_flag);
|
||||||
writel(0, phba->HCregaddr);
|
|
||||||
readl(phba->HCregaddr); /* flush */
|
|
||||||
|
|
||||||
/* Restore PCI cmd register */
|
|
||||||
pci_write_config_word(phba->pcidev, PCI_COMMAND, phba->pci_cfg_value);
|
|
||||||
|
|
||||||
/* perform board reset */
|
/* perform board reset */
|
||||||
phba->fc_eventTag = 0;
|
phba->fc_eventTag = 0;
|
||||||
phba->fc_myDID = 0;
|
phba->fc_myDID = 0;
|
||||||
phba->fc_prevDID = Mask_DID;
|
phba->fc_prevDID = 0;
|
||||||
|
|
||||||
/* Reset HBA */
|
psli->sli_flag = 0;
|
||||||
lpfc_printf_log(phba,
|
|
||||||
KERN_INFO,
|
/* Turn off parity checking and serr during the physical reset */
|
||||||
LOG_SLI,
|
pci_read_config_word(phba->pcidev, PCI_COMMAND, &cfg_value);
|
||||||
"%d:0325 Reset HBA Data: x%x x%x x%x\n",
|
pci_write_config_word(phba->pcidev, PCI_COMMAND,
|
||||||
phba->brd_no,
|
(cfg_value &
|
||||||
phba->hba_state,
|
~(PCI_COMMAND_PARITY | PCI_COMMAND_SERR)));
|
||||||
phba->sli.sli_flag,
|
|
||||||
skip_post);
|
psli->sli_flag &= ~LPFC_SLI2_ACTIVE;
|
||||||
|
/* Now toggle INITFF bit in the Host Control Register */
|
||||||
|
writel(HC_INITFF, phba->HCregaddr);
|
||||||
|
mdelay(1);
|
||||||
|
readl(phba->HCregaddr); /* flush */
|
||||||
|
writel(0, phba->HCregaddr);
|
||||||
|
readl(phba->HCregaddr); /* flush */
|
||||||
|
|
||||||
|
/* Restore PCI cmd register */
|
||||||
|
pci_write_config_word(phba->pcidev, PCI_COMMAND, cfg_value);
|
||||||
|
|
||||||
/* Initialize relevant SLI info */
|
/* Initialize relevant SLI info */
|
||||||
for (i = 0; i < phba->sli.num_rings; i++) {
|
for (i = 0; i < psli->num_rings; i++) {
|
||||||
pring = &phba->sli.ring[i];
|
pring = &psli->ring[i];
|
||||||
pring->flag = 0;
|
pring->flag = 0;
|
||||||
pring->rspidx = 0;
|
pring->rspidx = 0;
|
||||||
pring->next_cmdidx = 0;
|
pring->next_cmdidx = 0;
|
||||||
|
@ -1611,27 +1763,64 @@ lpfc_sli_brdreset(struct lpfc_hba * phba, uint16_t skip_post)
|
||||||
pring->cmdidx = 0;
|
pring->cmdidx = 0;
|
||||||
pring->missbufcnt = 0;
|
pring->missbufcnt = 0;
|
||||||
}
|
}
|
||||||
spin_unlock_irqrestore(phba->host->host_lock, flags);
|
|
||||||
|
|
||||||
if (skip_post) {
|
phba->hba_state = LPFC_WARM_START;
|
||||||
mdelay(100);
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
lpfc_sli_brdrestart(struct lpfc_hba * phba)
|
||||||
|
{
|
||||||
|
MAILBOX_t *mb;
|
||||||
|
struct lpfc_sli *psli;
|
||||||
|
uint16_t skip_post;
|
||||||
|
volatile uint32_t word0;
|
||||||
|
void __iomem *to_slim;
|
||||||
|
|
||||||
|
spin_lock_irq(phba->host->host_lock);
|
||||||
|
|
||||||
|
psli = &phba->sli;
|
||||||
|
|
||||||
|
/* Restart HBA */
|
||||||
|
lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
|
||||||
|
"%d:0328 Restart HBA Data: x%x x%x\n", phba->brd_no,
|
||||||
|
phba->hba_state, psli->sli_flag);
|
||||||
|
|
||||||
|
word0 = 0;
|
||||||
|
mb = (MAILBOX_t *) &word0;
|
||||||
|
mb->mbxCommand = MBX_RESTART;
|
||||||
|
mb->mbxHc = 1;
|
||||||
|
|
||||||
|
lpfc_reset_barrier(phba);
|
||||||
|
|
||||||
|
to_slim = phba->MBslimaddr;
|
||||||
|
writel(*(uint32_t *) mb, to_slim);
|
||||||
|
readl(to_slim); /* flush */
|
||||||
|
|
||||||
|
/* Only skip post after fc_ffinit is completed */
|
||||||
|
if (phba->hba_state) {
|
||||||
|
skip_post = 1;
|
||||||
|
word0 = 1; /* This is really setting up word1 */
|
||||||
} else {
|
} else {
|
||||||
|
skip_post = 0;
|
||||||
|
word0 = 0; /* This is really setting up word1 */
|
||||||
|
}
|
||||||
|
to_slim = (uint8_t *) phba->MBslimaddr + sizeof (uint32_t);
|
||||||
|
writel(*(uint32_t *) mb, to_slim);
|
||||||
|
readl(to_slim); /* flush */
|
||||||
|
|
||||||
|
lpfc_sli_brdreset(phba);
|
||||||
|
phba->stopped = 0;
|
||||||
|
phba->hba_state = LPFC_INIT_START;
|
||||||
|
|
||||||
|
spin_unlock_irq(phba->host->host_lock);
|
||||||
|
|
||||||
|
if (skip_post)
|
||||||
|
mdelay(100);
|
||||||
|
else
|
||||||
mdelay(2000);
|
mdelay(2000);
|
||||||
}
|
|
||||||
|
|
||||||
spin_lock_irqsave(phba->host->host_lock, flags);
|
lpfc_hba_down_post(phba);
|
||||||
/* Cleanup preposted buffers on the ELS ring */
|
|
||||||
pring = &phba->sli.ring[LPFC_ELS_RING];
|
|
||||||
list_for_each_entry_safe(mp, next_mp, &pring->postbufq, list) {
|
|
||||||
list_del(&mp->list);
|
|
||||||
pring->postbufq_cnt--;
|
|
||||||
lpfc_mbuf_free(phba, mp->virt, mp->phys);
|
|
||||||
kfree(mp);
|
|
||||||
}
|
|
||||||
spin_unlock_irqrestore(phba->host->host_lock, flags);
|
|
||||||
|
|
||||||
for (i = 0; i < phba->sli.num_rings; i++)
|
|
||||||
lpfc_sli_abort_iocb_ring(phba, &phba->sli.ring[i]);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1691,7 +1880,8 @@ lpfc_sli_chipset_init(struct lpfc_hba *phba)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i == 15) {
|
if (i == 15) {
|
||||||
lpfc_sli_brdreset(phba, 0);
|
phba->hba_state = LPFC_STATE_UNKNOWN; /* Do post */
|
||||||
|
lpfc_sli_brdrestart(phba);
|
||||||
}
|
}
|
||||||
/* Read the HBA Host Status Register */
|
/* Read the HBA Host Status Register */
|
||||||
status = readl(phba->HSregaddr);
|
status = readl(phba->HSregaddr);
|
||||||
|
@ -1735,8 +1925,8 @@ lpfc_sli_hba_setup(struct lpfc_hba * phba)
|
||||||
}
|
}
|
||||||
|
|
||||||
while (resetcount < 2 && !done) {
|
while (resetcount < 2 && !done) {
|
||||||
phba->hba_state = 0;
|
phba->hba_state = LPFC_STATE_UNKNOWN;
|
||||||
lpfc_sli_brdreset(phba, 0);
|
lpfc_sli_brdrestart(phba);
|
||||||
msleep(2500);
|
msleep(2500);
|
||||||
rc = lpfc_sli_chipset_init(phba);
|
rc = lpfc_sli_chipset_init(phba);
|
||||||
if (rc)
|
if (rc)
|
||||||
|
@ -1920,6 +2110,21 @@ lpfc_sli_issue_mbox(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmbox, uint32_t flag)
|
||||||
mb = &pmbox->mb;
|
mb = &pmbox->mb;
|
||||||
status = MBX_SUCCESS;
|
status = MBX_SUCCESS;
|
||||||
|
|
||||||
|
if (phba->hba_state == LPFC_HBA_ERROR) {
|
||||||
|
spin_unlock_irqrestore(phba->host->host_lock, drvr_flag);
|
||||||
|
|
||||||
|
/* Mbox command <mbxCommand> cannot issue */
|
||||||
|
LOG_MBOX_CANNOT_ISSUE_DATA( phba, mb, psli, flag)
|
||||||
|
return (MBX_NOT_FINISHED);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mb->mbxCommand != MBX_KILL_BOARD && flag & MBX_NOWAIT &&
|
||||||
|
!(readl(phba->HCregaddr) & HC_MBINT_ENA)) {
|
||||||
|
spin_unlock_irqrestore(phba->host->host_lock, drvr_flag);
|
||||||
|
LOG_MBOX_CANNOT_ISSUE_DATA( phba, mb, psli, flag)
|
||||||
|
return (MBX_NOT_FINISHED);
|
||||||
|
}
|
||||||
|
|
||||||
if (psli->sli_flag & LPFC_SLI_MBOX_ACTIVE) {
|
if (psli->sli_flag & LPFC_SLI_MBOX_ACTIVE) {
|
||||||
/* Polling for a mbox command when another one is already active
|
/* Polling for a mbox command when another one is already active
|
||||||
* is not allowed in SLI. Also, the driver must have established
|
* is not allowed in SLI. Also, the driver must have established
|
||||||
|
@ -2002,7 +2207,8 @@ lpfc_sli_issue_mbox(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmbox, uint32_t flag)
|
||||||
|
|
||||||
/* If we are not polling, we MUST be in SLI2 mode */
|
/* If we are not polling, we MUST be in SLI2 mode */
|
||||||
if (flag != MBX_POLL) {
|
if (flag != MBX_POLL) {
|
||||||
if (!(psli->sli_flag & LPFC_SLI2_ACTIVE)) {
|
if (!(psli->sli_flag & LPFC_SLI2_ACTIVE) &&
|
||||||
|
(mb->mbxCommand != MBX_KILL_BOARD)) {
|
||||||
psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE;
|
psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE;
|
||||||
spin_unlock_irqrestore(phba->host->host_lock,
|
spin_unlock_irqrestore(phba->host->host_lock,
|
||||||
drvr_flag);
|
drvr_flag);
|
||||||
|
@ -2086,8 +2292,9 @@ lpfc_sli_issue_mbox(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmbox, uint32_t flag)
|
||||||
ha_copy = readl(phba->HAregaddr);
|
ha_copy = readl(phba->HAregaddr);
|
||||||
|
|
||||||
/* Wait for command to complete */
|
/* Wait for command to complete */
|
||||||
while (((word0 & OWN_CHIP) == OWN_CHIP)
|
while (((word0 & OWN_CHIP) == OWN_CHIP) ||
|
||||||
|| !(ha_copy & HA_MBATT)) {
|
(!(ha_copy & HA_MBATT) &&
|
||||||
|
(phba->hba_state > LPFC_WARM_START))) {
|
||||||
if (i++ >= 100) {
|
if (i++ >= 100) {
|
||||||
psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE;
|
psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE;
|
||||||
spin_unlock_irqrestore(phba->host->host_lock,
|
spin_unlock_irqrestore(phba->host->host_lock,
|
||||||
|
@ -2237,16 +2444,6 @@ lpfc_sli_issue_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
|
||||||
!(phba->sli.sli_flag & LPFC_PROCESS_LA)))
|
!(phba->sli.sli_flag & LPFC_PROCESS_LA)))
|
||||||
goto iocb_busy;
|
goto iocb_busy;
|
||||||
|
|
||||||
/*
|
|
||||||
* Check to see if this is a high priority command.
|
|
||||||
* If so bypass tx queue processing.
|
|
||||||
*/
|
|
||||||
if (unlikely((flag & SLI_IOCB_HIGH_PRIORITY) &&
|
|
||||||
(iocb = lpfc_sli_next_iocb_slot(phba, pring)))) {
|
|
||||||
lpfc_sli_submit_iocb(phba, pring, iocb, piocb);
|
|
||||||
piocb = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
while ((iocb = lpfc_sli_next_iocb_slot(phba, pring)) &&
|
while ((iocb = lpfc_sli_next_iocb_slot(phba, pring)) &&
|
||||||
(nextiocb = lpfc_sli_next_iocb(phba, pring, &piocb)))
|
(nextiocb = lpfc_sli_next_iocb(phba, pring, &piocb)))
|
||||||
lpfc_sli_submit_iocb(phba, pring, iocb, nextiocb);
|
lpfc_sli_submit_iocb(phba, pring, iocb, nextiocb);
|
||||||
|
@ -2274,6 +2471,37 @@ lpfc_sli_issue_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
|
||||||
return IOCB_BUSY;
|
return IOCB_BUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
lpfc_extra_ring_setup( struct lpfc_hba *phba)
|
||||||
|
{
|
||||||
|
struct lpfc_sli *psli;
|
||||||
|
struct lpfc_sli_ring *pring;
|
||||||
|
|
||||||
|
psli = &phba->sli;
|
||||||
|
|
||||||
|
/* Adjust cmd/rsp ring iocb entries more evenly */
|
||||||
|
pring = &psli->ring[psli->fcp_ring];
|
||||||
|
pring->numCiocb -= SLI2_IOCB_CMD_R1XTRA_ENTRIES;
|
||||||
|
pring->numRiocb -= SLI2_IOCB_RSP_R1XTRA_ENTRIES;
|
||||||
|
pring->numCiocb -= SLI2_IOCB_CMD_R3XTRA_ENTRIES;
|
||||||
|
pring->numRiocb -= SLI2_IOCB_RSP_R3XTRA_ENTRIES;
|
||||||
|
|
||||||
|
pring = &psli->ring[1];
|
||||||
|
pring->numCiocb += SLI2_IOCB_CMD_R1XTRA_ENTRIES;
|
||||||
|
pring->numRiocb += SLI2_IOCB_RSP_R1XTRA_ENTRIES;
|
||||||
|
pring->numCiocb += SLI2_IOCB_CMD_R3XTRA_ENTRIES;
|
||||||
|
pring->numRiocb += SLI2_IOCB_RSP_R3XTRA_ENTRIES;
|
||||||
|
|
||||||
|
/* Setup default profile for this ring */
|
||||||
|
pring->iotag_max = 4096;
|
||||||
|
pring->num_mask = 1;
|
||||||
|
pring->prt[0].profile = 0; /* Mask 0 */
|
||||||
|
pring->prt[0].rctl = FC_UNSOL_DATA;
|
||||||
|
pring->prt[0].type = 5;
|
||||||
|
pring->prt[0].lpfc_sli_rcv_unsol_event = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
lpfc_sli_setup(struct lpfc_hba *phba)
|
lpfc_sli_setup(struct lpfc_hba *phba)
|
||||||
{
|
{
|
||||||
|
@ -2357,6 +2585,8 @@ lpfc_sli_setup(struct lpfc_hba *phba)
|
||||||
"SLI2 SLIM Data: x%x x%x\n",
|
"SLI2 SLIM Data: x%x x%x\n",
|
||||||
phba->brd_no, totiocb, MAX_SLI2_IOCB);
|
phba->brd_no, totiocb, MAX_SLI2_IOCB);
|
||||||
}
|
}
|
||||||
|
if (phba->cfg_multi_ring_support == 2)
|
||||||
|
lpfc_extra_ring_setup(phba);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -2465,15 +2695,6 @@ lpfc_sli_hba_down(struct lpfc_hba * phba)
|
||||||
|
|
||||||
spin_unlock_irqrestore(phba->host->host_lock, flags);
|
spin_unlock_irqrestore(phba->host->host_lock, flags);
|
||||||
|
|
||||||
/*
|
|
||||||
* Provided the hba is not in an error state, reset it. It is not
|
|
||||||
* capable of IO anymore.
|
|
||||||
*/
|
|
||||||
if (phba->hba_state != LPFC_HBA_ERROR) {
|
|
||||||
phba->hba_state = LPFC_INIT_START;
|
|
||||||
lpfc_sli_brdreset(phba, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2877,11 +3098,10 @@ lpfc_sli_issue_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq,
|
||||||
pmboxq->context1 = NULL;
|
pmboxq->context1 = NULL;
|
||||||
/* if schedule_timeout returns 0, we timed out and were not
|
/* if schedule_timeout returns 0, we timed out and were not
|
||||||
woken up */
|
woken up */
|
||||||
if (timeleft == 0) {
|
if ((timeleft == 0) || signal_pending(current))
|
||||||
retval = MBX_TIMEOUT;
|
retval = MBX_TIMEOUT;
|
||||||
} else {
|
else
|
||||||
retval = MBX_SUCCESS;
|
retval = MBX_SUCCESS;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2987,13 +3207,7 @@ lpfc_intr_handler(int irq, void *dev_id, struct pt_regs * regs)
|
||||||
/* Clear Chip error bit */
|
/* Clear Chip error bit */
|
||||||
writel(HA_ERATT, phba->HAregaddr);
|
writel(HA_ERATT, phba->HAregaddr);
|
||||||
readl(phba->HAregaddr); /* flush */
|
readl(phba->HAregaddr); /* flush */
|
||||||
|
phba->stopped = 1;
|
||||||
/*
|
|
||||||
* Reseting the HBA is the only reliable way
|
|
||||||
* to shutdown interrupt when there is a
|
|
||||||
* ERROR.
|
|
||||||
*/
|
|
||||||
lpfc_sli_send_reset(phba, phba->hba_state);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_lock(phba->host->host_lock);
|
spin_lock(phba->host->host_lock);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
* This file is part of the Emulex Linux Device Driver for *
|
* This file is part of the Emulex Linux Device Driver for *
|
||||||
* Fibre Channel Host Bus Adapters. *
|
* Fibre Channel Host Bus Adapters. *
|
||||||
* Copyright (C) 2004-2005 Emulex. All rights reserved. *
|
* Copyright (C) 2004-2006 Emulex. All rights reserved. *
|
||||||
* EMULEX and SLI are trademarks of Emulex. *
|
* EMULEX and SLI are trademarks of Emulex. *
|
||||||
* www.emulex.com *
|
* www.emulex.com *
|
||||||
* *
|
* *
|
||||||
|
@ -61,7 +61,6 @@ struct lpfc_iocbq {
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SLI_IOCB_RET_IOCB 1 /* Return IOCB if cmd ring full */
|
#define SLI_IOCB_RET_IOCB 1 /* Return IOCB if cmd ring full */
|
||||||
#define SLI_IOCB_HIGH_PRIORITY 2 /* High priority command */
|
|
||||||
|
|
||||||
#define IOCB_SUCCESS 0
|
#define IOCB_SUCCESS 0
|
||||||
#define IOCB_BUSY 1
|
#define IOCB_BUSY 1
|
||||||
|
@ -200,8 +199,6 @@ struct lpfc_sli {
|
||||||
struct timer_list mbox_tmo; /* Hold clk to timeout active mbox
|
struct timer_list mbox_tmo; /* Hold clk to timeout active mbox
|
||||||
cmd */
|
cmd */
|
||||||
|
|
||||||
uint32_t *MBhostaddr; /* virtual address for mbox cmds */
|
|
||||||
|
|
||||||
#define LPFC_IOCBQ_LOOKUP_INCREMENT 1024
|
#define LPFC_IOCBQ_LOOKUP_INCREMENT 1024
|
||||||
struct lpfc_iocbq ** iocbq_lookup; /* array to lookup IOCB by IOTAG */
|
struct lpfc_iocbq ** iocbq_lookup; /* array to lookup IOCB by IOTAG */
|
||||||
size_t iocbq_lookup_len; /* current lengs of the array */
|
size_t iocbq_lookup_len; /* current lengs of the array */
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
* This file is part of the Emulex Linux Device Driver for *
|
* This file is part of the Emulex Linux Device Driver for *
|
||||||
* Fibre Channel Host Bus Adapters. *
|
* Fibre Channel Host Bus Adapters. *
|
||||||
* Copyright (C) 2004-2005 Emulex. All rights reserved. *
|
* Copyright (C) 2004-2006 Emulex. All rights reserved. *
|
||||||
* EMULEX and SLI are trademarks of Emulex. *
|
* EMULEX and SLI are trademarks of Emulex. *
|
||||||
* www.emulex.com *
|
* www.emulex.com *
|
||||||
* *
|
* *
|
||||||
|
@ -18,12 +18,12 @@
|
||||||
* included with this package. *
|
* included with this package. *
|
||||||
*******************************************************************/
|
*******************************************************************/
|
||||||
|
|
||||||
#define LPFC_DRIVER_VERSION "8.1.1"
|
#define LPFC_DRIVER_VERSION "8.1.4"
|
||||||
|
|
||||||
#define LPFC_DRIVER_NAME "lpfc"
|
#define LPFC_DRIVER_NAME "lpfc"
|
||||||
|
|
||||||
#define LPFC_MODULE_DESC "Emulex LightPulse Fibre Channel SCSI driver " \
|
#define LPFC_MODULE_DESC "Emulex LightPulse Fibre Channel SCSI driver " \
|
||||||
LPFC_DRIVER_VERSION
|
LPFC_DRIVER_VERSION
|
||||||
#define LPFC_COPYRIGHT "Copyright(c) 2004-2005 Emulex. All rights reserved."
|
#define LPFC_COPYRIGHT "Copyright(c) 2004-2006 Emulex. All rights reserved."
|
||||||
|
|
||||||
#define DFC_API_VERSION "0.0.0"
|
#define DFC_API_VERSION "0.0.0"
|
||||||
|
|
|
@ -772,8 +772,6 @@ megasas_queue_command(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd *))
|
||||||
goto out_return_cmd;
|
goto out_return_cmd;
|
||||||
|
|
||||||
cmd->scmd = scmd;
|
cmd->scmd = scmd;
|
||||||
scmd->SCp.ptr = (char *)cmd;
|
|
||||||
scmd->SCp.sent_command = jiffies;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Issue the command to the FW
|
* Issue the command to the FW
|
||||||
|
@ -804,6 +802,12 @@ static int megasas_slave_configure(struct scsi_device *sdev)
|
||||||
*/
|
*/
|
||||||
if (sdev->channel < MEGASAS_MAX_PD_CHANNELS && sdev->type == TYPE_DISK)
|
if (sdev->channel < MEGASAS_MAX_PD_CHANNELS && sdev->type == TYPE_DISK)
|
||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The RAID firmware may require extended timeouts.
|
||||||
|
*/
|
||||||
|
if (sdev->channel >= MEGASAS_MAX_PD_CHANNELS)
|
||||||
|
sdev->timeout = 90 * HZ;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -875,23 +879,6 @@ static int megasas_generic_reset(struct scsi_cmnd *scmd)
|
||||||
return ret_val;
|
return ret_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum scsi_eh_timer_return megasas_reset_timer(struct scsi_cmnd *scmd)
|
|
||||||
{
|
|
||||||
unsigned long seconds;
|
|
||||||
|
|
||||||
if (scmd->SCp.ptr) {
|
|
||||||
seconds = (jiffies - scmd->SCp.sent_command) / HZ;
|
|
||||||
|
|
||||||
if (seconds < 90) {
|
|
||||||
return EH_RESET_TIMER;
|
|
||||||
} else {
|
|
||||||
return EH_NOT_HANDLED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return EH_HANDLED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* megasas_reset_device - Device reset handler entry point
|
* megasas_reset_device - Device reset handler entry point
|
||||||
*/
|
*/
|
||||||
|
@ -962,7 +949,6 @@ static struct scsi_host_template megasas_template = {
|
||||||
.eh_device_reset_handler = megasas_reset_device,
|
.eh_device_reset_handler = megasas_reset_device,
|
||||||
.eh_bus_reset_handler = megasas_reset_bus_host,
|
.eh_bus_reset_handler = megasas_reset_bus_host,
|
||||||
.eh_host_reset_handler = megasas_reset_bus_host,
|
.eh_host_reset_handler = megasas_reset_bus_host,
|
||||||
.eh_timed_out = megasas_reset_timer,
|
|
||||||
.use_clustering = ENABLE_CLUSTERING,
|
.use_clustering = ENABLE_CLUSTERING,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -69,6 +69,10 @@
|
||||||
** Low PCI traffic for command handling when on-chip RAM is present.
|
** Low PCI traffic for command handling when on-chip RAM is present.
|
||||||
** Aggressive SCSI SCRIPTS optimizations.
|
** Aggressive SCSI SCRIPTS optimizations.
|
||||||
**
|
**
|
||||||
|
** 2005 by Matthew Wilcox and James Bottomley
|
||||||
|
** PCI-ectomy. This driver now supports only the 720 chip (see the
|
||||||
|
** NCR_Q720 and zalon drivers for the bus probe logic).
|
||||||
|
**
|
||||||
*******************************************************************************
|
*******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -90,13 +94,6 @@
|
||||||
|
|
||||||
#define SCSI_NCR_DEBUG_FLAGS (0)
|
#define SCSI_NCR_DEBUG_FLAGS (0)
|
||||||
|
|
||||||
/*==========================================================
|
|
||||||
**
|
|
||||||
** Include files
|
|
||||||
**
|
|
||||||
**==========================================================
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <linux/blkdev.h>
|
#include <linux/blkdev.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/dma-mapping.h>
|
#include <linux/dma-mapping.h>
|
||||||
|
@ -121,6 +118,7 @@
|
||||||
|
|
||||||
#include <scsi/scsi.h>
|
#include <scsi/scsi.h>
|
||||||
#include <scsi/scsi_cmnd.h>
|
#include <scsi/scsi_cmnd.h>
|
||||||
|
#include <scsi/scsi_dbg.h>
|
||||||
#include <scsi/scsi_device.h>
|
#include <scsi/scsi_device.h>
|
||||||
#include <scsi/scsi_tcq.h>
|
#include <scsi/scsi_tcq.h>
|
||||||
#include <scsi/scsi_transport.h>
|
#include <scsi/scsi_transport.h>
|
||||||
|
@ -128,10 +126,8 @@
|
||||||
|
|
||||||
#include "ncr53c8xx.h"
|
#include "ncr53c8xx.h"
|
||||||
|
|
||||||
#define NAME53C "ncr53c"
|
|
||||||
#define NAME53C8XX "ncr53c8xx"
|
#define NAME53C8XX "ncr53c8xx"
|
||||||
|
|
||||||
|
|
||||||
/*==========================================================
|
/*==========================================================
|
||||||
**
|
**
|
||||||
** Debugging tags
|
** Debugging tags
|
||||||
|
@ -2111,7 +2107,7 @@ static struct script script0 __initdata = {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** The M_REJECT problem seems to be due to a selection
|
** The MESSAGE_REJECT problem seems to be due to a selection
|
||||||
** timing problem.
|
** timing problem.
|
||||||
** Wait immediately for the selection to complete.
|
** Wait immediately for the selection to complete.
|
||||||
** (2.5x behaves so)
|
** (2.5x behaves so)
|
||||||
|
@ -2162,7 +2158,7 @@ static struct script script0 __initdata = {
|
||||||
/*
|
/*
|
||||||
** Selection complete.
|
** Selection complete.
|
||||||
** Send the IDENTIFY and SIMPLE_TAG messages
|
** Send the IDENTIFY and SIMPLE_TAG messages
|
||||||
** (and the M_X_SYNC_REQ message)
|
** (and the EXTENDED_SDTR message)
|
||||||
*/
|
*/
|
||||||
SCR_MOVE_TBL ^ SCR_MSG_OUT,
|
SCR_MOVE_TBL ^ SCR_MSG_OUT,
|
||||||
offsetof (struct dsb, smsg),
|
offsetof (struct dsb, smsg),
|
||||||
|
@ -2191,7 +2187,7 @@ static struct script script0 __initdata = {
|
||||||
/*
|
/*
|
||||||
** Initialize the msgout buffer with a NOOP message.
|
** Initialize the msgout buffer with a NOOP message.
|
||||||
*/
|
*/
|
||||||
SCR_LOAD_REG (scratcha, M_NOOP),
|
SCR_LOAD_REG (scratcha, NOP),
|
||||||
0,
|
0,
|
||||||
SCR_COPY (1),
|
SCR_COPY (1),
|
||||||
RADDR (scratcha),
|
RADDR (scratcha),
|
||||||
|
@ -2343,21 +2339,21 @@ static struct script script0 __initdata = {
|
||||||
/*
|
/*
|
||||||
** Handle this message.
|
** Handle this message.
|
||||||
*/
|
*/
|
||||||
SCR_JUMP ^ IFTRUE (DATA (M_COMPLETE)),
|
SCR_JUMP ^ IFTRUE (DATA (COMMAND_COMPLETE)),
|
||||||
PADDR (complete),
|
PADDR (complete),
|
||||||
SCR_JUMP ^ IFTRUE (DATA (M_DISCONNECT)),
|
SCR_JUMP ^ IFTRUE (DATA (DISCONNECT)),
|
||||||
PADDR (disconnect),
|
PADDR (disconnect),
|
||||||
SCR_JUMP ^ IFTRUE (DATA (M_SAVE_DP)),
|
SCR_JUMP ^ IFTRUE (DATA (SAVE_POINTERS)),
|
||||||
PADDR (save_dp),
|
PADDR (save_dp),
|
||||||
SCR_JUMP ^ IFTRUE (DATA (M_RESTORE_DP)),
|
SCR_JUMP ^ IFTRUE (DATA (RESTORE_POINTERS)),
|
||||||
PADDR (restore_dp),
|
PADDR (restore_dp),
|
||||||
SCR_JUMP ^ IFTRUE (DATA (M_EXTENDED)),
|
SCR_JUMP ^ IFTRUE (DATA (EXTENDED_MESSAGE)),
|
||||||
PADDRH (msg_extended),
|
PADDRH (msg_extended),
|
||||||
SCR_JUMP ^ IFTRUE (DATA (M_NOOP)),
|
SCR_JUMP ^ IFTRUE (DATA (NOP)),
|
||||||
PADDR (clrack),
|
PADDR (clrack),
|
||||||
SCR_JUMP ^ IFTRUE (DATA (M_REJECT)),
|
SCR_JUMP ^ IFTRUE (DATA (MESSAGE_REJECT)),
|
||||||
PADDRH (msg_reject),
|
PADDRH (msg_reject),
|
||||||
SCR_JUMP ^ IFTRUE (DATA (M_IGN_RESIDUE)),
|
SCR_JUMP ^ IFTRUE (DATA (IGNORE_WIDE_RESIDUE)),
|
||||||
PADDRH (msg_ign_residue),
|
PADDRH (msg_ign_residue),
|
||||||
/*
|
/*
|
||||||
** Rest of the messages left as
|
** Rest of the messages left as
|
||||||
|
@ -2372,7 +2368,7 @@ static struct script script0 __initdata = {
|
||||||
*/
|
*/
|
||||||
SCR_INT,
|
SCR_INT,
|
||||||
SIR_REJECT_SENT,
|
SIR_REJECT_SENT,
|
||||||
SCR_LOAD_REG (scratcha, M_REJECT),
|
SCR_LOAD_REG (scratcha, MESSAGE_REJECT),
|
||||||
0,
|
0,
|
||||||
}/*-------------------------< SETMSG >----------------------*/,{
|
}/*-------------------------< SETMSG >----------------------*/,{
|
||||||
SCR_COPY (1),
|
SCR_COPY (1),
|
||||||
|
@ -2564,7 +2560,7 @@ static struct script script0 __initdata = {
|
||||||
/*
|
/*
|
||||||
** If it was no ABORT message ...
|
** If it was no ABORT message ...
|
||||||
*/
|
*/
|
||||||
SCR_JUMP ^ IFTRUE (DATA (M_ABORT)),
|
SCR_JUMP ^ IFTRUE (DATA (ABORT_TASK_SET)),
|
||||||
PADDRH (msg_out_abort),
|
PADDRH (msg_out_abort),
|
||||||
/*
|
/*
|
||||||
** ... wait for the next phase
|
** ... wait for the next phase
|
||||||
|
@ -2576,7 +2572,7 @@ static struct script script0 __initdata = {
|
||||||
/*
|
/*
|
||||||
** ... else clear the message ...
|
** ... else clear the message ...
|
||||||
*/
|
*/
|
||||||
SCR_LOAD_REG (scratcha, M_NOOP),
|
SCR_LOAD_REG (scratcha, NOP),
|
||||||
0,
|
0,
|
||||||
SCR_COPY (4),
|
SCR_COPY (4),
|
||||||
RADDR (scratcha),
|
RADDR (scratcha),
|
||||||
|
@ -3035,7 +3031,7 @@ static struct scripth scripth0 __initdata = {
|
||||||
*/
|
*/
|
||||||
SCR_MOVE_ABS (1) ^ SCR_MSG_IN,
|
SCR_MOVE_ABS (1) ^ SCR_MSG_IN,
|
||||||
NADDR (msgin[2]),
|
NADDR (msgin[2]),
|
||||||
SCR_JUMP ^ IFTRUE (DATA (M_X_WIDE_REQ)),
|
SCR_JUMP ^ IFTRUE (DATA (EXTENDED_WDTR)),
|
||||||
PADDRH (msg_wdtr),
|
PADDRH (msg_wdtr),
|
||||||
/*
|
/*
|
||||||
** unknown extended message
|
** unknown extended message
|
||||||
|
@ -3069,7 +3065,7 @@ static struct scripth scripth0 __initdata = {
|
||||||
|
|
||||||
}/*-------------------------< SEND_WDTR >----------------*/,{
|
}/*-------------------------< SEND_WDTR >----------------*/,{
|
||||||
/*
|
/*
|
||||||
** Send the M_X_WIDE_REQ
|
** Send the EXTENDED_WDTR
|
||||||
*/
|
*/
|
||||||
SCR_MOVE_ABS (4) ^ SCR_MSG_OUT,
|
SCR_MOVE_ABS (4) ^ SCR_MSG_OUT,
|
||||||
NADDR (msgout),
|
NADDR (msgout),
|
||||||
|
@ -3089,7 +3085,7 @@ static struct scripth scripth0 __initdata = {
|
||||||
*/
|
*/
|
||||||
SCR_MOVE_ABS (1) ^ SCR_MSG_IN,
|
SCR_MOVE_ABS (1) ^ SCR_MSG_IN,
|
||||||
NADDR (msgin[2]),
|
NADDR (msgin[2]),
|
||||||
SCR_JUMP ^ IFTRUE (DATA (M_X_SYNC_REQ)),
|
SCR_JUMP ^ IFTRUE (DATA (EXTENDED_SDTR)),
|
||||||
PADDRH (msg_sdtr),
|
PADDRH (msg_sdtr),
|
||||||
/*
|
/*
|
||||||
** unknown extended message
|
** unknown extended message
|
||||||
|
@ -3124,7 +3120,7 @@ static struct scripth scripth0 __initdata = {
|
||||||
|
|
||||||
}/*-------------------------< SEND_SDTR >-------------*/,{
|
}/*-------------------------< SEND_SDTR >-------------*/,{
|
||||||
/*
|
/*
|
||||||
** Send the M_X_SYNC_REQ
|
** Send the EXTENDED_SDTR
|
||||||
*/
|
*/
|
||||||
SCR_MOVE_ABS (5) ^ SCR_MSG_OUT,
|
SCR_MOVE_ABS (5) ^ SCR_MSG_OUT,
|
||||||
NADDR (msgout),
|
NADDR (msgout),
|
||||||
|
@ -3202,10 +3198,10 @@ static struct scripth scripth0 __initdata = {
|
||||||
|
|
||||||
}/*-------------------------< RESET >----------------------*/,{
|
}/*-------------------------< RESET >----------------------*/,{
|
||||||
/*
|
/*
|
||||||
** Send a M_RESET message if bad IDENTIFY
|
** Send a TARGET_RESET message if bad IDENTIFY
|
||||||
** received on reselection.
|
** received on reselection.
|
||||||
*/
|
*/
|
||||||
SCR_LOAD_REG (scratcha, M_ABORT_TAG),
|
SCR_LOAD_REG (scratcha, ABORT_TASK),
|
||||||
0,
|
0,
|
||||||
SCR_JUMP,
|
SCR_JUMP,
|
||||||
PADDRH (abort_resel),
|
PADDRH (abort_resel),
|
||||||
|
@ -3213,7 +3209,7 @@ static struct scripth scripth0 __initdata = {
|
||||||
/*
|
/*
|
||||||
** Abort a wrong tag received on reselection.
|
** Abort a wrong tag received on reselection.
|
||||||
*/
|
*/
|
||||||
SCR_LOAD_REG (scratcha, M_ABORT_TAG),
|
SCR_LOAD_REG (scratcha, ABORT_TASK),
|
||||||
0,
|
0,
|
||||||
SCR_JUMP,
|
SCR_JUMP,
|
||||||
PADDRH (abort_resel),
|
PADDRH (abort_resel),
|
||||||
|
@ -3221,7 +3217,7 @@ static struct scripth scripth0 __initdata = {
|
||||||
/*
|
/*
|
||||||
** Abort a reselection when no active CCB.
|
** Abort a reselection when no active CCB.
|
||||||
*/
|
*/
|
||||||
SCR_LOAD_REG (scratcha, M_ABORT),
|
SCR_LOAD_REG (scratcha, ABORT_TASK_SET),
|
||||||
0,
|
0,
|
||||||
}/*-------------------------< ABORT_RESEL >----------------*/,{
|
}/*-------------------------< ABORT_RESEL >----------------*/,{
|
||||||
SCR_COPY (1),
|
SCR_COPY (1),
|
||||||
|
@ -3333,7 +3329,7 @@ static struct scripth scripth0 __initdata = {
|
||||||
** Read the message, since we got it directly
|
** Read the message, since we got it directly
|
||||||
** from the SCSI BUS data lines.
|
** from the SCSI BUS data lines.
|
||||||
** Signal problem to C code for logging the event.
|
** Signal problem to C code for logging the event.
|
||||||
** Send a M_ABORT to clear all pending tasks.
|
** Send an ABORT_TASK_SET to clear all pending tasks.
|
||||||
*/
|
*/
|
||||||
SCR_INT,
|
SCR_INT,
|
||||||
SIR_RESEL_BAD_LUN,
|
SIR_RESEL_BAD_LUN,
|
||||||
|
@ -3345,7 +3341,7 @@ static struct scripth scripth0 __initdata = {
|
||||||
/*
|
/*
|
||||||
** We donnot have a task for that I_T_L.
|
** We donnot have a task for that I_T_L.
|
||||||
** Signal problem to C code for logging the event.
|
** Signal problem to C code for logging the event.
|
||||||
** Send a M_ABORT message.
|
** Send an ABORT_TASK_SET message.
|
||||||
*/
|
*/
|
||||||
SCR_INT,
|
SCR_INT,
|
||||||
SIR_RESEL_BAD_I_T_L,
|
SIR_RESEL_BAD_I_T_L,
|
||||||
|
@ -3355,7 +3351,7 @@ static struct scripth scripth0 __initdata = {
|
||||||
/*
|
/*
|
||||||
** We donnot have a task that matches the tag.
|
** We donnot have a task that matches the tag.
|
||||||
** Signal problem to C code for logging the event.
|
** Signal problem to C code for logging the event.
|
||||||
** Send a M_ABORTTAG message.
|
** Send an ABORT_TASK message.
|
||||||
*/
|
*/
|
||||||
SCR_INT,
|
SCR_INT,
|
||||||
SIR_RESEL_BAD_I_T_L_Q,
|
SIR_RESEL_BAD_I_T_L_Q,
|
||||||
|
@ -3366,7 +3362,7 @@ static struct scripth scripth0 __initdata = {
|
||||||
** We donnot know the target that reselected us.
|
** We donnot know the target that reselected us.
|
||||||
** Grab the first message if any (IDENTIFY).
|
** Grab the first message if any (IDENTIFY).
|
||||||
** Signal problem to C code for logging the event.
|
** Signal problem to C code for logging the event.
|
||||||
** M_RESET message.
|
** TARGET_RESET message.
|
||||||
*/
|
*/
|
||||||
SCR_INT,
|
SCR_INT,
|
||||||
SIR_RESEL_BAD_TARGET,
|
SIR_RESEL_BAD_TARGET,
|
||||||
|
@ -4109,17 +4105,11 @@ static int ncr_prepare_nego(struct ncb *np, struct ccb *cp, u_char *msgptr)
|
||||||
|
|
||||||
switch (nego) {
|
switch (nego) {
|
||||||
case NS_SYNC:
|
case NS_SYNC:
|
||||||
msgptr[msglen++] = M_EXTENDED;
|
msglen += spi_populate_sync_msg(msgptr + msglen,
|
||||||
msgptr[msglen++] = 3;
|
tp->maxoffs ? tp->minsync : 0, tp->maxoffs);
|
||||||
msgptr[msglen++] = M_X_SYNC_REQ;
|
|
||||||
msgptr[msglen++] = tp->maxoffs ? tp->minsync : 0;
|
|
||||||
msgptr[msglen++] = tp->maxoffs;
|
|
||||||
break;
|
break;
|
||||||
case NS_WIDE:
|
case NS_WIDE:
|
||||||
msgptr[msglen++] = M_EXTENDED;
|
msglen += spi_populate_width_msg(msgptr + msglen, tp->usrwide);
|
||||||
msgptr[msglen++] = 2;
|
|
||||||
msgptr[msglen++] = M_X_WIDE_REQ;
|
|
||||||
msgptr[msglen++] = tp->usrwide;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4220,7 +4210,7 @@ static int ncr_queue_command (struct ncb *np, struct scsi_cmnd *cmd)
|
||||||
**----------------------------------------------------
|
**----------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
idmsg = M_IDENTIFY | sdev->lun;
|
idmsg = IDENTIFY(0, sdev->lun);
|
||||||
|
|
||||||
if (cp ->tag != NO_TAG ||
|
if (cp ->tag != NO_TAG ||
|
||||||
(cp != np->ccb && np->disc && !(tp->usrflag & UF_NODISC)))
|
(cp != np->ccb && np->disc && !(tp->usrflag & UF_NODISC)))
|
||||||
|
@ -4239,7 +4229,7 @@ static int ncr_queue_command (struct ncb *np, struct scsi_cmnd *cmd)
|
||||||
*/
|
*/
|
||||||
if (lp && time_after(jiffies, lp->tags_stime)) {
|
if (lp && time_after(jiffies, lp->tags_stime)) {
|
||||||
if (lp->tags_smap) {
|
if (lp->tags_smap) {
|
||||||
order = M_ORDERED_TAG;
|
order = ORDERED_QUEUE_TAG;
|
||||||
if ((DEBUG_FLAGS & DEBUG_TAGS)||bootverbose>2){
|
if ((DEBUG_FLAGS & DEBUG_TAGS)||bootverbose>2){
|
||||||
PRINT_ADDR(cmd,
|
PRINT_ADDR(cmd,
|
||||||
"ordered tag forced.\n");
|
"ordered tag forced.\n");
|
||||||
|
@ -4257,10 +4247,10 @@ static int ncr_queue_command (struct ncb *np, struct scsi_cmnd *cmd)
|
||||||
case 0x08: /* READ_SMALL (6) */
|
case 0x08: /* READ_SMALL (6) */
|
||||||
case 0x28: /* READ_BIG (10) */
|
case 0x28: /* READ_BIG (10) */
|
||||||
case 0xa8: /* READ_HUGE (12) */
|
case 0xa8: /* READ_HUGE (12) */
|
||||||
order = M_SIMPLE_TAG;
|
order = SIMPLE_QUEUE_TAG;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
order = M_ORDERED_TAG;
|
order = ORDERED_QUEUE_TAG;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
msgptr[msglen++] = order;
|
msgptr[msglen++] = order;
|
||||||
|
@ -6229,9 +6219,9 @@ static int ncr_int_par (struct ncb *np)
|
||||||
if (!(dbc & 0xc0000000))
|
if (!(dbc & 0xc0000000))
|
||||||
phase = (dbc >> 24) & 7;
|
phase = (dbc >> 24) & 7;
|
||||||
if (phase == 7)
|
if (phase == 7)
|
||||||
msg = M_PARITY;
|
msg = MSG_PARITY_ERROR;
|
||||||
else
|
else
|
||||||
msg = M_ID_ERROR;
|
msg = INITIATOR_ERROR;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -6795,6 +6785,8 @@ void ncr_int_sir (struct ncb *np)
|
||||||
/*-----------------------------------------------------------------------------
|
/*-----------------------------------------------------------------------------
|
||||||
**
|
**
|
||||||
** Was Sie schon immer ueber transfermode negotiation wissen wollten ...
|
** Was Sie schon immer ueber transfermode negotiation wissen wollten ...
|
||||||
|
** ("Everything you've always wanted to know about transfer mode
|
||||||
|
** negotiation")
|
||||||
**
|
**
|
||||||
** We try to negotiate sync and wide transfer only after
|
** We try to negotiate sync and wide transfer only after
|
||||||
** a successful inquire command. We look at byte 7 of the
|
** a successful inquire command. We look at byte 7 of the
|
||||||
|
@ -6896,8 +6888,8 @@ void ncr_int_sir (struct ncb *np)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
np->msgin [0] = M_NOOP;
|
np->msgin [0] = NOP;
|
||||||
np->msgout[0] = M_NOOP;
|
np->msgout[0] = NOP;
|
||||||
cp->nego_status = 0;
|
cp->nego_status = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -6991,12 +6983,7 @@ void ncr_int_sir (struct ncb *np)
|
||||||
spi_offset(starget) = ofs;
|
spi_offset(starget) = ofs;
|
||||||
ncr_setsync(np, cp, scntl3, (fak<<5)|ofs);
|
ncr_setsync(np, cp, scntl3, (fak<<5)|ofs);
|
||||||
|
|
||||||
np->msgout[0] = M_EXTENDED;
|
spi_populate_sync_msg(np->msgout, per, ofs);
|
||||||
np->msgout[1] = 3;
|
|
||||||
np->msgout[2] = M_X_SYNC_REQ;
|
|
||||||
np->msgout[3] = per;
|
|
||||||
np->msgout[4] = ofs;
|
|
||||||
|
|
||||||
cp->nego_status = NS_SYNC;
|
cp->nego_status = NS_SYNC;
|
||||||
|
|
||||||
if (DEBUG_FLAGS & DEBUG_NEGO) {
|
if (DEBUG_FLAGS & DEBUG_NEGO) {
|
||||||
|
@ -7007,7 +6994,7 @@ void ncr_int_sir (struct ncb *np)
|
||||||
OUTL_DSP (NCB_SCRIPT_PHYS (np, msg_bad));
|
OUTL_DSP (NCB_SCRIPT_PHYS (np, msg_bad));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
np->msgin [0] = M_NOOP;
|
np->msgin [0] = NOP;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -7082,13 +7069,9 @@ void ncr_int_sir (struct ncb *np)
|
||||||
|
|
||||||
spi_width(starget) = wide;
|
spi_width(starget) = wide;
|
||||||
ncr_setwide(np, cp, wide, 1);
|
ncr_setwide(np, cp, wide, 1);
|
||||||
|
spi_populate_width_msg(np->msgout, wide);
|
||||||
|
|
||||||
np->msgout[0] = M_EXTENDED;
|
np->msgin [0] = NOP;
|
||||||
np->msgout[1] = 2;
|
|
||||||
np->msgout[2] = M_X_WIDE_REQ;
|
|
||||||
np->msgout[3] = wide;
|
|
||||||
|
|
||||||
np->msgin [0] = M_NOOP;
|
|
||||||
|
|
||||||
cp->nego_status = NS_WIDE;
|
cp->nego_status = NS_WIDE;
|
||||||
|
|
||||||
|
@ -7107,12 +7090,12 @@ void ncr_int_sir (struct ncb *np)
|
||||||
case SIR_REJECT_RECEIVED:
|
case SIR_REJECT_RECEIVED:
|
||||||
/*-----------------------------------------------
|
/*-----------------------------------------------
|
||||||
**
|
**
|
||||||
** We received a M_REJECT message.
|
** We received a MESSAGE_REJECT.
|
||||||
**
|
**
|
||||||
**-----------------------------------------------
|
**-----------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
PRINT_ADDR(cp->cmd, "M_REJECT received (%x:%x).\n",
|
PRINT_ADDR(cp->cmd, "MESSAGE_REJECT received (%x:%x).\n",
|
||||||
(unsigned)scr_to_cpu(np->lastmsg), np->msgout[0]);
|
(unsigned)scr_to_cpu(np->lastmsg), np->msgout[0]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -7124,7 +7107,7 @@ void ncr_int_sir (struct ncb *np)
|
||||||
**-----------------------------------------------
|
**-----------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ncr_print_msg(cp, "M_REJECT sent for", np->msgin);
|
ncr_print_msg(cp, "MESSAGE_REJECT sent for", np->msgin);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/*--------------------------------------------------------------------
|
/*--------------------------------------------------------------------
|
||||||
|
@ -7143,7 +7126,7 @@ void ncr_int_sir (struct ncb *np)
|
||||||
**-----------------------------------------------
|
**-----------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
PRINT_ADDR(cp->cmd, "M_IGN_RESIDUE received, but not yet "
|
PRINT_ADDR(cp->cmd, "IGNORE_WIDE_RESIDUE received, but not yet "
|
||||||
"implemented.\n");
|
"implemented.\n");
|
||||||
break;
|
break;
|
||||||
#if 0
|
#if 0
|
||||||
|
@ -7156,7 +7139,7 @@ void ncr_int_sir (struct ncb *np)
|
||||||
**-----------------------------------------------
|
**-----------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
PRINT_ADDR(cp->cmd, "M_DISCONNECT received, but datapointer "
|
PRINT_ADDR(cp->cmd, "DISCONNECT received, but datapointer "
|
||||||
"not saved: data=%x save=%x goal=%x.\n",
|
"not saved: data=%x save=%x goal=%x.\n",
|
||||||
(unsigned) INL (nc_temp),
|
(unsigned) INL (nc_temp),
|
||||||
(unsigned) scr_to_cpu(np->header.savep),
|
(unsigned) scr_to_cpu(np->header.savep),
|
||||||
|
@ -7862,7 +7845,7 @@ static int __init ncr_snooptest (struct ncb* np)
|
||||||
**==========================================================
|
**==========================================================
|
||||||
**
|
**
|
||||||
** Note: we have to return the correct value.
|
** Note: we have to return the correct value.
|
||||||
** THERE IS NO SAVE DEFAULT VALUE.
|
** THERE IS NO SAFE DEFAULT VALUE.
|
||||||
**
|
**
|
||||||
** Most NCR/SYMBIOS boards are delivered with a 40 Mhz clock.
|
** Most NCR/SYMBIOS boards are delivered with a 40 Mhz clock.
|
||||||
** 53C860 and 53C875 rev. 1 support fast20 transfers but
|
** 53C860 and 53C875 rev. 1 support fast20 transfers but
|
||||||
|
@ -8562,7 +8545,7 @@ struct Scsi_Host * __init ncr_attach(struct scsi_host_template *tpnt,
|
||||||
|
|
||||||
/* use SIMPLE TAG messages by default */
|
/* use SIMPLE TAG messages by default */
|
||||||
#ifdef SCSI_NCR_ALWAYS_SIMPLE_TAG
|
#ifdef SCSI_NCR_ALWAYS_SIMPLE_TAG
|
||||||
np->order = M_SIMPLE_TAG;
|
np->order = SIMPLE_QUEUE_TAG;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
spin_unlock_irqrestore(&np->smp_lock, flags);
|
spin_unlock_irqrestore(&np->smp_lock, flags);
|
||||||
|
|
|
@ -56,8 +56,10 @@
|
||||||
#include <linux/config.h>
|
#include <linux/config.h>
|
||||||
#include <scsi/scsi_host.h>
|
#include <scsi/scsi_host.h>
|
||||||
|
|
||||||
|
#include <linux/config.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** If you want a driver as small as possible, do not define the
|
** If you want a driver as small as possible, donnot define the
|
||||||
** following options.
|
** following options.
|
||||||
*/
|
*/
|
||||||
#define SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT
|
#define SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT
|
||||||
|
@ -1254,39 +1256,6 @@ struct scr_tblsel {
|
||||||
**-----------------------------------------------------------
|
**-----------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
** Messages
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define M_COMPLETE COMMAND_COMPLETE
|
|
||||||
#define M_EXTENDED EXTENDED_MESSAGE
|
|
||||||
#define M_SAVE_DP SAVE_POINTERS
|
|
||||||
#define M_RESTORE_DP RESTORE_POINTERS
|
|
||||||
#define M_DISCONNECT DISCONNECT
|
|
||||||
#define M_ID_ERROR INITIATOR_ERROR
|
|
||||||
#define M_ABORT ABORT_TASK_SET
|
|
||||||
#define M_REJECT MESSAGE_REJECT
|
|
||||||
#define M_NOOP NOP
|
|
||||||
#define M_PARITY MSG_PARITY_ERROR
|
|
||||||
#define M_LCOMPLETE LINKED_CMD_COMPLETE
|
|
||||||
#define M_FCOMPLETE LINKED_FLG_CMD_COMPLETE
|
|
||||||
#define M_RESET TARGET_RESET
|
|
||||||
#define M_ABORT_TAG ABORT_TASK
|
|
||||||
#define M_CLEAR_QUEUE CLEAR_TASK_SET
|
|
||||||
#define M_INIT_REC INITIATE_RECOVERY
|
|
||||||
#define M_REL_REC RELEASE_RECOVERY
|
|
||||||
#define M_TERMINATE (0x11)
|
|
||||||
#define M_SIMPLE_TAG SIMPLE_QUEUE_TAG
|
|
||||||
#define M_HEAD_TAG HEAD_OF_QUEUE_TAG
|
|
||||||
#define M_ORDERED_TAG ORDERED_QUEUE_TAG
|
|
||||||
#define M_IGN_RESIDUE IGNORE_WIDE_RESIDUE
|
|
||||||
#define M_IDENTIFY (0x80)
|
|
||||||
|
|
||||||
#define M_X_MODIFY_DP EXTENDED_MODIFY_DATA_POINTER
|
|
||||||
#define M_X_SYNC_REQ EXTENDED_SDTR
|
|
||||||
#define M_X_WIDE_REQ EXTENDED_WDTR
|
|
||||||
#define M_X_PPR_REQ EXTENDED_PPR
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Status
|
** Status
|
||||||
*/
|
*/
|
||||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -518,7 +518,8 @@ struct osst_buffer {
|
||||||
int writing;
|
int writing;
|
||||||
int midlevel_result;
|
int midlevel_result;
|
||||||
int syscall_result;
|
int syscall_result;
|
||||||
struct scsi_request *last_SRpnt;
|
struct osst_request *last_SRpnt;
|
||||||
|
struct st_cmdstatus cmdstat;
|
||||||
unsigned char *b_data;
|
unsigned char *b_data;
|
||||||
os_aux_t *aux; /* onstream AUX structure at end of each block */
|
os_aux_t *aux; /* onstream AUX structure at end of each block */
|
||||||
unsigned short use_sg; /* zero or number of s/g segments for this adapter */
|
unsigned short use_sg; /* zero or number of s/g segments for this adapter */
|
||||||
|
@ -626,6 +627,15 @@ struct osst_tape {
|
||||||
struct gendisk *drive;
|
struct gendisk *drive;
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
/* scsi tape command */
|
||||||
|
struct osst_request {
|
||||||
|
unsigned char cmd[MAX_COMMAND_SIZE];
|
||||||
|
unsigned char sense[SCSI_SENSE_BUFFERSIZE];
|
||||||
|
int result;
|
||||||
|
struct osst_tape *stp;
|
||||||
|
struct completion *waiting;
|
||||||
|
};
|
||||||
|
|
||||||
/* Values of write_type */
|
/* Values of write_type */
|
||||||
#define OS_WRITE_DATA 0
|
#define OS_WRITE_DATA 0
|
||||||
#define OS_WRITE_EOD 1
|
#define OS_WRITE_EOD 1
|
||||||
|
|
|
@ -143,7 +143,6 @@ static struct scsi_host_template adma_ata_sht = {
|
||||||
.name = DRV_NAME,
|
.name = DRV_NAME,
|
||||||
.ioctl = ata_scsi_ioctl,
|
.ioctl = ata_scsi_ioctl,
|
||||||
.queuecommand = ata_scsi_queuecmd,
|
.queuecommand = ata_scsi_queuecmd,
|
||||||
.eh_timed_out = ata_scsi_timed_out,
|
|
||||||
.eh_strategy_handler = ata_scsi_error,
|
.eh_strategy_handler = ata_scsi_error,
|
||||||
.can_queue = ATA_DEF_QUEUE,
|
.can_queue = ATA_DEF_QUEUE,
|
||||||
.this_id = ATA_SHT_THIS_ID,
|
.this_id = ATA_SHT_THIS_ID,
|
||||||
|
|
|
@ -10,14 +10,13 @@ config SCSI_QLA_FC
|
||||||
By default, firmware for the ISP parts will be loaded
|
By default, firmware for the ISP parts will be loaded
|
||||||
via the Firmware Loader interface.
|
via the Firmware Loader interface.
|
||||||
|
|
||||||
ISP Firmware Filename
|
ISP Firmware Filename
|
||||||
---------- -----------------
|
---------- -----------------
|
||||||
21xx ql2100_fw.bin
|
21xx ql2100_fw.bin
|
||||||
22xx ql2200_fw.bin
|
22xx ql2200_fw.bin
|
||||||
2300, 2312 ql2300_fw.bin
|
2300, 2312, 6312 ql2300_fw.bin
|
||||||
2322 ql2322_fw.bin
|
2322, 6322 ql2322_fw.bin
|
||||||
6312, 6322 ql6312_fw.bin
|
24xx ql2400_fw.bin
|
||||||
24xx ql2400_fw.bin
|
|
||||||
|
|
||||||
Upon request, the driver caches the firmware image until
|
Upon request, the driver caches the firmware image until
|
||||||
the driver is unloaded.
|
the driver is unloaded.
|
||||||
|
@ -51,23 +50,17 @@ config SCSI_QLA22XX
|
||||||
This driver supports the QLogic 22xx (ISP2200) host adapter family.
|
This driver supports the QLogic 22xx (ISP2200) host adapter family.
|
||||||
|
|
||||||
config SCSI_QLA2300
|
config SCSI_QLA2300
|
||||||
tristate " Build QLogic ISP2300 firmware-module"
|
tristate " Build QLogic ISP2300/ISP6312 firmware-module"
|
||||||
depends on SCSI_QLA_FC && SCSI_QLA2XXX_EMBEDDED_FIRMWARE
|
depends on SCSI_QLA_FC && SCSI_QLA2XXX_EMBEDDED_FIRMWARE
|
||||||
---help---
|
---help---
|
||||||
This driver supports the QLogic 2300 (ISP2300 and ISP2312) host
|
This driver supports the QLogic 2300 (ISP2300, ISP2312 and
|
||||||
adapter family.
|
ISP6312) host adapter family.
|
||||||
|
|
||||||
config SCSI_QLA2322
|
config SCSI_QLA2322
|
||||||
tristate " Build QLogic ISP2322 firmware-module"
|
tristate " Build QLogic ISP2322/ISP6322 firmware-module"
|
||||||
depends on SCSI_QLA_FC && SCSI_QLA2XXX_EMBEDDED_FIRMWARE
|
depends on SCSI_QLA_FC && SCSI_QLA2XXX_EMBEDDED_FIRMWARE
|
||||||
---help---
|
---help---
|
||||||
This driver supports the QLogic 2322 (ISP2322) host adapter family.
|
This driver supports the QLogic 2322 (ISP2322 and ISP6322) host
|
||||||
|
|
||||||
config SCSI_QLA6312
|
|
||||||
tristate " Build QLogic ISP63xx firmware-module"
|
|
||||||
depends on SCSI_QLA_FC && SCSI_QLA2XXX_EMBEDDED_FIRMWARE
|
|
||||||
---help---
|
|
||||||
This driver supports the QLogic 63xx (ISP6312 and ISP6322) host
|
|
||||||
adapter family.
|
adapter family.
|
||||||
|
|
||||||
config SCSI_QLA24XX
|
config SCSI_QLA24XX
|
||||||
|
|
|
@ -9,12 +9,10 @@ qla2100-y := ql2100.o ql2100_fw.o
|
||||||
qla2200-y := ql2200.o ql2200_fw.o
|
qla2200-y := ql2200.o ql2200_fw.o
|
||||||
qla2300-y := ql2300.o ql2300_fw.o
|
qla2300-y := ql2300.o ql2300_fw.o
|
||||||
qla2322-y := ql2322.o ql2322_fw.o
|
qla2322-y := ql2322.o ql2322_fw.o
|
||||||
qla6312-y := ql6312.o ql6312_fw.o
|
|
||||||
qla2400-y := ql2400.o ql2400_fw.o
|
qla2400-y := ql2400.o ql2400_fw.o
|
||||||
|
|
||||||
obj-$(CONFIG_SCSI_QLA21XX) += qla2xxx.o qla2100.o
|
obj-$(CONFIG_SCSI_QLA21XX) += qla2xxx.o qla2100.o
|
||||||
obj-$(CONFIG_SCSI_QLA22XX) += qla2xxx.o qla2200.o
|
obj-$(CONFIG_SCSI_QLA22XX) += qla2xxx.o qla2200.o
|
||||||
obj-$(CONFIG_SCSI_QLA2300) += qla2xxx.o qla2300.o
|
obj-$(CONFIG_SCSI_QLA2300) += qla2xxx.o qla2300.o
|
||||||
obj-$(CONFIG_SCSI_QLA2322) += qla2xxx.o qla2322.o
|
obj-$(CONFIG_SCSI_QLA2322) += qla2xxx.o qla2322.o
|
||||||
obj-$(CONFIG_SCSI_QLA6312) += qla2xxx.o qla6312.o
|
|
||||||
obj-$(CONFIG_SCSI_QLA24XX) += qla2xxx.o qla2400.o
|
obj-$(CONFIG_SCSI_QLA24XX) += qla2xxx.o qla2400.o
|
||||||
|
|
|
@ -40,6 +40,11 @@ static struct qla_board_info qla_board_tbl[] = {
|
||||||
.isp_name = "ISP2312",
|
.isp_name = "ISP2312",
|
||||||
.fw_info = qla_fw_tbl,
|
.fw_info = qla_fw_tbl,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.drv_name = qla_driver_name,
|
||||||
|
.isp_name = "ISP6312",
|
||||||
|
.fw_info = qla_fw_tbl,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct pci_device_id qla2300_pci_tbl[] = {
|
static struct pci_device_id qla2300_pci_tbl[] = {
|
||||||
|
@ -57,6 +62,13 @@ static struct pci_device_id qla2300_pci_tbl[] = {
|
||||||
.subdevice = PCI_ANY_ID,
|
.subdevice = PCI_ANY_ID,
|
||||||
.driver_data = (unsigned long)&qla_board_tbl[1],
|
.driver_data = (unsigned long)&qla_board_tbl[1],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.vendor = PCI_VENDOR_ID_QLOGIC,
|
||||||
|
.device = PCI_DEVICE_ID_QLOGIC_ISP6312,
|
||||||
|
.subvendor = PCI_ANY_ID,
|
||||||
|
.subdevice = PCI_ANY_ID,
|
||||||
|
.driver_data = (unsigned long)&qla_board_tbl[2],
|
||||||
|
},
|
||||||
{0, 0},
|
{0, 0},
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(pci, qla2300_pci_tbl);
|
MODULE_DEVICE_TABLE(pci, qla2300_pci_tbl);
|
||||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -52,6 +52,11 @@ static struct qla_board_info qla_board_tbl[] = {
|
||||||
.isp_name = "ISP2322",
|
.isp_name = "ISP2322",
|
||||||
.fw_info = qla_fw_tbl,
|
.fw_info = qla_fw_tbl,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.drv_name = qla_driver_name,
|
||||||
|
.isp_name = "ISP6322",
|
||||||
|
.fw_info = qla_fw_tbl,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct pci_device_id qla2322_pci_tbl[] = {
|
static struct pci_device_id qla2322_pci_tbl[] = {
|
||||||
|
@ -62,6 +67,13 @@ static struct pci_device_id qla2322_pci_tbl[] = {
|
||||||
.subdevice = PCI_ANY_ID,
|
.subdevice = PCI_ANY_ID,
|
||||||
.driver_data = (unsigned long)&qla_board_tbl[0],
|
.driver_data = (unsigned long)&qla_board_tbl[0],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.vendor = PCI_VENDOR_ID_QLOGIC,
|
||||||
|
.device = PCI_DEVICE_ID_QLOGIC_ISP6322,
|
||||||
|
.subvendor = PCI_ANY_ID,
|
||||||
|
.subdevice = PCI_ANY_ID,
|
||||||
|
.driver_data = (unsigned long)&qla_board_tbl[1],
|
||||||
|
},
|
||||||
{0, 0},
|
{0, 0},
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(pci, qla2322_pci_tbl);
|
MODULE_DEVICE_TABLE(pci, qla2322_pci_tbl);
|
||||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -49,6 +49,18 @@ static struct qla_board_info qla_board_tbl[] = {
|
||||||
.fw_info = qla_fw_tbl,
|
.fw_info = qla_fw_tbl,
|
||||||
.fw_fname = "ql2400_fw.bin",
|
.fw_fname = "ql2400_fw.bin",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.drv_name = qla_driver_name,
|
||||||
|
.isp_name = "ISP5422",
|
||||||
|
.fw_info = qla_fw_tbl,
|
||||||
|
.fw_fname = "ql2400_fw.bin",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.drv_name = qla_driver_name,
|
||||||
|
.isp_name = "ISP5432",
|
||||||
|
.fw_info = qla_fw_tbl,
|
||||||
|
.fw_fname = "ql2400_fw.bin",
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct pci_device_id qla24xx_pci_tbl[] = {
|
static struct pci_device_id qla24xx_pci_tbl[] = {
|
||||||
|
@ -66,6 +78,21 @@ static struct pci_device_id qla24xx_pci_tbl[] = {
|
||||||
.subdevice = PCI_ANY_ID,
|
.subdevice = PCI_ANY_ID,
|
||||||
.driver_data = (unsigned long)&qla_board_tbl[1],
|
.driver_data = (unsigned long)&qla_board_tbl[1],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.vendor = PCI_VENDOR_ID_QLOGIC,
|
||||||
|
.device = PCI_DEVICE_ID_QLOGIC_ISP5422,
|
||||||
|
.subvendor = PCI_ANY_ID,
|
||||||
|
.subdevice = PCI_ANY_ID,
|
||||||
|
.driver_data = (unsigned long)&qla_board_tbl[2],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.vendor = PCI_VENDOR_ID_QLOGIC,
|
||||||
|
.device = PCI_DEVICE_ID_QLOGIC_ISP5432,
|
||||||
|
.subvendor = PCI_ANY_ID,
|
||||||
|
.subdevice = PCI_ANY_ID,
|
||||||
|
.driver_data = (unsigned long)&qla_board_tbl[3],
|
||||||
|
},
|
||||||
|
|
||||||
{0, 0},
|
{0, 0},
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(pci, qla24xx_pci_tbl);
|
MODULE_DEVICE_TABLE(pci, qla24xx_pci_tbl);
|
||||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,101 +0,0 @@
|
||||||
/*
|
|
||||||
* QLogic Fibre Channel HBA Driver
|
|
||||||
* Copyright (c) 2003-2005 QLogic Corporation
|
|
||||||
*
|
|
||||||
* See LICENSE.qla2xxx for copyright and licensing details.
|
|
||||||
*/
|
|
||||||
#include <linux/init.h>
|
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/pci.h>
|
|
||||||
|
|
||||||
#include "qla_def.h"
|
|
||||||
|
|
||||||
static char qla_driver_name[] = "qla6312";
|
|
||||||
|
|
||||||
extern unsigned char fw2300flx_version[];
|
|
||||||
extern unsigned char fw2300flx_version_str[];
|
|
||||||
extern unsigned short fw2300flx_addr01;
|
|
||||||
extern unsigned short fw2300flx_code01[];
|
|
||||||
extern unsigned short fw2300flx_length01;
|
|
||||||
|
|
||||||
static struct qla_fw_info qla_fw_tbl[] = {
|
|
||||||
{
|
|
||||||
.addressing = FW_INFO_ADDR_NORMAL,
|
|
||||||
.fwcode = &fw2300flx_code01[0],
|
|
||||||
.fwlen = &fw2300flx_length01,
|
|
||||||
.fwstart = &fw2300flx_addr01,
|
|
||||||
},
|
|
||||||
{ FW_INFO_ADDR_NOMORE, },
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct qla_board_info qla_board_tbl[] = {
|
|
||||||
{
|
|
||||||
.drv_name = qla_driver_name,
|
|
||||||
.isp_name = "ISP6312",
|
|
||||||
.fw_info = qla_fw_tbl,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.drv_name = qla_driver_name,
|
|
||||||
.isp_name = "ISP6322",
|
|
||||||
.fw_info = qla_fw_tbl,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct pci_device_id qla6312_pci_tbl[] = {
|
|
||||||
{
|
|
||||||
.vendor = PCI_VENDOR_ID_QLOGIC,
|
|
||||||
.device = PCI_DEVICE_ID_QLOGIC_ISP6312,
|
|
||||||
.subvendor = PCI_ANY_ID,
|
|
||||||
.subdevice = PCI_ANY_ID,
|
|
||||||
.driver_data = (unsigned long)&qla_board_tbl[0],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.vendor = PCI_VENDOR_ID_QLOGIC,
|
|
||||||
.device = PCI_DEVICE_ID_QLOGIC_ISP6322,
|
|
||||||
.subvendor = PCI_ANY_ID,
|
|
||||||
.subdevice = PCI_ANY_ID,
|
|
||||||
.driver_data = (unsigned long)&qla_board_tbl[1],
|
|
||||||
},
|
|
||||||
{0, 0},
|
|
||||||
};
|
|
||||||
MODULE_DEVICE_TABLE(pci, qla6312_pci_tbl);
|
|
||||||
|
|
||||||
static int __devinit
|
|
||||||
qla6312_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
|
||||||
{
|
|
||||||
return qla2x00_probe_one(pdev,
|
|
||||||
(struct qla_board_info *)id->driver_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __devexit
|
|
||||||
qla6312_remove_one(struct pci_dev *pdev)
|
|
||||||
{
|
|
||||||
qla2x00_remove_one(pdev);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct pci_driver qla6312_pci_driver = {
|
|
||||||
.name = "qla6312",
|
|
||||||
.id_table = qla6312_pci_tbl,
|
|
||||||
.probe = qla6312_probe_one,
|
|
||||||
.remove = __devexit_p(qla6312_remove_one),
|
|
||||||
};
|
|
||||||
|
|
||||||
static int __init
|
|
||||||
qla6312_init(void)
|
|
||||||
{
|
|
||||||
return pci_module_init(&qla6312_pci_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __exit
|
|
||||||
qla6312_exit(void)
|
|
||||||
{
|
|
||||||
pci_unregister_driver(&qla6312_pci_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
module_init(qla6312_init);
|
|
||||||
module_exit(qla6312_exit);
|
|
||||||
|
|
||||||
MODULE_AUTHOR("QLogic Corporation");
|
|
||||||
MODULE_DESCRIPTION("QLogic ISP63xx FC-SCSI Host Bus Adapter driver");
|
|
||||||
MODULE_LICENSE("GPL");
|
|
||||||
MODULE_VERSION(QLA2XXX_VERSION);
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -50,7 +50,7 @@ qla2x00_sysfs_write_fw_dump(struct kobject *kobj, char *buf, loff_t off,
|
||||||
ha->host_no);
|
ha->host_no);
|
||||||
|
|
||||||
vfree(ha->fw_dump_buffer);
|
vfree(ha->fw_dump_buffer);
|
||||||
if (!IS_QLA24XX(ha) && !IS_QLA25XX(ha))
|
if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha))
|
||||||
free_pages((unsigned long)ha->fw_dump,
|
free_pages((unsigned long)ha->fw_dump,
|
||||||
ha->fw_dump_order);
|
ha->fw_dump_order);
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ qla2x00_sysfs_write_fw_dump(struct kobject *kobj, char *buf, loff_t off,
|
||||||
if ((ha->fw_dump || ha->fw_dumped) && !ha->fw_dump_reading) {
|
if ((ha->fw_dump || ha->fw_dumped) && !ha->fw_dump_reading) {
|
||||||
ha->fw_dump_reading = 1;
|
ha->fw_dump_reading = 1;
|
||||||
|
|
||||||
if (IS_QLA24XX(ha) || IS_QLA25XX(ha))
|
if (IS_QLA24XX(ha) || IS_QLA54XX(ha))
|
||||||
dump_size = FW_DUMP_SIZE_24XX;
|
dump_size = FW_DUMP_SIZE_24XX;
|
||||||
else {
|
else {
|
||||||
dump_size = FW_DUMP_SIZE_1M;
|
dump_size = FW_DUMP_SIZE_1M;
|
||||||
|
@ -138,7 +138,7 @@ qla2x00_sysfs_write_nvram(struct kobject *kobj, char *buf, loff_t off,
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Checksum NVRAM. */
|
/* Checksum NVRAM. */
|
||||||
if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) {
|
if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
|
||||||
uint32_t *iter;
|
uint32_t *iter;
|
||||||
uint32_t chksum;
|
uint32_t chksum;
|
||||||
|
|
||||||
|
@ -308,6 +308,61 @@ static struct bin_attribute sysfs_optrom_ctl_attr = {
|
||||||
.write = qla2x00_sysfs_write_optrom_ctl,
|
.write = qla2x00_sysfs_write_optrom_ctl,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static ssize_t
|
||||||
|
qla2x00_sysfs_read_vpd(struct kobject *kobj, char *buf, loff_t off,
|
||||||
|
size_t count)
|
||||||
|
{
|
||||||
|
struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj,
|
||||||
|
struct device, kobj)));
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
if (!capable(CAP_SYS_ADMIN) || off != 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha))
|
||||||
|
return -ENOTSUPP;
|
||||||
|
|
||||||
|
/* Read NVRAM. */
|
||||||
|
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||||
|
ha->isp_ops.read_nvram(ha, (uint8_t *)buf, ha->vpd_base, ha->vpd_size);
|
||||||
|
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||||
|
|
||||||
|
return ha->vpd_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t
|
||||||
|
qla2x00_sysfs_write_vpd(struct kobject *kobj, char *buf, loff_t off,
|
||||||
|
size_t count)
|
||||||
|
{
|
||||||
|
struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj,
|
||||||
|
struct device, kobj)));
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->vpd_size)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha))
|
||||||
|
return -ENOTSUPP;
|
||||||
|
|
||||||
|
/* Write NVRAM. */
|
||||||
|
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||||
|
ha->isp_ops.write_nvram(ha, (uint8_t *)buf, ha->vpd_base, count);
|
||||||
|
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct bin_attribute sysfs_vpd_attr = {
|
||||||
|
.attr = {
|
||||||
|
.name = "vpd",
|
||||||
|
.mode = S_IRUSR | S_IWUSR,
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
},
|
||||||
|
.size = 0,
|
||||||
|
.read = qla2x00_sysfs_read_vpd,
|
||||||
|
.write = qla2x00_sysfs_write_vpd,
|
||||||
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
qla2x00_alloc_sysfs_attr(scsi_qla_host_t *ha)
|
qla2x00_alloc_sysfs_attr(scsi_qla_host_t *ha)
|
||||||
{
|
{
|
||||||
|
@ -318,6 +373,7 @@ qla2x00_alloc_sysfs_attr(scsi_qla_host_t *ha)
|
||||||
sysfs_create_bin_file(&host->shost_gendev.kobj, &sysfs_optrom_attr);
|
sysfs_create_bin_file(&host->shost_gendev.kobj, &sysfs_optrom_attr);
|
||||||
sysfs_create_bin_file(&host->shost_gendev.kobj,
|
sysfs_create_bin_file(&host->shost_gendev.kobj,
|
||||||
&sysfs_optrom_ctl_attr);
|
&sysfs_optrom_ctl_attr);
|
||||||
|
sysfs_create_bin_file(&host->shost_gendev.kobj, &sysfs_vpd_attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -330,6 +386,7 @@ qla2x00_free_sysfs_attr(scsi_qla_host_t *ha)
|
||||||
sysfs_remove_bin_file(&host->shost_gendev.kobj, &sysfs_optrom_attr);
|
sysfs_remove_bin_file(&host->shost_gendev.kobj, &sysfs_optrom_attr);
|
||||||
sysfs_remove_bin_file(&host->shost_gendev.kobj,
|
sysfs_remove_bin_file(&host->shost_gendev.kobj,
|
||||||
&sysfs_optrom_ctl_attr);
|
&sysfs_optrom_ctl_attr);
|
||||||
|
sysfs_remove_bin_file(&host->shost_gendev.kobj, &sysfs_vpd_attr);
|
||||||
|
|
||||||
if (ha->beacon_blink_led == 1)
|
if (ha->beacon_blink_led == 1)
|
||||||
ha->isp_ops.beacon_off(ha);
|
ha->isp_ops.beacon_off(ha);
|
||||||
|
@ -450,9 +507,6 @@ qla2x00_zio_show(struct class_device *cdev, char *buf)
|
||||||
int len = 0;
|
int len = 0;
|
||||||
|
|
||||||
switch (ha->zio_mode) {
|
switch (ha->zio_mode) {
|
||||||
case QLA_ZIO_MODE_5:
|
|
||||||
len += snprintf(buf + len, PAGE_SIZE-len, "Mode 5\n");
|
|
||||||
break;
|
|
||||||
case QLA_ZIO_MODE_6:
|
case QLA_ZIO_MODE_6:
|
||||||
len += snprintf(buf + len, PAGE_SIZE-len, "Mode 6\n");
|
len += snprintf(buf + len, PAGE_SIZE-len, "Mode 6\n");
|
||||||
break;
|
break;
|
||||||
|
@ -470,20 +524,16 @@ qla2x00_zio_store(struct class_device *cdev, const char *buf, size_t count)
|
||||||
int val = 0;
|
int val = 0;
|
||||||
uint16_t zio_mode;
|
uint16_t zio_mode;
|
||||||
|
|
||||||
|
if (!IS_ZIO_SUPPORTED(ha))
|
||||||
|
return -ENOTSUPP;
|
||||||
|
|
||||||
if (sscanf(buf, "%d", &val) != 1)
|
if (sscanf(buf, "%d", &val) != 1)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
switch (val) {
|
if (val)
|
||||||
case 1:
|
|
||||||
zio_mode = QLA_ZIO_MODE_5;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
zio_mode = QLA_ZIO_MODE_6;
|
zio_mode = QLA_ZIO_MODE_6;
|
||||||
break;
|
else
|
||||||
default:
|
|
||||||
zio_mode = QLA_ZIO_DISABLED;
|
zio_mode = QLA_ZIO_DISABLED;
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Update per-hba values and queue a reset. */
|
/* Update per-hba values and queue a reset. */
|
||||||
if (zio_mode != QLA_ZIO_DISABLED || ha->zio_mode != QLA_ZIO_DISABLED) {
|
if (zio_mode != QLA_ZIO_DISABLED || ha->zio_mode != QLA_ZIO_DISABLED) {
|
||||||
|
@ -750,7 +800,7 @@ qla2x00_get_fc_host_stats(struct Scsi_Host *shost)
|
||||||
pfc_host_stat = &ha->fc_host_stat;
|
pfc_host_stat = &ha->fc_host_stat;
|
||||||
memset(pfc_host_stat, -1, sizeof(struct fc_host_statistics));
|
memset(pfc_host_stat, -1, sizeof(struct fc_host_statistics));
|
||||||
|
|
||||||
if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) {
|
if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
|
||||||
rval = qla24xx_get_isp_stats(ha, (uint32_t *)&stat_buf,
|
rval = qla24xx_get_isp_stats(ha, (uint32_t *)&stat_buf,
|
||||||
sizeof(stat_buf) / 4, mb_stat);
|
sizeof(stat_buf) / 4, mb_stat);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -31,82 +31,6 @@
|
||||||
#include <scsi/scsi_cmnd.h>
|
#include <scsi/scsi_cmnd.h>
|
||||||
#include <scsi/scsi_transport_fc.h>
|
#include <scsi/scsi_transport_fc.h>
|
||||||
|
|
||||||
#if defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE)
|
|
||||||
#if defined(CONFIG_SCSI_QLA21XX) || defined(CONFIG_SCSI_QLA21XX_MODULE)
|
|
||||||
#define IS_QLA2100(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2100)
|
|
||||||
#else
|
|
||||||
#define IS_QLA2100(ha) 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(CONFIG_SCSI_QLA22XX) || defined(CONFIG_SCSI_QLA22XX_MODULE)
|
|
||||||
#define IS_QLA2200(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2200)
|
|
||||||
#else
|
|
||||||
#define IS_QLA2200(ha) 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(CONFIG_SCSI_QLA2300) || defined(CONFIG_SCSI_QLA2300_MODULE)
|
|
||||||
#define IS_QLA2300(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2300)
|
|
||||||
#define IS_QLA2312(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2312)
|
|
||||||
#else
|
|
||||||
#define IS_QLA2300(ha) 0
|
|
||||||
#define IS_QLA2312(ha) 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(CONFIG_SCSI_QLA2322) || defined(CONFIG_SCSI_QLA2322_MODULE)
|
|
||||||
#define IS_QLA2322(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2322)
|
|
||||||
#else
|
|
||||||
#define IS_QLA2322(ha) 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(CONFIG_SCSI_QLA6312) || defined(CONFIG_SCSI_QLA6312_MODULE)
|
|
||||||
#define IS_QLA6312(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP6312)
|
|
||||||
#define IS_QLA6322(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP6322)
|
|
||||||
#else
|
|
||||||
#define IS_QLA6312(ha) 0
|
|
||||||
#define IS_QLA6322(ha) 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(CONFIG_SCSI_QLA24XX) || defined(CONFIG_SCSI_QLA24XX_MODULE)
|
|
||||||
#define IS_QLA2422(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2422)
|
|
||||||
#define IS_QLA2432(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2432)
|
|
||||||
#else
|
|
||||||
#define IS_QLA2422(ha) 0
|
|
||||||
#define IS_QLA2432(ha) 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(CONFIG_SCSI_QLA25XX) || defined(CONFIG_SCSI_QLA25XX_MODULE)
|
|
||||||
#define IS_QLA2512(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2512)
|
|
||||||
#define IS_QLA2522(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2522)
|
|
||||||
#else
|
|
||||||
#define IS_QLA2512(ha) 0
|
|
||||||
#define IS_QLA2522(ha) 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#else /* !defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE) */
|
|
||||||
|
|
||||||
#define IS_QLA2100(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2100)
|
|
||||||
#define IS_QLA2200(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2200)
|
|
||||||
#define IS_QLA2300(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2300)
|
|
||||||
#define IS_QLA2312(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2312)
|
|
||||||
#define IS_QLA2322(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2322)
|
|
||||||
#define IS_QLA6312(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP6312)
|
|
||||||
#define IS_QLA6322(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP6322)
|
|
||||||
#define IS_QLA2422(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2422)
|
|
||||||
#define IS_QLA2432(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2432)
|
|
||||||
#define IS_QLA2512(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2512)
|
|
||||||
#define IS_QLA2522(ha) ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2522)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define IS_QLA23XX(ha) (IS_QLA2300(ha) || IS_QLA2312(ha) || IS_QLA2322(ha) || \
|
|
||||||
IS_QLA6312(ha) || IS_QLA6322(ha))
|
|
||||||
#define IS_QLA24XX(ha) (IS_QLA2422(ha) || IS_QLA2432(ha))
|
|
||||||
#define IS_QLA25XX(ha) (IS_QLA2512(ha) || IS_QLA2522(ha))
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Only non-ISP2[12]00 have extended addressing support in the firmware.
|
|
||||||
*/
|
|
||||||
#define HAS_EXTENDED_IDS(ha) (!IS_QLA2100(ha) && !IS_QLA2200(ha))
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We have MAILBOX_REGISTER_COUNT sized arrays in a few places,
|
* We have MAILBOX_REGISTER_COUNT sized arrays in a few places,
|
||||||
* but that's fine as we don't look at the last 24 ones for
|
* but that's fine as we don't look at the last 24 ones for
|
||||||
|
@ -838,7 +762,6 @@ typedef struct {
|
||||||
#define PD_STATE_WAIT_PORT_LOGOUT_ACK 11
|
#define PD_STATE_WAIT_PORT_LOGOUT_ACK 11
|
||||||
|
|
||||||
|
|
||||||
#define QLA_ZIO_MODE_5 (BIT_2 | BIT_0)
|
|
||||||
#define QLA_ZIO_MODE_6 (BIT_2 | BIT_1)
|
#define QLA_ZIO_MODE_6 (BIT_2 | BIT_1)
|
||||||
#define QLA_ZIO_DISABLED 0
|
#define QLA_ZIO_DISABLED 0
|
||||||
#define QLA_ZIO_DEFAULT_TIMER 2
|
#define QLA_ZIO_DEFAULT_TIMER 2
|
||||||
|
@ -2300,6 +2223,47 @@ typedef struct scsi_qla_host {
|
||||||
#define SWITCH_FOUND BIT_3
|
#define SWITCH_FOUND BIT_3
|
||||||
#define DFLG_NO_CABLE BIT_4
|
#define DFLG_NO_CABLE BIT_4
|
||||||
|
|
||||||
|
uint32_t device_type;
|
||||||
|
#define DT_ISP2100 BIT_0
|
||||||
|
#define DT_ISP2200 BIT_1
|
||||||
|
#define DT_ISP2300 BIT_2
|
||||||
|
#define DT_ISP2312 BIT_3
|
||||||
|
#define DT_ISP2322 BIT_4
|
||||||
|
#define DT_ISP6312 BIT_5
|
||||||
|
#define DT_ISP6322 BIT_6
|
||||||
|
#define DT_ISP2422 BIT_7
|
||||||
|
#define DT_ISP2432 BIT_8
|
||||||
|
#define DT_ISP5422 BIT_9
|
||||||
|
#define DT_ISP5432 BIT_10
|
||||||
|
#define DT_ISP_LAST (DT_ISP5432 << 1)
|
||||||
|
|
||||||
|
#define DT_ZIO_SUPPORTED BIT_28
|
||||||
|
#define DT_OEM_001 BIT_29
|
||||||
|
#define DT_ISP2200A BIT_30
|
||||||
|
#define DT_EXTENDED_IDS BIT_31
|
||||||
|
|
||||||
|
#define DT_MASK(ha) ((ha)->device_type & (DT_ISP_LAST - 1))
|
||||||
|
#define IS_QLA2100(ha) (DT_MASK(ha) & DT_ISP2100)
|
||||||
|
#define IS_QLA2200(ha) (DT_MASK(ha) & DT_ISP2200)
|
||||||
|
#define IS_QLA2300(ha) (DT_MASK(ha) & DT_ISP2300)
|
||||||
|
#define IS_QLA2312(ha) (DT_MASK(ha) & DT_ISP2312)
|
||||||
|
#define IS_QLA2322(ha) (DT_MASK(ha) & DT_ISP2322)
|
||||||
|
#define IS_QLA6312(ha) (DT_MASK(ha) & DT_ISP6312)
|
||||||
|
#define IS_QLA6322(ha) (DT_MASK(ha) & DT_ISP6322)
|
||||||
|
#define IS_QLA2422(ha) (DT_MASK(ha) & DT_ISP2422)
|
||||||
|
#define IS_QLA2432(ha) (DT_MASK(ha) & DT_ISP2432)
|
||||||
|
#define IS_QLA5422(ha) (DT_MASK(ha) & DT_ISP5422)
|
||||||
|
#define IS_QLA5432(ha) (DT_MASK(ha) & DT_ISP5432)
|
||||||
|
|
||||||
|
#define IS_QLA23XX(ha) (IS_QLA2300(ha) || IS_QLA2312(ha) || IS_QLA2322(ha) || \
|
||||||
|
IS_QLA6312(ha) || IS_QLA6322(ha))
|
||||||
|
#define IS_QLA24XX(ha) (IS_QLA2422(ha) || IS_QLA2432(ha))
|
||||||
|
#define IS_QLA54XX(ha) (IS_QLA5422(ha) || IS_QLA5432(ha))
|
||||||
|
|
||||||
|
#define IS_ZIO_SUPPORTED(ha) ((ha)->device_type & DT_ZIO_SUPPORTED)
|
||||||
|
#define IS_OEM_001(ha) ((ha)->device_type & DT_OEM_001)
|
||||||
|
#define HAS_EXTENDED_IDS(ha) ((ha)->device_type & DT_EXTENDED_IDS)
|
||||||
|
|
||||||
/* SRB cache. */
|
/* SRB cache. */
|
||||||
#define SRB_MIN_REQ 128
|
#define SRB_MIN_REQ 128
|
||||||
mempool_t *srb_mempool;
|
mempool_t *srb_mempool;
|
||||||
|
@ -2381,6 +2345,8 @@ typedef struct scsi_qla_host {
|
||||||
/* NVRAM configuration data */
|
/* NVRAM configuration data */
|
||||||
uint16_t nvram_size;
|
uint16_t nvram_size;
|
||||||
uint16_t nvram_base;
|
uint16_t nvram_base;
|
||||||
|
uint16_t vpd_size;
|
||||||
|
uint16_t vpd_base;
|
||||||
|
|
||||||
uint16_t loop_reset_delay;
|
uint16_t loop_reset_delay;
|
||||||
uint8_t retry_count;
|
uint8_t retry_count;
|
||||||
|
@ -2414,11 +2380,7 @@ typedef struct scsi_qla_host {
|
||||||
struct sns_cmd_pkt *sns_cmd;
|
struct sns_cmd_pkt *sns_cmd;
|
||||||
dma_addr_t sns_cmd_dma;
|
dma_addr_t sns_cmd_dma;
|
||||||
|
|
||||||
pid_t dpc_pid;
|
struct task_struct *dpc_thread;
|
||||||
int dpc_should_die;
|
|
||||||
struct completion dpc_inited;
|
|
||||||
struct completion dpc_exited;
|
|
||||||
struct semaphore *dpc_wait;
|
|
||||||
uint8_t dpc_active; /* DPC routine is active */
|
uint8_t dpc_active; /* DPC routine is active */
|
||||||
|
|
||||||
/* Timeout timers. */
|
/* Timeout timers. */
|
||||||
|
|
|
@ -1,146 +1,81 @@
|
||||||
#define QLA_MODEL_NAMES 0x44
|
#define QLA_MODEL_NAMES 0x4A
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Adapter model names.
|
* Adapter model names and descriptions.
|
||||||
*/
|
*/
|
||||||
static char *qla2x00_model_name[QLA_MODEL_NAMES] = {
|
static char *qla2x00_model_name[QLA_MODEL_NAMES*2] = {
|
||||||
"QLA2340", /* 0x100 */
|
"QLA2340", "133MHz PCI-X to 2Gb FC, Single Channel", /* 0x100 */
|
||||||
"QLA2342", /* 0x101 */
|
"QLA2342", "133MHz PCI-X to 2Gb FC, Dual Channel", /* 0x101 */
|
||||||
"QLA2344", /* 0x102 */
|
"QLA2344", "133MHz PCI-X to 2Gb FC, Quad Channel", /* 0x102 */
|
||||||
"QCP2342", /* 0x103 */
|
"QCP2342", "cPCI to 2Gb FC, Dual Channel", /* 0x103 */
|
||||||
"QSB2340", /* 0x104 */
|
"QSB2340", "SBUS to 2Gb FC, Single Channel", /* 0x104 */
|
||||||
"QSB2342", /* 0x105 */
|
"QSB2342", "SBUS to 2Gb FC, Dual Channel", /* 0x105 */
|
||||||
"QLA2310", /* 0x106 */
|
"QLA2310", "Sun 66MHz PCI-X to 2Gb FC, Single Channel", /* 0x106 */
|
||||||
"QLA2332", /* 0x107 */
|
"QLA2332", "Sun 66MHz PCI-X to 2Gb FC, Single Channel", /* 0x107 */
|
||||||
"QCP2332", /* 0x108 */
|
"QCP2332", "Sun cPCI to 2Gb FC, Dual Channel", /* 0x108 */
|
||||||
"QCP2340", /* 0x109 */
|
"QCP2340", "cPCI to 2Gb FC, Single Channel", /* 0x109 */
|
||||||
"QLA2342", /* 0x10a */
|
"QLA2342", "Sun 133MHz PCI-X to 2Gb FC, Dual Channel", /* 0x10a */
|
||||||
"QCP2342", /* 0x10b */
|
"QCP2342", "Sun - cPCI to 2Gb FC, Dual Channel", /* 0x10b */
|
||||||
"QLA2350", /* 0x10c */
|
"QLA2350", "133MHz PCI-X to 2Gb FC, Single Channel", /* 0x10c */
|
||||||
"QLA2352", /* 0x10d */
|
"QLA2352", "133MHz PCI-X to 2Gb FC, Dual Channel", /* 0x10d */
|
||||||
"QLA2352", /* 0x10e */
|
"QLA2352", "Sun 133MHz PCI-X to 2Gb FC, Dual Channel", /* 0x10e */
|
||||||
"HPQ SVS", /* 0x10f */
|
" ", " ", /* 0x10f */
|
||||||
"HPQ SVS", /* 0x110 */
|
" ", " ", /* 0x110 */
|
||||||
" ", /* 0x111 */
|
" ", " ", /* 0x111 */
|
||||||
" ", /* 0x112 */
|
" ", " ", /* 0x112 */
|
||||||
" ", /* 0x113 */
|
" ", " ", /* 0x113 */
|
||||||
" ", /* 0x114 */
|
" ", " ", /* 0x114 */
|
||||||
"QLA2360", /* 0x115 */
|
"QLA2360", "133MHz PCI-X to 2Gb FC, Single Channel", /* 0x115 */
|
||||||
"QLA2362", /* 0x116 */
|
"QLA2362", "133MHz PCI-X to 2Gb FC, Dual Channel", /* 0x116 */
|
||||||
"QLE2360", /* 0x117 */
|
"QLE2360", "PCI-Express to 2Gb FC, Single Channel", /* 0x117 */
|
||||||
"QLE2362", /* 0x118 */
|
"QLE2362", "PCI-Express to 2Gb FC, Dual Channel", /* 0x118 */
|
||||||
"QLA200", /* 0x119 */
|
"QLA200", "133MHz PCI-X to 2Gb FC Optical", /* 0x119 */
|
||||||
"QLA200C", /* 0x11a */
|
" ", " ", /* 0x11a */
|
||||||
"QLA200P", /* 0x11b */
|
" ", " ", /* 0x11b */
|
||||||
"QLA200P", /* 0x11c */
|
"QLA200P", "133MHz PCI-X to 2Gb FC SFP", /* 0x11c */
|
||||||
" ", /* 0x11d */
|
" ", " ", /* 0x11d */
|
||||||
" ", /* 0x11e */
|
" ", " ", /* 0x11e */
|
||||||
" ", /* 0x11f */
|
" ", " ", /* 0x11f */
|
||||||
" ", /* 0x120 */
|
" ", " ", /* 0x120 */
|
||||||
" ", /* 0x121 */
|
" ", " ", /* 0x121 */
|
||||||
" ", /* 0x122 */
|
" ", " ", /* 0x122 */
|
||||||
" ", /* 0x123 */
|
" ", " ", /* 0x123 */
|
||||||
" ", /* 0x124 */
|
" ", " ", /* 0x124 */
|
||||||
" ", /* 0x125 */
|
" ", " ", /* 0x125 */
|
||||||
" ", /* 0x126 */
|
" ", " ", /* 0x126 */
|
||||||
" ", /* 0x127 */
|
" ", " ", /* 0x127 */
|
||||||
" ", /* 0x128 */
|
" ", " ", /* 0x128 */
|
||||||
" ", /* 0x129 */
|
" ", " ", /* 0x129 */
|
||||||
" ", /* 0x12a */
|
" ", " ", /* 0x12a */
|
||||||
" ", /* 0x12b */
|
" ", " ", /* 0x12b */
|
||||||
" ", /* 0x12c */
|
" ", " ", /* 0x12c */
|
||||||
" ", /* 0x12d */
|
" ", " ", /* 0x12d */
|
||||||
" ", /* 0x12e */
|
" ", " ", /* 0x12e */
|
||||||
"QLA210", /* 0x12f */
|
"QLA210", "133MHz PCI-X to 2Gb FC, Single Channel", /* 0x12f */
|
||||||
"EMC 250", /* 0x130 */
|
"EMC 250", "133MHz PCI-X to 2Gb FC, Single Channel", /* 0x130 */
|
||||||
"HP A7538A", /* 0x131 */
|
"HP A7538A", "HP 1p2g PCI-X to 2Gb FC, Single Channel", /* 0x131 */
|
||||||
"QLA210", /* 0x132 */
|
"QLA210", "Sun 133MHz PCI-X to 2Gb FC, Single Channel", /* 0x132 */
|
||||||
"QLA2460", /* 0x133 */
|
"QLA2460", "PCI-X 2.0 to 4Gb FC, Single Channel", /* 0x133 */
|
||||||
"QLA2462", /* 0x134 */
|
"QLA2462", "PCI-X 2.0 to 4Gb FC, Dual Channel", /* 0x134 */
|
||||||
"QMC2462", /* 0x135 */
|
"QMC2462", "IBM eServer BC 4Gb FC Expansion Card", /* 0x135 */
|
||||||
"QMC2462S", /* 0x136 */
|
"QMC2462S", "IBM eServer BC 4Gb FC Expansion Card SFF", /* 0x136 */
|
||||||
"QLE2460", /* 0x137 */
|
"QLE2460", "PCI-Express to 4Gb FC, Single Channel", /* 0x137 */
|
||||||
"QLE2462", /* 0x138 */
|
"QLE2462", "PCI-Express to 4Gb FC, Dual Channel", /* 0x138 */
|
||||||
"QME2462", /* 0x139 */
|
"QME2462", "Dell BS PCI-Express to 4Gb FC, Dual Channel", /* 0x139 */
|
||||||
"QLA2440", /* 0x13a */
|
" ", " ", /* 0x13a */
|
||||||
"QLA2442", /* 0x13b */
|
" ", " ", /* 0x13b */
|
||||||
"QSM2442", /* 0x13c */
|
" ", " ", /* 0x13c */
|
||||||
"QSM2462", /* 0x13d */
|
"QEM2462", "Sun Server I/O Module 4Gb FC, Dual Channel", /* 0x13d */
|
||||||
"QLE210", /* 0x13e */
|
"QLE210", "PCI-Express to 2Gb FC, Single Channel", /* 0x13e */
|
||||||
"QLE220", /* 0x13f */
|
"QLE220", "PCI-Express to 4Gb FC, Single Channel", /* 0x13f */
|
||||||
"QLA2460", /* 0x140 */
|
"QLA2460", "Sun PCI-X 2.0 to 4Gb FC, Single Channel", /* 0x140 */
|
||||||
"QLA2462", /* 0x141 */
|
"QLA2462", "Sun PCI-X 2.0 to 4Gb FC, Dual Channel", /* 0x141 */
|
||||||
"QLE2460", /* 0x142 */
|
"QLE2460", "Sun PCI-Express to 2Gb FC, Single Channel", /* 0x142 */
|
||||||
"QLE2462" /* 0x143 */
|
"QLE2462", "Sun PCI-Express to 4Gb FC, Single Channel", /* 0x143 */
|
||||||
};
|
"QEM2462" "Server I/O Module 4Gb FC, Dual Channel", /* 0x144 */
|
||||||
|
"QLE2440", "PCI-Express to 4Gb FC, Single Channel", /* 0x145 */
|
||||||
static char *qla2x00_model_desc[QLA_MODEL_NAMES] = {
|
"QLE2464", "PCI-Express to 4Gb FC, Quad Channel", /* 0x146 */
|
||||||
"133MHz PCI-X to 2Gb FC, Single Channel", /* 0x100 */
|
"QLA2440", "PCI-X 2.0 to 4Gb FC, Single Channel", /* 0x147 */
|
||||||
"133MHz PCI-X to 2Gb FC, Dual Channel", /* 0x101 */
|
" ", " ", /* 0x148 */
|
||||||
"133MHz PCI-X to 2Gb FC, Quad Channel", /* 0x102 */
|
"QLA2340", "Sun 133MHz PCI-X to 2Gb FC, Single Channel", /* 0x149 */
|
||||||
" ", /* 0x103 */
|
|
||||||
" ", /* 0x104 */
|
|
||||||
" ", /* 0x105 */
|
|
||||||
" ", /* 0x106 */
|
|
||||||
" ", /* 0x107 */
|
|
||||||
" ", /* 0x108 */
|
|
||||||
" ", /* 0x109 */
|
|
||||||
" ", /* 0x10a */
|
|
||||||
" ", /* 0x10b */
|
|
||||||
"133MHz PCI-X to 2Gb FC, Single Channel", /* 0x10c */
|
|
||||||
"133MHz PCI-X to 2Gb FC, Dual Channel", /* 0x10d */
|
|
||||||
" ", /* 0x10e */
|
|
||||||
"HPQ SVS HBA- Initiator device", /* 0x10f */
|
|
||||||
"HPQ SVS HBA- Target device", /* 0x110 */
|
|
||||||
" ", /* 0x111 */
|
|
||||||
" ", /* 0x112 */
|
|
||||||
" ", /* 0x113 */
|
|
||||||
" ", /* 0x114 */
|
|
||||||
"133MHz PCI-X to 2Gb FC, Single Channel", /* 0x115 */
|
|
||||||
"133MHz PCI-X to 2Gb FC, Dual Channel", /* 0x116 */
|
|
||||||
"PCI-Express to 2Gb FC, Single Channel", /* 0x117 */
|
|
||||||
"PCI-Express to 2Gb FC, Dual Channel", /* 0x118 */
|
|
||||||
"133MHz PCI-X to 2Gb FC Optical", /* 0x119 */
|
|
||||||
"133MHz PCI-X to 2Gb FC Copper", /* 0x11a */
|
|
||||||
"133MHz PCI-X to 2Gb FC SFP", /* 0x11b */
|
|
||||||
"133MHz PCI-X to 2Gb FC SFP", /* 0x11c */
|
|
||||||
" ", /* 0x11d */
|
|
||||||
" ", /* 0x11e */
|
|
||||||
" ", /* 0x11f */
|
|
||||||
" ", /* 0x120 */
|
|
||||||
" ", /* 0x121 */
|
|
||||||
" ", /* 0x122 */
|
|
||||||
" ", /* 0x123 */
|
|
||||||
" ", /* 0x124 */
|
|
||||||
" ", /* 0x125 */
|
|
||||||
" ", /* 0x126 */
|
|
||||||
" ", /* 0x127 */
|
|
||||||
" ", /* 0x128 */
|
|
||||||
" ", /* 0x129 */
|
|
||||||
" ", /* 0x12a */
|
|
||||||
" ", /* 0x12b */
|
|
||||||
" ", /* 0x12c */
|
|
||||||
" ", /* 0x12d */
|
|
||||||
" ", /* 0x12e */
|
|
||||||
"133MHz PCI-X to 2Gb FC SFF", /* 0x12f */
|
|
||||||
"133MHz PCI-X to 2Gb FC SFF", /* 0x130 */
|
|
||||||
"HP 1p2g QLA2340", /* 0x131 */
|
|
||||||
"133MHz PCI-X to 2Gb FC, Single Channel", /* 0x132 */
|
|
||||||
"PCI-X 2.0 to 4Gb FC, Single Channel", /* 0x133 */
|
|
||||||
"PCI-X 2.0 to 4Gb FC, Dual Channel", /* 0x134 */
|
|
||||||
"IBM eServer BC 4Gb FC Expansion Card", /* 0x135 */
|
|
||||||
"IBM eServer BC 4Gb FC Expansion Card SFF", /* 0x136 */
|
|
||||||
"PCI-Express to 4Gb FC, Single Channel", /* 0x137 */
|
|
||||||
"PCI-Express to 4Gb FC, Dual Channel", /* 0x138 */
|
|
||||||
"Dell PCI-Express to 4Gb FC, Dual Channel", /* 0x139 */
|
|
||||||
"PCI-X 1.0 to 4Gb FC, Single Channel", /* 0x13a */
|
|
||||||
"PCI-X 1.0 to 4Gb FC, Dual Channel", /* 0x13b */
|
|
||||||
"Server I/O Module 4Gb FC, Single Channel", /* 0x13c */
|
|
||||||
"Server I/O Module 4Gb FC, Single Channel", /* 0x13d */
|
|
||||||
"PCI-Express to 2Gb FC, Single Channel", /* 0x13e */
|
|
||||||
"PCI-Express to 4Gb FC, Single Channel", /* 0x13f */
|
|
||||||
"Sun PCI-X 2.0 to 4Gb FC, Single Channel", /* 0x140 */
|
|
||||||
"Sun PCI-X 2.0 to 4Gb FC, Dual Channel", /* 0x141 */
|
|
||||||
"Sun PCI-Express to 2Gb FC, Single Channel", /* 0x142 */
|
|
||||||
"Sun PCI-Express to 4Gb FC, Single Channel" /* 0x143 */
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -759,7 +759,7 @@ struct device_reg_24xx {
|
||||||
#define FA_NVRAM_FUNC0_ADDR 0x80
|
#define FA_NVRAM_FUNC0_ADDR 0x80
|
||||||
#define FA_NVRAM_FUNC1_ADDR 0x180
|
#define FA_NVRAM_FUNC1_ADDR 0x180
|
||||||
|
|
||||||
#define FA_NVRAM_VPD_SIZE 0x80
|
#define FA_NVRAM_VPD_SIZE 0x200
|
||||||
#define FA_NVRAM_VPD0_ADDR 0x00
|
#define FA_NVRAM_VPD0_ADDR 0x00
|
||||||
#define FA_NVRAM_VPD1_ADDR 0x100
|
#define FA_NVRAM_VPD1_ADDR 0x100
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -42,7 +42,7 @@ extern int qla2x00_loop_resync(scsi_qla_host_t *);
|
||||||
|
|
||||||
extern int qla2x00_find_new_loop_id(scsi_qla_host_t *, fc_port_t *);
|
extern int qla2x00_find_new_loop_id(scsi_qla_host_t *, fc_port_t *);
|
||||||
extern int qla2x00_fabric_login(scsi_qla_host_t *, fc_port_t *, uint16_t *);
|
extern int qla2x00_fabric_login(scsi_qla_host_t *, fc_port_t *, uint16_t *);
|
||||||
extern int qla2x00_local_device_login(scsi_qla_host_t *, uint16_t);
|
extern int qla2x00_local_device_login(scsi_qla_host_t *, fc_port_t *);
|
||||||
|
|
||||||
extern void qla2x00_restart_queues(scsi_qla_host_t *, uint8_t);
|
extern void qla2x00_restart_queues(scsi_qla_host_t *, uint8_t);
|
||||||
|
|
||||||
|
@ -81,6 +81,8 @@ extern struct fw_blob *qla2x00_request_firmware(scsi_qla_host_t *);
|
||||||
|
|
||||||
extern int qla2x00_wait_for_hba_online(scsi_qla_host_t *);
|
extern int qla2x00_wait_for_hba_online(scsi_qla_host_t *);
|
||||||
|
|
||||||
|
extern void qla2xxx_wake_dpc(scsi_qla_host_t *);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Global Function Prototypes in qla_iocb.c source file.
|
* Global Function Prototypes in qla_iocb.c source file.
|
||||||
*/
|
*/
|
||||||
|
@ -164,7 +166,8 @@ qla24xx_login_fabric(scsi_qla_host_t *, uint16_t, uint8_t, uint8_t, uint8_t,
|
||||||
uint16_t *, uint8_t);
|
uint16_t *, uint8_t);
|
||||||
|
|
||||||
extern int
|
extern int
|
||||||
qla2x00_login_local_device(scsi_qla_host_t *, uint16_t, uint16_t *, uint8_t);
|
qla2x00_login_local_device(scsi_qla_host_t *, fc_port_t *, uint16_t *,
|
||||||
|
uint8_t);
|
||||||
|
|
||||||
extern int
|
extern int
|
||||||
qla2x00_fabric_logout(scsi_qla_host_t *, uint16_t, uint8_t, uint8_t, uint8_t);
|
qla2x00_fabric_logout(scsi_qla_host_t *, uint16_t, uint8_t, uint8_t, uint8_t);
|
||||||
|
|
|
@ -126,7 +126,7 @@ qla2x00_chk_ms_status(scsi_qla_host_t *ha, ms_iocb_entry_t *ms_pkt,
|
||||||
DEBUG2_3(printk("scsi(%ld): %s failed, error status (%x).\n",
|
DEBUG2_3(printk("scsi(%ld): %s failed, error status (%x).\n",
|
||||||
ha->host_no, routine, ms_pkt->entry_status));
|
ha->host_no, routine, ms_pkt->entry_status));
|
||||||
} else {
|
} else {
|
||||||
if (IS_QLA24XX(ha) || IS_QLA25XX(ha))
|
if (IS_QLA24XX(ha) || IS_QLA54XX(ha))
|
||||||
comp_status =
|
comp_status =
|
||||||
((struct ct_entry_24xx *)ms_pkt)->comp_status;
|
((struct ct_entry_24xx *)ms_pkt)->comp_status;
|
||||||
else
|
else
|
||||||
|
@ -1200,7 +1200,7 @@ qla2x00_update_ms_fdmi_iocb(scsi_qla_host_t *ha, uint32_t req_size)
|
||||||
ms_iocb_entry_t *ms_pkt = ha->ms_iocb;
|
ms_iocb_entry_t *ms_pkt = ha->ms_iocb;
|
||||||
struct ct_entry_24xx *ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb;
|
struct ct_entry_24xx *ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb;
|
||||||
|
|
||||||
if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) {
|
if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
|
||||||
ct_pkt->cmd_byte_count = cpu_to_le32(req_size);
|
ct_pkt->cmd_byte_count = cpu_to_le32(req_size);
|
||||||
ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count;
|
ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1529,9 +1529,7 @@ qla2x00_fdmi_rpa(scsi_qla_host_t *ha)
|
||||||
eiter = (struct ct_fdmi_port_attr *) (entries + size);
|
eiter = (struct ct_fdmi_port_attr *) (entries + size);
|
||||||
eiter->type = __constant_cpu_to_be16(FDMI_PORT_SUPPORT_SPEED);
|
eiter->type = __constant_cpu_to_be16(FDMI_PORT_SUPPORT_SPEED);
|
||||||
eiter->len = __constant_cpu_to_be16(4 + 4);
|
eiter->len = __constant_cpu_to_be16(4 + 4);
|
||||||
if (IS_QLA25XX(ha))
|
if (IS_QLA24XX(ha) || IS_QLA54XX(ha))
|
||||||
eiter->a.sup_speed = __constant_cpu_to_be32(8);
|
|
||||||
else if (IS_QLA24XX(ha))
|
|
||||||
eiter->a.sup_speed = __constant_cpu_to_be32(4);
|
eiter->a.sup_speed = __constant_cpu_to_be32(4);
|
||||||
else if (IS_QLA23XX(ha))
|
else if (IS_QLA23XX(ha))
|
||||||
eiter->a.sup_speed = __constant_cpu_to_be32(2);
|
eiter->a.sup_speed = __constant_cpu_to_be32(2);
|
||||||
|
@ -1566,7 +1564,7 @@ qla2x00_fdmi_rpa(scsi_qla_host_t *ha)
|
||||||
eiter = (struct ct_fdmi_port_attr *) (entries + size);
|
eiter = (struct ct_fdmi_port_attr *) (entries + size);
|
||||||
eiter->type = __constant_cpu_to_be16(FDMI_PORT_MAX_FRAME_SIZE);
|
eiter->type = __constant_cpu_to_be16(FDMI_PORT_MAX_FRAME_SIZE);
|
||||||
eiter->len = __constant_cpu_to_be16(4 + 4);
|
eiter->len = __constant_cpu_to_be16(4 + 4);
|
||||||
max_frame_size = IS_QLA24XX(ha) || IS_QLA25XX(ha) ?
|
max_frame_size = IS_QLA24XX(ha) || IS_QLA54XX(ha) ?
|
||||||
(uint32_t) icb24->frame_payload_size:
|
(uint32_t) icb24->frame_payload_size:
|
||||||
(uint32_t) ha->init_cb->frame_payload_size;
|
(uint32_t) ha->init_cb->frame_payload_size;
|
||||||
eiter->a.max_frame_size = cpu_to_be32(max_frame_size);
|
eiter->a.max_frame_size = cpu_to_be32(max_frame_size);
|
||||||
|
|
|
@ -387,7 +387,7 @@ qla2x00_isp_firmware(scsi_qla_host_t *ha)
|
||||||
|
|
||||||
/* Verify checksum of loaded RISC code. */
|
/* Verify checksum of loaded RISC code. */
|
||||||
rval = qla2x00_verify_checksum(ha,
|
rval = qla2x00_verify_checksum(ha,
|
||||||
IS_QLA24XX(ha) || IS_QLA25XX(ha) ? RISC_SADDRESS :
|
IS_QLA24XX(ha) || IS_QLA54XX(ha) ? RISC_SADDRESS :
|
||||||
*ha->brd_info->fw_info[0].fwstart);
|
*ha->brd_info->fw_info[0].fwstart);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -727,6 +727,7 @@ qla2x00_chip_diag(scsi_qla_host_t *ha)
|
||||||
DEBUG3(printk("scsi(%ld): Found QLA2200A chip.\n",
|
DEBUG3(printk("scsi(%ld): Found QLA2200A chip.\n",
|
||||||
ha->host_no));
|
ha->host_no));
|
||||||
|
|
||||||
|
ha->device_type |= DT_ISP2200A;
|
||||||
ha->fw_transfer_size = 128;
|
ha->fw_transfer_size = 128;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -821,7 +822,7 @@ qla2x00_resize_request_q(scsi_qla_host_t *ha)
|
||||||
if (IS_QLA2100(ha) || IS_QLA2200(ha))
|
if (IS_QLA2100(ha) || IS_QLA2200(ha))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (IS_QLA24XX(ha) || IS_QLA25XX(ha))
|
if (IS_QLA24XX(ha) || IS_QLA54XX(ha))
|
||||||
qla2x00_alloc_fw_dump(ha);
|
qla2x00_alloc_fw_dump(ha);
|
||||||
|
|
||||||
/* Retrieve IOCB counts available to the firmware. */
|
/* Retrieve IOCB counts available to the firmware. */
|
||||||
|
@ -1002,6 +1003,10 @@ qla2x00_update_fw_options(scsi_qla_host_t *ha)
|
||||||
if (ha->flags.enable_led_scheme)
|
if (ha->flags.enable_led_scheme)
|
||||||
ha->fw_options[2] |= BIT_12;
|
ha->fw_options[2] |= BIT_12;
|
||||||
|
|
||||||
|
/* Detect ISP6312. */
|
||||||
|
if (IS_QLA6312(ha))
|
||||||
|
ha->fw_options[2] |= BIT_13;
|
||||||
|
|
||||||
/* Update firmware options. */
|
/* Update firmware options. */
|
||||||
qla2x00_set_fw_options(ha, ha->fw_options);
|
qla2x00_set_fw_options(ha, ha->fw_options);
|
||||||
}
|
}
|
||||||
|
@ -1500,9 +1505,9 @@ qla2x00_nvram_config(scsi_qla_host_t *ha)
|
||||||
index = (ha->pdev->subsystem_device & 0xff);
|
index = (ha->pdev->subsystem_device & 0xff);
|
||||||
if (index < QLA_MODEL_NAMES) {
|
if (index < QLA_MODEL_NAMES) {
|
||||||
strcpy(ha->model_number,
|
strcpy(ha->model_number,
|
||||||
qla2x00_model_name[index]);
|
qla2x00_model_name[index * 2]);
|
||||||
ha->model_desc =
|
ha->model_desc =
|
||||||
qla2x00_model_desc[index];
|
qla2x00_model_name[index * 2 + 1];
|
||||||
} else {
|
} else {
|
||||||
strcpy(ha->model_number, "QLA23xx");
|
strcpy(ha->model_number, "QLA23xx");
|
||||||
}
|
}
|
||||||
|
@ -1654,6 +1659,8 @@ qla2x00_nvram_config(scsi_qla_host_t *ha)
|
||||||
~(BIT_3 | BIT_2 | BIT_1 | BIT_0);
|
~(BIT_3 | BIT_2 | BIT_1 | BIT_0);
|
||||||
ha->flags.process_response_queue = 0;
|
ha->flags.process_response_queue = 0;
|
||||||
if (ha->zio_mode != QLA_ZIO_DISABLED) {
|
if (ha->zio_mode != QLA_ZIO_DISABLED) {
|
||||||
|
ha->zio_mode = QLA_ZIO_MODE_6;
|
||||||
|
|
||||||
DEBUG2(printk("scsi(%ld): ZIO mode %d enabled; timer "
|
DEBUG2(printk("scsi(%ld): ZIO mode %d enabled; timer "
|
||||||
"delay (%d us).\n", ha->host_no, ha->zio_mode,
|
"delay (%d us).\n", ha->host_no, ha->zio_mode,
|
||||||
ha->zio_timer * 100));
|
ha->zio_timer * 100));
|
||||||
|
@ -2122,7 +2129,7 @@ qla2x00_configure_fabric(scsi_qla_host_t *ha)
|
||||||
LIST_HEAD(new_fcports);
|
LIST_HEAD(new_fcports);
|
||||||
|
|
||||||
/* If FL port exists, then SNS is present */
|
/* If FL port exists, then SNS is present */
|
||||||
if (IS_QLA24XX(ha) || IS_QLA25XX(ha))
|
if (IS_QLA24XX(ha) || IS_QLA54XX(ha))
|
||||||
loop_id = NPH_F_PORT;
|
loop_id = NPH_F_PORT;
|
||||||
else
|
else
|
||||||
loop_id = SNS_FL_PORT;
|
loop_id = SNS_FL_PORT;
|
||||||
|
@ -2148,7 +2155,7 @@ qla2x00_configure_fabric(scsi_qla_host_t *ha)
|
||||||
qla2x00_fdmi_register(ha);
|
qla2x00_fdmi_register(ha);
|
||||||
|
|
||||||
/* Ensure we are logged into the SNS. */
|
/* Ensure we are logged into the SNS. */
|
||||||
if (IS_QLA24XX(ha) || IS_QLA25XX(ha))
|
if (IS_QLA24XX(ha) || IS_QLA54XX(ha))
|
||||||
loop_id = NPH_SNS;
|
loop_id = NPH_SNS;
|
||||||
else
|
else
|
||||||
loop_id = SIMPLE_NAME_SERVER;
|
loop_id = SIMPLE_NAME_SERVER;
|
||||||
|
@ -2639,7 +2646,7 @@ qla2x00_device_resync(scsi_qla_host_t *ha)
|
||||||
if (ql2xprocessrscn &&
|
if (ql2xprocessrscn &&
|
||||||
!IS_QLA2100(ha) && !IS_QLA2200(ha) &&
|
!IS_QLA2100(ha) && !IS_QLA2200(ha) &&
|
||||||
!IS_QLA6312(ha) && !IS_QLA6322(ha) &&
|
!IS_QLA6312(ha) && !IS_QLA6322(ha) &&
|
||||||
!IS_QLA24XX(ha) && !IS_QLA25XX(ha) &&
|
!IS_QLA24XX(ha) && !IS_QLA54XX(ha) &&
|
||||||
ha->flags.init_done) {
|
ha->flags.init_done) {
|
||||||
/* Handle port RSCN via asyncronous IOCBs */
|
/* Handle port RSCN via asyncronous IOCBs */
|
||||||
rval2 = qla2x00_handle_port_rscn(ha, rscn_entry,
|
rval2 = qla2x00_handle_port_rscn(ha, rscn_entry,
|
||||||
|
@ -2881,13 +2888,13 @@ qla2x00_fabric_login(scsi_qla_host_t *ha, fc_port_t *fcport,
|
||||||
* 3 - Fatal error
|
* 3 - Fatal error
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
qla2x00_local_device_login(scsi_qla_host_t *ha, uint16_t loop_id)
|
qla2x00_local_device_login(scsi_qla_host_t *ha, fc_port_t *fcport)
|
||||||
{
|
{
|
||||||
int rval;
|
int rval;
|
||||||
uint16_t mb[MAILBOX_REGISTER_COUNT];
|
uint16_t mb[MAILBOX_REGISTER_COUNT];
|
||||||
|
|
||||||
memset(mb, 0, sizeof(mb));
|
memset(mb, 0, sizeof(mb));
|
||||||
rval = qla2x00_login_local_device(ha, loop_id, mb, BIT_0);
|
rval = qla2x00_login_local_device(ha, fcport, mb, BIT_0);
|
||||||
if (rval == QLA_SUCCESS) {
|
if (rval == QLA_SUCCESS) {
|
||||||
/* Interrogate mailbox registers for any errors */
|
/* Interrogate mailbox registers for any errors */
|
||||||
if (mb[0] == MBS_COMMAND_ERROR)
|
if (mb[0] == MBS_COMMAND_ERROR)
|
||||||
|
@ -3129,7 +3136,7 @@ qla2x00_restart_isp(scsi_qla_host_t *ha)
|
||||||
|
|
||||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||||
|
|
||||||
if (!IS_QLA24XX(ha) && !IS_QLA25XX(ha)) {
|
if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha)) {
|
||||||
/*
|
/*
|
||||||
* Disable SRAM, Instruction RAM and GP RAM
|
* Disable SRAM, Instruction RAM and GP RAM
|
||||||
* parity.
|
* parity.
|
||||||
|
@ -3145,7 +3152,7 @@ qla2x00_restart_isp(scsi_qla_host_t *ha)
|
||||||
|
|
||||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||||
|
|
||||||
if (!IS_QLA24XX(ha) && !IS_QLA25XX(ha)) {
|
if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha)) {
|
||||||
/* Enable proper parity */
|
/* Enable proper parity */
|
||||||
if (IS_QLA2300(ha))
|
if (IS_QLA2300(ha))
|
||||||
/* SRAM parity */
|
/* SRAM parity */
|
||||||
|
@ -3258,8 +3265,12 @@ qla24xx_nvram_config(scsi_qla_host_t *ha)
|
||||||
/* Determine NVRAM starting address. */
|
/* Determine NVRAM starting address. */
|
||||||
ha->nvram_size = sizeof(struct nvram_24xx);
|
ha->nvram_size = sizeof(struct nvram_24xx);
|
||||||
ha->nvram_base = FA_NVRAM_FUNC0_ADDR;
|
ha->nvram_base = FA_NVRAM_FUNC0_ADDR;
|
||||||
if (PCI_FUNC(ha->pdev->devfn))
|
ha->vpd_size = FA_NVRAM_VPD_SIZE;
|
||||||
|
ha->vpd_base = FA_NVRAM_VPD0_ADDR;
|
||||||
|
if (PCI_FUNC(ha->pdev->devfn)) {
|
||||||
ha->nvram_base = FA_NVRAM_FUNC1_ADDR;
|
ha->nvram_base = FA_NVRAM_FUNC1_ADDR;
|
||||||
|
ha->vpd_base = FA_NVRAM_VPD1_ADDR;
|
||||||
|
}
|
||||||
|
|
||||||
/* Get NVRAM data and calculate checksum. */
|
/* Get NVRAM data and calculate checksum. */
|
||||||
dptr = (uint32_t *)nv;
|
dptr = (uint32_t *)nv;
|
||||||
|
@ -3368,7 +3379,7 @@ qla24xx_nvram_config(scsi_qla_host_t *ha)
|
||||||
|
|
||||||
index = (ha->pdev->subsystem_device & 0xff);
|
index = (ha->pdev->subsystem_device & 0xff);
|
||||||
if (index < QLA_MODEL_NAMES)
|
if (index < QLA_MODEL_NAMES)
|
||||||
ha->model_desc = qla2x00_model_desc[index];
|
ha->model_desc = qla2x00_model_name[index * 2 + 1];
|
||||||
} else
|
} else
|
||||||
strcpy(ha->model_number, "QLA2462");
|
strcpy(ha->model_number, "QLA2462");
|
||||||
|
|
||||||
|
@ -3465,6 +3476,8 @@ qla24xx_nvram_config(scsi_qla_host_t *ha)
|
||||||
~(BIT_3 | BIT_2 | BIT_1 | BIT_0));
|
~(BIT_3 | BIT_2 | BIT_1 | BIT_0));
|
||||||
ha->flags.process_response_queue = 0;
|
ha->flags.process_response_queue = 0;
|
||||||
if (ha->zio_mode != QLA_ZIO_DISABLED) {
|
if (ha->zio_mode != QLA_ZIO_DISABLED) {
|
||||||
|
ha->zio_mode = QLA_ZIO_MODE_6;
|
||||||
|
|
||||||
DEBUG2(printk("scsi(%ld): ZIO mode %d enabled; timer delay "
|
DEBUG2(printk("scsi(%ld): ZIO mode %d enabled; timer delay "
|
||||||
"(%d us).\n", ha->host_no, ha->zio_mode,
|
"(%d us).\n", ha->host_no, ha->zio_mode,
|
||||||
ha->zio_timer * 100));
|
ha->zio_timer * 100));
|
||||||
|
|
|
@ -163,7 +163,7 @@ static inline int qla2x00_is_reserved_id(scsi_qla_host_t *, uint16_t);
|
||||||
static inline int
|
static inline int
|
||||||
qla2x00_is_reserved_id(scsi_qla_host_t *ha, uint16_t loop_id)
|
qla2x00_is_reserved_id(scsi_qla_host_t *ha, uint16_t loop_id)
|
||||||
{
|
{
|
||||||
if (IS_QLA24XX(ha) || IS_QLA25XX(ha))
|
if (IS_QLA24XX(ha) || IS_QLA54XX(ha))
|
||||||
return (loop_id > NPH_LAST_HANDLE);
|
return (loop_id > NPH_LAST_HANDLE);
|
||||||
|
|
||||||
return ((loop_id > ha->last_loop_id && loop_id < SNS_FIRST_LOOP_ID) ||
|
return ((loop_id > ha->last_loop_id && loop_id < SNS_FIRST_LOOP_ID) ||
|
||||||
|
|
|
@ -466,7 +466,7 @@ __qla2x00_marker(scsi_qla_host_t *ha, uint16_t loop_id, uint16_t lun,
|
||||||
mrk->entry_type = MARKER_TYPE;
|
mrk->entry_type = MARKER_TYPE;
|
||||||
mrk->modifier = type;
|
mrk->modifier = type;
|
||||||
if (type != MK_SYNC_ALL) {
|
if (type != MK_SYNC_ALL) {
|
||||||
if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) {
|
if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
|
||||||
mrk24 = (struct mrk_entry_24xx *) mrk;
|
mrk24 = (struct mrk_entry_24xx *) mrk;
|
||||||
mrk24->nport_handle = cpu_to_le16(loop_id);
|
mrk24->nport_handle = cpu_to_le16(loop_id);
|
||||||
mrk24->lun[1] = LSB(lun);
|
mrk24->lun[1] = LSB(lun);
|
||||||
|
@ -519,7 +519,7 @@ qla2x00_req_pkt(scsi_qla_host_t *ha)
|
||||||
for (timer = HZ; timer; timer--) {
|
for (timer = HZ; timer; timer--) {
|
||||||
if ((req_cnt + 2) >= ha->req_q_cnt) {
|
if ((req_cnt + 2) >= ha->req_q_cnt) {
|
||||||
/* Calculate number of free request entries. */
|
/* Calculate number of free request entries. */
|
||||||
if (IS_QLA24XX(ha) || IS_QLA25XX(ha))
|
if (IS_QLA24XX(ha) || IS_QLA54XX(ha))
|
||||||
cnt = (uint16_t)RD_REG_DWORD(
|
cnt = (uint16_t)RD_REG_DWORD(
|
||||||
®->isp24.req_q_out);
|
®->isp24.req_q_out);
|
||||||
else
|
else
|
||||||
|
@ -593,7 +593,7 @@ qla2x00_isp_cmd(scsi_qla_host_t *ha)
|
||||||
ha->request_ring_ptr++;
|
ha->request_ring_ptr++;
|
||||||
|
|
||||||
/* Set chip new ring index. */
|
/* Set chip new ring index. */
|
||||||
if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) {
|
if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
|
||||||
WRT_REG_DWORD(®->isp24.req_q_in, ha->req_ring_index);
|
WRT_REG_DWORD(®->isp24.req_q_in, ha->req_ring_index);
|
||||||
RD_REG_DWORD_RELAXED(®->isp24.req_q_in);
|
RD_REG_DWORD_RELAXED(®->isp24.req_q_in);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -343,7 +343,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
|
||||||
|
|
||||||
ha->isp_ops.fw_dump(ha, 1);
|
ha->isp_ops.fw_dump(ha, 1);
|
||||||
|
|
||||||
if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) {
|
if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
|
||||||
if (mb[1] == 0 && mb[2] == 0) {
|
if (mb[1] == 0 && mb[2] == 0) {
|
||||||
qla_printk(KERN_ERR, ha,
|
qla_printk(KERN_ERR, ha,
|
||||||
"Unrecoverable Hardware Error: adapter "
|
"Unrecoverable Hardware Error: adapter "
|
||||||
|
@ -521,7 +521,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
|
||||||
*/
|
*/
|
||||||
if (ql2xprocessrscn &&
|
if (ql2xprocessrscn &&
|
||||||
!IS_QLA2100(ha) && !IS_QLA2200(ha) && !IS_QLA6312(ha) &&
|
!IS_QLA2100(ha) && !IS_QLA2200(ha) && !IS_QLA6312(ha) &&
|
||||||
!IS_QLA6322(ha) && !IS_QLA24XX(ha) && !IS_QLA25XX(ha) &&
|
!IS_QLA6322(ha) && !IS_QLA24XX(ha) && !IS_QLA54XX(ha) &&
|
||||||
ha->flags.init_done && mb[1] != 0xffff &&
|
ha->flags.init_done && mb[1] != 0xffff &&
|
||||||
((ha->operating_mode == P2P && mb[1] != 0) ||
|
((ha->operating_mode == P2P && mb[1] != 0) ||
|
||||||
(ha->operating_mode != P2P && mb[1] !=
|
(ha->operating_mode != P2P && mb[1] !=
|
||||||
|
@ -638,7 +638,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
|
||||||
"scsi(%ld): [R|Z]IO update completion.\n",
|
"scsi(%ld): [R|Z]IO update completion.\n",
|
||||||
ha->host_no));
|
ha->host_no));
|
||||||
|
|
||||||
if (IS_QLA24XX(ha) || IS_QLA25XX(ha))
|
if (IS_QLA24XX(ha) || IS_QLA54XX(ha))
|
||||||
qla24xx_process_response_queue(ha);
|
qla24xx_process_response_queue(ha);
|
||||||
else
|
else
|
||||||
qla2x00_process_response_queue(ha);
|
qla2x00_process_response_queue(ha);
|
||||||
|
@ -810,7 +810,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt)
|
||||||
|
|
||||||
sts = (sts_entry_t *) pkt;
|
sts = (sts_entry_t *) pkt;
|
||||||
sts24 = (struct sts_entry_24xx *) pkt;
|
sts24 = (struct sts_entry_24xx *) pkt;
|
||||||
if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) {
|
if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
|
||||||
comp_status = le16_to_cpu(sts24->comp_status);
|
comp_status = le16_to_cpu(sts24->comp_status);
|
||||||
scsi_status = le16_to_cpu(sts24->scsi_status) & SS_MASK;
|
scsi_status = le16_to_cpu(sts24->scsi_status) & SS_MASK;
|
||||||
} else {
|
} else {
|
||||||
|
@ -838,9 +838,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt)
|
||||||
qla_printk(KERN_WARNING, ha, "Status Entry invalid handle.\n");
|
qla_printk(KERN_WARNING, ha, "Status Entry invalid handle.\n");
|
||||||
|
|
||||||
set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
|
set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
|
||||||
if (ha->dpc_wait && !ha->dpc_active)
|
qla2xxx_wake_dpc(ha);
|
||||||
up(ha->dpc_wait);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
cp = sp->cmd;
|
cp = sp->cmd;
|
||||||
|
@ -862,7 +860,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt)
|
||||||
fcport = sp->fcport;
|
fcport = sp->fcport;
|
||||||
|
|
||||||
sense_len = rsp_info_len = resid_len = 0;
|
sense_len = rsp_info_len = resid_len = 0;
|
||||||
if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) {
|
if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
|
||||||
sense_len = le32_to_cpu(sts24->sense_len);
|
sense_len = le32_to_cpu(sts24->sense_len);
|
||||||
rsp_info_len = le32_to_cpu(sts24->rsp_data_len);
|
rsp_info_len = le32_to_cpu(sts24->rsp_data_len);
|
||||||
resid_len = le32_to_cpu(sts24->rsp_residual_count);
|
resid_len = le32_to_cpu(sts24->rsp_residual_count);
|
||||||
|
@ -880,7 +878,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt)
|
||||||
/* Check for any FCP transport errors. */
|
/* Check for any FCP transport errors. */
|
||||||
if (scsi_status & SS_RESPONSE_INFO_LEN_VALID) {
|
if (scsi_status & SS_RESPONSE_INFO_LEN_VALID) {
|
||||||
/* Sense data lies beyond any FCP RESPONSE data. */
|
/* Sense data lies beyond any FCP RESPONSE data. */
|
||||||
if (IS_QLA24XX(ha) || IS_QLA25XX(ha))
|
if (IS_QLA24XX(ha) || IS_QLA54XX(ha))
|
||||||
sense_data += rsp_info_len;
|
sense_data += rsp_info_len;
|
||||||
if (rsp_info_len > 3 && rsp_info[3]) {
|
if (rsp_info_len > 3 && rsp_info[3]) {
|
||||||
DEBUG2(printk("scsi(%ld:%d:%d:%d) FCP I/O protocol "
|
DEBUG2(printk("scsi(%ld:%d:%d:%d) FCP I/O protocol "
|
||||||
|
@ -1119,7 +1117,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt)
|
||||||
case CS_TIMEOUT:
|
case CS_TIMEOUT:
|
||||||
cp->result = DID_BUS_BUSY << 16;
|
cp->result = DID_BUS_BUSY << 16;
|
||||||
|
|
||||||
if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) {
|
if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
|
||||||
DEBUG2(printk(KERN_INFO
|
DEBUG2(printk(KERN_INFO
|
||||||
"scsi(%ld:%d:%d:%d): TIMEOUT status detected "
|
"scsi(%ld:%d:%d:%d): TIMEOUT status detected "
|
||||||
"0x%x-0x%x\n", ha->host_no, cp->device->channel,
|
"0x%x-0x%x\n", ha->host_no, cp->device->channel,
|
||||||
|
@ -1199,7 +1197,7 @@ qla2x00_status_cont_entry(scsi_qla_host_t *ha, sts_cont_entry_t *pkt)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Move sense data. */
|
/* Move sense data. */
|
||||||
if (IS_QLA24XX(ha) || IS_QLA25XX(ha))
|
if (IS_QLA24XX(ha) || IS_QLA54XX(ha))
|
||||||
host_to_fcp_swap(pkt->data, sizeof(pkt->data));
|
host_to_fcp_swap(pkt->data, sizeof(pkt->data));
|
||||||
memcpy(sp->request_sense_ptr, pkt->data, sense_sz);
|
memcpy(sp->request_sense_ptr, pkt->data, sense_sz);
|
||||||
DEBUG5(qla2x00_dump_buffer(sp->request_sense_ptr, sense_sz));
|
DEBUG5(qla2x00_dump_buffer(sp->request_sense_ptr, sense_sz));
|
||||||
|
@ -1271,8 +1269,7 @@ qla2x00_error_entry(scsi_qla_host_t *ha, sts_entry_t *pkt)
|
||||||
"Error entry - invalid handle\n");
|
"Error entry - invalid handle\n");
|
||||||
|
|
||||||
set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
|
set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
|
||||||
if (ha->dpc_wait && !ha->dpc_active)
|
qla2xxx_wake_dpc(ha);
|
||||||
up(ha->dpc_wait);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -91,7 +91,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp)
|
||||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||||
|
|
||||||
/* Load mailbox registers. */
|
/* Load mailbox registers. */
|
||||||
if (IS_QLA24XX(ha) || IS_QLA25XX(ha))
|
if (IS_QLA24XX(ha) || IS_QLA54XX(ha))
|
||||||
optr = (uint16_t __iomem *)®->isp24.mailbox0;
|
optr = (uint16_t __iomem *)®->isp24.mailbox0;
|
||||||
else
|
else
|
||||||
optr = (uint16_t __iomem *)MAILBOX_REG(ha, ®->isp, 0);
|
optr = (uint16_t __iomem *)MAILBOX_REG(ha, ®->isp, 0);
|
||||||
|
@ -155,7 +155,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp)
|
||||||
|
|
||||||
set_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
|
set_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
|
||||||
|
|
||||||
if (IS_QLA24XX(ha) || IS_QLA25XX(ha))
|
if (IS_QLA24XX(ha) || IS_QLA54XX(ha))
|
||||||
WRT_REG_DWORD(®->isp24.hccr, HCCRX_SET_HOST_INT);
|
WRT_REG_DWORD(®->isp24.hccr, HCCRX_SET_HOST_INT);
|
||||||
else
|
else
|
||||||
WRT_REG_WORD(®->isp.hccr, HCCR_SET_HOST_INT);
|
WRT_REG_WORD(®->isp.hccr, HCCR_SET_HOST_INT);
|
||||||
|
@ -179,7 +179,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp)
|
||||||
DEBUG3_11(printk("%s(%ld): cmd=%x POLLING MODE.\n", __func__,
|
DEBUG3_11(printk("%s(%ld): cmd=%x POLLING MODE.\n", __func__,
|
||||||
ha->host_no, command);)
|
ha->host_no, command);)
|
||||||
|
|
||||||
if (IS_QLA24XX(ha) || IS_QLA25XX(ha))
|
if (IS_QLA24XX(ha) || IS_QLA54XX(ha))
|
||||||
WRT_REG_DWORD(®->isp24.hccr, HCCRX_SET_HOST_INT);
|
WRT_REG_DWORD(®->isp24.hccr, HCCRX_SET_HOST_INT);
|
||||||
else
|
else
|
||||||
WRT_REG_WORD(®->isp.hccr, HCCR_SET_HOST_INT);
|
WRT_REG_WORD(®->isp.hccr, HCCR_SET_HOST_INT);
|
||||||
|
@ -237,7 +237,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp)
|
||||||
uint16_t mb0;
|
uint16_t mb0;
|
||||||
uint32_t ictrl;
|
uint32_t ictrl;
|
||||||
|
|
||||||
if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) {
|
if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
|
||||||
mb0 = RD_REG_WORD(®->isp24.mailbox0);
|
mb0 = RD_REG_WORD(®->isp24.mailbox0);
|
||||||
ictrl = RD_REG_DWORD(®->isp24.ictrl);
|
ictrl = RD_REG_DWORD(®->isp24.ictrl);
|
||||||
} else {
|
} else {
|
||||||
|
@ -284,9 +284,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp)
|
||||||
"Mailbox command timeout occured. Scheduling ISP "
|
"Mailbox command timeout occured. Scheduling ISP "
|
||||||
"abort.\n");
|
"abort.\n");
|
||||||
set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
|
set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
|
||||||
if (ha->dpc_wait && !ha->dpc_active)
|
qla2xxx_wake_dpc(ha);
|
||||||
up(ha->dpc_wait);
|
|
||||||
|
|
||||||
} else if (!abort_active) {
|
} else if (!abort_active) {
|
||||||
/* call abort directly since we are in the DPC thread */
|
/* call abort directly since we are in the DPC thread */
|
||||||
DEBUG(printk("%s(%ld): timeout calling abort_isp\n",
|
DEBUG(printk("%s(%ld): timeout calling abort_isp\n",
|
||||||
|
@ -336,7 +334,7 @@ qla2x00_load_ram(scsi_qla_host_t *ha, dma_addr_t req_dma, uint32_t risc_addr,
|
||||||
|
|
||||||
DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no));
|
DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no));
|
||||||
|
|
||||||
if (MSW(risc_addr) || IS_QLA24XX(ha) || IS_QLA25XX(ha)) {
|
if (MSW(risc_addr) || IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
|
||||||
mcp->mb[0] = MBC_LOAD_RISC_RAM_EXTENDED;
|
mcp->mb[0] = MBC_LOAD_RISC_RAM_EXTENDED;
|
||||||
mcp->mb[8] = MSW(risc_addr);
|
mcp->mb[8] = MSW(risc_addr);
|
||||||
mcp->out_mb = MBX_8|MBX_0;
|
mcp->out_mb = MBX_8|MBX_0;
|
||||||
|
@ -350,7 +348,7 @@ qla2x00_load_ram(scsi_qla_host_t *ha, dma_addr_t req_dma, uint32_t risc_addr,
|
||||||
mcp->mb[6] = MSW(MSD(req_dma));
|
mcp->mb[6] = MSW(MSD(req_dma));
|
||||||
mcp->mb[7] = LSW(MSD(req_dma));
|
mcp->mb[7] = LSW(MSD(req_dma));
|
||||||
mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_1;
|
mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_1;
|
||||||
if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) {
|
if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
|
||||||
mcp->mb[4] = MSW(risc_code_size);
|
mcp->mb[4] = MSW(risc_code_size);
|
||||||
mcp->mb[5] = LSW(risc_code_size);
|
mcp->mb[5] = LSW(risc_code_size);
|
||||||
mcp->out_mb |= MBX_5|MBX_4;
|
mcp->out_mb |= MBX_5|MBX_4;
|
||||||
|
@ -401,7 +399,7 @@ qla2x00_execute_fw(scsi_qla_host_t *ha, uint32_t risc_addr)
|
||||||
mcp->mb[0] = MBC_EXECUTE_FIRMWARE;
|
mcp->mb[0] = MBC_EXECUTE_FIRMWARE;
|
||||||
mcp->out_mb = MBX_0;
|
mcp->out_mb = MBX_0;
|
||||||
mcp->in_mb = MBX_0;
|
mcp->in_mb = MBX_0;
|
||||||
if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) {
|
if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
|
||||||
mcp->mb[1] = MSW(risc_addr);
|
mcp->mb[1] = MSW(risc_addr);
|
||||||
mcp->mb[2] = LSW(risc_addr);
|
mcp->mb[2] = LSW(risc_addr);
|
||||||
mcp->mb[3] = 0;
|
mcp->mb[3] = 0;
|
||||||
|
@ -424,7 +422,7 @@ qla2x00_execute_fw(scsi_qla_host_t *ha, uint32_t risc_addr)
|
||||||
DEBUG2_3_11(printk("%s(%ld): failed=%x mb[0]=%x.\n", __func__,
|
DEBUG2_3_11(printk("%s(%ld): failed=%x mb[0]=%x.\n", __func__,
|
||||||
ha->host_no, rval, mcp->mb[0]));
|
ha->host_no, rval, mcp->mb[0]));
|
||||||
} else {
|
} else {
|
||||||
if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) {
|
if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
|
||||||
DEBUG11(printk("%s(%ld): done exchanges=%x.\n",
|
DEBUG11(printk("%s(%ld): done exchanges=%x.\n",
|
||||||
__func__, ha->host_no, mcp->mb[1]);)
|
__func__, ha->host_no, mcp->mb[1]);)
|
||||||
} else {
|
} else {
|
||||||
|
@ -565,7 +563,7 @@ qla2x00_set_fw_options(scsi_qla_host_t *ha, uint16_t *fwopts)
|
||||||
mcp->mb[3] = fwopts[3];
|
mcp->mb[3] = fwopts[3];
|
||||||
mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
|
mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
|
||||||
mcp->in_mb = MBX_0;
|
mcp->in_mb = MBX_0;
|
||||||
if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) {
|
if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
|
||||||
mcp->in_mb |= MBX_1;
|
mcp->in_mb |= MBX_1;
|
||||||
} else {
|
} else {
|
||||||
mcp->mb[10] = fwopts[10];
|
mcp->mb[10] = fwopts[10];
|
||||||
|
@ -678,7 +676,7 @@ qla2x00_verify_checksum(scsi_qla_host_t *ha, uint32_t risc_addr)
|
||||||
mcp->mb[0] = MBC_VERIFY_CHECKSUM;
|
mcp->mb[0] = MBC_VERIFY_CHECKSUM;
|
||||||
mcp->out_mb = MBX_0;
|
mcp->out_mb = MBX_0;
|
||||||
mcp->in_mb = MBX_0;
|
mcp->in_mb = MBX_0;
|
||||||
if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) {
|
if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
|
||||||
mcp->mb[1] = MSW(risc_addr);
|
mcp->mb[1] = MSW(risc_addr);
|
||||||
mcp->mb[2] = LSW(risc_addr);
|
mcp->mb[2] = LSW(risc_addr);
|
||||||
mcp->out_mb |= MBX_2|MBX_1;
|
mcp->out_mb |= MBX_2|MBX_1;
|
||||||
|
@ -695,7 +693,7 @@ qla2x00_verify_checksum(scsi_qla_host_t *ha, uint32_t risc_addr)
|
||||||
|
|
||||||
if (rval != QLA_SUCCESS) {
|
if (rval != QLA_SUCCESS) {
|
||||||
DEBUG2_3_11(printk("%s(%ld): failed=%x chk sum=%x.\n", __func__,
|
DEBUG2_3_11(printk("%s(%ld): failed=%x chk sum=%x.\n", __func__,
|
||||||
ha->host_no, rval, (IS_QLA24XX(ha) || IS_QLA25XX(ha) ?
|
ha->host_no, rval, (IS_QLA24XX(ha) || IS_QLA54XX(ha) ?
|
||||||
(mcp->mb[2] << 16) | mcp->mb[1]: mcp->mb[1]));)
|
(mcp->mb[2] << 16) | mcp->mb[1]: mcp->mb[1]));)
|
||||||
} else {
|
} else {
|
||||||
DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no);)
|
DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no);)
|
||||||
|
@ -753,7 +751,7 @@ qla2x00_issue_iocb(scsi_qla_host_t *ha, void* buffer, dma_addr_t phys_addr,
|
||||||
|
|
||||||
/* Mask reserved bits. */
|
/* Mask reserved bits. */
|
||||||
sts_entry->entry_status &=
|
sts_entry->entry_status &=
|
||||||
IS_QLA24XX(ha) || IS_QLA25XX(ha) ? RF_MASK_24XX :RF_MASK;
|
IS_QLA24XX(ha) || IS_QLA54XX(ha) ? RF_MASK_24XX :RF_MASK;
|
||||||
}
|
}
|
||||||
|
|
||||||
return rval;
|
return rval;
|
||||||
|
@ -1093,7 +1091,7 @@ qla2x00_get_port_database(scsi_qla_host_t *ha, fc_port_t *fcport, uint8_t opt)
|
||||||
memset(pd, 0, max(PORT_DATABASE_SIZE, PORT_DATABASE_24XX_SIZE));
|
memset(pd, 0, max(PORT_DATABASE_SIZE, PORT_DATABASE_24XX_SIZE));
|
||||||
|
|
||||||
mcp->mb[0] = MBC_GET_PORT_DATABASE;
|
mcp->mb[0] = MBC_GET_PORT_DATABASE;
|
||||||
if (opt != 0 && !IS_QLA24XX(ha) && !IS_QLA25XX(ha))
|
if (opt != 0 && !IS_QLA24XX(ha) && !IS_QLA54XX(ha))
|
||||||
mcp->mb[0] = MBC_ENHANCED_GET_PORT_DATABASE;
|
mcp->mb[0] = MBC_ENHANCED_GET_PORT_DATABASE;
|
||||||
mcp->mb[2] = MSW(pd_dma);
|
mcp->mb[2] = MSW(pd_dma);
|
||||||
mcp->mb[3] = LSW(pd_dma);
|
mcp->mb[3] = LSW(pd_dma);
|
||||||
|
@ -1101,7 +1099,7 @@ qla2x00_get_port_database(scsi_qla_host_t *ha, fc_port_t *fcport, uint8_t opt)
|
||||||
mcp->mb[7] = LSW(MSD(pd_dma));
|
mcp->mb[7] = LSW(MSD(pd_dma));
|
||||||
mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
|
mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
|
||||||
mcp->in_mb = MBX_0;
|
mcp->in_mb = MBX_0;
|
||||||
if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) {
|
if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
|
||||||
mcp->mb[1] = fcport->loop_id;
|
mcp->mb[1] = fcport->loop_id;
|
||||||
mcp->mb[10] = opt;
|
mcp->mb[10] = opt;
|
||||||
mcp->out_mb |= MBX_10|MBX_1;
|
mcp->out_mb |= MBX_10|MBX_1;
|
||||||
|
@ -1114,7 +1112,7 @@ qla2x00_get_port_database(scsi_qla_host_t *ha, fc_port_t *fcport, uint8_t opt)
|
||||||
mcp->mb[1] = fcport->loop_id << 8 | opt;
|
mcp->mb[1] = fcport->loop_id << 8 | opt;
|
||||||
mcp->out_mb |= MBX_1;
|
mcp->out_mb |= MBX_1;
|
||||||
}
|
}
|
||||||
mcp->buf_size = (IS_QLA24XX(ha) || IS_QLA25XX(ha) ?
|
mcp->buf_size = (IS_QLA24XX(ha) || IS_QLA54XX(ha) ?
|
||||||
PORT_DATABASE_24XX_SIZE : PORT_DATABASE_SIZE);
|
PORT_DATABASE_24XX_SIZE : PORT_DATABASE_SIZE);
|
||||||
mcp->flags = MBX_DMA_IN;
|
mcp->flags = MBX_DMA_IN;
|
||||||
mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
|
mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
|
||||||
|
@ -1122,7 +1120,7 @@ qla2x00_get_port_database(scsi_qla_host_t *ha, fc_port_t *fcport, uint8_t opt)
|
||||||
if (rval != QLA_SUCCESS)
|
if (rval != QLA_SUCCESS)
|
||||||
goto gpd_error_out;
|
goto gpd_error_out;
|
||||||
|
|
||||||
if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) {
|
if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
|
||||||
pd24 = (struct port_database_24xx *) pd;
|
pd24 = (struct port_database_24xx *) pd;
|
||||||
|
|
||||||
/* Check for logged in state. */
|
/* Check for logged in state. */
|
||||||
|
@ -1339,7 +1337,7 @@ qla2x00_lip_reset(scsi_qla_host_t *ha)
|
||||||
|
|
||||||
DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);)
|
DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);)
|
||||||
|
|
||||||
if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) {
|
if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
|
||||||
mcp->mb[0] = MBC_LIP_FULL_LOGIN;
|
mcp->mb[0] = MBC_LIP_FULL_LOGIN;
|
||||||
mcp->mb[1] = BIT_0;
|
mcp->mb[1] = BIT_0;
|
||||||
mcp->mb[2] = 0xff;
|
mcp->mb[2] = 0xff;
|
||||||
|
@ -1633,20 +1631,25 @@ qla2x00_login_fabric(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain,
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
qla2x00_login_local_device(scsi_qla_host_t *ha, uint16_t loop_id,
|
qla2x00_login_local_device(scsi_qla_host_t *ha, fc_port_t *fcport,
|
||||||
uint16_t *mb_ret, uint8_t opt)
|
uint16_t *mb_ret, uint8_t opt)
|
||||||
{
|
{
|
||||||
int rval;
|
int rval;
|
||||||
mbx_cmd_t mc;
|
mbx_cmd_t mc;
|
||||||
mbx_cmd_t *mcp = &mc;
|
mbx_cmd_t *mcp = &mc;
|
||||||
|
|
||||||
|
if (IS_QLA24XX(ha) || IS_QLA54XX(ha))
|
||||||
|
return qla24xx_login_fabric(ha, fcport->loop_id,
|
||||||
|
fcport->d_id.b.domain, fcport->d_id.b.area,
|
||||||
|
fcport->d_id.b.al_pa, mb_ret, opt);
|
||||||
|
|
||||||
DEBUG3(printk("%s(%ld): entered.\n", __func__, ha->host_no);)
|
DEBUG3(printk("%s(%ld): entered.\n", __func__, ha->host_no);)
|
||||||
|
|
||||||
mcp->mb[0] = MBC_LOGIN_LOOP_PORT;
|
mcp->mb[0] = MBC_LOGIN_LOOP_PORT;
|
||||||
if (HAS_EXTENDED_IDS(ha))
|
if (HAS_EXTENDED_IDS(ha))
|
||||||
mcp->mb[1] = loop_id;
|
mcp->mb[1] = fcport->loop_id;
|
||||||
else
|
else
|
||||||
mcp->mb[1] = loop_id << 8;
|
mcp->mb[1] = fcport->loop_id << 8;
|
||||||
mcp->mb[2] = opt;
|
mcp->mb[2] = opt;
|
||||||
mcp->out_mb = MBX_2|MBX_1|MBX_0;
|
mcp->out_mb = MBX_2|MBX_1|MBX_0;
|
||||||
mcp->in_mb = MBX_7|MBX_6|MBX_1|MBX_0;
|
mcp->in_mb = MBX_7|MBX_6|MBX_1|MBX_0;
|
||||||
|
@ -1868,7 +1871,7 @@ qla2x00_get_id_list(scsi_qla_host_t *ha, void *id_list, dma_addr_t id_list_dma,
|
||||||
|
|
||||||
mcp->mb[0] = MBC_GET_ID_LIST;
|
mcp->mb[0] = MBC_GET_ID_LIST;
|
||||||
mcp->out_mb = MBX_0;
|
mcp->out_mb = MBX_0;
|
||||||
if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) {
|
if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
|
||||||
mcp->mb[2] = MSW(id_list_dma);
|
mcp->mb[2] = MSW(id_list_dma);
|
||||||
mcp->mb[3] = LSW(id_list_dma);
|
mcp->mb[3] = LSW(id_list_dma);
|
||||||
mcp->mb[6] = MSW(MSD(id_list_dma));
|
mcp->mb[6] = MSW(MSD(id_list_dma));
|
||||||
|
@ -2059,7 +2062,7 @@ qla2x00_get_link_status(scsi_qla_host_t *ha, uint16_t loop_id,
|
||||||
mcp->mb[7] = LSW(MSD(stat_buf_dma));
|
mcp->mb[7] = LSW(MSD(stat_buf_dma));
|
||||||
mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
|
mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
|
||||||
mcp->in_mb = MBX_0;
|
mcp->in_mb = MBX_0;
|
||||||
if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) {
|
if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
|
||||||
mcp->mb[1] = loop_id;
|
mcp->mb[1] = loop_id;
|
||||||
mcp->mb[4] = 0;
|
mcp->mb[4] = 0;
|
||||||
mcp->mb[10] = 0;
|
mcp->mb[10] = 0;
|
||||||
|
@ -2326,7 +2329,7 @@ qla2x00_system_error(scsi_qla_host_t *ha)
|
||||||
mbx_cmd_t mc;
|
mbx_cmd_t mc;
|
||||||
mbx_cmd_t *mcp = &mc;
|
mbx_cmd_t *mcp = &mc;
|
||||||
|
|
||||||
if (!IS_QLA24XX(ha) && !IS_QLA25XX(ha))
|
if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha))
|
||||||
return QLA_FUNCTION_FAILED;
|
return QLA_FUNCTION_FAILED;
|
||||||
|
|
||||||
DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no));
|
DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no));
|
||||||
|
@ -2408,9 +2411,9 @@ qla2x00_set_serdes_params(scsi_qla_host_t *ha, uint16_t sw_em_1g,
|
||||||
|
|
||||||
mcp->mb[0] = MBC_SERDES_PARAMS;
|
mcp->mb[0] = MBC_SERDES_PARAMS;
|
||||||
mcp->mb[1] = BIT_0;
|
mcp->mb[1] = BIT_0;
|
||||||
mcp->mb[2] = sw_em_1g;
|
mcp->mb[2] = sw_em_1g | BIT_15;
|
||||||
mcp->mb[3] = sw_em_2g;
|
mcp->mb[3] = sw_em_2g | BIT_15;
|
||||||
mcp->mb[4] = sw_em_4g;
|
mcp->mb[4] = sw_em_4g | BIT_15;
|
||||||
mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
|
mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
|
||||||
mcp->in_mb = MBX_0;
|
mcp->in_mb = MBX_0;
|
||||||
mcp->tov = 30;
|
mcp->tov = 30;
|
||||||
|
@ -2436,7 +2439,7 @@ qla2x00_stop_firmware(scsi_qla_host_t *ha)
|
||||||
mbx_cmd_t mc;
|
mbx_cmd_t mc;
|
||||||
mbx_cmd_t *mcp = &mc;
|
mbx_cmd_t *mcp = &mc;
|
||||||
|
|
||||||
if (!IS_QLA24XX(ha) && !IS_QLA25XX(ha))
|
if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha))
|
||||||
return QLA_FUNCTION_FAILED;
|
return QLA_FUNCTION_FAILED;
|
||||||
|
|
||||||
DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no));
|
DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no));
|
||||||
|
|
|
@ -8,8 +8,8 @@
|
||||||
|
|
||||||
#include <linux/moduleparam.h>
|
#include <linux/moduleparam.h>
|
||||||
#include <linux/vmalloc.h>
|
#include <linux/vmalloc.h>
|
||||||
#include <linux/smp_lock.h>
|
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
|
#include <linux/kthread.h>
|
||||||
|
|
||||||
#include <scsi/scsi_tcq.h>
|
#include <scsi/scsi_tcq.h>
|
||||||
#include <scsi/scsicam.h>
|
#include <scsi/scsicam.h>
|
||||||
|
@ -1146,6 +1146,57 @@ qla2x00_config_dma_addressing(scsi_qla_host_t *ha)
|
||||||
pci_set_consistent_dma_mask(ha->pdev, DMA_32BIT_MASK);
|
pci_set_consistent_dma_mask(ha->pdev, DMA_32BIT_MASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
qla2x00_set_isp_flags(scsi_qla_host_t *ha)
|
||||||
|
{
|
||||||
|
ha->device_type = DT_EXTENDED_IDS;
|
||||||
|
switch (ha->pdev->device) {
|
||||||
|
case PCI_DEVICE_ID_QLOGIC_ISP2100:
|
||||||
|
ha->device_type |= DT_ISP2100;
|
||||||
|
ha->device_type &= ~DT_EXTENDED_IDS;
|
||||||
|
break;
|
||||||
|
case PCI_DEVICE_ID_QLOGIC_ISP2200:
|
||||||
|
ha->device_type |= DT_ISP2200;
|
||||||
|
ha->device_type &= ~DT_EXTENDED_IDS;
|
||||||
|
break;
|
||||||
|
case PCI_DEVICE_ID_QLOGIC_ISP2300:
|
||||||
|
ha->device_type |= DT_ISP2300;
|
||||||
|
ha->device_type |= DT_ZIO_SUPPORTED;
|
||||||
|
break;
|
||||||
|
case PCI_DEVICE_ID_QLOGIC_ISP2312:
|
||||||
|
ha->device_type |= DT_ISP2312;
|
||||||
|
ha->device_type |= DT_ZIO_SUPPORTED;
|
||||||
|
break;
|
||||||
|
case PCI_DEVICE_ID_QLOGIC_ISP2322:
|
||||||
|
ha->device_type |= DT_ISP2322;
|
||||||
|
ha->device_type |= DT_ZIO_SUPPORTED;
|
||||||
|
if (ha->pdev->subsystem_vendor == 0x1028 &&
|
||||||
|
ha->pdev->subsystem_device == 0x0170)
|
||||||
|
ha->device_type |= DT_OEM_001;
|
||||||
|
break;
|
||||||
|
case PCI_DEVICE_ID_QLOGIC_ISP6312:
|
||||||
|
ha->device_type |= DT_ISP6312;
|
||||||
|
break;
|
||||||
|
case PCI_DEVICE_ID_QLOGIC_ISP6322:
|
||||||
|
ha->device_type |= DT_ISP6322;
|
||||||
|
break;
|
||||||
|
case PCI_DEVICE_ID_QLOGIC_ISP2422:
|
||||||
|
ha->device_type |= DT_ISP2422;
|
||||||
|
ha->device_type |= DT_ZIO_SUPPORTED;
|
||||||
|
break;
|
||||||
|
case PCI_DEVICE_ID_QLOGIC_ISP2432:
|
||||||
|
ha->device_type |= DT_ISP2432;
|
||||||
|
ha->device_type |= DT_ZIO_SUPPORTED;
|
||||||
|
break;
|
||||||
|
case PCI_DEVICE_ID_QLOGIC_ISP5422:
|
||||||
|
ha->device_type |= DT_ISP5422;
|
||||||
|
break;
|
||||||
|
case PCI_DEVICE_ID_QLOGIC_ISP5432:
|
||||||
|
ha->device_type |= DT_ISP5432;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
qla2x00_iospace_config(scsi_qla_host_t *ha)
|
qla2x00_iospace_config(scsi_qla_host_t *ha)
|
||||||
{
|
{
|
||||||
|
@ -1307,7 +1358,8 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info)
|
||||||
ha->brd_info = brd_info;
|
ha->brd_info = brd_info;
|
||||||
sprintf(ha->host_str, "%s_%ld", ha->brd_info->drv_name, ha->host_no);
|
sprintf(ha->host_str, "%s_%ld", ha->brd_info->drv_name, ha->host_no);
|
||||||
|
|
||||||
ha->dpc_pid = -1;
|
/* Set ISP-type information. */
|
||||||
|
qla2x00_set_isp_flags(ha);
|
||||||
|
|
||||||
/* Configure PCI I/O space */
|
/* Configure PCI I/O space */
|
||||||
ret = qla2x00_iospace_config(ha);
|
ret = qla2x00_iospace_config(ha);
|
||||||
|
@ -1386,7 +1438,7 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info)
|
||||||
ha->gid_list_info_size = 6;
|
ha->gid_list_info_size = 6;
|
||||||
if (IS_QLA2322(ha) || IS_QLA6322(ha))
|
if (IS_QLA2322(ha) || IS_QLA6322(ha))
|
||||||
ha->optrom_size = OPTROM_SIZE_2322;
|
ha->optrom_size = OPTROM_SIZE_2322;
|
||||||
} else if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) {
|
} else if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
|
||||||
host->max_id = MAX_TARGETS_2200;
|
host->max_id = MAX_TARGETS_2200;
|
||||||
ha->mbx_count = MAILBOX_REGISTER_COUNT;
|
ha->mbx_count = MAILBOX_REGISTER_COUNT;
|
||||||
ha->request_q_length = REQUEST_ENTRY_CNT_24XX;
|
ha->request_q_length = REQUEST_ENTRY_CNT_24XX;
|
||||||
|
@ -1449,9 +1501,6 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info)
|
||||||
*/
|
*/
|
||||||
spin_lock_init(&ha->mbx_reg_lock);
|
spin_lock_init(&ha->mbx_reg_lock);
|
||||||
|
|
||||||
init_completion(&ha->dpc_inited);
|
|
||||||
init_completion(&ha->dpc_exited);
|
|
||||||
|
|
||||||
qla2x00_config_dma_addressing(ha);
|
qla2x00_config_dma_addressing(ha);
|
||||||
if (qla2x00_mem_alloc(ha)) {
|
if (qla2x00_mem_alloc(ha)) {
|
||||||
qla_printk(KERN_WARNING, ha,
|
qla_printk(KERN_WARNING, ha,
|
||||||
|
@ -1478,16 +1527,14 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info)
|
||||||
/*
|
/*
|
||||||
* Startup the kernel thread for this host adapter
|
* Startup the kernel thread for this host adapter
|
||||||
*/
|
*/
|
||||||
ha->dpc_should_die = 0;
|
ha->dpc_thread = kthread_create(qla2x00_do_dpc, ha,
|
||||||
ha->dpc_pid = kernel_thread(qla2x00_do_dpc, ha, 0);
|
"%s_dpc", ha->host_str);
|
||||||
if (ha->dpc_pid < 0) {
|
if (IS_ERR(ha->dpc_thread)) {
|
||||||
qla_printk(KERN_WARNING, ha,
|
qla_printk(KERN_WARNING, ha,
|
||||||
"Unable to start DPC thread!\n");
|
"Unable to start DPC thread!\n");
|
||||||
|
ret = PTR_ERR(ha->dpc_thread);
|
||||||
ret = -ENODEV;
|
|
||||||
goto probe_failed;
|
goto probe_failed;
|
||||||
}
|
}
|
||||||
wait_for_completion(&ha->dpc_inited);
|
|
||||||
|
|
||||||
host->this_id = 255;
|
host->this_id = 255;
|
||||||
host->cmd_per_lun = 3;
|
host->cmd_per_lun = 3;
|
||||||
|
@ -1517,7 +1564,7 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info)
|
||||||
|
|
||||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||||
reg = ha->iobase;
|
reg = ha->iobase;
|
||||||
if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) {
|
if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
|
||||||
WRT_REG_DWORD(®->isp24.hccr, HCCRX_CLR_HOST_INT);
|
WRT_REG_DWORD(®->isp24.hccr, HCCRX_CLR_HOST_INT);
|
||||||
WRT_REG_DWORD(®->isp24.hccr, HCCRX_CLR_RISC_INT);
|
WRT_REG_DWORD(®->isp24.hccr, HCCRX_CLR_RISC_INT);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1621,8 +1668,6 @@ EXPORT_SYMBOL_GPL(qla2x00_remove_one);
|
||||||
static void
|
static void
|
||||||
qla2x00_free_device(scsi_qla_host_t *ha)
|
qla2x00_free_device(scsi_qla_host_t *ha)
|
||||||
{
|
{
|
||||||
int ret;
|
|
||||||
|
|
||||||
/* Abort any outstanding IO descriptors. */
|
/* Abort any outstanding IO descriptors. */
|
||||||
if (!IS_QLA2100(ha) && !IS_QLA2200(ha))
|
if (!IS_QLA2100(ha) && !IS_QLA2200(ha))
|
||||||
qla2x00_cancel_io_descriptors(ha);
|
qla2x00_cancel_io_descriptors(ha);
|
||||||
|
@ -1632,18 +1677,15 @@ qla2x00_free_device(scsi_qla_host_t *ha)
|
||||||
qla2x00_stop_timer(ha);
|
qla2x00_stop_timer(ha);
|
||||||
|
|
||||||
/* Kill the kernel thread for this host */
|
/* Kill the kernel thread for this host */
|
||||||
if (ha->dpc_pid >= 0) {
|
if (ha->dpc_thread) {
|
||||||
ha->dpc_should_die = 1;
|
struct task_struct *t = ha->dpc_thread;
|
||||||
wmb();
|
|
||||||
ret = kill_proc(ha->dpc_pid, SIGHUP, 1);
|
|
||||||
if (ret) {
|
|
||||||
qla_printk(KERN_ERR, ha,
|
|
||||||
"Unable to signal DPC thread -- (%d)\n", ret);
|
|
||||||
|
|
||||||
/* TODO: SOMETHING MORE??? */
|
/*
|
||||||
} else {
|
* qla2xxx_wake_dpc checks for ->dpc_thread
|
||||||
wait_for_completion(&ha->dpc_exited);
|
* so we need to zero it out.
|
||||||
}
|
*/
|
||||||
|
ha->dpc_thread = NULL;
|
||||||
|
kthread_stop(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Stop currently executing firmware. */
|
/* Stop currently executing firmware. */
|
||||||
|
@ -1775,8 +1817,8 @@ qla2x00_mark_all_devices_lost(scsi_qla_host_t *ha, int defer)
|
||||||
atomic_set(&fcport->state, FCS_DEVICE_LOST);
|
atomic_set(&fcport->state, FCS_DEVICE_LOST);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (defer && ha->dpc_wait && !ha->dpc_active)
|
if (defer)
|
||||||
up(ha->dpc_wait);
|
qla2xxx_wake_dpc(ha);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1993,7 +2035,6 @@ qla2x00_mem_free(scsi_qla_host_t *ha)
|
||||||
{
|
{
|
||||||
struct list_head *fcpl, *fcptemp;
|
struct list_head *fcpl, *fcptemp;
|
||||||
fc_port_t *fcport;
|
fc_port_t *fcport;
|
||||||
unsigned int wtime;/* max wait time if mbx cmd is busy. */
|
|
||||||
|
|
||||||
if (ha == NULL) {
|
if (ha == NULL) {
|
||||||
/* error */
|
/* error */
|
||||||
|
@ -2001,11 +2042,6 @@ qla2x00_mem_free(scsi_qla_host_t *ha)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make sure all other threads are stopped. */
|
|
||||||
wtime = 60 * 1000;
|
|
||||||
while (ha->dpc_wait && wtime)
|
|
||||||
wtime = msleep_interruptible(wtime);
|
|
||||||
|
|
||||||
/* free ioctl memory */
|
/* free ioctl memory */
|
||||||
qla2x00_free_ioctl_mem(ha);
|
qla2x00_free_ioctl_mem(ha);
|
||||||
|
|
||||||
|
@ -2156,7 +2192,6 @@ qla2x00_free_sp_pool( scsi_qla_host_t *ha)
|
||||||
static int
|
static int
|
||||||
qla2x00_do_dpc(void *data)
|
qla2x00_do_dpc(void *data)
|
||||||
{
|
{
|
||||||
DECLARE_MUTEX_LOCKED(sem);
|
|
||||||
scsi_qla_host_t *ha;
|
scsi_qla_host_t *ha;
|
||||||
fc_port_t *fcport;
|
fc_port_t *fcport;
|
||||||
uint8_t status;
|
uint8_t status;
|
||||||
|
@ -2164,32 +2199,19 @@ qla2x00_do_dpc(void *data)
|
||||||
|
|
||||||
ha = (scsi_qla_host_t *)data;
|
ha = (scsi_qla_host_t *)data;
|
||||||
|
|
||||||
lock_kernel();
|
|
||||||
|
|
||||||
daemonize("%s_dpc", ha->host_str);
|
|
||||||
allow_signal(SIGHUP);
|
|
||||||
|
|
||||||
ha->dpc_wait = &sem;
|
|
||||||
|
|
||||||
set_user_nice(current, -20);
|
set_user_nice(current, -20);
|
||||||
|
|
||||||
unlock_kernel();
|
while (!kthread_should_stop()) {
|
||||||
|
|
||||||
complete(&ha->dpc_inited);
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
DEBUG3(printk("qla2x00: DPC handler sleeping\n"));
|
DEBUG3(printk("qla2x00: DPC handler sleeping\n"));
|
||||||
|
|
||||||
if (down_interruptible(&sem))
|
set_current_state(TASK_INTERRUPTIBLE);
|
||||||
break;
|
schedule();
|
||||||
|
__set_current_state(TASK_RUNNING);
|
||||||
if (ha->dpc_should_die)
|
|
||||||
break;
|
|
||||||
|
|
||||||
DEBUG3(printk("qla2x00: DPC handler waking up\n"));
|
DEBUG3(printk("qla2x00: DPC handler waking up\n"));
|
||||||
|
|
||||||
/* Initialization not yet finished. Don't do anything yet. */
|
/* Initialization not yet finished. Don't do anything yet. */
|
||||||
if (!ha->flags.init_done || ha->dpc_active)
|
if (!ha->flags.init_done)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
DEBUG3(printk("scsi(%ld): DPC handler\n", ha->host_no));
|
DEBUG3(printk("scsi(%ld): DPC handler\n", ha->host_no));
|
||||||
|
@ -2273,7 +2295,7 @@ qla2x00_do_dpc(void *data)
|
||||||
} else
|
} else
|
||||||
status =
|
status =
|
||||||
qla2x00_local_device_login(
|
qla2x00_local_device_login(
|
||||||
ha, fcport->loop_id);
|
ha, fcport);
|
||||||
|
|
||||||
if (status == QLA_SUCCESS) {
|
if (status == QLA_SUCCESS) {
|
||||||
fcport->old_loop_id = fcport->loop_id;
|
fcport->old_loop_id = fcport->loop_id;
|
||||||
|
@ -2356,10 +2378,16 @@ qla2x00_do_dpc(void *data)
|
||||||
/*
|
/*
|
||||||
* Make sure that nobody tries to wake us up again.
|
* Make sure that nobody tries to wake us up again.
|
||||||
*/
|
*/
|
||||||
ha->dpc_wait = NULL;
|
|
||||||
ha->dpc_active = 0;
|
ha->dpc_active = 0;
|
||||||
|
|
||||||
complete_and_exit(&ha->dpc_exited, 0);
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
qla2xxx_wake_dpc(scsi_qla_host_t *ha)
|
||||||
|
{
|
||||||
|
if (ha->dpc_thread)
|
||||||
|
wake_up_process(ha->dpc_thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2540,11 +2568,8 @@ qla2x00_timer(scsi_qla_host_t *ha)
|
||||||
test_bit(LOGIN_RETRY_NEEDED, &ha->dpc_flags) ||
|
test_bit(LOGIN_RETRY_NEEDED, &ha->dpc_flags) ||
|
||||||
test_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) ||
|
test_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) ||
|
||||||
test_bit(BEACON_BLINK_NEEDED, &ha->dpc_flags) ||
|
test_bit(BEACON_BLINK_NEEDED, &ha->dpc_flags) ||
|
||||||
test_bit(RELOGIN_NEEDED, &ha->dpc_flags)) &&
|
test_bit(RELOGIN_NEEDED, &ha->dpc_flags)))
|
||||||
ha->dpc_wait && !ha->dpc_active) {
|
qla2xxx_wake_dpc(ha);
|
||||||
|
|
||||||
up(ha->dpc_wait);
|
|
||||||
}
|
|
||||||
|
|
||||||
qla2x00_restart_timer(ha, WATCH_INTERVAL);
|
qla2x00_restart_timer(ha, WATCH_INTERVAL);
|
||||||
}
|
}
|
||||||
|
@ -2576,13 +2601,12 @@ qla2x00_down_timeout(struct semaphore *sema, unsigned long timeout)
|
||||||
|
|
||||||
/* Firmware interface routines. */
|
/* Firmware interface routines. */
|
||||||
|
|
||||||
#define FW_BLOBS 6
|
#define FW_BLOBS 5
|
||||||
#define FW_ISP21XX 0
|
#define FW_ISP21XX 0
|
||||||
#define FW_ISP22XX 1
|
#define FW_ISP22XX 1
|
||||||
#define FW_ISP2300 2
|
#define FW_ISP2300 2
|
||||||
#define FW_ISP2322 3
|
#define FW_ISP2322 3
|
||||||
#define FW_ISP63XX 4
|
#define FW_ISP24XX 4
|
||||||
#define FW_ISP24XX 5
|
|
||||||
|
|
||||||
static DECLARE_MUTEX(qla_fw_lock);
|
static DECLARE_MUTEX(qla_fw_lock);
|
||||||
|
|
||||||
|
@ -2591,7 +2615,6 @@ static struct fw_blob qla_fw_blobs[FW_BLOBS] = {
|
||||||
{ .name = "ql2200_fw.bin", .segs = { 0x1000, 0 }, },
|
{ .name = "ql2200_fw.bin", .segs = { 0x1000, 0 }, },
|
||||||
{ .name = "ql2300_fw.bin", .segs = { 0x800, 0 }, },
|
{ .name = "ql2300_fw.bin", .segs = { 0x800, 0 }, },
|
||||||
{ .name = "ql2322_fw.bin", .segs = { 0x800, 0x1c000, 0x1e000, 0 }, },
|
{ .name = "ql2322_fw.bin", .segs = { 0x800, 0x1c000, 0x1e000, 0 }, },
|
||||||
{ .name = "ql6312_fw.bin", .segs = { 0x800, 0 }, },
|
|
||||||
{ .name = "ql2400_fw.bin", },
|
{ .name = "ql2400_fw.bin", },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2605,13 +2628,11 @@ qla2x00_request_firmware(scsi_qla_host_t *ha)
|
||||||
blob = &qla_fw_blobs[FW_ISP21XX];
|
blob = &qla_fw_blobs[FW_ISP21XX];
|
||||||
} else if (IS_QLA2200(ha)) {
|
} else if (IS_QLA2200(ha)) {
|
||||||
blob = &qla_fw_blobs[FW_ISP22XX];
|
blob = &qla_fw_blobs[FW_ISP22XX];
|
||||||
} else if (IS_QLA2300(ha) || IS_QLA2312(ha)) {
|
} else if (IS_QLA2300(ha) || IS_QLA2312(ha) || IS_QLA6312(ha)) {
|
||||||
blob = &qla_fw_blobs[FW_ISP2300];
|
blob = &qla_fw_blobs[FW_ISP2300];
|
||||||
} else if (IS_QLA2322(ha)) {
|
} else if (IS_QLA2322(ha) || IS_QLA6322(ha)) {
|
||||||
blob = &qla_fw_blobs[FW_ISP2322];
|
blob = &qla_fw_blobs[FW_ISP2322];
|
||||||
} else if (IS_QLA6312(ha) || IS_QLA6322(ha)) {
|
} else if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
|
||||||
blob = &qla_fw_blobs[FW_ISP63XX];
|
|
||||||
} else if (IS_QLA24XX(ha)) {
|
|
||||||
blob = &qla_fw_blobs[FW_ISP24XX];
|
blob = &qla_fw_blobs[FW_ISP24XX];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2667,6 +2688,10 @@ static struct pci_device_id qla2xxx_pci_tbl[] = {
|
||||||
PCI_ANY_ID, PCI_ANY_ID, },
|
PCI_ANY_ID, PCI_ANY_ID, },
|
||||||
{ PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2432,
|
{ PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2432,
|
||||||
PCI_ANY_ID, PCI_ANY_ID, },
|
PCI_ANY_ID, PCI_ANY_ID, },
|
||||||
|
{ PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP5422,
|
||||||
|
PCI_ANY_ID, PCI_ANY_ID, },
|
||||||
|
{ PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP5432,
|
||||||
|
PCI_ANY_ID, PCI_ANY_ID, },
|
||||||
{ 0 },
|
{ 0 },
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(pci, qla2xxx_pci_tbl);
|
MODULE_DEVICE_TABLE(pci, qla2xxx_pci_tbl);
|
||||||
|
|
|
@ -1191,11 +1191,6 @@ qla2x00_poll_flash(scsi_qla_host_t *ha, uint32_t addr, uint8_t poll_data,
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define IS_OEM_001(ha) \
|
|
||||||
((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2322 && \
|
|
||||||
(ha)->pdev->subsystem_vendor == 0x1028 && \
|
|
||||||
(ha)->pdev->subsystem_device == 0x0170)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* qla2x00_program_flash_address() - Programs a flash address
|
* qla2x00_program_flash_address() - Programs a flash address
|
||||||
* @ha: HA context
|
* @ha: HA context
|
||||||
|
@ -1354,7 +1349,7 @@ qla2x00_resume_hba(struct scsi_qla_host *ha)
|
||||||
/* Resume HBA. */
|
/* Resume HBA. */
|
||||||
clear_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags);
|
clear_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags);
|
||||||
set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
|
set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
|
||||||
up(ha->dpc_wait);
|
qla2xxx_wake_dpc(ha);
|
||||||
qla2x00_wait_for_hba_online(ha);
|
qla2x00_wait_for_hba_online(ha);
|
||||||
scsi_unblock_requests(ha->host);
|
scsi_unblock_requests(ha->host);
|
||||||
}
|
}
|
||||||
|
@ -1652,7 +1647,7 @@ qla24xx_write_optrom_data(struct scsi_qla_host *ha, uint8_t *buf,
|
||||||
/* Resume HBA -- RISC reset needed. */
|
/* Resume HBA -- RISC reset needed. */
|
||||||
clear_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags);
|
clear_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags);
|
||||||
set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
|
set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
|
||||||
up(ha->dpc_wait);
|
qla2xxx_wake_dpc(ha);
|
||||||
qla2x00_wait_for_hba_online(ha);
|
qla2x00_wait_for_hba_online(ha);
|
||||||
scsi_unblock_requests(ha->host);
|
scsi_unblock_requests(ha->host);
|
||||||
|
|
||||||
|
|
|
@ -378,7 +378,6 @@ static struct scsi_host_template mv_sht = {
|
||||||
.name = DRV_NAME,
|
.name = DRV_NAME,
|
||||||
.ioctl = ata_scsi_ioctl,
|
.ioctl = ata_scsi_ioctl,
|
||||||
.queuecommand = ata_scsi_queuecmd,
|
.queuecommand = ata_scsi_queuecmd,
|
||||||
.eh_timed_out = ata_scsi_timed_out,
|
|
||||||
.eh_strategy_handler = ata_scsi_error,
|
.eh_strategy_handler = ata_scsi_error,
|
||||||
.can_queue = MV_USE_Q_DEPTH,
|
.can_queue = MV_USE_Q_DEPTH,
|
||||||
.this_id = ATA_SHT_THIS_ID,
|
.this_id = ATA_SHT_THIS_ID,
|
||||||
|
|
|
@ -229,7 +229,6 @@ static struct scsi_host_template nv_sht = {
|
||||||
.name = DRV_NAME,
|
.name = DRV_NAME,
|
||||||
.ioctl = ata_scsi_ioctl,
|
.ioctl = ata_scsi_ioctl,
|
||||||
.queuecommand = ata_scsi_queuecmd,
|
.queuecommand = ata_scsi_queuecmd,
|
||||||
.eh_timed_out = ata_scsi_timed_out,
|
|
||||||
.eh_strategy_handler = ata_scsi_error,
|
.eh_strategy_handler = ata_scsi_error,
|
||||||
.can_queue = ATA_DEF_QUEUE,
|
.can_queue = ATA_DEF_QUEUE,
|
||||||
.this_id = ATA_SHT_THIS_ID,
|
.this_id = ATA_SHT_THIS_ID,
|
||||||
|
|
|
@ -111,7 +111,6 @@ static struct scsi_host_template pdc_ata_sht = {
|
||||||
.name = DRV_NAME,
|
.name = DRV_NAME,
|
||||||
.ioctl = ata_scsi_ioctl,
|
.ioctl = ata_scsi_ioctl,
|
||||||
.queuecommand = ata_scsi_queuecmd,
|
.queuecommand = ata_scsi_queuecmd,
|
||||||
.eh_timed_out = ata_scsi_timed_out,
|
|
||||||
.eh_strategy_handler = ata_scsi_error,
|
.eh_strategy_handler = ata_scsi_error,
|
||||||
.can_queue = ATA_DEF_QUEUE,
|
.can_queue = ATA_DEF_QUEUE,
|
||||||
.this_id = ATA_SHT_THIS_ID,
|
.this_id = ATA_SHT_THIS_ID,
|
||||||
|
|
|
@ -132,7 +132,6 @@ static struct scsi_host_template qs_ata_sht = {
|
||||||
.name = DRV_NAME,
|
.name = DRV_NAME,
|
||||||
.ioctl = ata_scsi_ioctl,
|
.ioctl = ata_scsi_ioctl,
|
||||||
.queuecommand = ata_scsi_queuecmd,
|
.queuecommand = ata_scsi_queuecmd,
|
||||||
.eh_timed_out = ata_scsi_timed_out,
|
|
||||||
.eh_strategy_handler = ata_scsi_error,
|
.eh_strategy_handler = ata_scsi_error,
|
||||||
.can_queue = ATA_DEF_QUEUE,
|
.can_queue = ATA_DEF_QUEUE,
|
||||||
.this_id = ATA_SHT_THIS_ID,
|
.this_id = ATA_SHT_THIS_ID,
|
||||||
|
|
|
@ -146,7 +146,6 @@ static struct scsi_host_template sil_sht = {
|
||||||
.name = DRV_NAME,
|
.name = DRV_NAME,
|
||||||
.ioctl = ata_scsi_ioctl,
|
.ioctl = ata_scsi_ioctl,
|
||||||
.queuecommand = ata_scsi_queuecmd,
|
.queuecommand = ata_scsi_queuecmd,
|
||||||
.eh_timed_out = ata_scsi_timed_out,
|
|
||||||
.eh_strategy_handler = ata_scsi_error,
|
.eh_strategy_handler = ata_scsi_error,
|
||||||
.can_queue = ATA_DEF_QUEUE,
|
.can_queue = ATA_DEF_QUEUE,
|
||||||
.this_id = ATA_SHT_THIS_ID,
|
.this_id = ATA_SHT_THIS_ID,
|
||||||
|
|
|
@ -281,7 +281,6 @@ static struct scsi_host_template sil24_sht = {
|
||||||
.name = DRV_NAME,
|
.name = DRV_NAME,
|
||||||
.ioctl = ata_scsi_ioctl,
|
.ioctl = ata_scsi_ioctl,
|
||||||
.queuecommand = ata_scsi_queuecmd,
|
.queuecommand = ata_scsi_queuecmd,
|
||||||
.eh_timed_out = ata_scsi_timed_out,
|
|
||||||
.eh_strategy_handler = ata_scsi_error,
|
.eh_strategy_handler = ata_scsi_error,
|
||||||
.can_queue = ATA_DEF_QUEUE,
|
.can_queue = ATA_DEF_QUEUE,
|
||||||
.this_id = ATA_SHT_THIS_ID,
|
.this_id = ATA_SHT_THIS_ID,
|
||||||
|
|
|
@ -87,7 +87,6 @@ static struct scsi_host_template sis_sht = {
|
||||||
.name = DRV_NAME,
|
.name = DRV_NAME,
|
||||||
.ioctl = ata_scsi_ioctl,
|
.ioctl = ata_scsi_ioctl,
|
||||||
.queuecommand = ata_scsi_queuecmd,
|
.queuecommand = ata_scsi_queuecmd,
|
||||||
.eh_timed_out = ata_scsi_timed_out,
|
|
||||||
.eh_strategy_handler = ata_scsi_error,
|
.eh_strategy_handler = ata_scsi_error,
|
||||||
.can_queue = ATA_DEF_QUEUE,
|
.can_queue = ATA_DEF_QUEUE,
|
||||||
.this_id = ATA_SHT_THIS_ID,
|
.this_id = ATA_SHT_THIS_ID,
|
||||||
|
|
|
@ -288,7 +288,6 @@ static struct scsi_host_template k2_sata_sht = {
|
||||||
.name = DRV_NAME,
|
.name = DRV_NAME,
|
||||||
.ioctl = ata_scsi_ioctl,
|
.ioctl = ata_scsi_ioctl,
|
||||||
.queuecommand = ata_scsi_queuecmd,
|
.queuecommand = ata_scsi_queuecmd,
|
||||||
.eh_timed_out = ata_scsi_timed_out,
|
|
||||||
.eh_strategy_handler = ata_scsi_error,
|
.eh_strategy_handler = ata_scsi_error,
|
||||||
.can_queue = ATA_DEF_QUEUE,
|
.can_queue = ATA_DEF_QUEUE,
|
||||||
.this_id = ATA_SHT_THIS_ID,
|
.this_id = ATA_SHT_THIS_ID,
|
||||||
|
|
|
@ -182,7 +182,6 @@ static struct scsi_host_template pdc_sata_sht = {
|
||||||
.name = DRV_NAME,
|
.name = DRV_NAME,
|
||||||
.ioctl = ata_scsi_ioctl,
|
.ioctl = ata_scsi_ioctl,
|
||||||
.queuecommand = ata_scsi_queuecmd,
|
.queuecommand = ata_scsi_queuecmd,
|
||||||
.eh_timed_out = ata_scsi_timed_out,
|
|
||||||
.eh_strategy_handler = ata_scsi_error,
|
.eh_strategy_handler = ata_scsi_error,
|
||||||
.can_queue = ATA_DEF_QUEUE,
|
.can_queue = ATA_DEF_QUEUE,
|
||||||
.this_id = ATA_SHT_THIS_ID,
|
.this_id = ATA_SHT_THIS_ID,
|
||||||
|
|
|
@ -75,7 +75,6 @@ static struct scsi_host_template uli_sht = {
|
||||||
.name = DRV_NAME,
|
.name = DRV_NAME,
|
||||||
.ioctl = ata_scsi_ioctl,
|
.ioctl = ata_scsi_ioctl,
|
||||||
.queuecommand = ata_scsi_queuecmd,
|
.queuecommand = ata_scsi_queuecmd,
|
||||||
.eh_timed_out = ata_scsi_timed_out,
|
|
||||||
.eh_strategy_handler = ata_scsi_error,
|
.eh_strategy_handler = ata_scsi_error,
|
||||||
.can_queue = ATA_DEF_QUEUE,
|
.can_queue = ATA_DEF_QUEUE,
|
||||||
.this_id = ATA_SHT_THIS_ID,
|
.this_id = ATA_SHT_THIS_ID,
|
||||||
|
|
|
@ -94,7 +94,6 @@ static struct scsi_host_template svia_sht = {
|
||||||
.name = DRV_NAME,
|
.name = DRV_NAME,
|
||||||
.ioctl = ata_scsi_ioctl,
|
.ioctl = ata_scsi_ioctl,
|
||||||
.queuecommand = ata_scsi_queuecmd,
|
.queuecommand = ata_scsi_queuecmd,
|
||||||
.eh_timed_out = ata_scsi_timed_out,
|
|
||||||
.eh_strategy_handler = ata_scsi_error,
|
.eh_strategy_handler = ata_scsi_error,
|
||||||
.can_queue = ATA_DEF_QUEUE,
|
.can_queue = ATA_DEF_QUEUE,
|
||||||
.this_id = ATA_SHT_THIS_ID,
|
.this_id = ATA_SHT_THIS_ID,
|
||||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче