aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/message/fusion
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/message/fusion')
-rw-r--r--drivers/message/fusion/Kconfig1
-rw-r--r--drivers/message/fusion/Makefile1
-rw-r--r--drivers/message/fusion/lsi/mpi_log_sas.h105
-rw-r--r--drivers/message/fusion/mptbase.c205
-rw-r--r--drivers/message/fusion/mptbase.h36
-rw-r--r--drivers/message/fusion/mptctl.c8
-rw-r--r--drivers/message/fusion/mptfc.c39
-rw-r--r--drivers/message/fusion/mptlan.c5
-rw-r--r--drivers/message/fusion/mptsas.c818
-rw-r--r--drivers/message/fusion/mptscsih.c2486
-rw-r--r--drivers/message/fusion/mptscsih.h12
-rw-r--r--drivers/message/fusion/mptspi.c735
12 files changed, 1648 insertions, 2803 deletions
diff --git a/drivers/message/fusion/Kconfig b/drivers/message/fusion/Kconfig
index e67cf15e9c39..bbc229852881 100644
--- a/drivers/message/fusion/Kconfig
+++ b/drivers/message/fusion/Kconfig
@@ -9,6 +9,7 @@ config FUSION_SPI
9 tristate "Fusion MPT ScsiHost drivers for SPI" 9 tristate "Fusion MPT ScsiHost drivers for SPI"
10 depends on PCI && SCSI 10 depends on PCI && SCSI
11 select FUSION 11 select FUSION
12 select SCSI_SPI_ATTRS
12 ---help--- 13 ---help---
13 SCSI HOST support for a parallel SCSI host adapters. 14 SCSI HOST support for a parallel SCSI host adapters.
14 15
diff --git a/drivers/message/fusion/Makefile b/drivers/message/fusion/Makefile
index 33ace373241c..51740b346224 100644
--- a/drivers/message/fusion/Makefile
+++ b/drivers/message/fusion/Makefile
@@ -4,6 +4,7 @@
4#EXTRA_CFLAGS += -DMPT_DEBUG_MSG_FRAME 4#EXTRA_CFLAGS += -DMPT_DEBUG_MSG_FRAME
5#EXTRA_CFLAGS += -DMPT_DEBUG_SG 5#EXTRA_CFLAGS += -DMPT_DEBUG_SG
6#EXTRA_CFLAGS += -DMPT_DEBUG_EVENTS 6#EXTRA_CFLAGS += -DMPT_DEBUG_EVENTS
7#EXTRA_CFLAGS += -DMPT_DEBUG_VERBOSE_EVENTS
7#EXTRA_CFLAGS += -DMPT_DEBUG_INIT 8#EXTRA_CFLAGS += -DMPT_DEBUG_INIT
8#EXTRA_CFLAGS += -DMPT_DEBUG_EXIT 9#EXTRA_CFLAGS += -DMPT_DEBUG_EXIT
9#EXTRA_CFLAGS += -DMPT_DEBUG_FAIL 10#EXTRA_CFLAGS += -DMPT_DEBUG_FAIL
diff --git a/drivers/message/fusion/lsi/mpi_log_sas.h b/drivers/message/fusion/lsi/mpi_log_sas.h
index 9259d1ad6e6e..a9c14ad132ce 100644
--- a/drivers/message/fusion/lsi/mpi_log_sas.h
+++ b/drivers/message/fusion/lsi/mpi_log_sas.h
@@ -3,38 +3,11 @@
3 * * 3 * *
4 * Copyright 2003 LSI Logic Corporation. All rights reserved. * 4 * Copyright 2003 LSI Logic Corporation. All rights reserved. *
5 * * 5 * *
6 * This file is confidential and a trade secret of LSI Logic. The * 6 * Description *
7 * receipt of or possession of this file does not convey any rights to * 7 * ------------ *
8 * reproduce or disclose its contents or to manufacture, use, or sell * 8 * This include file contains SAS firmware interface IOC Log Info codes *
9 * anything it may describe, in whole, or in part, without the specific *
10 * written consent of LSI Logic Corporation. *
11 * * 9 * *
12 *************************************************************************** 10 *-------------------------------------------------------------------------*
13 *
14 * Name: iopiIocLogInfo.h
15 * Title: SAS Firmware IOP Interface IOC Log Info Definitions
16 * Programmer: Guy Kendall
17 * Creation Date: September 24, 2003
18 *
19 * Version History
20 * ---------------
21 *
22 * Last Updated
23 * -------------
24 * Version %version: 22 %
25 * Date Updated %date_modified: %
26 * Programmer %created_by: nperucca %
27 *
28 * Date Who Description
29 * -------- --- -------------------------------------------------------
30 * 09/24/03 GWK Initial version
31 *
32 *
33 * Description
34 * ------------
35 * This include file contains SAS firmware interface IOC Log Info codes
36 *
37 *-------------------------------------------------------------------------
38 */ 11 */
39 12
40#ifndef IOPI_IOCLOGINFO_H_INCLUDED 13#ifndef IOPI_IOCLOGINFO_H_INCLUDED
@@ -57,6 +30,8 @@
57#define IOC_LOGINFO_ORIGINATOR_PL (0x01000000) 30#define IOC_LOGINFO_ORIGINATOR_PL (0x01000000)
58#define IOC_LOGINFO_ORIGINATOR_IR (0x02000000) 31#define IOC_LOGINFO_ORIGINATOR_IR (0x02000000)
59 32
33#define IOC_LOGINFO_ORIGINATOR_MASK (0x0F000000)
34
60/****************************************************************************/ 35/****************************************************************************/
61/* LOGINFO_CODE defines */ 36/* LOGINFO_CODE defines */
62/****************************************************************************/ 37/****************************************************************************/
@@ -78,11 +53,27 @@
78#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_DEFAULT (0x00030700) /* Default Page not found */ 53#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_DEFAULT (0x00030700) /* Default Page not found */
79#define IOP_LOGINFO_CODE_TASK_TERMINATED (0x00050000) 54#define IOP_LOGINFO_CODE_TASK_TERMINATED (0x00050000)
80 55
56#define IOP_LOGINFO_CODE_ENCL_MGMT_READ_ACTION_ERR0R (0x00060001) /* Read Action not supported for SEP msg */
57#define IOP_LOGINFO_CODE_ENCL_MGMT_INVALID_BUS_ID_ERR0R (0x00060002) /* Invalid Bus/ID in SEP msg */
58
59#define IOP_LOGINFO_CODE_TARGET_ASSIST_TERMINATED (0x00070001)
60#define IOP_LOGINFO_CODE_TARGET_STATUS_SEND_TERMINATED (0x00070002)
61#define IOP_LOGINFO_CODE_TARGET_MODE_ABORT_ALL_IO (0x00070003)
62#define IOP_LOGINFO_CODE_TARGET_MODE_ABORT_EXACT_IO (0x00070004)
63#define IOP_LOGINFO_CODE_TARGET_MODE_ABORT_EXACT_IO_REQ (0x00070005)
81 64
82/****************************************************************************/ 65/****************************************************************************/
83/* PL LOGINFO_CODE defines, valid if IOC_LOGINFO_ORIGINATOR = PL */ 66/* PL LOGINFO_CODE defines, valid if IOC_LOGINFO_ORIGINATOR = PL */
84/****************************************************************************/ 67/****************************************************************************/
85#define PL_LOGINFO_CODE_OPEN_FAILURE (0x00010000) 68#define PL_LOGINFO_CODE_OPEN_FAILURE (0x00010000)
69#define PL_LOG_INFO_CODE_OPEN_FAILURE_NO_DEST_TIME_OUT (0x00010001)
70#define PL_LOGINFO_CODE_OPEN_FAILURE_BAD_DESTINATION (0x00010011)
71#define PL_LOGINFO_CODE_OPEN_FAILURE_PROTOCOL_NOT_SUPPORTED (0x00010013)
72#define PL_LOGINFO_CODE_OPEN_FAILURE_STP_RESOURCES_BSY (0x00010018)
73#define PL_LOGINFO_CODE_OPEN_FAILURE_WRONG_DESTINATION (0x00010019)
74#define PL_LOGINFO_CODE_OPEN_FAILURE_ORR_TIMEOUT (0X0001001A)
75#define PL_LOGINFO_CODE_OPEN_FAILURE_PATHWAY_BLOCKED (0x0001001B)
76#define PL_LOGINFO_CODE_OPEN_FAILURE_AWT_MAXED (0x0001001C)
86#define PL_LOGINFO_CODE_INVALID_SGL (0x00020000) 77#define PL_LOGINFO_CODE_INVALID_SGL (0x00020000)
87#define PL_LOGINFO_CODE_WRONG_REL_OFF_OR_FRAME_LENGTH (0x00030000) 78#define PL_LOGINFO_CODE_WRONG_REL_OFF_OR_FRAME_LENGTH (0x00030000)
88#define PL_LOGINFO_CODE_FRAME_XFER_ERROR (0x00040000) 79#define PL_LOGINFO_CODE_FRAME_XFER_ERROR (0x00040000)
@@ -97,6 +88,7 @@
97#define PL_LOGINFO_CODE_SATA_LINK_DOWN (0x000D0000) 88#define PL_LOGINFO_CODE_SATA_LINK_DOWN (0x000D0000)
98#define PL_LOGINFO_CODE_DISCOVERY_SATA_INIT_W_IOS (0x000E0000) 89#define PL_LOGINFO_CODE_DISCOVERY_SATA_INIT_W_IOS (0x000E0000)
99#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE (0x000F0000) 90#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE (0x000F0000)
91#define PL_LOGINFO_CODE_CONFIG_PL_NOT_INITIALIZED (0x000F0001) /* PL not yet initialized, can't do config page req. */
100#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_PT (0x000F0100) /* Invalid Page Type */ 92#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_PT (0x000F0100) /* Invalid Page Type */
101#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_NUM_PHYS (0x000F0200) /* Invalid Number of Phys */ 93#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_NUM_PHYS (0x000F0200) /* Invalid Number of Phys */
102#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_NOT_IMP (0x000F0300) /* Case Not Handled */ 94#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_NOT_IMP (0x000F0300) /* Case Not Handled */
@@ -105,11 +97,23 @@
105#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_PHY (0x000F0600) /* Invalid Phy */ 97#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_PHY (0x000F0600) /* Invalid Phy */
106#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_NO_OWNER (0x000F0700) /* No Owner Found */ 98#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_NO_OWNER (0x000F0700) /* No Owner Found */
107#define PL_LOGINFO_CODE_DSCVRY_SATA_INIT_TIMEOUT (0x00100000) 99#define PL_LOGINFO_CODE_DSCVRY_SATA_INIT_TIMEOUT (0x00100000)
108#define PL_LOGINFO_CODE_RESET (0x00110000) 100#define PL_LOGINFO_CODE_RESET (0x00110000) /* See Sub-Codes below */
109#define PL_LOGINFO_CODE_ABORT (0x00120000) 101#define PL_LOGINFO_CODE_ABORT (0x00120000) /* See Sub-Codes below */
110#define PL_LOGINFO_CODE_IO_NOT_YET_EXECUTED (0x00130000) 102#define PL_LOGINFO_CODE_IO_NOT_YET_EXECUTED (0x00130000)
111#define PL_LOGINFO_CODE_IO_EXECUTED (0x00140000) 103#define PL_LOGINFO_CODE_IO_EXECUTED (0x00140000)
104#define PL_LOGINFO_CODE_PERS_RESV_OUT_NOT_AFFIL_OWNER (0x00150000)
105#define PL_LOGINFO_CODE_OPEN_TXDMA_ABORT (0x00160000)
112#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE (0x00000100) 106#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE (0x00000100)
107#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_NO_DEST_TIMEOUT (0x00000101)
108#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_ORR_TIMEOUT (0x0000011A) /* Open Reject (Retry) Timeout */
109#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_PATHWAY_BLOCKED (0x0000011B)
110#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_AWT_MAXED (0x0000011C) /* Arbitration Wait Timer Maxed */
111
112#define PL_LOGINFO_SUB_CODE_TARGET_BUS_RESET (0x00000120)
113#define PL_LOGINFO_SUB_CODE_TRANSPORT_LAYER (0x00000130) /* Leave lower nibble (1-f) reserved. */
114#define PL_LOGINFO_SUB_CODE_PORT_LAYER (0x00000140) /* Leave lower nibble (1-f) reserved. */
115
116
113#define PL_LOGINFO_SUB_CODE_INVALID_SGL (0x00000200) 117#define PL_LOGINFO_SUB_CODE_INVALID_SGL (0x00000200)
114#define PL_LOGINFO_SUB_CODE_WRONG_REL_OFF_OR_FRAME_LENGTH (0x00000300) 118#define PL_LOGINFO_SUB_CODE_WRONG_REL_OFF_OR_FRAME_LENGTH (0x00000300)
115#define PL_LOGINFO_SUB_CODE_FRAME_XFER_ERROR (0x00000400) 119#define PL_LOGINFO_SUB_CODE_FRAME_XFER_ERROR (0x00000400)
@@ -123,26 +127,39 @@
123#define PL_LOGINFO_SUB_CODE_RX_FM_CURRENT_FRAME_ERROR (0x00000C00) 127#define PL_LOGINFO_SUB_CODE_RX_FM_CURRENT_FRAME_ERROR (0x00000C00)
124#define PL_LOGINFO_SUB_CODE_SATA_LINK_DOWN (0x00000D00) 128#define PL_LOGINFO_SUB_CODE_SATA_LINK_DOWN (0x00000D00)
125#define PL_LOGINFO_SUB_CODE_DISCOVERY_SATA_INIT_W_IOS (0x00000E00) 129#define PL_LOGINFO_SUB_CODE_DISCOVERY_SATA_INIT_W_IOS (0x00000E00)
130#define PL_LOGINFO_SUB_CODE_DISCOVERY_REMOTE_SEP_RESET (0x00000E01)
131#define PL_LOGINFO_SUB_CODE_SECOND_OPEN (0x00000F00)
126#define PL_LOGINFO_SUB_CODE_DSCVRY_SATA_INIT_TIMEOUT (0x00001000) 132#define PL_LOGINFO_SUB_CODE_DSCVRY_SATA_INIT_TIMEOUT (0x00001000)
127 133
128 134
129#define PL_LOGINFO_CODE_ENCL_MGMT_SMP_FRAME_FAILURE (0x00200000) /* Can't get SMP Frame */ 135#define PL_LOGINFO_CODE_ENCL_MGMT_SMP_FRAME_FAILURE (0x00200000) /* Can't get SMP Frame */
130#define PL_LOGINFO_CODE_ENCL_MGMT_SMP_READ_ERROR (0x00200001) /* Error occured on SMP Read */ 136#define PL_LOGINFO_CODE_ENCL_MGMT_SMP_READ_ERROR (0x00200010) /* Error occured on SMP Read */
131#define PL_LOGINFO_CODE_ENCL_MGMT_SMP_WRITE_ERROR (0x00200002) /* Error occured on SMP Write */ 137#define PL_LOGINFO_CODE_ENCL_MGMT_SMP_WRITE_ERROR (0x00200020) /* Error occured on SMP Write */
132#define PL_LOGINFO_CODE_ENCL_MGMT_NOT_SUPPORTED_ON_ENCL (0x00200004) /* Encl Mgmt services not available for this WWID */ 138#define PL_LOGINFO_CODE_ENCL_MGMT_NOT_SUPPORTED_ON_ENCL (0x00200040) /* Encl Mgmt services not available for this WWID */
133#define PL_LOGINFO_CODE_ENCL_MGMT_ADDR_MODE_NOT_SUPPORTED (0x00200005) /* Address Mode not suppored */ 139#define PL_LOGINFO_CODE_ENCL_MGMT_ADDR_MODE_NOT_SUPPORTED (0x00200050) /* Address Mode not suppored */
134#define PL_LOGINFO_CODE_ENCL_MGMT_BAD_SLOT_NUM (0x00200006) /* Invalid Slot Number in SEP Msg */ 140#define PL_LOGINFO_CODE_ENCL_MGMT_BAD_SLOT_NUM (0x00200060) /* Invalid Slot Number in SEP Msg */
135#define PL_LOGINFO_CODE_ENCL_MGMT_SGPIO_NOT_PRESENT (0x00200007) /* SGPIO not present/enabled */ 141#define PL_LOGINFO_CODE_ENCL_MGMT_SGPIO_NOT_PRESENT (0x00200070) /* SGPIO not present/enabled */
142#define PL_LOGINFO_CODE_ENCL_MGMT_GPIO_NOT_CONFIGURED (0x00200080) /* GPIO not configured */
143#define PL_LOGINFO_CODE_ENCL_MGMT_GPIO_FRAME_ERROR (0x00200090) /* GPIO can't allocate a frame */
144#define PL_LOGINFO_CODE_ENCL_MGMT_GPIO_CONFIG_PAGE_ERROR (0x002000A0) /* GPIO failed config page request */
145#define PL_LOGINFO_CODE_ENCL_MGMT_SES_FRAME_ALLOC_ERROR (0x002000B0) /* Can't get frame for SES command */
146#define PL_LOGINFO_CODE_ENCL_MGMT_SES_IO_ERROR (0x002000C0) /* I/O execution error */
147#define PL_LOGINFO_CODE_ENCL_MGMT_SES_RETRIES_EXHAUSTED (0x002000D0) /* SEP I/O retries exhausted */
148#define PL_LOGINFO_CODE_ENCL_MGMT_SMP_FRAME_ALLOC_ERROR (0x002000E0) /* Can't get frame for SMP command */
136 149
137#define PL_LOGINFO_DA_SEP_NOT_PRESENT (0x00200100) /* SEP not present when msg received */ 150#define PL_LOGINFO_DA_SEP_NOT_PRESENT (0x00200100) /* SEP not present when msg received */
138#define PL_LOGINFO_DA_SEP_SINGLE_THREAD_ERROR (0x00200101) /* Can only accept 1 msg at a time */ 151#define PL_LOGINFO_DA_SEP_SINGLE_THREAD_ERROR (0x00200101) /* Can only accept 1 msg at a time */
139#define PL_LOGINFO_DA_SEP_ISTWI_INTR_IN_IDLE_STATE (0x00200102) /* ISTWI interrupt recvd. while IDLE */ 152#define PL_LOGINFO_DA_SEP_ISTWI_INTR_IN_IDLE_STATE (0x00200102) /* ISTWI interrupt recvd. while IDLE */
140#define PL_LOGINFO_DA_SEP_RECEIVED_NACK_FROM_SLAVE (0x00200103) /* SEP NACK'd, it is busy */ 153#define PL_LOGINFO_DA_SEP_RECEIVED_NACK_FROM_SLAVE (0x00200103) /* SEP NACK'd, it is busy */
141#define PL_LOGINFO_DA_SEP_BAD_STATUS_HDR_CHKSUM (0x00200104) /* SEP stopped or sent bad chksum in Hdr */ 154#define PL_LOGINFO_DA_SEP_DID_NOT_RECEIVE_ACK (0x00200104) /* SEP didn't rcv. ACK (Last Rcvd Bit = 1) */
142#define PL_LOGINFO_DA_SEP_UNSUPPORTED_SCSI_STATUS_1 (0x00200105) /* SEP returned unknown scsi status */ 155#define PL_LOGINFO_DA_SEP_BAD_STATUS_HDR_CHKSUM (0x00200105) /* SEP stopped or sent bad chksum in Hdr */
143#define PL_LOGINFO_DA_SEP_UNSUPPORTED_SCSI_STATUS_2 (0x00200106) /* SEP returned unknown scsi status */ 156#define PL_LOGINFO_DA_SEP_STOP_ON_DATA (0x00200106) /* SEP stopped while transfering data */
144#define PL_LOGINFO_DA_SEP_CHKSUM_ERROR_AFTER_STOP (0x00200107) /* SEP returned bad chksum after STOP */ 157#define PL_LOGINFO_DA_SEP_STOP_ON_SENSE_DATA (0x00200107) /* SEP stopped while transfering sense data */
145#define PL_LOGINFO_DA_SEP_CHKSUM_ERROR_AFTER_STOP_GETDATA (0x00200108) /* SEP returned bad chksum after STOP while gettin data*/ 158#define PL_LOGINFO_DA_SEP_UNSUPPORTED_SCSI_STATUS_1 (0x00200108) /* SEP returned unknown scsi status */
159#define PL_LOGINFO_DA_SEP_UNSUPPORTED_SCSI_STATUS_2 (0x00200109) /* SEP returned unknown scsi status */
160#define PL_LOGINFO_DA_SEP_CHKSUM_ERROR_AFTER_STOP (0x0020010A) /* SEP returned bad chksum after STOP */
161#define PL_LOGINFO_DA_SEP_CHKSUM_ERROR_AFTER_STOP_GETDATA (0x0020010B) /* SEP returned bad chksum after STOP while gettin data*/
162#define PL_LOGINFO_DA_SEP_UNSUPPORTED_COMMAND (0x0020010C) /* SEP doesn't support CDB opcode */
146 163
147 164
148/****************************************************************************/ 165/****************************************************************************/
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index 642a61b6d0a4..266414ca2814 100644
--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -180,6 +180,7 @@ static void mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
180static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info); 180static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info);
181static void mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info); 181static void mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info);
182static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info); 182static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info);
183static int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc);
183 184
184/* module entry point */ 185/* module entry point */
185static int __init fusion_init (void); 186static int __init fusion_init (void);
@@ -428,7 +429,7 @@ mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
428 results = ProcessEventNotification(ioc, pEvReply, &evHandlers); 429 results = ProcessEventNotification(ioc, pEvReply, &evHandlers);
429 if (results != evHandlers) { 430 if (results != evHandlers) {
430 /* CHECKME! Any special handling needed here? */ 431 /* CHECKME! Any special handling needed here? */
431 devtprintk((MYIOC_s_WARN_FMT "Called %d event handlers, sum results = %d\n", 432 devtverboseprintk((MYIOC_s_WARN_FMT "Called %d event handlers, sum results = %d\n",
432 ioc->name, evHandlers, results)); 433 ioc->name, evHandlers, results));
433 } 434 }
434 435
@@ -438,10 +439,10 @@ mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
438 */ 439 */
439 if (pEvReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY) { 440 if (pEvReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY) {
440 freereq = 0; 441 freereq = 0;
441 devtprintk((MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p does not return Request frame\n", 442 devtverboseprintk((MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p does not return Request frame\n",
442 ioc->name, pEvReply)); 443 ioc->name, pEvReply));
443 } else { 444 } else {
444 devtprintk((MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p returns Request frame\n", 445 devtverboseprintk((MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p returns Request frame\n",
445 ioc->name, pEvReply)); 446 ioc->name, pEvReply));
446 } 447 }
447 448
@@ -1120,65 +1121,6 @@ mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
1120 return -1; 1121 return -1;
1121} 1122}
1122 1123
1123int
1124mpt_alt_ioc_wait(MPT_ADAPTER *ioc)
1125{
1126 int loop_count = 30 * 4; /* Wait 30 seconds */
1127 int status = -1; /* -1 means failed to get board READY */
1128
1129 do {
1130 spin_lock(&ioc->initializing_hba_lock);
1131 if (ioc->initializing_hba_lock_flag == 0) {
1132 ioc->initializing_hba_lock_flag=1;
1133 spin_unlock(&ioc->initializing_hba_lock);
1134 status = 0;
1135 break;
1136 }
1137 spin_unlock(&ioc->initializing_hba_lock);
1138 set_current_state(TASK_INTERRUPTIBLE);
1139 schedule_timeout(HZ/4);
1140 } while (--loop_count);
1141
1142 return status;
1143}
1144
1145/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1146/*
1147 * mpt_bringup_adapter - This is a wrapper function for mpt_do_ioc_recovery
1148 * @ioc: Pointer to MPT adapter structure
1149 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1150 *
1151 * This routine performs all the steps necessary to bring the IOC
1152 * to a OPERATIONAL state.
1153 *
1154 * Special Note: This function was added with spin lock's so as to allow
1155 * the dv(domain validation) work thread to succeed on the other channel
1156 * that maybe occuring at the same time when this function is called.
1157 * Without this lock, the dv would fail when message frames were
1158 * requested during hba bringup on the alternate ioc.
1159 */
1160static int
1161mpt_bringup_adapter(MPT_ADAPTER *ioc, int sleepFlag)
1162{
1163 int r;
1164
1165 if(ioc->alt_ioc) {
1166 if((r=mpt_alt_ioc_wait(ioc->alt_ioc)!=0))
1167 return r;
1168 }
1169
1170 r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
1171 CAN_SLEEP);
1172
1173 if(ioc->alt_ioc) {
1174 spin_lock(&ioc->alt_ioc->initializing_hba_lock);
1175 ioc->alt_ioc->initializing_hba_lock_flag=0;
1176 spin_unlock(&ioc->alt_ioc->initializing_hba_lock);
1177 }
1178
1179return r;
1180}
1181
1182/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1124/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1183/* 1125/*
1184 * mpt_attach - Install a PCI intelligent MPT adapter. 1126 * mpt_attach - Install a PCI intelligent MPT adapter.
@@ -1482,7 +1424,8 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1482 */ 1424 */
1483 mpt_detect_bound_ports(ioc, pdev); 1425 mpt_detect_bound_ports(ioc, pdev);
1484 1426
1485 if ((r = mpt_bringup_adapter(ioc, CAN_SLEEP)) != 0){ 1427 if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
1428 CAN_SLEEP)) != 0){
1486 printk(KERN_WARNING MYNAM 1429 printk(KERN_WARNING MYNAM
1487 ": WARNING - %s did not initialize properly! (%d)\n", 1430 ": WARNING - %s did not initialize properly! (%d)\n",
1488 ioc->name, r); 1431 ioc->name, r);
@@ -1629,7 +1572,6 @@ mpt_resume(struct pci_dev *pdev)
1629 MPT_ADAPTER *ioc = pci_get_drvdata(pdev); 1572 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1630 u32 device_state = pdev->current_state; 1573 u32 device_state = pdev->current_state;
1631 int recovery_state; 1574 int recovery_state;
1632 int ii;
1633 1575
1634 printk(MYIOC_s_INFO_FMT 1576 printk(MYIOC_s_INFO_FMT
1635 "pci-resume: pdev=0x%p, slot=%s, Previous operating state [D%d]\n", 1577 "pci-resume: pdev=0x%p, slot=%s, Previous operating state [D%d]\n",
@@ -1643,14 +1585,6 @@ mpt_resume(struct pci_dev *pdev)
1643 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM); 1585 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
1644 ioc->active = 1; 1586 ioc->active = 1;
1645 1587
1646 /* F/W not running */
1647 if(!CHIPREG_READ32(&ioc->chip->Doorbell)) {
1648 /* enable domain validation flags */
1649 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
1650 ioc->spi_data.dvStatus[ii] |= MPT_SCSICFG_NEED_DV;
1651 }
1652 }
1653
1654 printk(MYIOC_s_INFO_FMT 1588 printk(MYIOC_s_INFO_FMT
1655 "pci-resume: ioc-state=0x%x,doorbell=0x%x\n", 1589 "pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
1656 ioc->name, 1590 ioc->name,
@@ -4938,7 +4872,7 @@ done_and_free:
4938 return rc; 4872 return rc;
4939} 4873}
4940 4874
4941int 4875static int
4942mpt_read_ioc_pg_3(MPT_ADAPTER *ioc) 4876mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
4943{ 4877{
4944 IOCPage3_t *pIoc3; 4878 IOCPage3_t *pIoc3;
@@ -5146,13 +5080,13 @@ SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch)
5146 5080
5147 evnp = (EventNotification_t *) mpt_get_msg_frame(mpt_base_index, ioc); 5081 evnp = (EventNotification_t *) mpt_get_msg_frame(mpt_base_index, ioc);
5148 if (evnp == NULL) { 5082 if (evnp == NULL) {
5149 devtprintk((MYIOC_s_WARN_FMT "Unable to allocate event request frame!\n", 5083 devtverboseprintk((MYIOC_s_WARN_FMT "Unable to allocate event request frame!\n",
5150 ioc->name)); 5084 ioc->name));
5151 return 0; 5085 return 0;
5152 } 5086 }
5153 memset(evnp, 0, sizeof(*evnp)); 5087 memset(evnp, 0, sizeof(*evnp));
5154 5088
5155 devtprintk((MYIOC_s_INFO_FMT "Sending EventNotification (%d) request %p\n", ioc->name, EvSwitch, evnp)); 5089 devtverboseprintk((MYIOC_s_INFO_FMT "Sending EventNotification (%d) request %p\n", ioc->name, EvSwitch, evnp));
5156 5090
5157 evnp->Function = MPI_FUNCTION_EVENT_NOTIFICATION; 5091 evnp->Function = MPI_FUNCTION_EVENT_NOTIFICATION;
5158 evnp->ChainOffset = 0; 5092 evnp->ChainOffset = 0;
@@ -5907,24 +5841,27 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr)
5907 break; 5841 break;
5908 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE: 5842 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
5909 { 5843 {
5844 char buf[50];
5845 u8 id = (u8)(evData0);
5910 u8 ReasonCode = (u8)(evData0 >> 16); 5846 u8 ReasonCode = (u8)(evData0 >> 16);
5911 switch (ReasonCode) { 5847 switch (ReasonCode) {
5912 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED: 5848 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
5913 ds = "SAS Device Status Change: Added"; 5849 sprintf(buf,"SAS Device Status Change: Added: id=%d", id);
5914 break; 5850 break;
5915 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING: 5851 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
5916 ds = "SAS Device Status Change: Deleted"; 5852 sprintf(buf,"SAS Device Status Change: Deleted: id=%d", id);
5917 break; 5853 break;
5918 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA: 5854 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
5919 ds = "SAS Device Status Change: SMART Data"; 5855 sprintf(buf,"SAS Device Status Change: SMART Data: id=%d", id);
5920 break; 5856 break;
5921 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED: 5857 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
5922 ds = "SAS Device Status Change: No Persistancy Added"; 5858 sprintf(buf,"SAS Device Status Change: No Persistancy Added: id=%d", id);
5923 break; 5859 break;
5924 default: 5860 default:
5925 ds = "SAS Device Status Change: Unknown"; 5861 sprintf(buf,"SAS Device Status Change: Unknown: id=%d", id);
5926 break; 5862 break;
5927 } 5863 }
5864 ds = buf;
5928 break; 5865 break;
5929 } 5866 }
5930 case MPI_EVENT_ON_BUS_TIMER_EXPIRED: 5867 case MPI_EVENT_ON_BUS_TIMER_EXPIRED:
@@ -5940,11 +5877,97 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr)
5940 ds = "Persistent Table Full"; 5877 ds = "Persistent Table Full";
5941 break; 5878 break;
5942 case MPI_EVENT_SAS_PHY_LINK_STATUS: 5879 case MPI_EVENT_SAS_PHY_LINK_STATUS:
5943 ds = "SAS PHY Link Status"; 5880 {
5881 char buf[50];
5882 u8 LinkRates = (u8)(evData0 >> 8);
5883 u8 PhyNumber = (u8)(evData0);
5884 LinkRates = (LinkRates & MPI_EVENT_SAS_PLS_LR_CURRENT_MASK) >>
5885 MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT;
5886 switch (LinkRates) {
5887 case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN:
5888 sprintf(buf,"SAS PHY Link Status: Phy=%d:"
5889 " Rate Unknown",PhyNumber);
5890 break;
5891 case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED:
5892 sprintf(buf,"SAS PHY Link Status: Phy=%d:"
5893 " Phy Disabled",PhyNumber);
5894 break;
5895 case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION:
5896 sprintf(buf,"SAS PHY Link Status: Phy=%d:"
5897 " Failed Speed Nego",PhyNumber);
5898 break;
5899 case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE:
5900 sprintf(buf,"SAS PHY Link Status: Phy=%d:"
5901 " Sata OOB Completed",PhyNumber);
5902 break;
5903 case MPI_EVENT_SAS_PLS_LR_RATE_1_5:
5904 sprintf(buf,"SAS PHY Link Status: Phy=%d:"
5905 " Rate 1.5 Gbps",PhyNumber);
5906 break;
5907 case MPI_EVENT_SAS_PLS_LR_RATE_3_0:
5908 sprintf(buf,"SAS PHY Link Status: Phy=%d:"
5909 " Rate 3.0 Gpbs",PhyNumber);
5910 break;
5911 default:
5912 sprintf(buf,"SAS PHY Link Status: Phy=%d", PhyNumber);
5913 break;
5914 }
5915 ds = buf;
5944 break; 5916 break;
5917 }
5945 case MPI_EVENT_SAS_DISCOVERY_ERROR: 5918 case MPI_EVENT_SAS_DISCOVERY_ERROR:
5946 ds = "SAS Discovery Error"; 5919 ds = "SAS Discovery Error";
5947 break; 5920 break;
5921 case MPI_EVENT_IR_RESYNC_UPDATE:
5922 {
5923 u8 resync_complete = (u8)(evData0 >> 16);
5924 char buf[40];
5925 sprintf(buf,"IR Resync Update: Complete = %d:",resync_complete);
5926 ds = buf;
5927 break;
5928 }
5929 case MPI_EVENT_IR2:
5930 {
5931 u8 ReasonCode = (u8)(evData0 >> 16);
5932 switch (ReasonCode) {
5933 case MPI_EVENT_IR2_RC_LD_STATE_CHANGED:
5934 ds = "IR2: LD State Changed";
5935 break;
5936 case MPI_EVENT_IR2_RC_PD_STATE_CHANGED:
5937 ds = "IR2: PD State Changed";
5938 break;
5939 case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL:
5940 ds = "IR2: Bad Block Table Full";
5941 break;
5942 case MPI_EVENT_IR2_RC_PD_INSERTED:
5943 ds = "IR2: PD Inserted";
5944 break;
5945 case MPI_EVENT_IR2_RC_PD_REMOVED:
5946 ds = "IR2: PD Removed";
5947 break;
5948 case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED:
5949 ds = "IR2: Foreign CFG Detected";
5950 break;
5951 case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR:
5952 ds = "IR2: Rebuild Medium Error";
5953 break;
5954 default:
5955 ds = "IR2";
5956 break;
5957 }
5958 break;
5959 }
5960 case MPI_EVENT_SAS_DISCOVERY:
5961 {
5962 if (evData0)
5963 ds = "SAS Discovery: Start";
5964 else
5965 ds = "SAS Discovery: Stop";
5966 break;
5967 }
5968 case MPI_EVENT_LOG_ENTRY_ADDED:
5969 ds = "SAS Log Entry Added";
5970 break;
5948 5971
5949 /* 5972 /*
5950 * MPT base "custom" events may be added here... 5973 * MPT base "custom" events may be added here...
@@ -5989,12 +6012,12 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply
5989 } 6012 }
5990 6013
5991 EventDescriptionStr(event, evData0, evStr); 6014 EventDescriptionStr(event, evData0, evStr);
5992 devtprintk((MYIOC_s_INFO_FMT "MPT event (%s=%02Xh) detected!\n", 6015 devtprintk((MYIOC_s_INFO_FMT "MPT event:(%02Xh) : %s\n",
5993 ioc->name, 6016 ioc->name,
5994 evStr, 6017 event,
5995 event)); 6018 evStr));
5996 6019
5997#if defined(MPT_DEBUG) || defined(MPT_DEBUG_EVENTS) 6020#if defined(MPT_DEBUG) || defined(MPT_DEBUG_VERBOSE_EVENTS)
5998 printk(KERN_INFO MYNAM ": Event data:\n" KERN_INFO); 6021 printk(KERN_INFO MYNAM ": Event data:\n" KERN_INFO);
5999 for (ii = 0; ii < evDataLen; ii++) 6022 for (ii = 0; ii < evDataLen; ii++)
6000 printk(" %08x", le32_to_cpu(pEventReply->Data[ii])); 6023 printk(" %08x", le32_to_cpu(pEventReply->Data[ii]));
@@ -6053,7 +6076,7 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply
6053 */ 6076 */
6054 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) { 6077 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
6055 if (MptEvHandlers[ii]) { 6078 if (MptEvHandlers[ii]) {
6056 devtprintk((MYIOC_s_INFO_FMT "Routing Event to event handler #%d\n", 6079 devtverboseprintk((MYIOC_s_INFO_FMT "Routing Event to event handler #%d\n",
6057 ioc->name, ii)); 6080 ioc->name, ii));
6058 r += (*(MptEvHandlers[ii]))(ioc, pEventReply); 6081 r += (*(MptEvHandlers[ii]))(ioc, pEventReply);
6059 handlers++; 6082 handlers++;
@@ -6065,10 +6088,10 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply
6065 * If needed, send (a single) EventAck. 6088 * If needed, send (a single) EventAck.
6066 */ 6089 */
6067 if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) { 6090 if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) {
6068 devtprintk((MYIOC_s_WARN_FMT 6091 devtverboseprintk((MYIOC_s_WARN_FMT
6069 "EventAck required\n",ioc->name)); 6092 "EventAck required\n",ioc->name));
6070 if ((ii = SendEventAck(ioc, pEventReply)) != 0) { 6093 if ((ii = SendEventAck(ioc, pEventReply)) != 0) {
6071 devtprintk((MYIOC_s_WARN_FMT "SendEventAck returned %d\n", 6094 devtverboseprintk((MYIOC_s_WARN_FMT "SendEventAck returned %d\n",
6072 ioc->name, ii)); 6095 ioc->name, ii));
6073 } 6096 }
6074 } 6097 }
@@ -6205,8 +6228,8 @@ mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
6205 "Abort", /* 12h */ 6228 "Abort", /* 12h */
6206 "IO Not Yet Executed", /* 13h */ 6229 "IO Not Yet Executed", /* 13h */
6207 "IO Executed", /* 14h */ 6230 "IO Executed", /* 14h */
6208 NULL, /* 15h */ 6231 "Persistant Reservation Out Not Affiliation Owner", /* 15h */
6209 NULL, /* 16h */ 6232 "Open Transmit DMA Abort", /* 16h */
6210 NULL, /* 17h */ 6233 NULL, /* 17h */
6211 NULL, /* 18h */ 6234 NULL, /* 18h */
6212 NULL, /* 19h */ 6235 NULL, /* 19h */
@@ -6431,11 +6454,9 @@ EXPORT_SYMBOL(mpt_stm_index);
6431EXPORT_SYMBOL(mpt_HardResetHandler); 6454EXPORT_SYMBOL(mpt_HardResetHandler);
6432EXPORT_SYMBOL(mpt_config); 6455EXPORT_SYMBOL(mpt_config);
6433EXPORT_SYMBOL(mpt_findImVolumes); 6456EXPORT_SYMBOL(mpt_findImVolumes);
6434EXPORT_SYMBOL(mpt_read_ioc_pg_3);
6435EXPORT_SYMBOL(mpt_alloc_fw_memory); 6457EXPORT_SYMBOL(mpt_alloc_fw_memory);
6436EXPORT_SYMBOL(mpt_free_fw_memory); 6458EXPORT_SYMBOL(mpt_free_fw_memory);
6437EXPORT_SYMBOL(mptbase_sas_persist_operation); 6459EXPORT_SYMBOL(mptbase_sas_persist_operation);
6438EXPORT_SYMBOL(mpt_alt_ioc_wait);
6439EXPORT_SYMBOL(mptbase_GetFcPortPage0); 6460EXPORT_SYMBOL(mptbase_GetFcPortPage0);
6440 6461
6441 6462
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h
index 723d54300953..be7e8501b53c 100644
--- a/drivers/message/fusion/mptbase.h
+++ b/drivers/message/fusion/mptbase.h
@@ -76,8 +76,8 @@
76#define COPYRIGHT "Copyright (c) 1999-2005 " MODULEAUTHOR 76#define COPYRIGHT "Copyright (c) 1999-2005 " MODULEAUTHOR
77#endif 77#endif
78 78
79#define MPT_LINUX_VERSION_COMMON "3.03.07" 79#define MPT_LINUX_VERSION_COMMON "3.03.08"
80#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.03.07" 80#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.03.08"
81#define WHAT_MAGIC_STRING "@" "(" "#" ")" 81#define WHAT_MAGIC_STRING "@" "(" "#" ")"
82 82
83#define show_mptmod_ver(s,ver) \ 83#define show_mptmod_ver(s,ver) \
@@ -331,6 +331,7 @@ typedef struct _SYSIF_REGS
331 * VirtDevice - FC LUN device or SCSI target device 331 * VirtDevice - FC LUN device or SCSI target device
332 */ 332 */
333typedef struct _VirtTarget { 333typedef struct _VirtTarget {
334 struct scsi_target *starget;
334 u8 tflags; 335 u8 tflags;
335 u8 ioc_id; 336 u8 ioc_id;
336 u8 target_id; 337 u8 target_id;
@@ -343,14 +344,10 @@ typedef struct _VirtTarget {
343 u8 type; /* byte 0 of Inquiry data */ 344 u8 type; /* byte 0 of Inquiry data */
344 u32 num_luns; 345 u32 num_luns;
345 u32 luns[8]; /* Max LUNs is 256 */ 346 u32 luns[8]; /* Max LUNs is 256 */
346 u8 inq_data[8];
347} VirtTarget; 347} VirtTarget;
348 348
349typedef struct _VirtDevice { 349typedef struct _VirtDevice {
350 VirtTarget *vtarget; 350 VirtTarget *vtarget;
351 u8 ioc_id;
352 u8 bus_id;
353 u8 target_id;
354 u8 configured_lun; 351 u8 configured_lun;
355 u32 lun; 352 u32 lun;
356} VirtDevice; 353} VirtDevice;
@@ -364,6 +361,7 @@ typedef struct _VirtDevice {
364#define MPT_TARGET_FLAGS_Q_YES 0x08 361#define MPT_TARGET_FLAGS_Q_YES 0x08
365#define MPT_TARGET_FLAGS_VALID_56 0x10 362#define MPT_TARGET_FLAGS_VALID_56 0x10
366#define MPT_TARGET_FLAGS_SAF_TE_ISSUED 0x20 363#define MPT_TARGET_FLAGS_SAF_TE_ISSUED 0x20
364#define MPT_TARGET_FLAGS_RAID_COMPONENT 0x40
367 365
368/* 366/*
369 * /proc/mpt interface 367 * /proc/mpt interface
@@ -447,13 +445,6 @@ typedef struct _mpt_ioctl_events {
447 * Substructure to store SCSI specific configuration page data 445 * Substructure to store SCSI specific configuration page data
448 */ 446 */
449 /* dvStatus defines: */ 447 /* dvStatus defines: */
450#define MPT_SCSICFG_NEGOTIATE 0x01 /* Negotiate on next IO */
451#define MPT_SCSICFG_NEED_DV 0x02 /* Schedule DV */
452#define MPT_SCSICFG_DV_PENDING 0x04 /* DV on this physical id pending */
453#define MPT_SCSICFG_DV_NOT_DONE 0x08 /* DV has not been performed */
454#define MPT_SCSICFG_BLK_NEGO 0x10 /* WriteSDP1 with WDTR and SDTR disabled */
455#define MPT_SCSICFG_RELOAD_IOC_PG3 0x20 /* IOC Pg 3 data is obsolete */
456 /* Args passed to writeSDP1: */
457#define MPT_SCSICFG_USE_NVRAM 0x01 /* WriteSDP1 using NVRAM */ 448#define MPT_SCSICFG_USE_NVRAM 0x01 /* WriteSDP1 using NVRAM */
458#define MPT_SCSICFG_ALL_IDS 0x02 /* WriteSDP1 to all IDS */ 449#define MPT_SCSICFG_ALL_IDS 0x02 /* WriteSDP1 to all IDS */
459/* #define MPT_SCSICFG_BLK_NEGO 0x10 WriteSDP1 with WDTR and SDTR disabled */ 450/* #define MPT_SCSICFG_BLK_NEGO 0x10 WriteSDP1 with WDTR and SDTR disabled */
@@ -464,7 +455,6 @@ typedef struct _SpiCfgData {
464 IOCPage4_t *pIocPg4; /* SEP devices addressing */ 455 IOCPage4_t *pIocPg4; /* SEP devices addressing */
465 dma_addr_t IocPg4_dma; /* Phys Addr of IOCPage4 data */ 456 dma_addr_t IocPg4_dma; /* Phys Addr of IOCPage4 data */
466 int IocPg4Sz; /* IOCPage4 size */ 457 int IocPg4Sz; /* IOCPage4 size */
467 u8 dvStatus[MPT_MAX_SCSI_DEVICES];
468 u8 minSyncFactor; /* 0xFF if async */ 458 u8 minSyncFactor; /* 0xFF if async */
469 u8 maxSyncOffset; /* 0 if async */ 459 u8 maxSyncOffset; /* 0 if async */
470 u8 maxBusWidth; /* 0 if narrow, 1 if wide */ 460 u8 maxBusWidth; /* 0 if narrow, 1 if wide */
@@ -474,13 +464,11 @@ typedef struct _SpiCfgData {
474 u8 sdp0version; /* SDP0 version */ 464 u8 sdp0version; /* SDP0 version */
475 u8 sdp0length; /* SDP0 length */ 465 u8 sdp0length; /* SDP0 length */
476 u8 dvScheduled; /* 1 if scheduled */ 466 u8 dvScheduled; /* 1 if scheduled */
477 u8 forceDv; /* 1 to force DV scheduling */
478 u8 noQas; /* Disable QAS for this adapter */ 467 u8 noQas; /* Disable QAS for this adapter */
479 u8 Saf_Te; /* 1 to force all Processors as 468 u8 Saf_Te; /* 1 to force all Processors as
480 * SAF-TE if Inquiry data length 469 * SAF-TE if Inquiry data length
481 * is too short to check for SAF-TE 470 * is too short to check for SAF-TE
482 */ 471 */
483 u8 mpt_dv; /* command line option: enhanced=1, basic=0 */
484 u8 bus_reset; /* 1 to allow bus reset */ 472 u8 bus_reset; /* 1 to allow bus reset */
485 u8 rsvd[1]; 473 u8 rsvd[1];
486}SpiCfgData; 474}SpiCfgData;
@@ -631,6 +619,10 @@ typedef struct _MPT_ADAPTER
631 struct net_device *netdev; 619 struct net_device *netdev;
632 struct list_head sas_topology; 620 struct list_head sas_topology;
633 struct mutex sas_topology_mutex; 621 struct mutex sas_topology_mutex;
622 struct mutex sas_discovery_mutex;
623 u8 sas_discovery_runtime;
624 u8 sas_discovery_ignore_events;
625 int sas_index; /* index refrencing */
634 MPT_SAS_MGMT sas_mgmt; 626 MPT_SAS_MGMT sas_mgmt;
635 int num_ports; 627 int num_ports;
636 struct work_struct mptscsih_persistTask; 628 struct work_struct mptscsih_persistTask;
@@ -728,12 +720,18 @@ typedef struct _mpt_sge {
728#define dhsprintk(x) 720#define dhsprintk(x)
729#endif 721#endif
730 722
731#ifdef MPT_DEBUG_EVENTS 723#if defined(MPT_DEBUG_EVENTS) || defined(MPT_DEBUG_VERBOSE_EVENTS)
732#define devtprintk(x) printk x 724#define devtprintk(x) printk x
733#else 725#else
734#define devtprintk(x) 726#define devtprintk(x)
735#endif 727#endif
736 728
729#ifdef MPT_DEBUG_VERBOSE_EVENTS
730#define devtverboseprintk(x) printk x
731#else
732#define devtverboseprintk(x)
733#endif
734
737#ifdef MPT_DEBUG_RESET 735#ifdef MPT_DEBUG_RESET
738#define drsprintk(x) printk x 736#define drsprintk(x) printk x
739#else 737#else
@@ -1030,10 +1028,8 @@ extern int mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *cfg);
1030extern void mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size); 1028extern void mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size);
1031extern void mpt_free_fw_memory(MPT_ADAPTER *ioc); 1029extern void mpt_free_fw_memory(MPT_ADAPTER *ioc);
1032extern int mpt_findImVolumes(MPT_ADAPTER *ioc); 1030extern int mpt_findImVolumes(MPT_ADAPTER *ioc);
1033extern int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc);
1034extern int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode); 1031extern int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
1035extern int mptbase_GetFcPortPage0(MPT_ADAPTER *ioc, int portnum); 1032extern int mptbase_GetFcPortPage0(MPT_ADAPTER *ioc, int portnum);
1036extern int mpt_alt_ioc_wait(MPT_ADAPTER *ioc);
1037 1033
1038/* 1034/*
1039 * Public data decl's... 1035 * Public data decl's...
diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c
index 9b64e07400da..b4967bb8a7d6 100644
--- a/drivers/message/fusion/mptctl.c
+++ b/drivers/message/fusion/mptctl.c
@@ -140,7 +140,7 @@ static int mptctl_ioc_reset(MPT_ADAPTER *ioc, int reset_phase);
140 * Event Handler function 140 * Event Handler function
141 */ 141 */
142static int mptctl_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply); 142static int mptctl_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
143struct fasync_struct *async_queue=NULL; 143static struct fasync_struct *async_queue=NULL;
144 144
145/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 145/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
146/* 146/*
@@ -497,7 +497,7 @@ mptctl_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
497 if (event == 0x21 ) { 497 if (event == 0x21 ) {
498 ioc->aen_event_read_flag=1; 498 ioc->aen_event_read_flag=1;
499 dctlprintk(("Raised SIGIO to application\n")); 499 dctlprintk(("Raised SIGIO to application\n"));
500 devtprintk(("Raised SIGIO to application\n")); 500 devtverboseprintk(("Raised SIGIO to application\n"));
501 kill_fasync(&async_queue, SIGIO, POLL_IN); 501 kill_fasync(&async_queue, SIGIO, POLL_IN);
502 return 1; 502 return 1;
503 } 503 }
@@ -515,7 +515,7 @@ mptctl_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
515 if (ioc->events && (ioc->eventTypes & ( 1 << event))) { 515 if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
516 ioc->aen_event_read_flag=1; 516 ioc->aen_event_read_flag=1;
517 dctlprintk(("Raised SIGIO to application\n")); 517 dctlprintk(("Raised SIGIO to application\n"));
518 devtprintk(("Raised SIGIO to application\n")); 518 devtverboseprintk(("Raised SIGIO to application\n"));
519 kill_fasync(&async_queue, SIGIO, POLL_IN); 519 kill_fasync(&async_queue, SIGIO, POLL_IN);
520 } 520 }
521 return 1; 521 return 1;
@@ -2968,7 +2968,7 @@ static int __init mptctl_init(void)
2968 } 2968 }
2969 2969
2970 if (mpt_event_register(mptctl_id, mptctl_event_process) == 0) { 2970 if (mpt_event_register(mptctl_id, mptctl_event_process) == 0) {
2971 devtprintk((KERN_INFO MYNAM 2971 devtverboseprintk((KERN_INFO MYNAM
2972 ": Registered for IOC event notifications\n")); 2972 ": Registered for IOC event notifications\n"));
2973 } 2973 }
2974 2974
diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c
index c3a3499bce2a..b343f2a68b1c 100644
--- a/drivers/message/fusion/mptfc.c
+++ b/drivers/message/fusion/mptfc.c
@@ -154,7 +154,7 @@ MODULE_DEVICE_TABLE(pci, mptfc_pci_table);
154 154
155static struct scsi_transport_template *mptfc_transport_template = NULL; 155static struct scsi_transport_template *mptfc_transport_template = NULL;
156 156
157struct fc_function_template mptfc_transport_functions = { 157static struct fc_function_template mptfc_transport_functions = {
158 .dd_fcrport_size = 8, 158 .dd_fcrport_size = 8,
159 .show_host_node_name = 1, 159 .show_host_node_name = 1,
160 .show_host_port_name = 1, 160 .show_host_port_name = 1,
@@ -349,24 +349,6 @@ mptfc_generate_rport_ids(FCDevicePage0_t *pg0, struct fc_rport_identifiers *rid)
349} 349}
350 350
351static void 351static void
352mptfc_remap_sdev(struct scsi_device *sdev, void *arg)
353{
354 VirtDevice *vdev;
355 VirtTarget *vtarget;
356 struct scsi_target *starget;
357
358 starget = scsi_target(sdev);
359 if (starget->hostdata == arg) {
360 vtarget = arg;
361 vdev = sdev->hostdata;
362 if (vdev) {
363 vdev->bus_id = vtarget->bus_id;
364 vdev->target_id = vtarget->target_id;
365 }
366 }
367}
368
369static void
370mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0) 352mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0)
371{ 353{
372 struct fc_rport_identifiers rport_ids; 354 struct fc_rport_identifiers rport_ids;
@@ -423,8 +405,6 @@ mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0)
423 if (vtarget) { 405 if (vtarget) {
424 vtarget->target_id = pg0->CurrentTargetID; 406 vtarget->target_id = pg0->CurrentTargetID;
425 vtarget->bus_id = pg0->CurrentBus; 407 vtarget->bus_id = pg0->CurrentBus;
426 starget_for_each_device(ri->starget,
427 vtarget,mptfc_remap_sdev);
428 } 408 }
429 ri->remap_needed = 0; 409 ri->remap_needed = 0;
430 } 410 }
@@ -432,7 +412,7 @@ mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0)
432 "mptfc_reg_dev.%d: %x, %llx / %llx, tid %d, " 412 "mptfc_reg_dev.%d: %x, %llx / %llx, tid %d, "
433 "rport tid %d, tmo %d\n", 413 "rport tid %d, tmo %d\n",
434 ioc->name, 414 ioc->name,
435 oc->sh->host_no, 415 ioc->sh->host_no,
436 pg0->PortIdentifier, 416 pg0->PortIdentifier,
437 pg0->WWNN, 417 pg0->WWNN,
438 pg0->WWPN, 418 pg0->WWPN,
@@ -514,7 +494,7 @@ mptfc_target_alloc(struct scsi_target *starget)
514 * Return non-zero if allocation fails. 494 * Return non-zero if allocation fails.
515 * Init memory once per LUN. 495 * Init memory once per LUN.
516 */ 496 */
517int 497static int
518mptfc_slave_alloc(struct scsi_device *sdev) 498mptfc_slave_alloc(struct scsi_device *sdev)
519{ 499{
520 MPT_SCSI_HOST *hd; 500 MPT_SCSI_HOST *hd;
@@ -553,23 +533,26 @@ mptfc_slave_alloc(struct scsi_device *sdev)
553 } 533 }
554 534
555 vdev->vtarget = vtarget; 535 vdev->vtarget = vtarget;
556 vdev->ioc_id = hd->ioc->id;
557 vdev->lun = sdev->lun; 536 vdev->lun = sdev->lun;
558 vdev->target_id = vtarget->target_id;
559 vdev->bus_id = vtarget->bus_id;
560 537
561 spin_unlock_irqrestore(&hd->ioc->fc_rport_lock,flags); 538 spin_unlock_irqrestore(&hd->ioc->fc_rport_lock,flags);
562 539
563 vtarget->num_luns++; 540 vtarget->num_luns++;
564 541
542#ifdef DMPT_DEBUG_FC
543 {
544 struct mptfc_rport_info *ri;
545 ri = *((struct mptfc_rport_info **)rport->dd_data);
565 dfcprintk ((MYIOC_s_INFO_FMT 546 dfcprintk ((MYIOC_s_INFO_FMT
566 "mptfc_slv_alloc.%d: num_luns %d, sdev.id %d, " 547 "mptfc_slv_alloc.%d: num_luns %d, sdev.id %d, "
567 "CurrentTargetID %d, %x %llx %llx\n", 548 "CurrentTargetID %d, %x %llx %llx\n",
568 ioc->name, 549 hd->ioc->name,
569 sdev->host->host_no, 550 sdev->host->host_no,
570 vtarget->num_luns, 551 vtarget->num_luns,
571 sdev->id, ri->pg0.CurrentTargetID, 552 sdev->id, ri->pg0.CurrentTargetID,
572 ri->pg0.PortIdentifier, ri->pg0.WWPN, ri->pg0.WWNN)); 553 ri->pg0.PortIdentifier, ri->pg0.WWPN, ri->pg0.WWNN));
554 }
555#endif
573 556
574 return 0; 557 return 0;
575} 558}
@@ -941,7 +924,7 @@ mptfc_init(void)
941 mptfcInternalCtx = mpt_register(mptscsih_scandv_complete, MPTFC_DRIVER); 924 mptfcInternalCtx = mpt_register(mptscsih_scandv_complete, MPTFC_DRIVER);
942 925
943 if (mpt_event_register(mptfcDoneCtx, mptscsih_event_process) == 0) { 926 if (mpt_event_register(mptfcDoneCtx, mptscsih_event_process) == 0) {
944 devtprintk((KERN_INFO MYNAM 927 devtverboseprintk((KERN_INFO MYNAM
945 ": Registered for IOC event notifications\n")); 928 ": Registered for IOC event notifications\n"));
946 } 929 }
947 930
diff --git a/drivers/message/fusion/mptlan.c b/drivers/message/fusion/mptlan.c
index 73f59528212a..314c3a27585d 100644
--- a/drivers/message/fusion/mptlan.c
+++ b/drivers/message/fusion/mptlan.c
@@ -1152,10 +1152,7 @@ mpt_lan_receive_post_reply(struct net_device *dev,
1152 priv->mpt_rxfidx_tail, 1152 priv->mpt_rxfidx_tail,
1153 MPT_LAN_MAX_BUCKETS_OUT); 1153 MPT_LAN_MAX_BUCKETS_OUT);
1154 1154
1155 panic("Damn it Jim! I'm a doctor, not a programmer! " 1155 return -1;
1156 "Oh, wait a sec, I am a programmer. "
1157 "And, who's Jim?!?!\n"
1158 "Arrgghh! We've done it again!\n");
1159 } 1156 }
1160 1157
1161 if (remaining == 0) 1158 if (remaining == 0)
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c
index 2512d0e6155e..010d4a39269b 100644
--- a/drivers/message/fusion/mptsas.c
+++ b/drivers/message/fusion/mptsas.c
@@ -104,6 +104,13 @@ struct mptsas_hotplug_event {
104 u16 handle; 104 u16 handle;
105 u16 parent_handle; 105 u16 parent_handle;
106 u8 phy_id; 106 u8 phy_id;
107 u8 phys_disk_num;
108 u8 phys_disk_num_valid;
109};
110
111struct mptsas_discovery_event {
112 struct work_struct work;
113 MPT_ADAPTER *ioc;
107}; 114};
108 115
109/* 116/*
@@ -117,6 +124,8 @@ struct mptsas_hotplug_event {
117struct mptsas_devinfo { 124struct mptsas_devinfo {
118 u16 handle; /* unique id to address this device */ 125 u16 handle; /* unique id to address this device */
119 u16 handle_parent; /* unique id to address parent device */ 126 u16 handle_parent; /* unique id to address parent device */
127 u16 handle_enclosure; /* enclosure identifier of the enclosure */
128 u16 slot; /* physical slot in enclosure */
120 u8 phy_id; /* phy number of parent device */ 129 u8 phy_id; /* phy number of parent device */
121 u8 port_id; /* sas physical port this device 130 u8 port_id; /* sas physical port this device
122 is assoc'd with */ 131 is assoc'd with */
@@ -137,6 +146,7 @@ struct mptsas_phyinfo {
137 struct mptsas_devinfo attached; /* point to attached device info */ 146 struct mptsas_devinfo attached; /* point to attached device info */
138 struct sas_phy *phy; 147 struct sas_phy *phy;
139 struct sas_rphy *rphy; 148 struct sas_rphy *rphy;
149 struct scsi_target *starget;
140}; 150};
141 151
142struct mptsas_portinfo { 152struct mptsas_portinfo {
@@ -146,6 +156,17 @@ struct mptsas_portinfo {
146 struct mptsas_phyinfo *phy_info; 156 struct mptsas_phyinfo *phy_info;
147}; 157};
148 158
159struct mptsas_enclosure {
160 u64 enclosure_logical_id; /* The WWN for the enclosure */
161 u16 enclosure_handle; /* unique id to address this */
162 u16 flags; /* details enclosure management */
163 u16 num_slot; /* num slots */
164 u16 start_slot; /* first slot */
165 u8 start_id; /* starting logical target id */
166 u8 start_channel; /* starting logical channel id */
167 u8 sep_id; /* SEP device logical target id */
168 u8 sep_channel; /* SEP channel logical channel id */
169};
149 170
150#ifdef SASDEBUG 171#ifdef SASDEBUG
151static void mptsas_print_phy_data(MPI_SAS_IO_UNIT0_PHY_DATA *phy_data) 172static void mptsas_print_phy_data(MPI_SAS_IO_UNIT0_PHY_DATA *phy_data)
@@ -205,6 +226,7 @@ static void mptsas_print_device_pg0(SasDevicePage0_t *pg0)
205 226
206 printk("---- SAS DEVICE PAGE 0 ---------\n"); 227 printk("---- SAS DEVICE PAGE 0 ---------\n");
207 printk("Handle=0x%X\n" ,le16_to_cpu(pg0->DevHandle)); 228 printk("Handle=0x%X\n" ,le16_to_cpu(pg0->DevHandle));
229 printk("Parent Handle=0x%X\n" ,le16_to_cpu(pg0->ParentDevHandle));
208 printk("Enclosure Handle=0x%X\n", le16_to_cpu(pg0->EnclosureHandle)); 230 printk("Enclosure Handle=0x%X\n", le16_to_cpu(pg0->EnclosureHandle));
209 printk("Slot=0x%X\n", le16_to_cpu(pg0->Slot)); 231 printk("Slot=0x%X\n", le16_to_cpu(pg0->Slot));
210 printk("SAS Address=0x%llX\n", le64_to_cpu(sas_address)); 232 printk("SAS Address=0x%llX\n", le64_to_cpu(sas_address));
@@ -243,6 +265,111 @@ static void mptsas_print_expander_pg1(SasExpanderPage1_t *pg1)
243#define mptsas_print_expander_pg1(pg1) do { } while (0) 265#define mptsas_print_expander_pg1(pg1) do { } while (0)
244#endif 266#endif
245 267
268static inline MPT_ADAPTER *phy_to_ioc(struct sas_phy *phy)
269{
270 struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
271 return ((MPT_SCSI_HOST *)shost->hostdata)->ioc;
272}
273
274static inline MPT_ADAPTER *rphy_to_ioc(struct sas_rphy *rphy)
275{
276 struct Scsi_Host *shost = dev_to_shost(rphy->dev.parent->parent);
277 return ((MPT_SCSI_HOST *)shost->hostdata)->ioc;
278}
279
280/*
281 * mptsas_find_portinfo_by_handle
282 *
283 * This function should be called with the sas_topology_mutex already held
284 */
285static struct mptsas_portinfo *
286mptsas_find_portinfo_by_handle(MPT_ADAPTER *ioc, u16 handle)
287{
288 struct mptsas_portinfo *port_info, *rc=NULL;
289 int i;
290
291 list_for_each_entry(port_info, &ioc->sas_topology, list)
292 for (i = 0; i < port_info->num_phys; i++)
293 if (port_info->phy_info[i].identify.handle == handle) {
294 rc = port_info;
295 goto out;
296 }
297 out:
298 return rc;
299}
300
301static int
302mptsas_sas_enclosure_pg0(MPT_ADAPTER *ioc, struct mptsas_enclosure *enclosure,
303 u32 form, u32 form_specific)
304{
305 ConfigExtendedPageHeader_t hdr;
306 CONFIGPARMS cfg;
307 SasEnclosurePage0_t *buffer;
308 dma_addr_t dma_handle;
309 int error;
310 __le64 le_identifier;
311
312 memset(&hdr, 0, sizeof(hdr));
313 hdr.PageVersion = MPI_SASENCLOSURE0_PAGEVERSION;
314 hdr.PageNumber = 0;
315 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
316 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_ENCLOSURE;
317
318 cfg.cfghdr.ehdr = &hdr;
319 cfg.physAddr = -1;
320 cfg.pageAddr = form + form_specific;
321 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
322 cfg.dir = 0; /* read */
323 cfg.timeout = 10;
324
325 error = mpt_config(ioc, &cfg);
326 if (error)
327 goto out;
328 if (!hdr.ExtPageLength) {
329 error = -ENXIO;
330 goto out;
331 }
332
333 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
334 &dma_handle);
335 if (!buffer) {
336 error = -ENOMEM;
337 goto out;
338 }
339
340 cfg.physAddr = dma_handle;
341 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
342
343 error = mpt_config(ioc, &cfg);
344 if (error)
345 goto out_free_consistent;
346
347 /* save config data */
348 memcpy(&le_identifier, &buffer->EnclosureLogicalID, sizeof(__le64));
349 enclosure->enclosure_logical_id = le64_to_cpu(le_identifier);
350 enclosure->enclosure_handle = le16_to_cpu(buffer->EnclosureHandle);
351 enclosure->flags = le16_to_cpu(buffer->Flags);
352 enclosure->num_slot = le16_to_cpu(buffer->NumSlots);
353 enclosure->start_slot = le16_to_cpu(buffer->StartSlot);
354 enclosure->start_id = buffer->StartTargetID;
355 enclosure->start_channel = buffer->StartBus;
356 enclosure->sep_id = buffer->SEPTargetID;
357 enclosure->sep_channel = buffer->SEPBus;
358
359 out_free_consistent:
360 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
361 buffer, dma_handle);
362 out:
363 return error;
364}
365
366static int
367mptsas_slave_configure(struct scsi_device *sdev)
368{
369 sas_read_port_mode_page(sdev);
370
371 return mptscsih_slave_configure(sdev);
372}
246 373
247/* 374/*
248 * This is pretty ugly. We will be able to seriously clean it up 375 * This is pretty ugly. We will be able to seriously clean it up
@@ -259,6 +386,7 @@ mptsas_slave_alloc(struct scsi_device *sdev)
259 VirtTarget *vtarget; 386 VirtTarget *vtarget;
260 VirtDevice *vdev; 387 VirtDevice *vdev;
261 struct scsi_target *starget; 388 struct scsi_target *starget;
389 u32 target_id;
262 int i; 390 int i;
263 391
264 vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL); 392 vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
@@ -267,10 +395,10 @@ mptsas_slave_alloc(struct scsi_device *sdev)
267 hd->ioc->name, sizeof(VirtDevice)); 395 hd->ioc->name, sizeof(VirtDevice));
268 return -ENOMEM; 396 return -ENOMEM;
269 } 397 }
270 vdev->ioc_id = hd->ioc->id;
271 sdev->hostdata = vdev; 398 sdev->hostdata = vdev;
272 starget = scsi_target(sdev); 399 starget = scsi_target(sdev);
273 vtarget = starget->hostdata; 400 vtarget = starget->hostdata;
401 vtarget->ioc_id = hd->ioc->id;
274 vdev->vtarget = vtarget; 402 vdev->vtarget = vtarget;
275 if (vtarget->num_luns == 0) { 403 if (vtarget->num_luns == 0) {
276 vtarget->tflags = MPT_TARGET_FLAGS_Q_YES|MPT_TARGET_FLAGS_VALID_INQUIRY; 404 vtarget->tflags = MPT_TARGET_FLAGS_Q_YES|MPT_TARGET_FLAGS_VALID_INQUIRY;
@@ -281,8 +409,8 @@ mptsas_slave_alloc(struct scsi_device *sdev)
281 RAID volumes placed beyond the last expected port. 409 RAID volumes placed beyond the last expected port.
282 */ 410 */
283 if (sdev->channel == hd->ioc->num_ports) { 411 if (sdev->channel == hd->ioc->num_ports) {
284 vdev->target_id = sdev->id; 412 target_id = sdev->id;
285 vdev->bus_id = 0; 413 vtarget->bus_id = 0;
286 vdev->lun = 0; 414 vdev->lun = 0;
287 goto out; 415 goto out;
288 } 416 }
@@ -293,11 +421,21 @@ mptsas_slave_alloc(struct scsi_device *sdev)
293 for (i = 0; i < p->num_phys; i++) { 421 for (i = 0; i < p->num_phys; i++) {
294 if (p->phy_info[i].attached.sas_address == 422 if (p->phy_info[i].attached.sas_address ==
295 rphy->identify.sas_address) { 423 rphy->identify.sas_address) {
296 vdev->target_id = 424 target_id = p->phy_info[i].attached.id;
297 p->phy_info[i].attached.id; 425 vtarget->bus_id = p->phy_info[i].attached.channel;
298 vdev->bus_id = p->phy_info[i].attached.channel;
299 vdev->lun = sdev->lun; 426 vdev->lun = sdev->lun;
300 mutex_unlock(&hd->ioc->sas_topology_mutex); 427 p->phy_info[i].starget = sdev->sdev_target;
428 /*
429 * Exposing hidden disk (RAID)
430 */
431 if (mptscsih_is_phys_disk(hd->ioc, target_id)) {
432 target_id = mptscsih_raid_id_to_num(hd,
433 target_id);
434 vdev->vtarget->tflags |=
435 MPT_TARGET_FLAGS_RAID_COMPONENT;
436 sdev->no_uld_attach = 1;
437 }
438 mutex_unlock(&hd->ioc->sas_topology_mutex);
301 goto out; 439 goto out;
302 } 440 }
303 } 441 }
@@ -308,9 +446,7 @@ mptsas_slave_alloc(struct scsi_device *sdev)
308 return -ENXIO; 446 return -ENXIO;
309 447
310 out: 448 out:
311 vtarget->ioc_id = vdev->ioc_id; 449 vtarget->target_id = target_id;
312 vtarget->target_id = vdev->target_id;
313 vtarget->bus_id = vdev->bus_id;
314 vtarget->num_luns++; 450 vtarget->num_luns++;
315 return 0; 451 return 0;
316} 452}
@@ -320,41 +456,17 @@ mptsas_slave_destroy(struct scsi_device *sdev)
320{ 456{
321 struct Scsi_Host *host = sdev->host; 457 struct Scsi_Host *host = sdev->host;
322 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; 458 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
323 struct sas_rphy *rphy;
324 struct mptsas_portinfo *p;
325 int i;
326 VirtDevice *vdev; 459 VirtDevice *vdev;
327 460
328 /* 461 /*
329 * Handle hotplug removal case.
330 * We need to clear out attached data structure.
331 */
332 rphy = dev_to_rphy(sdev->sdev_target->dev.parent);
333
334 mutex_lock(&hd->ioc->sas_topology_mutex);
335 list_for_each_entry(p, &hd->ioc->sas_topology, list) {
336 for (i = 0; i < p->num_phys; i++) {
337 if (p->phy_info[i].attached.sas_address ==
338 rphy->identify.sas_address) {
339 memset(&p->phy_info[i].attached, 0,
340 sizeof(struct mptsas_devinfo));
341 p->phy_info[i].rphy = NULL;
342 goto out;
343 }
344 }
345 }
346
347 out:
348 mutex_unlock(&hd->ioc->sas_topology_mutex);
349 /*
350 * Issue target reset to flush firmware outstanding commands. 462 * Issue target reset to flush firmware outstanding commands.
351 */ 463 */
352 vdev = sdev->hostdata; 464 vdev = sdev->hostdata;
353 if (vdev->configured_lun){ 465 if (vdev->configured_lun){
354 if (mptscsih_TMHandler(hd, 466 if (mptscsih_TMHandler(hd,
355 MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 467 MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
356 vdev->bus_id, 468 vdev->vtarget->bus_id,
357 vdev->target_id, 469 vdev->vtarget->target_id,
358 0, 0, 5 /* 5 second timeout */) 470 0, 0, 5 /* 5 second timeout */)
359 < 0){ 471 < 0){
360 472
@@ -364,7 +476,7 @@ mptsas_slave_destroy(struct scsi_device *sdev)
364 printk(MYIOC_s_WARN_FMT 476 printk(MYIOC_s_WARN_FMT
365 "Error processing TaskMgmt id=%d TARGET_RESET\n", 477 "Error processing TaskMgmt id=%d TARGET_RESET\n",
366 hd->ioc->name, 478 hd->ioc->name,
367 vdev->target_id); 479 vdev->vtarget->target_id);
368 480
369 hd->tmPending = 0; 481 hd->tmPending = 0;
370 hd->tmState = TM_STATE_NONE; 482 hd->tmState = TM_STATE_NONE;
@@ -382,7 +494,7 @@ static struct scsi_host_template mptsas_driver_template = {
382 .queuecommand = mptscsih_qcmd, 494 .queuecommand = mptscsih_qcmd,
383 .target_alloc = mptscsih_target_alloc, 495 .target_alloc = mptscsih_target_alloc,
384 .slave_alloc = mptsas_slave_alloc, 496 .slave_alloc = mptsas_slave_alloc,
385 .slave_configure = mptscsih_slave_configure, 497 .slave_configure = mptsas_slave_configure,
386 .target_destroy = mptscsih_target_destroy, 498 .target_destroy = mptscsih_target_destroy,
387 .slave_destroy = mptsas_slave_destroy, 499 .slave_destroy = mptsas_slave_destroy,
388 .change_queue_depth = mptscsih_change_queue_depth, 500 .change_queue_depth = mptscsih_change_queue_depth,
@@ -399,12 +511,6 @@ static struct scsi_host_template mptsas_driver_template = {
399 .use_clustering = ENABLE_CLUSTERING, 511 .use_clustering = ENABLE_CLUSTERING,
400}; 512};
401 513
402static inline MPT_ADAPTER *phy_to_ioc(struct sas_phy *phy)
403{
404 struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
405 return ((MPT_SCSI_HOST *)shost->hostdata)->ioc;
406}
407
408static int mptsas_get_linkerrors(struct sas_phy *phy) 514static int mptsas_get_linkerrors(struct sas_phy *phy)
409{ 515{
410 MPT_ADAPTER *ioc = phy_to_ioc(phy); 516 MPT_ADAPTER *ioc = phy_to_ioc(phy);
@@ -546,8 +652,67 @@ static int mptsas_phy_reset(struct sas_phy *phy, int hard_reset)
546 return error; 652 return error;
547} 653}
548 654
655static int
656mptsas_get_enclosure_identifier(struct sas_rphy *rphy, u64 *identifier)
657{
658 MPT_ADAPTER *ioc = rphy_to_ioc(rphy);
659 int i, error;
660 struct mptsas_portinfo *p;
661 struct mptsas_enclosure enclosure_info;
662 u64 enclosure_handle;
663
664 mutex_lock(&ioc->sas_topology_mutex);
665 list_for_each_entry(p, &ioc->sas_topology, list) {
666 for (i = 0; i < p->num_phys; i++) {
667 if (p->phy_info[i].attached.sas_address ==
668 rphy->identify.sas_address) {
669 enclosure_handle = p->phy_info[i].
670 attached.handle_enclosure;
671 goto found_info;
672 }
673 }
674 }
675 mutex_unlock(&ioc->sas_topology_mutex);
676 return -ENXIO;
677
678 found_info:
679 mutex_unlock(&ioc->sas_topology_mutex);
680 memset(&enclosure_info, 0, sizeof(struct mptsas_enclosure));
681 error = mptsas_sas_enclosure_pg0(ioc, &enclosure_info,
682 (MPI_SAS_ENCLOS_PGAD_FORM_HANDLE <<
683 MPI_SAS_ENCLOS_PGAD_FORM_SHIFT), enclosure_handle);
684 if (!error)
685 *identifier = enclosure_info.enclosure_logical_id;
686 return error;
687}
688
689static int
690mptsas_get_bay_identifier(struct sas_rphy *rphy)
691{
692 MPT_ADAPTER *ioc = rphy_to_ioc(rphy);
693 struct mptsas_portinfo *p;
694 int i, rc;
695
696 mutex_lock(&ioc->sas_topology_mutex);
697 list_for_each_entry(p, &ioc->sas_topology, list) {
698 for (i = 0; i < p->num_phys; i++) {
699 if (p->phy_info[i].attached.sas_address ==
700 rphy->identify.sas_address) {
701 rc = p->phy_info[i].attached.slot;
702 goto out;
703 }
704 }
705 }
706 rc = -ENXIO;
707 out:
708 mutex_unlock(&ioc->sas_topology_mutex);
709 return rc;
710}
711
549static struct sas_function_template mptsas_transport_functions = { 712static struct sas_function_template mptsas_transport_functions = {
550 .get_linkerrors = mptsas_get_linkerrors, 713 .get_linkerrors = mptsas_get_linkerrors,
714 .get_enclosure_identifier = mptsas_get_enclosure_identifier,
715 .get_bay_identifier = mptsas_get_bay_identifier,
551 .phy_reset = mptsas_phy_reset, 716 .phy_reset = mptsas_phy_reset,
552}; 717};
553 718
@@ -607,6 +772,9 @@ mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
607 goto out_free_consistent; 772 goto out_free_consistent;
608 } 773 }
609 774
775 if (port_info->num_phys)
776 port_info->handle =
777 le16_to_cpu(buffer->PhyData[0].ControllerDevHandle);
610 for (i = 0; i < port_info->num_phys; i++) { 778 for (i = 0; i < port_info->num_phys; i++) {
611 mptsas_print_phy_data(&buffer->PhyData[i]); 779 mptsas_print_phy_data(&buffer->PhyData[i]);
612 port_info->phy_info[i].phy_id = i; 780 port_info->phy_info[i].phy_id = i;
@@ -713,6 +881,7 @@ mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info,
713 cfg.dir = 0; /* read */ 881 cfg.dir = 0; /* read */
714 cfg.timeout = 10; 882 cfg.timeout = 10;
715 883
884 memset(device_info, 0, sizeof(struct mptsas_devinfo));
716 error = mpt_config(ioc, &cfg); 885 error = mpt_config(ioc, &cfg);
717 if (error) 886 if (error)
718 goto out; 887 goto out;
@@ -739,6 +908,9 @@ mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info,
739 908
740 device_info->handle = le16_to_cpu(buffer->DevHandle); 909 device_info->handle = le16_to_cpu(buffer->DevHandle);
741 device_info->handle_parent = le16_to_cpu(buffer->ParentDevHandle); 910 device_info->handle_parent = le16_to_cpu(buffer->ParentDevHandle);
911 device_info->handle_enclosure =
912 le16_to_cpu(buffer->EnclosureHandle);
913 device_info->slot = le16_to_cpu(buffer->Slot);
742 device_info->phy_id = buffer->PhyNum; 914 device_info->phy_id = buffer->PhyNum;
743 device_info->port_id = buffer->PhysicalPort; 915 device_info->port_id = buffer->PhysicalPort;
744 device_info->id = buffer->TargetID; 916 device_info->id = buffer->TargetID;
@@ -780,6 +952,7 @@ mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info,
780 cfg.dir = 0; /* read */ 952 cfg.dir = 0; /* read */
781 cfg.timeout = 10; 953 cfg.timeout = 10;
782 954
955 memset(port_info, 0, sizeof(struct mptsas_portinfo));
783 error = mpt_config(ioc, &cfg); 956 error = mpt_config(ioc, &cfg);
784 if (error) 957 if (error)
785 goto out; 958 goto out;
@@ -880,7 +1053,6 @@ mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
880 phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle); 1053 phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
881 phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle); 1054 phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
882 1055
883
884 out_free_consistent: 1056 out_free_consistent:
885 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4, 1057 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
886 buffer, dma_handle); 1058 buffer, dma_handle);
@@ -970,12 +1142,19 @@ mptsas_parse_device_info(struct sas_identify *identify,
970static int mptsas_probe_one_phy(struct device *dev, 1142static int mptsas_probe_one_phy(struct device *dev,
971 struct mptsas_phyinfo *phy_info, int index, int local) 1143 struct mptsas_phyinfo *phy_info, int index, int local)
972{ 1144{
1145 MPT_ADAPTER *ioc;
973 struct sas_phy *phy; 1146 struct sas_phy *phy;
974 int error; 1147 int error;
975 1148
976 phy = sas_phy_alloc(dev, index); 1149 if (!dev)
977 if (!phy) 1150 return -ENODEV;
978 return -ENOMEM; 1151
1152 if (!phy_info->phy) {
1153 phy = sas_phy_alloc(dev, index);
1154 if (!phy)
1155 return -ENOMEM;
1156 } else
1157 phy = phy_info->phy;
979 1158
980 phy->port_identifier = phy_info->port_id; 1159 phy->port_identifier = phy_info->port_id;
981 mptsas_parse_device_info(&phy->identify, &phy_info->identify); 1160 mptsas_parse_device_info(&phy->identify, &phy_info->identify);
@@ -1061,24 +1240,54 @@ static int mptsas_probe_one_phy(struct device *dev,
1061 break; 1240 break;
1062 } 1241 }
1063 1242
1064 if (local) 1243 if (!phy_info->phy) {
1065 phy->local_attached = 1;
1066 1244
1067 error = sas_phy_add(phy); 1245 if (local)
1068 if (error) { 1246 phy->local_attached = 1;
1069 sas_phy_free(phy); 1247
1070 return error; 1248 error = sas_phy_add(phy);
1249 if (error) {
1250 sas_phy_free(phy);
1251 return error;
1252 }
1253 phy_info->phy = phy;
1071 } 1254 }
1072 phy_info->phy = phy;
1073 1255
1074 if (phy_info->attached.handle) { 1256 if ((phy_info->attached.handle) &&
1257 (!phy_info->rphy)) {
1258
1075 struct sas_rphy *rphy; 1259 struct sas_rphy *rphy;
1260 struct sas_identify identify;
1261
1262 ioc = phy_to_ioc(phy_info->phy);
1076 1263
1077 rphy = sas_rphy_alloc(phy); 1264 /*
1265 * Let the hotplug_work thread handle processing
1266 * the adding/removing of devices that occur
1267 * after start of day.
1268 */
1269 if (ioc->sas_discovery_runtime &&
1270 mptsas_is_end_device(&phy_info->attached))
1271 return 0;
1272
1273 mptsas_parse_device_info(&identify, &phy_info->attached);
1274 switch (identify.device_type) {
1275 case SAS_END_DEVICE:
1276 rphy = sas_end_device_alloc(phy);
1277 break;
1278 case SAS_EDGE_EXPANDER_DEVICE:
1279 case SAS_FANOUT_EXPANDER_DEVICE:
1280 rphy = sas_expander_alloc(phy, identify.device_type);
1281 break;
1282 default:
1283 rphy = NULL;
1284 break;
1285 }
1078 if (!rphy) 1286 if (!rphy)
1079 return 0; /* non-fatal: an rphy can be added later */ 1287 return 0; /* non-fatal: an rphy can be added later */
1080 1288
1081 mptsas_parse_device_info(&rphy->identify, &phy_info->attached); 1289 rphy->identify = identify;
1290
1082 error = sas_rphy_add(rphy); 1291 error = sas_rphy_add(rphy);
1083 if (error) { 1292 if (error) {
1084 sas_rphy_free(rphy); 1293 sas_rphy_free(rphy);
@@ -1092,24 +1301,37 @@ static int mptsas_probe_one_phy(struct device *dev,
1092} 1301}
1093 1302
1094static int 1303static int
1095mptsas_probe_hba_phys(MPT_ADAPTER *ioc, int *index) 1304mptsas_probe_hba_phys(MPT_ADAPTER *ioc)
1096{ 1305{
1097 struct mptsas_portinfo *port_info; 1306 struct mptsas_portinfo *port_info, *hba;
1098 u32 handle = 0xFFFF; 1307 u32 handle = 0xFFFF;
1099 int error = -ENOMEM, i; 1308 int error = -ENOMEM, i;
1100 1309
1101 port_info = kzalloc(sizeof(*port_info), GFP_KERNEL); 1310 hba = kzalloc(sizeof(*port_info), GFP_KERNEL);
1102 if (!port_info) 1311 if (! hba)
1103 goto out; 1312 goto out;
1104 1313
1105 error = mptsas_sas_io_unit_pg0(ioc, port_info); 1314 error = mptsas_sas_io_unit_pg0(ioc, hba);
1106 if (error) 1315 if (error)
1107 goto out_free_port_info; 1316 goto out_free_port_info;
1108 1317
1109 ioc->num_ports = port_info->num_phys;
1110 mutex_lock(&ioc->sas_topology_mutex); 1318 mutex_lock(&ioc->sas_topology_mutex);
1111 list_add_tail(&port_info->list, &ioc->sas_topology); 1319 port_info = mptsas_find_portinfo_by_handle(ioc, hba->handle);
1320 if (!port_info) {
1321 port_info = hba;
1322 list_add_tail(&port_info->list, &ioc->sas_topology);
1323 } else {
1324 port_info->handle = hba->handle;
1325 for (i = 0; i < hba->num_phys; i++)
1326 port_info->phy_info[i].negotiated_link_rate =
1327 hba->phy_info[i].negotiated_link_rate;
1328 if (hba->phy_info)
1329 kfree(hba->phy_info);
1330 kfree(hba);
1331 hba = NULL;
1332 }
1112 mutex_unlock(&ioc->sas_topology_mutex); 1333 mutex_unlock(&ioc->sas_topology_mutex);
1334 ioc->num_ports = port_info->num_phys;
1113 1335
1114 for (i = 0; i < port_info->num_phys; i++) { 1336 for (i = 0; i < port_info->num_phys; i++) {
1115 mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i], 1337 mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i],
@@ -1132,38 +1354,49 @@ mptsas_probe_hba_phys(MPT_ADAPTER *ioc, int *index)
1132 } 1354 }
1133 1355
1134 mptsas_probe_one_phy(&ioc->sh->shost_gendev, 1356 mptsas_probe_one_phy(&ioc->sh->shost_gendev,
1135 &port_info->phy_info[i], *index, 1); 1357 &port_info->phy_info[i], ioc->sas_index, 1);
1136 (*index)++; 1358 ioc->sas_index++;
1137 } 1359 }
1138 1360
1139 return 0; 1361 return 0;
1140 1362
1141 out_free_port_info: 1363 out_free_port_info:
1142 kfree(port_info); 1364 if (hba)
1365 kfree(hba);
1143 out: 1366 out:
1144 return error; 1367 return error;
1145} 1368}
1146 1369
1147static int 1370static int
1148mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle, int *index) 1371mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle)
1149{ 1372{
1150 struct mptsas_portinfo *port_info, *p; 1373 struct mptsas_portinfo *port_info, *p, *ex;
1151 int error = -ENOMEM, i, j; 1374 int error = -ENOMEM, i, j;
1152 1375
1153 port_info = kzalloc(sizeof(*port_info), GFP_KERNEL); 1376 ex = kzalloc(sizeof(*port_info), GFP_KERNEL);
1154 if (!port_info) 1377 if (!ex)
1155 goto out; 1378 goto out;
1156 1379
1157 error = mptsas_sas_expander_pg0(ioc, port_info, 1380 error = mptsas_sas_expander_pg0(ioc, ex,
1158 (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE << 1381 (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
1159 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), *handle); 1382 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), *handle);
1160 if (error) 1383 if (error)
1161 goto out_free_port_info; 1384 goto out_free_port_info;
1162 1385
1163 *handle = port_info->handle; 1386 *handle = ex->handle;
1164 1387
1165 mutex_lock(&ioc->sas_topology_mutex); 1388 mutex_lock(&ioc->sas_topology_mutex);
1166 list_add_tail(&port_info->list, &ioc->sas_topology); 1389 port_info = mptsas_find_portinfo_by_handle(ioc, *handle);
1390 if (!port_info) {
1391 port_info = ex;
1392 list_add_tail(&port_info->list, &ioc->sas_topology);
1393 } else {
1394 port_info->handle = ex->handle;
1395 if (ex->phy_info)
1396 kfree(ex->phy_info);
1397 kfree(ex);
1398 ex = NULL;
1399 }
1167 mutex_unlock(&ioc->sas_topology_mutex); 1400 mutex_unlock(&ioc->sas_topology_mutex);
1168 1401
1169 for (i = 0; i < port_info->num_phys; i++) { 1402 for (i = 0; i < port_info->num_phys; i++) {
@@ -1189,6 +1422,8 @@ mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle, int *index)
1189 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE << 1422 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
1190 MPI_SAS_DEVICE_PGAD_FORM_SHIFT), 1423 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
1191 port_info->phy_info[i].attached.handle); 1424 port_info->phy_info[i].attached.handle);
1425 port_info->phy_info[i].attached.phy_id =
1426 port_info->phy_info[i].phy_id;
1192 } 1427 }
1193 1428
1194 /* 1429 /*
@@ -1208,27 +1443,137 @@ mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle, int *index)
1208 mutex_unlock(&ioc->sas_topology_mutex); 1443 mutex_unlock(&ioc->sas_topology_mutex);
1209 1444
1210 mptsas_probe_one_phy(parent, &port_info->phy_info[i], 1445 mptsas_probe_one_phy(parent, &port_info->phy_info[i],
1211 *index, 0); 1446 ioc->sas_index, 0);
1212 (*index)++; 1447 ioc->sas_index++;
1213 } 1448 }
1214 1449
1215 return 0; 1450 return 0;
1216 1451
1217 out_free_port_info: 1452 out_free_port_info:
1218 kfree(port_info); 1453 if (ex) {
1454 if (ex->phy_info)
1455 kfree(ex->phy_info);
1456 kfree(ex);
1457 }
1219 out: 1458 out:
1220 return error; 1459 return error;
1221} 1460}
1222 1461
1462/*
1463 * mptsas_delete_expander_phys
1464 *
1465 *
1466 * This will traverse topology, and remove expanders
1467 * that are no longer present
1468 */
1469static void
1470mptsas_delete_expander_phys(MPT_ADAPTER *ioc)
1471{
1472 struct mptsas_portinfo buffer;
1473 struct mptsas_portinfo *port_info, *n, *parent;
1474 int i;
1475
1476 mutex_lock(&ioc->sas_topology_mutex);
1477 list_for_each_entry_safe(port_info, n, &ioc->sas_topology, list) {
1478
1479 if (port_info->phy_info &&
1480 (!(port_info->phy_info[0].identify.device_info &
1481 MPI_SAS_DEVICE_INFO_SMP_TARGET)))
1482 continue;
1483
1484 if (mptsas_sas_expander_pg0(ioc, &buffer,
1485 (MPI_SAS_EXPAND_PGAD_FORM_HANDLE <<
1486 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), port_info->handle)) {
1487
1488 /*
1489 * Obtain the port_info instance to the parent port
1490 */
1491 parent = mptsas_find_portinfo_by_handle(ioc,
1492 port_info->phy_info[0].identify.handle_parent);
1493
1494 if (!parent)
1495 goto next_port;
1496
1497 /*
1498 * Delete rphys in the parent that point
1499 * to this expander. The transport layer will
1500 * cleanup all the children.
1501 */
1502 for (i = 0; i < parent->num_phys; i++) {
1503 if ((!parent->phy_info[i].rphy) ||
1504 (parent->phy_info[i].attached.sas_address !=
1505 port_info->phy_info[i].identify.sas_address))
1506 continue;
1507 sas_rphy_delete(parent->phy_info[i].rphy);
1508 memset(&parent->phy_info[i].attached, 0,
1509 sizeof(struct mptsas_devinfo));
1510 parent->phy_info[i].rphy = NULL;
1511 parent->phy_info[i].starget = NULL;
1512 }
1513 next_port:
1514 list_del(&port_info->list);
1515 if (port_info->phy_info)
1516 kfree(port_info->phy_info);
1517 kfree(port_info);
1518 }
1519 /*
1520 * Free this memory allocated from inside
1521 * mptsas_sas_expander_pg0
1522 */
1523 if (buffer.phy_info)
1524 kfree(buffer.phy_info);
1525 }
1526 mutex_unlock(&ioc->sas_topology_mutex);
1527}
1528
1529/*
1530 * Start of day discovery
1531 */
1223static void 1532static void
1224mptsas_scan_sas_topology(MPT_ADAPTER *ioc) 1533mptsas_scan_sas_topology(MPT_ADAPTER *ioc)
1225{ 1534{
1226 u32 handle = 0xFFFF; 1535 u32 handle = 0xFFFF;
1227 int index = 0; 1536 int i;
1537
1538 mutex_lock(&ioc->sas_discovery_mutex);
1539 mptsas_probe_hba_phys(ioc);
1540 while (!mptsas_probe_expander_phys(ioc, &handle))
1541 ;
1542 /*
1543 Reporting RAID volumes.
1544 */
1545 if (!ioc->raid_data.pIocPg2)
1546 goto out;
1547 if (!ioc->raid_data.pIocPg2->NumActiveVolumes)
1548 goto out;
1549 for (i=0; i<ioc->raid_data.pIocPg2->NumActiveVolumes; i++) {
1550 scsi_add_device(ioc->sh, ioc->num_ports,
1551 ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID, 0);
1552 }
1553 out:
1554 mutex_unlock(&ioc->sas_discovery_mutex);
1555}
1556
1557/*
1558 * Work queue thread to handle Runtime discovery
1559 * Mere purpose is the hot add/delete of expanders
1560 */
1561static void
1562mptscsih_discovery_work(void * arg)
1563{
1564 struct mptsas_discovery_event *ev = arg;
1565 MPT_ADAPTER *ioc = ev->ioc;
1566 u32 handle = 0xFFFF;
1228 1567
1229 mptsas_probe_hba_phys(ioc, &index); 1568 mutex_lock(&ioc->sas_discovery_mutex);
1230 while (!mptsas_probe_expander_phys(ioc, &handle, &index)) 1569 ioc->sas_discovery_runtime=1;
1570 mptsas_delete_expander_phys(ioc);
1571 mptsas_probe_hba_phys(ioc);
1572 while (!mptsas_probe_expander_phys(ioc, &handle))
1231 ; 1573 ;
1574 kfree(ev);
1575 ioc->sas_discovery_runtime=0;
1576 mutex_unlock(&ioc->sas_discovery_mutex);
1232} 1577}
1233 1578
1234static struct mptsas_phyinfo * 1579static struct mptsas_phyinfo *
@@ -1246,10 +1591,8 @@ mptsas_find_phyinfo_by_parent(MPT_ADAPTER *ioc, u16 parent_handle, u8 phy_id)
1246 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE << 1591 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
1247 MPI_SAS_DEVICE_PGAD_FORM_SHIFT), 1592 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
1248 parent_handle); 1593 parent_handle);
1249 if (error) { 1594 if (error)
1250 printk("mptsas: failed to retrieve device page\n");
1251 return NULL; 1595 return NULL;
1252 }
1253 1596
1254 /* 1597 /*
1255 * The phy_info structures are never deallocated during lifetime of 1598 * The phy_info structures are never deallocated during lifetime of
@@ -1296,6 +1639,35 @@ mptsas_find_phyinfo_by_target(MPT_ADAPTER *ioc, u32 id)
1296 return phy_info; 1639 return phy_info;
1297} 1640}
1298 1641
1642/*
1643 * Work queue thread to clear the persitency table
1644 */
1645static void
1646mptscsih_sas_persist_clear_table(void * arg)
1647{
1648 MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg;
1649
1650 mptbase_sas_persist_operation(ioc, MPI_SAS_OP_CLEAR_NOT_PRESENT);
1651}
1652
1653static void
1654mptsas_reprobe_lun(struct scsi_device *sdev, void *data)
1655{
1656 sdev->no_uld_attach = data ? 1 : 0;
1657 scsi_device_reprobe(sdev);
1658}
1659
1660static void
1661mptsas_reprobe_target(struct scsi_target *starget, int uld_attach)
1662{
1663 starget_for_each_device(starget, uld_attach ? (void *)1 : NULL,
1664 mptsas_reprobe_lun);
1665}
1666
1667
1668/*
1669 * Work queue thread to handle SAS hotplug events
1670 */
1299static void 1671static void
1300mptsas_hotplug_work(void *arg) 1672mptsas_hotplug_work(void *arg)
1301{ 1673{
@@ -1304,16 +1676,39 @@ mptsas_hotplug_work(void *arg)
1304 struct mptsas_phyinfo *phy_info; 1676 struct mptsas_phyinfo *phy_info;
1305 struct sas_rphy *rphy; 1677 struct sas_rphy *rphy;
1306 struct scsi_device *sdev; 1678 struct scsi_device *sdev;
1679 struct sas_identify identify;
1307 char *ds = NULL; 1680 char *ds = NULL;
1308 struct mptsas_devinfo sas_device; 1681 struct mptsas_devinfo sas_device;
1682 VirtTarget *vtarget;
1683
1684 mutex_lock(&ioc->sas_discovery_mutex);
1309 1685
1310 switch (ev->event_type) { 1686 switch (ev->event_type) {
1311 case MPTSAS_DEL_DEVICE: 1687 case MPTSAS_DEL_DEVICE:
1312 1688
1313 phy_info = mptsas_find_phyinfo_by_target(ioc, ev->id); 1689 phy_info = mptsas_find_phyinfo_by_target(ioc, ev->id);
1314 if (!phy_info) { 1690
1315 printk("mptsas: remove event for non-existant PHY.\n"); 1691 /*
1692 * Sanity checks, for non-existing phys and remote rphys.
1693 */
1694 if (!phy_info)
1316 break; 1695 break;
1696 if (!phy_info->rphy)
1697 break;
1698 if (phy_info->starget) {
1699 vtarget = phy_info->starget->hostdata;
1700
1701 if (!vtarget)
1702 break;
1703 /*
1704 * Handling RAID components
1705 */
1706 if (ev->phys_disk_num_valid) {
1707 vtarget->target_id = ev->phys_disk_num;
1708 vtarget->tflags |= MPT_TARGET_FLAGS_RAID_COMPONENT;
1709 mptsas_reprobe_target(vtarget->starget, 1);
1710 break;
1711 }
1317 } 1712 }
1318 1713
1319 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SSP_TARGET) 1714 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SSP_TARGET)
@@ -1327,55 +1722,74 @@ mptsas_hotplug_work(void *arg)
1327 "removing %s device, channel %d, id %d, phy %d\n", 1722 "removing %s device, channel %d, id %d, phy %d\n",
1328 ioc->name, ds, ev->channel, ev->id, phy_info->phy_id); 1723 ioc->name, ds, ev->channel, ev->id, phy_info->phy_id);
1329 1724
1330 if (phy_info->rphy) { 1725 sas_rphy_delete(phy_info->rphy);
1331 sas_rphy_delete(phy_info->rphy); 1726 memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo));
1332 phy_info->rphy = NULL; 1727 phy_info->rphy = NULL;
1333 } 1728 phy_info->starget = NULL;
1334 break; 1729 break;
1335 case MPTSAS_ADD_DEVICE: 1730 case MPTSAS_ADD_DEVICE:
1336 1731
1337 /* 1732 /*
1338 * When there is no sas address, 1733 * Refresh sas device pg0 data
1339 * RAID volumes are being deleted,
1340 * and hidden phy disk are being added.
1341 * We don't know the SAS data yet,
1342 * so lookup sas device page to get
1343 * pertaining info
1344 */ 1734 */
1345 if (!ev->sas_address) { 1735 if (mptsas_sas_device_pg0(ioc, &sas_device,
1346 if (mptsas_sas_device_pg0(ioc, 1736 (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
1347 &sas_device, ev->id, 1737 MPI_SAS_DEVICE_PGAD_FORM_SHIFT), ev->id))
1348 (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID << 1738 break;
1349 MPI_SAS_DEVICE_PGAD_FORM_SHIFT)))
1350 break;
1351 ev->handle = sas_device.handle;
1352 ev->parent_handle = sas_device.handle_parent;
1353 ev->channel = sas_device.channel;
1354 ev->phy_id = sas_device.phy_id;
1355 ev->sas_address = sas_device.sas_address;
1356 ev->device_info = sas_device.device_info;
1357 }
1358 1739
1359 phy_info = mptsas_find_phyinfo_by_parent(ioc, 1740 phy_info = mptsas_find_phyinfo_by_parent(ioc,
1360 ev->parent_handle, ev->phy_id); 1741 sas_device.handle_parent, sas_device.phy_id);
1742
1361 if (!phy_info) { 1743 if (!phy_info) {
1362 printk("mptsas: add event for non-existant PHY.\n"); 1744 u32 handle = 0xFFFF;
1363 break; 1745
1746 /*
1747 * Its possible when an expander has been hot added
1748 * containing attached devices, the sas firmware
1749 * may send a RC_ADDED event prior to the
1750 * DISCOVERY STOP event. If that occurs, our
1751 * view of the topology in the driver in respect to this
1752 * expander might of not been setup, and we hit this
1753 * condition.
1754 * Therefore, this code kicks off discovery to
1755 * refresh the data.
1756 * Then again, we check whether the parent phy has
1757 * been created.
1758 */
1759 ioc->sas_discovery_runtime=1;
1760 mptsas_delete_expander_phys(ioc);
1761 mptsas_probe_hba_phys(ioc);
1762 while (!mptsas_probe_expander_phys(ioc, &handle))
1763 ;
1764 ioc->sas_discovery_runtime=0;
1765
1766 phy_info = mptsas_find_phyinfo_by_parent(ioc,
1767 sas_device.handle_parent, sas_device.phy_id);
1768 if (!phy_info)
1769 break;
1364 } 1770 }
1365 1771
1366 if (phy_info->rphy) { 1772 if (phy_info->starget) {
1367 printk("mptsas: trying to add existing device.\n"); 1773 vtarget = phy_info->starget->hostdata;
1774
1775 if (!vtarget)
1776 break;
1777 /*
1778 * Handling RAID components
1779 */
1780 if (vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) {
1781 vtarget->tflags &= ~MPT_TARGET_FLAGS_RAID_COMPONENT;
1782 vtarget->target_id = ev->id;
1783 mptsas_reprobe_target(phy_info->starget, 0);
1784 }
1368 break; 1785 break;
1369 } 1786 }
1370 1787
1371 /* fill attached info */ 1788 if (phy_info->rphy)
1372 phy_info->attached.handle = ev->handle; 1789 break;
1373 phy_info->attached.phy_id = ev->phy_id; 1790
1374 phy_info->attached.port_id = phy_info->identify.port_id; 1791 memcpy(&phy_info->attached, &sas_device,
1375 phy_info->attached.id = ev->id; 1792 sizeof(struct mptsas_devinfo));
1376 phy_info->attached.channel = ev->channel;
1377 phy_info->attached.sas_address = ev->sas_address;
1378 phy_info->attached.device_info = ev->device_info;
1379 1793
1380 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SSP_TARGET) 1794 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SSP_TARGET)
1381 ds = "ssp"; 1795 ds = "ssp";
@@ -1388,13 +1802,23 @@ mptsas_hotplug_work(void *arg)
1388 "attaching %s device, channel %d, id %d, phy %d\n", 1802 "attaching %s device, channel %d, id %d, phy %d\n",
1389 ioc->name, ds, ev->channel, ev->id, ev->phy_id); 1803 ioc->name, ds, ev->channel, ev->id, ev->phy_id);
1390 1804
1391 1805 mptsas_parse_device_info(&identify, &phy_info->attached);
1392 rphy = sas_rphy_alloc(phy_info->phy); 1806 switch (identify.device_type) {
1807 case SAS_END_DEVICE:
1808 rphy = sas_end_device_alloc(phy_info->phy);
1809 break;
1810 case SAS_EDGE_EXPANDER_DEVICE:
1811 case SAS_FANOUT_EXPANDER_DEVICE:
1812 rphy = sas_expander_alloc(phy_info->phy, identify.device_type);
1813 break;
1814 default:
1815 rphy = NULL;
1816 break;
1817 }
1393 if (!rphy) 1818 if (!rphy)
1394 break; /* non-fatal: an rphy can be added later */ 1819 break; /* non-fatal: an rphy can be added later */
1395 1820
1396 rphy->scsi_target_id = phy_info->attached.id; 1821 rphy->identify = identify;
1397 mptsas_parse_device_info(&rphy->identify, &phy_info->attached);
1398 if (sas_rphy_add(rphy)) { 1822 if (sas_rphy_add(rphy)) {
1399 sas_rphy_free(rphy); 1823 sas_rphy_free(rphy);
1400 break; 1824 break;
@@ -1413,7 +1837,7 @@ mptsas_hotplug_work(void *arg)
1413 break; 1837 break;
1414 } 1838 }
1415 printk(MYIOC_s_INFO_FMT 1839 printk(MYIOC_s_INFO_FMT
1416 "attaching device, channel %d, id %d\n", 1840 "attaching raid volume, channel %d, id %d\n",
1417 ioc->name, ioc->num_ports, ev->id); 1841 ioc->name, ioc->num_ports, ev->id);
1418 scsi_add_device(ioc->sh, 1842 scsi_add_device(ioc->sh,
1419 ioc->num_ports, 1843 ioc->num_ports,
@@ -1430,7 +1854,7 @@ mptsas_hotplug_work(void *arg)
1430 if (!sdev) 1854 if (!sdev)
1431 break; 1855 break;
1432 printk(MYIOC_s_INFO_FMT 1856 printk(MYIOC_s_INFO_FMT
1433 "removing device, channel %d, id %d\n", 1857 "removing raid volume, channel %d, id %d\n",
1434 ioc->name, ioc->num_ports, ev->id); 1858 ioc->name, ioc->num_ports, ev->id);
1435 scsi_remove_device(sdev); 1859 scsi_remove_device(sdev);
1436 scsi_device_put(sdev); 1860 scsi_device_put(sdev);
@@ -1439,6 +1863,7 @@ mptsas_hotplug_work(void *arg)
1439 } 1863 }
1440 1864
1441 kfree(ev); 1865 kfree(ev);
1866 mutex_unlock(&ioc->sas_discovery_mutex);
1442} 1867}
1443 1868
1444static void 1869static void
@@ -1455,35 +1880,51 @@ mptscsih_send_sas_event(MPT_ADAPTER *ioc,
1455 MPI_SAS_DEVICE_INFO_SATA_DEVICE )) == 0) 1880 MPI_SAS_DEVICE_INFO_SATA_DEVICE )) == 0)
1456 return; 1881 return;
1457 1882
1458 if ((sas_event_data->ReasonCode & 1883 switch (sas_event_data->ReasonCode) {
1459 (MPI_EVENT_SAS_DEV_STAT_RC_ADDED | 1884 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
1460 MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING)) == 0) 1885 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
1461 return; 1886 ev = kmalloc(sizeof(*ev), GFP_ATOMIC);
1887 if (!ev) {
1888 printk(KERN_WARNING "mptsas: lost hotplug event\n");
1889 break;
1890 }
1462 1891
1463 ev = kmalloc(sizeof(*ev), GFP_ATOMIC); 1892 INIT_WORK(&ev->work, mptsas_hotplug_work, ev);
1464 if (!ev) { 1893 ev->ioc = ioc;
1465 printk(KERN_WARNING "mptsas: lost hotplug event\n"); 1894 ev->handle = le16_to_cpu(sas_event_data->DevHandle);
1466 return; 1895 ev->parent_handle =
1896 le16_to_cpu(sas_event_data->ParentDevHandle);
1897 ev->channel = sas_event_data->Bus;
1898 ev->id = sas_event_data->TargetID;
1899 ev->phy_id = sas_event_data->PhyNum;
1900 memcpy(&sas_address, &sas_event_data->SASAddress,
1901 sizeof(__le64));
1902 ev->sas_address = le64_to_cpu(sas_address);
1903 ev->device_info = device_info;
1904
1905 if (sas_event_data->ReasonCode &
1906 MPI_EVENT_SAS_DEV_STAT_RC_ADDED)
1907 ev->event_type = MPTSAS_ADD_DEVICE;
1908 else
1909 ev->event_type = MPTSAS_DEL_DEVICE;
1910 schedule_work(&ev->work);
1911 break;
1912 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
1913 /*
1914 * Persistent table is full.
1915 */
1916 INIT_WORK(&ioc->mptscsih_persistTask,
1917 mptscsih_sas_persist_clear_table,
1918 (void *)ioc);
1919 schedule_work(&ioc->mptscsih_persistTask);
1920 break;
1921 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
1922 /* TODO */
1923 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
1924 /* TODO */
1925 default:
1926 break;
1467 } 1927 }
1468
1469
1470 INIT_WORK(&ev->work, mptsas_hotplug_work, ev);
1471 ev->ioc = ioc;
1472 ev->handle = le16_to_cpu(sas_event_data->DevHandle);
1473 ev->parent_handle = le16_to_cpu(sas_event_data->ParentDevHandle);
1474 ev->channel = sas_event_data->Bus;
1475 ev->id = sas_event_data->TargetID;
1476 ev->phy_id = sas_event_data->PhyNum;
1477 memcpy(&sas_address, &sas_event_data->SASAddress, sizeof(__le64));
1478 ev->sas_address = le64_to_cpu(sas_address);
1479 ev->device_info = device_info;
1480
1481 if (sas_event_data->ReasonCode & MPI_EVENT_SAS_DEV_STAT_RC_ADDED)
1482 ev->event_type = MPTSAS_ADD_DEVICE;
1483 else
1484 ev->event_type = MPTSAS_DEL_DEVICE;
1485
1486 schedule_work(&ev->work);
1487} 1928}
1488 1929
1489static void 1930static void
@@ -1512,6 +1953,9 @@ mptscsih_send_raid_event(MPT_ADAPTER *ioc,
1512 ev->event_type = MPTSAS_ADD_DEVICE; 1953 ev->event_type = MPTSAS_ADD_DEVICE;
1513 break; 1954 break;
1514 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED: 1955 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
1956 ioc->raid_data.isRaid = 1;
1957 ev->phys_disk_num_valid = 1;
1958 ev->phys_disk_num = raid_event_data->PhysDiskNum;
1515 ev->event_type = MPTSAS_DEL_DEVICE; 1959 ev->event_type = MPTSAS_DEL_DEVICE;
1516 break; 1960 break;
1517 case MPI_EVENT_RAID_RC_VOLUME_DELETED: 1961 case MPI_EVENT_RAID_RC_VOLUME_DELETED:
@@ -1533,15 +1977,31 @@ mptscsih_send_raid_event(MPT_ADAPTER *ioc,
1533 schedule_work(&ev->work); 1977 schedule_work(&ev->work);
1534} 1978}
1535 1979
1536/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1537/* work queue thread to clear the persitency table */
1538static void 1980static void
1539mptscsih_sas_persist_clear_table(void * arg) 1981mptscsih_send_discovery(MPT_ADAPTER *ioc,
1982 EVENT_DATA_SAS_DISCOVERY *discovery_data)
1540{ 1983{
1541 MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg; 1984 struct mptsas_discovery_event *ev;
1985
1986 /*
1987 * DiscoveryStatus
1988 *
1989 * This flag will be non-zero when firmware
1990 * kicks off discovery, and return to zero
1991 * once its completed.
1992 */
1993 if (discovery_data->DiscoveryStatus)
1994 return;
1995
1996 ev = kmalloc(sizeof(*ev), GFP_ATOMIC);
1997 if (!ev)
1998 return;
1999 memset(ev,0,sizeof(struct mptsas_discovery_event));
2000 INIT_WORK(&ev->work, mptscsih_discovery_work, ev);
2001 ev->ioc = ioc;
2002 schedule_work(&ev->work);
2003};
1542 2004
1543 mptbase_sas_persist_operation(ioc, MPI_SAS_OP_CLEAR_NOT_PRESENT);
1544}
1545 2005
1546static int 2006static int
1547mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply) 2007mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply)
@@ -1552,6 +2012,17 @@ mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply)
1552 if (!ioc->sh) 2012 if (!ioc->sh)
1553 goto out; 2013 goto out;
1554 2014
2015 /*
2016 * sas_discovery_ignore_events
2017 *
2018 * This flag is to prevent anymore processing of
2019 * sas events once mptsas_remove function is called.
2020 */
2021 if (ioc->sas_discovery_ignore_events) {
2022 rc = mptscsih_event_process(ioc, reply);
2023 goto out;
2024 }
2025
1555 switch (event) { 2026 switch (event) {
1556 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE: 2027 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
1557 mptscsih_send_sas_event(ioc, 2028 mptscsih_send_sas_event(ioc,
@@ -1567,6 +2038,10 @@ mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply)
1567 (void *)ioc); 2038 (void *)ioc);
1568 schedule_work(&ioc->mptscsih_persistTask); 2039 schedule_work(&ioc->mptscsih_persistTask);
1569 break; 2040 break;
2041 case MPI_EVENT_SAS_DISCOVERY:
2042 mptscsih_send_discovery(ioc,
2043 (EVENT_DATA_SAS_DISCOVERY *)reply->Data);
2044 break;
1570 default: 2045 default:
1571 rc = mptscsih_event_process(ioc, reply); 2046 rc = mptscsih_event_process(ioc, reply);
1572 break; 2047 break;
@@ -1668,7 +2143,7 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1668 2143
1669 INIT_LIST_HEAD(&ioc->sas_topology); 2144 INIT_LIST_HEAD(&ioc->sas_topology);
1670 mutex_init(&ioc->sas_topology_mutex); 2145 mutex_init(&ioc->sas_topology_mutex);
1671 2146 mutex_init(&ioc->sas_discovery_mutex);
1672 mutex_init(&ioc->sas_mgmt.mutex); 2147 mutex_init(&ioc->sas_mgmt.mutex);
1673 init_completion(&ioc->sas_mgmt.done); 2148 init_completion(&ioc->sas_mgmt.done);
1674 2149
@@ -1781,20 +2256,6 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1781 2256
1782 mptsas_scan_sas_topology(ioc); 2257 mptsas_scan_sas_topology(ioc);
1783 2258
1784 /*
1785 Reporting RAID volumes.
1786 */
1787 if (!ioc->raid_data.pIocPg2)
1788 return 0;
1789 if (!ioc->raid_data.pIocPg2->NumActiveVolumes)
1790 return 0;
1791 for (ii=0;ii<ioc->raid_data.pIocPg2->NumActiveVolumes;ii++) {
1792 scsi_add_device(sh,
1793 ioc->num_ports,
1794 ioc->raid_data.pIocPg2->RaidVolume[ii].VolumeID,
1795 0);
1796 }
1797
1798 return 0; 2259 return 0;
1799 2260
1800out_mptsas_probe: 2261out_mptsas_probe:
@@ -1808,11 +2269,14 @@ static void __devexit mptsas_remove(struct pci_dev *pdev)
1808 MPT_ADAPTER *ioc = pci_get_drvdata(pdev); 2269 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1809 struct mptsas_portinfo *p, *n; 2270 struct mptsas_portinfo *p, *n;
1810 2271
2272 ioc->sas_discovery_ignore_events=1;
1811 sas_remove_host(ioc->sh); 2273 sas_remove_host(ioc->sh);
1812 2274
1813 mutex_lock(&ioc->sas_topology_mutex); 2275 mutex_lock(&ioc->sas_topology_mutex);
1814 list_for_each_entry_safe(p, n, &ioc->sas_topology, list) { 2276 list_for_each_entry_safe(p, n, &ioc->sas_topology, list) {
1815 list_del(&p->list); 2277 list_del(&p->list);
2278 if (p->phy_info)
2279 kfree(p->phy_info);
1816 kfree(p); 2280 kfree(p);
1817 } 2281 }
1818 mutex_unlock(&ioc->sas_topology_mutex); 2282 mutex_unlock(&ioc->sas_topology_mutex);
@@ -1867,7 +2331,7 @@ mptsas_init(void)
1867 mptsasMgmtCtx = mpt_register(mptsas_mgmt_done, MPTSAS_DRIVER); 2331 mptsasMgmtCtx = mpt_register(mptsas_mgmt_done, MPTSAS_DRIVER);
1868 2332
1869 if (mpt_event_register(mptsasDoneCtx, mptsas_event_process) == 0) { 2333 if (mpt_event_register(mptsasDoneCtx, mptsas_event_process) == 0) {
1870 devtprintk((KERN_INFO MYNAM 2334 devtverboseprintk((KERN_INFO MYNAM
1871 ": Registered for IOC event notifications\n")); 2335 ": Registered for IOC event notifications\n"));
1872 } 2336 }
1873 2337
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index 4fee6befc93d..3729062db317 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -114,21 +114,6 @@ typedef struct _internal_cmd {
114 u8 rsvd; 114 u8 rsvd;
115} INTERNAL_CMD; 115} INTERNAL_CMD;
116 116
117typedef struct _negoparms {
118 u8 width;
119 u8 offset;
120 u8 factor;
121 u8 flags;
122} NEGOPARMS;
123
124typedef struct _dv_parameters {
125 NEGOPARMS max;
126 NEGOPARMS now;
127 u8 cmd;
128 u8 id;
129 u16 pad1;
130} DVPARAMETERS;
131
132/* 117/*
133 * Other private/forward protos... 118 * Other private/forward protos...
134 */ 119 */
@@ -149,28 +134,12 @@ static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 tar
149int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset); 134int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
150int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply); 135int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
151 136
152static void mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget, u8 lun, char *data, int dlen); 137static void mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget, struct scsi_device *sdev);
153static void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *vtarget, char byte56); 138static void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *vtarget, struct scsi_device *sdev);
154static void mptscsih_setDevicePage1Flags (u8 width, u8 factor, u8 offset, int *requestedPtr, int *configurationPtr, u8 flags);
155static void mptscsih_no_negotiate(MPT_SCSI_HOST *hd, struct scsi_cmnd *sc);
156static int mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target, int flags);
157static int mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus); 139static int mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus);
158int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r); 140int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
159static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd); 141static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd);
160static void mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice); 142static void mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice);
161static void mptscsih_negotiate_to_asyn_narrow(MPT_SCSI_HOST *hd, VirtDevice *vdevice);
162static int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id);
163
164#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
165static int mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io);
166static void mptscsih_domainValidation(void *hd);
167static void mptscsih_qas_check(MPT_SCSI_HOST *hd, int id);
168static int mptscsih_doDv(MPT_SCSI_HOST *hd, int channel, int target);
169static void mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage);
170static void mptscsih_fillbuf(char *buffer, int size, int index, int width);
171static void mptscsih_set_dvflags_raid(MPT_SCSI_HOST *hd, int id);
172static void mptscsih_set_dvflags(MPT_SCSI_HOST *hd, struct scsi_cmnd *sc);
173#endif
174 143
175void mptscsih_remove(struct pci_dev *); 144void mptscsih_remove(struct pci_dev *);
176void mptscsih_shutdown(struct pci_dev *); 145void mptscsih_shutdown(struct pci_dev *);
@@ -181,16 +150,6 @@ int mptscsih_resume(struct pci_dev *pdev);
181 150
182#define SNS_LEN(scp) sizeof((scp)->sense_buffer) 151#define SNS_LEN(scp) sizeof((scp)->sense_buffer)
183 152
184#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
185/*
186 * Domain Validation task structure
187 */
188static DEFINE_SPINLOCK(dvtaskQ_lock);
189static int dvtaskQ_active = 0;
190static int dvtaskQ_release = 0;
191static struct work_struct dvTaskQ_task;
192#endif
193
194/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 153/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
195/** 154/**
196 * mptscsih_add_sge - Place a simple SGE at address pAddr. 155 * mptscsih_add_sge - Place a simple SGE at address pAddr.
@@ -687,9 +646,6 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
687 */ 646 */
688 sc->result = DID_RESET << 16; 647 sc->result = DID_RESET << 16;
689 648
690 /* GEM Workaround. */
691 if (ioc->bus_type == SPI)
692 mptscsih_no_negotiate(hd, sc);
693 break; 649 break;
694 650
695 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */ 651 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
@@ -931,7 +887,7 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
931 dsprintk(( "search_running: found (sc=%p, mf = %p) target %d, lun %d \n", 887 dsprintk(( "search_running: found (sc=%p, mf = %p) target %d, lun %d \n",
932 hd->ScsiLookup[ii], mf, mf->TargetID, mf->LUN[1])); 888 hd->ScsiLookup[ii], mf, mf->TargetID, mf->LUN[1]));
933 889
934 if ((mf->TargetID != ((u8)vdevice->target_id)) || (mf->LUN[1] != ((u8) vdevice->lun))) 890 if ((mf->TargetID != ((u8)vdevice->vtarget->target_id)) || (mf->LUN[1] != ((u8) vdevice->lun)))
935 continue; 891 continue;
936 892
937 /* Cleanup 893 /* Cleanup
@@ -1005,10 +961,6 @@ mptscsih_remove(struct pci_dev *pdev)
1005 MPT_ADAPTER *ioc = pci_get_drvdata(pdev); 961 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1006 struct Scsi_Host *host = ioc->sh; 962 struct Scsi_Host *host = ioc->sh;
1007 MPT_SCSI_HOST *hd; 963 MPT_SCSI_HOST *hd;
1008#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
1009 int count;
1010 unsigned long flags;
1011#endif
1012 int sz1; 964 int sz1;
1013 965
1014 if(!host) { 966 if(!host) {
@@ -1021,25 +973,6 @@ mptscsih_remove(struct pci_dev *pdev)
1021 if((hd = (MPT_SCSI_HOST *)host->hostdata) == NULL) 973 if((hd = (MPT_SCSI_HOST *)host->hostdata) == NULL)
1022 return; 974 return;
1023 975
1024#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
1025 /* Check DV thread active */
1026 count = 10 * HZ;
1027 spin_lock_irqsave(&dvtaskQ_lock, flags);
1028 if (dvtaskQ_active) {
1029 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
1030 while(dvtaskQ_active && --count)
1031 schedule_timeout_interruptible(1);
1032 } else {
1033 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
1034 }
1035 if (!count)
1036 printk(KERN_ERR MYNAM ": ERROR - DV thread still active!\n");
1037#if defined(MPT_DEBUG_DV) || defined(MPT_DEBUG_DV_TINY)
1038 else
1039 printk(KERN_ERR MYNAM ": DV thread orig %d, count %d\n", 10 * HZ, count);
1040#endif
1041#endif
1042
1043 mptscsih_shutdown(pdev); 976 mptscsih_shutdown(pdev);
1044 977
1045 sz1=0; 978 sz1=0;
@@ -1127,21 +1060,6 @@ mptscsih_resume(struct pci_dev *pdev)
1127 if(!hd) 1060 if(!hd)
1128 return 0; 1061 return 0;
1129 1062
1130#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
1131 {
1132 unsigned long lflags;
1133 spin_lock_irqsave(&dvtaskQ_lock, lflags);
1134 if (!dvtaskQ_active) {
1135 dvtaskQ_active = 1;
1136 spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
1137 INIT_WORK(&dvTaskQ_task,
1138 mptscsih_domainValidation, (void *) hd);
1139 schedule_work(&dvTaskQ_task);
1140 } else {
1141 spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
1142 }
1143 }
1144#endif
1145 return 0; 1063 return 0;
1146} 1064}
1147 1065
@@ -1317,6 +1235,14 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1317 return SCSI_MLQUEUE_HOST_BUSY; 1235 return SCSI_MLQUEUE_HOST_BUSY;
1318 } 1236 }
1319 1237
1238 if ((hd->ioc->bus_type == SPI) &&
1239 vdev->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT &&
1240 mptscsih_raid_id_to_num(hd, SCpnt->device->id) < 0) {
1241 SCpnt->result = DID_NO_CONNECT << 16;
1242 done(SCpnt);
1243 return 0;
1244 }
1245
1320 /* 1246 /*
1321 * Put together a MPT SCSI request... 1247 * Put together a MPT SCSI request...
1322 */ 1248 */
@@ -1360,10 +1286,13 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1360 1286
1361 /* Use the above information to set up the message frame 1287 /* Use the above information to set up the message frame
1362 */ 1288 */
1363 pScsiReq->TargetID = (u8) vdev->target_id; 1289 pScsiReq->TargetID = (u8) vdev->vtarget->target_id;
1364 pScsiReq->Bus = vdev->bus_id; 1290 pScsiReq->Bus = vdev->vtarget->bus_id;
1365 pScsiReq->ChainOffset = 0; 1291 pScsiReq->ChainOffset = 0;
1366 pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST; 1292 if (vdev->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)
1293 pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
1294 else
1295 pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
1367 pScsiReq->CDBLength = SCpnt->cmd_len; 1296 pScsiReq->CDBLength = SCpnt->cmd_len;
1368 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE; 1297 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
1369 pScsiReq->Reserved = 0; 1298 pScsiReq->Reserved = 0;
@@ -1411,49 +1340,6 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1411 hd->ScsiLookup[my_idx] = SCpnt; 1340 hd->ScsiLookup[my_idx] = SCpnt;
1412 SCpnt->host_scribble = NULL; 1341 SCpnt->host_scribble = NULL;
1413 1342
1414#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
1415 if (hd->ioc->bus_type == SPI) {
1416 int dvStatus = hd->ioc->spi_data.dvStatus[vdev->target_id];
1417 int issueCmd = 1;
1418
1419 if (dvStatus || hd->ioc->spi_data.forceDv) {
1420
1421 if ((dvStatus & MPT_SCSICFG_NEED_DV) ||
1422 (hd->ioc->spi_data.forceDv & MPT_SCSICFG_NEED_DV)) {
1423 unsigned long lflags;
1424 /* Schedule DV if necessary */
1425 spin_lock_irqsave(&dvtaskQ_lock, lflags);
1426 if (!dvtaskQ_active) {
1427 dvtaskQ_active = 1;
1428 spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
1429 INIT_WORK(&dvTaskQ_task, mptscsih_domainValidation, (void *) hd);
1430
1431 schedule_work(&dvTaskQ_task);
1432 } else {
1433 spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
1434 }
1435 hd->ioc->spi_data.forceDv &= ~MPT_SCSICFG_NEED_DV;
1436 }
1437
1438 /* Trying to do DV to this target, extend timeout.
1439 * Wait to issue until flag is clear
1440 */
1441 if (dvStatus & MPT_SCSICFG_DV_PENDING) {
1442 mod_timer(&SCpnt->eh_timeout, jiffies + 40 * HZ);
1443 issueCmd = 0;
1444 }
1445
1446 /* Set the DV flags.
1447 */
1448 if (dvStatus & MPT_SCSICFG_DV_NOT_DONE)
1449 mptscsih_set_dvflags(hd, SCpnt);
1450
1451 if (!issueCmd)
1452 goto fail;
1453 }
1454 }
1455#endif
1456
1457 mpt_put_msg_frame(hd->ioc->DoneCtx, hd->ioc, mf); 1343 mpt_put_msg_frame(hd->ioc->DoneCtx, hd->ioc, mf);
1458 dmfprintk((MYIOC_s_INFO_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n", 1344 dmfprintk((MYIOC_s_INFO_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n",
1459 hd->ioc->name, SCpnt, mf, my_idx)); 1345 hd->ioc->name, SCpnt, mf, my_idx));
@@ -1816,7 +1702,7 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
1816 1702
1817 vdev = SCpnt->device->hostdata; 1703 vdev = SCpnt->device->hostdata;
1818 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK, 1704 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
1819 vdev->bus_id, vdev->target_id, vdev->lun, 1705 vdev->vtarget->bus_id, vdev->vtarget->target_id, vdev->lun,
1820 ctx2abort, mptscsih_get_tm_timeout(ioc)); 1706 ctx2abort, mptscsih_get_tm_timeout(ioc));
1821 1707
1822 printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n", 1708 printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n",
@@ -1867,7 +1753,7 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
1867 1753
1868 vdev = SCpnt->device->hostdata; 1754 vdev = SCpnt->device->hostdata;
1869 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 1755 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
1870 vdev->bus_id, vdev->target_id, 1756 vdev->vtarget->bus_id, vdev->vtarget->target_id,
1871 0, 0, mptscsih_get_tm_timeout(hd->ioc)); 1757 0, 0, mptscsih_get_tm_timeout(hd->ioc));
1872 1758
1873 printk (KERN_WARNING MYNAM ": %s: target reset: %s (sc=%p)\n", 1759 printk (KERN_WARNING MYNAM ": %s: target reset: %s (sc=%p)\n",
@@ -1918,7 +1804,7 @@ mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
1918 1804
1919 vdev = SCpnt->device->hostdata; 1805 vdev = SCpnt->device->hostdata;
1920 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS, 1806 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
1921 vdev->bus_id, 0, 0, 0, mptscsih_get_tm_timeout(hd->ioc)); 1807 vdev->vtarget->bus_id, 0, 0, 0, mptscsih_get_tm_timeout(hd->ioc));
1922 1808
1923 printk (KERN_WARNING MYNAM ": %s: bus reset: %s (sc=%p)\n", 1809 printk (KERN_WARNING MYNAM ": %s: bus reset: %s (sc=%p)\n",
1924 hd->ioc->name, 1810 hd->ioc->name,
@@ -2218,6 +2104,42 @@ mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
2218 return 0; 2104 return 0;
2219} 2105}
2220 2106
2107/* Search IOC page 3 to determine if this is hidden physical disk
2108 *
2109 */
2110int
2111mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id)
2112{
2113 int i;
2114
2115 if (!ioc->raid_data.isRaid || !ioc->raid_data.pIocPg3)
2116 return 0;
2117 for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2118 if (id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID)
2119 return 1;
2120 }
2121 return 0;
2122}
2123EXPORT_SYMBOL(mptscsih_is_phys_disk);
2124
2125int
2126mptscsih_raid_id_to_num(MPT_SCSI_HOST *hd, uint physdiskid)
2127{
2128 int i;
2129
2130 if (!hd->ioc->raid_data.isRaid || !hd->ioc->raid_data.pIocPg3)
2131 return -ENXIO;
2132
2133 for (i = 0; i < hd->ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2134 if (physdiskid ==
2135 hd->ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID)
2136 return hd->ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum;
2137 }
2138
2139 return -ENXIO;
2140}
2141EXPORT_SYMBOL(mptscsih_raid_id_to_num);
2142
2221/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 2143/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2222/* 2144/*
2223 * OS entry point to allow host driver to alloc memory 2145 * OS entry point to allow host driver to alloc memory
@@ -2233,6 +2155,7 @@ mptscsih_target_alloc(struct scsi_target *starget)
2233 if (!vtarget) 2155 if (!vtarget)
2234 return -ENOMEM; 2156 return -ENOMEM;
2235 starget->hostdata = vtarget; 2157 starget->hostdata = vtarget;
2158 vtarget->starget = starget;
2236 return 0; 2159 return 0;
2237} 2160}
2238 2161
@@ -2258,14 +2181,12 @@ mptscsih_slave_alloc(struct scsi_device *sdev)
2258 return -ENOMEM; 2181 return -ENOMEM;
2259 } 2182 }
2260 2183
2261 vdev->ioc_id = hd->ioc->id;
2262 vdev->target_id = sdev->id;
2263 vdev->bus_id = sdev->channel;
2264 vdev->lun = sdev->lun; 2184 vdev->lun = sdev->lun;
2265 sdev->hostdata = vdev; 2185 sdev->hostdata = vdev;
2266 2186
2267 starget = scsi_target(sdev); 2187 starget = scsi_target(sdev);
2268 vtarget = starget->hostdata; 2188 vtarget = starget->hostdata;
2189
2269 vdev->vtarget = vtarget; 2190 vdev->vtarget = vtarget;
2270 2191
2271 if (vtarget->num_luns == 0) { 2192 if (vtarget->num_luns == 0) {
@@ -2274,14 +2195,11 @@ mptscsih_slave_alloc(struct scsi_device *sdev)
2274 vtarget->tflags = MPT_TARGET_FLAGS_Q_YES; 2195 vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
2275 vtarget->target_id = sdev->id; 2196 vtarget->target_id = sdev->id;
2276 vtarget->bus_id = sdev->channel; 2197 vtarget->bus_id = sdev->channel;
2277 if (hd->ioc->bus_type == SPI) { 2198 if (hd->ioc->bus_type == SPI && sdev->channel == 0 &&
2278 if (hd->ioc->raid_data.isRaid & (1 << sdev->id)) { 2199 hd->ioc->raid_data.isRaid & (1 << sdev->id)) {
2279 vtarget->raidVolume = 1; 2200 vtarget->raidVolume = 1;
2280 ddvtprintk((KERN_INFO 2201 ddvtprintk((KERN_INFO
2281 "RAID Volume @ id %d\n", sdev->id)); 2202 "RAID Volume @ id %d\n", sdev->id));
2282 }
2283 } else {
2284 vtarget->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
2285 } 2203 }
2286 } 2204 }
2287 vtarget->num_luns++; 2205 vtarget->num_luns++;
@@ -2321,19 +2239,6 @@ mptscsih_slave_destroy(struct scsi_device *sdev)
2321 vtarget->luns[0] &= ~(1 << vdevice->lun); 2239 vtarget->luns[0] &= ~(1 << vdevice->lun);
2322 vtarget->num_luns--; 2240 vtarget->num_luns--;
2323 if (vtarget->num_luns == 0) { 2241 if (vtarget->num_luns == 0) {
2324 mptscsih_negotiate_to_asyn_narrow(hd, vdevice);
2325 if (hd->ioc->bus_type == SPI) {
2326 if (mptscsih_is_phys_disk(hd->ioc, vtarget->target_id)) {
2327 hd->ioc->spi_data.forceDv |= MPT_SCSICFG_RELOAD_IOC_PG3;
2328 } else {
2329 hd->ioc->spi_data.dvStatus[vtarget->target_id] =
2330 MPT_SCSICFG_NEGOTIATE;
2331 if (!hd->negoNvram) {
2332 hd->ioc->spi_data.dvStatus[vtarget->target_id] |=
2333 MPT_SCSICFG_DV_NOT_DONE;
2334 }
2335 }
2336 }
2337 hd->Targets[sdev->id] = NULL; 2242 hd->Targets[sdev->id] = NULL;
2338 } 2243 }
2339 mptscsih_synchronize_cache(hd, vdevice); 2244 mptscsih_synchronize_cache(hd, vdevice);
@@ -2362,18 +2267,13 @@ mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
2362 vtarget = starget->hostdata; 2267 vtarget = starget->hostdata;
2363 2268
2364 if (hd->ioc->bus_type == SPI) { 2269 if (hd->ioc->bus_type == SPI) {
2365 if (vtarget->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY) { 2270 if (!(vtarget->tflags & MPT_TARGET_FLAGS_Q_YES))
2366 if (!(vtarget->tflags & MPT_TARGET_FLAGS_Q_YES))
2367 max_depth = 1;
2368 else if (((vtarget->inq_data[0] & 0x1f) == 0x00) &&
2369 (vtarget->minSyncFactor <= MPT_ULTRA160 ))
2370 max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2371 else
2372 max_depth = MPT_SCSI_CMD_PER_DEV_LOW;
2373 } else {
2374 /* error case - No Inq. Data */
2375 max_depth = 1; 2271 max_depth = 1;
2376 } 2272 else if (sdev->type == TYPE_DISK &&
2273 vtarget->minSyncFactor <= MPT_ULTRA160)
2274 max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2275 else
2276 max_depth = MPT_SCSI_CMD_PER_DEV_LOW;
2377 } else 2277 } else
2378 max_depth = MPT_SCSI_CMD_PER_DEV_HIGH; 2278 max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2379 2279
@@ -2427,8 +2327,7 @@ mptscsih_slave_configure(struct scsi_device *sdev)
2427 lun_index = (vdevice->lun >> 5); /* 32 luns per lun_index */ 2327 lun_index = (vdevice->lun >> 5); /* 32 luns per lun_index */
2428 indexed_lun = (vdevice->lun % 32); 2328 indexed_lun = (vdevice->lun % 32);
2429 vtarget->luns[lun_index] |= (1 << indexed_lun); 2329 vtarget->luns[lun_index] |= (1 << indexed_lun);
2430 mptscsih_initTarget(hd, vtarget, sdev->lun, sdev->inquiry, 2330 mptscsih_initTarget(hd, vtarget, sdev);
2431 sdev->inquiry_len );
2432 mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH); 2331 mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH);
2433 2332
2434 dsprintk((MYIOC_s_INFO_FMT 2333 dsprintk((MYIOC_s_INFO_FMT
@@ -2597,10 +2496,6 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
2597 2496
2598 /* 4. Renegotiate to all devices, if SPI 2497 /* 4. Renegotiate to all devices, if SPI
2599 */ 2498 */
2600 if (ioc->bus_type == SPI) {
2601 dnegoprintk(("writeSDP1: ALL_IDS USE_NVRAM\n"));
2602 mptscsih_writeSDP1(hd, 0, 0, MPT_SCSICFG_ALL_IDS | MPT_SCSICFG_USE_NVRAM);
2603 }
2604 2499
2605 /* 5. Enable new commands to be posted 2500 /* 5. Enable new commands to be posted
2606 */ 2501 */
@@ -2624,13 +2519,6 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
2624 hd->cmdPtr = NULL; 2519 hd->cmdPtr = NULL;
2625 } 2520 }
2626 2521
2627 /* 7. SPI: Set flag to force DV and re-read IOC Page 3
2628 */
2629 if (ioc->bus_type == SPI) {
2630 ioc->spi_data.forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
2631 ddvtprintk(("Set reload IOC Pg3 Flag\n"));
2632 }
2633
2634 /* 7. FC: Rescan for blocked rports which might have returned. 2522 /* 7. FC: Rescan for blocked rports which might have returned.
2635 */ 2523 */
2636 else if (ioc->bus_type == FC) { 2524 else if (ioc->bus_type == FC) {
@@ -2659,7 +2547,7 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2659 int work_count; 2547 int work_count;
2660 unsigned long flags; 2548 unsigned long flags;
2661 2549
2662 devtprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n", 2550 devtverboseprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
2663 ioc->name, event)); 2551 ioc->name, event));
2664 2552
2665 if (ioc->sh == NULL || 2553 if (ioc->sh == NULL ||
@@ -2699,18 +2587,7 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2699 break; 2587 break;
2700 2588
2701 case MPI_EVENT_INTEGRATED_RAID: /* 0B */ 2589 case MPI_EVENT_INTEGRATED_RAID: /* 0B */
2702 {
2703#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
2704 pMpiEventDataRaid_t pRaidEventData =
2705 (pMpiEventDataRaid_t) pEvReply->Data;
2706 /* Domain Validation Needed */
2707 if (ioc->bus_type == SPI &&
2708 pRaidEventData->ReasonCode ==
2709 MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED)
2710 mptscsih_set_dvflags_raid(hd, pRaidEventData->PhysDiskNum);
2711#endif
2712 break; 2590 break;
2713 }
2714 2591
2715 case MPI_EVENT_NONE: /* 00 */ 2592 case MPI_EVENT_NONE: /* 00 */
2716 case MPI_EVENT_LOG_DATA: /* 01 */ 2593 case MPI_EVENT_LOG_DATA: /* 01 */
@@ -2729,9 +2606,7 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2729 * mptscsih_initTarget - Target, LUN alloc/free functionality. 2606 * mptscsih_initTarget - Target, LUN alloc/free functionality.
2730 * @hd: Pointer to MPT_SCSI_HOST structure 2607 * @hd: Pointer to MPT_SCSI_HOST structure
2731 * @vtarget: per target private data 2608 * @vtarget: per target private data
2732 * @lun: SCSI LUN id 2609 * @sdev: SCSI device
2733 * @data: Pointer to data
2734 * @dlen: Number of INQUIRY bytes
2735 * 2610 *
2736 * NOTE: It's only SAFE to call this routine if data points to 2611 * NOTE: It's only SAFE to call this routine if data points to
2737 * sane & valid STANDARD INQUIRY data! 2612 * sane & valid STANDARD INQUIRY data!
@@ -2741,98 +2616,46 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2741 * 2616 *
2742 */ 2617 */
2743static void 2618static void
2744mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget, u8 lun, char *data, int dlen) 2619mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget,
2620 struct scsi_device *sdev)
2745{ 2621{
2746 SpiCfgData *pSpi;
2747 char data_56;
2748 int inq_len;
2749
2750 dinitprintk((MYIOC_s_INFO_FMT "initTarget bus=%d id=%d lun=%d hd=%p\n", 2622 dinitprintk((MYIOC_s_INFO_FMT "initTarget bus=%d id=%d lun=%d hd=%p\n",
2751 hd->ioc->name, vtarget->bus_id, vtarget->target_id, lun, hd)); 2623 hd->ioc->name, vtarget->bus_id, vtarget->target_id, lun, hd));
2752 2624
2753 /*
2754 * If the peripheral qualifier filter is enabled then if the target reports a 0x1
2755 * (i.e. The targer is capable of supporting the specified peripheral device type
2756 * on this logical unit; however, the physical device is not currently connected
2757 * to this logical unit) it will be converted to a 0x3 (i.e. The target is not
2758 * capable of supporting a physical device on this logical unit). This is to work
2759 * around a bug in th emid-layer in some distributions in which the mid-layer will
2760 * continue to try to communicate to the LUN and evntually create a dummy LUN.
2761 */
2762 if (hd->mpt_pq_filter && dlen && (data[0] & 0xE0))
2763 data[0] |= 0x40;
2764
2765 /* Is LUN supported? If so, upper 2 bits will be 0 2625 /* Is LUN supported? If so, upper 2 bits will be 0
2766 * in first byte of inquiry data. 2626 * in first byte of inquiry data.
2767 */ 2627 */
2768 if (data[0] & 0xe0) 2628 if (sdev->inq_periph_qual != 0)
2769 return; 2629 return;
2770 2630
2771 if (vtarget == NULL) 2631 if (vtarget == NULL)
2772 return; 2632 return;
2773 2633
2774 if (data) 2634 vtarget->type = sdev->type;
2775 vtarget->type = data[0];
2776 2635
2777 if (hd->ioc->bus_type != SPI) 2636 if (hd->ioc->bus_type != SPI)
2778 return; 2637 return;
2779 2638
2780 if ((data[0] == TYPE_PROCESSOR) && (hd->ioc->spi_data.Saf_Te)) { 2639 if ((sdev->type == TYPE_PROCESSOR) && (hd->ioc->spi_data.Saf_Te)) {
2781 /* Treat all Processors as SAF-TE if 2640 /* Treat all Processors as SAF-TE if
2782 * command line option is set */ 2641 * command line option is set */
2783 vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED; 2642 vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
2784 mptscsih_writeIOCPage4(hd, vtarget->target_id, vtarget->bus_id); 2643 mptscsih_writeIOCPage4(hd, vtarget->target_id, vtarget->bus_id);
2785 }else if ((data[0] == TYPE_PROCESSOR) && 2644 }else if ((sdev->type == TYPE_PROCESSOR) &&
2786 !(vtarget->tflags & MPT_TARGET_FLAGS_SAF_TE_ISSUED )) { 2645 !(vtarget->tflags & MPT_TARGET_FLAGS_SAF_TE_ISSUED )) {
2787 if ( dlen > 49 ) { 2646 if (sdev->inquiry_len > 49 ) {
2788 vtarget->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY; 2647 if (sdev->inquiry[44] == 'S' &&
2789 if ( data[44] == 'S' && 2648 sdev->inquiry[45] == 'A' &&
2790 data[45] == 'A' && 2649 sdev->inquiry[46] == 'F' &&
2791 data[46] == 'F' && 2650 sdev->inquiry[47] == '-' &&
2792 data[47] == '-' && 2651 sdev->inquiry[48] == 'T' &&
2793 data[48] == 'T' && 2652 sdev->inquiry[49] == 'E' ) {
2794 data[49] == 'E' ) {
2795 vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED; 2653 vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
2796 mptscsih_writeIOCPage4(hd, vtarget->target_id, vtarget->bus_id); 2654 mptscsih_writeIOCPage4(hd, vtarget->target_id, vtarget->bus_id);
2797 } 2655 }
2798 } 2656 }
2799 } 2657 }
2800 if (!(vtarget->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY)) { 2658 mptscsih_setTargetNegoParms(hd, vtarget, sdev);
2801 inq_len = dlen < 8 ? dlen : 8;
2802 memcpy (vtarget->inq_data, data, inq_len);
2803 /* If have not done DV, set the DV flag.
2804 */
2805 pSpi = &hd->ioc->spi_data;
2806 if ((data[0] == TYPE_TAPE) || (data[0] == TYPE_PROCESSOR)) {
2807 if (pSpi->dvStatus[vtarget->target_id] & MPT_SCSICFG_DV_NOT_DONE)
2808 pSpi->dvStatus[vtarget->target_id] |= MPT_SCSICFG_NEED_DV;
2809 }
2810 vtarget->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
2811
2812 data_56 = 0x0F; /* Default to full capabilities if Inq data length is < 57 */
2813 if (dlen > 56) {
2814 if ( (!(vtarget->tflags & MPT_TARGET_FLAGS_VALID_56))) {
2815 /* Update the target capabilities
2816 */
2817 data_56 = data[56];
2818 vtarget->tflags |= MPT_TARGET_FLAGS_VALID_56;
2819 }
2820 }
2821 mptscsih_setTargetNegoParms(hd, vtarget, data_56);
2822 } else {
2823 /* Initial Inquiry may not request enough data bytes to
2824 * obtain byte 57. DV will; if target doesn't return
2825 * at least 57 bytes, data[56] will be zero. */
2826 if (dlen > 56) {
2827 if ( (!(vtarget->tflags & MPT_TARGET_FLAGS_VALID_56))) {
2828 /* Update the target capabilities
2829 */
2830 data_56 = data[56];
2831 vtarget->tflags |= MPT_TARGET_FLAGS_VALID_56;
2832 mptscsih_setTargetNegoParms(hd, vtarget, data_56);
2833 }
2834 }
2835 }
2836} 2659}
2837 2660
2838/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 2661/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -2842,66 +2665,51 @@ mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget, u8 lun, char *data,
2842 * 2665 *
2843 */ 2666 */
2844static void 2667static void
2845mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *target, char byte56) 2668mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *target,
2669 struct scsi_device *sdev)
2846{ 2670{
2847 SpiCfgData *pspi_data = &hd->ioc->spi_data; 2671 SpiCfgData *pspi_data = &hd->ioc->spi_data;
2848 int id = (int) target->target_id; 2672 int id = (int) target->target_id;
2849 int nvram; 2673 int nvram;
2850 VirtTarget *vtarget;
2851 int ii;
2852 u8 width = MPT_NARROW; 2674 u8 width = MPT_NARROW;
2853 u8 factor = MPT_ASYNC; 2675 u8 factor = MPT_ASYNC;
2854 u8 offset = 0; 2676 u8 offset = 0;
2855 u8 version, nfactor; 2677 u8 nfactor;
2856 u8 noQas = 1; 2678 u8 noQas = 1;
2857 2679
2858 target->negoFlags = pspi_data->noQas; 2680 target->negoFlags = pspi_data->noQas;
2859 2681
2860 /* noQas == 0 => device supports QAS. Need byte 56 of Inq to determine 2682 /* noQas == 0 => device supports QAS. */
2861 * support. If available, default QAS to off and allow enabling.
2862 * If not available, default QAS to on, turn off for non-disks.
2863 */
2864 2683
2865 /* Set flags based on Inquiry data 2684 if (sdev->scsi_level < SCSI_2) {
2866 */
2867 version = target->inq_data[2] & 0x07;
2868 if (version < 2) {
2869 width = 0; 2685 width = 0;
2870 factor = MPT_ULTRA2; 2686 factor = MPT_ULTRA2;
2871 offset = pspi_data->maxSyncOffset; 2687 offset = pspi_data->maxSyncOffset;
2872 target->tflags &= ~MPT_TARGET_FLAGS_Q_YES; 2688 target->tflags &= ~MPT_TARGET_FLAGS_Q_YES;
2873 } else { 2689 } else {
2874 if (target->inq_data[7] & 0x20) { 2690 if (scsi_device_wide(sdev)) {
2875 width = 1; 2691 width = 1;
2876 } 2692 }
2877 2693
2878 if (target->inq_data[7] & 0x10) { 2694 if (scsi_device_sync(sdev)) {
2879 factor = pspi_data->minSyncFactor; 2695 factor = pspi_data->minSyncFactor;
2880 if (target->tflags & MPT_TARGET_FLAGS_VALID_56) { 2696 if (!scsi_device_dt(sdev))
2881 /* bits 2 & 3 show Clocking support */
2882 if ((byte56 & 0x0C) == 0)
2883 factor = MPT_ULTRA2; 2697 factor = MPT_ULTRA2;
2698 else {
2699 if (!scsi_device_ius(sdev) &&
2700 !scsi_device_qas(sdev))
2701 factor = MPT_ULTRA160;
2884 else { 2702 else {
2885 if ((byte56 & 0x03) == 0) 2703 factor = MPT_ULTRA320;
2886 factor = MPT_ULTRA160; 2704 if (scsi_device_qas(sdev)) {
2887 else { 2705 ddvtprintk((KERN_INFO "Enabling QAS due to byte56=%02x on id=%d!\n", byte56, id));
2888 factor = MPT_ULTRA320; 2706 noQas = 0;
2889 if (byte56 & 0x02)
2890 {
2891 ddvtprintk((KERN_INFO "Enabling QAS due to byte56=%02x on id=%d!\n", byte56, id));
2892 noQas = 0;
2893 }
2894 if (target->inq_data[0] == TYPE_TAPE) {
2895 if (byte56 & 0x01)
2896 target->negoFlags |= MPT_TAPE_NEGO_IDP;
2897 }
2898 } 2707 }
2708 if (sdev->type == TYPE_TAPE &&
2709 scsi_device_ius(sdev))
2710 target->negoFlags |= MPT_TAPE_NEGO_IDP;
2899 } 2711 }
2900 } else {
2901 ddvtprintk((KERN_INFO "Enabling QAS on id=%d due to ~TARGET_FLAGS_VALID_56!\n", id));
2902 noQas = 0;
2903 } 2712 }
2904
2905 offset = pspi_data->maxSyncOffset; 2713 offset = pspi_data->maxSyncOffset;
2906 2714
2907 /* If RAID, never disable QAS 2715 /* If RAID, never disable QAS
@@ -2919,7 +2727,7 @@ mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *target, char byte56)
2919 } 2727 }
2920 } 2728 }
2921 2729
2922 if ( (target->inq_data[7] & 0x02) == 0) { 2730 if (!sdev->tagged_supported) {
2923 target->tflags &= ~MPT_TARGET_FLAGS_Q_YES; 2731 target->tflags &= ~MPT_TARGET_FLAGS_Q_YES;
2924 } 2732 }
2925 2733
@@ -2977,305 +2785,23 @@ mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *target, char byte56)
2977 if ( factor > MPT_ULTRA320 ) 2785 if ( factor > MPT_ULTRA320 )
2978 noQas = 0; 2786 noQas = 0;
2979 2787
2980 /* GEM, processor WORKAROUND 2788 if (noQas && (pspi_data->noQas == 0)) {
2981 */ 2789 pspi_data->noQas |= MPT_TARGET_NO_NEGO_QAS;
2982 if ((target->inq_data[0] == TYPE_PROCESSOR) || (target->inq_data[0] > 0x08)) { 2790 target->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
2983 target->negoFlags |= (MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC); 2791
2984 pspi_data->dvStatus[id] |= MPT_SCSICFG_BLK_NEGO; 2792 /* Disable QAS in a mixed configuration case
2985 } else { 2793 */
2986 if (noQas && (pspi_data->noQas == 0)) {
2987 pspi_data->noQas |= MPT_TARGET_NO_NEGO_QAS;
2988 target->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
2989
2990 /* Disable QAS in a mixed configuration case
2991 */
2992
2993 ddvtprintk((KERN_INFO "Disabling QAS due to noQas=%02x on id=%d!\n", noQas, id));
2994 for (ii = 0; ii < id; ii++) {
2995 if ( (vtarget = hd->Targets[ii]) ) {
2996 vtarget->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
2997 mptscsih_writeSDP1(hd, 0, ii, vtarget->negoFlags);
2998 }
2999 }
3000 }
3001 }
3002 2794
3003 /* Write SDP1 on this I/O to this target */ 2795 ddvtprintk((KERN_INFO "Disabling QAS due to noQas=%02x on id=%d!\n", noQas, id));
3004 if (pspi_data->dvStatus[id] & MPT_SCSICFG_NEGOTIATE) {
3005 ddvtprintk((KERN_INFO "MPT_SCSICFG_NEGOTIATE on id=%d!\n", id));
3006 mptscsih_writeSDP1(hd, 0, id, hd->negoNvram);
3007 pspi_data->dvStatus[id] &= ~MPT_SCSICFG_NEGOTIATE;
3008 } else if (pspi_data->dvStatus[id] & MPT_SCSICFG_BLK_NEGO) {
3009 ddvtprintk((KERN_INFO "MPT_SCSICFG_BLK_NEGO on id=%d!\n", id));
3010 mptscsih_writeSDP1(hd, 0, id, MPT_SCSICFG_BLK_NEGO);
3011 pspi_data->dvStatus[id] &= ~MPT_SCSICFG_BLK_NEGO;
3012 } 2796 }
3013} 2797}
3014 2798
3015/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 2799/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3016/*
3017 * If no Target, bus reset on 1st I/O. Set the flag to
3018 * prevent any future negotiations to this device.
3019 */
3020static void
3021mptscsih_no_negotiate(MPT_SCSI_HOST *hd, struct scsi_cmnd *sc)
3022{
3023 VirtDevice *vdev;
3024
3025 if ((vdev = sc->device->hostdata) != NULL)
3026 hd->ioc->spi_data.dvStatus[vdev->target_id] |= MPT_SCSICFG_BLK_NEGO;
3027 return;
3028}
3029 2800
3030/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 2801/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3031/* 2802/*
3032 * SCSI Config Page functionality ... 2803 * SCSI Config Page functionality ...
3033 */ 2804 */
3034/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3035/* mptscsih_setDevicePage1Flags - add Requested and Configuration fields flags
3036 * based on width, factor and offset parameters.
3037 * @width: bus width
3038 * @factor: sync factor
3039 * @offset: sync offset
3040 * @requestedPtr: pointer to requested values (updated)
3041 * @configurationPtr: pointer to configuration values (updated)
3042 * @flags: flags to block WDTR or SDTR negotiation
3043 *
3044 * Return: None.
3045 *
3046 * Remark: Called by writeSDP1 and _dv_params
3047 */
3048static void
3049mptscsih_setDevicePage1Flags (u8 width, u8 factor, u8 offset, int *requestedPtr, int *configurationPtr, u8 flags)
3050{
3051 u8 nowide = flags & MPT_TARGET_NO_NEGO_WIDE;
3052 u8 nosync = flags & MPT_TARGET_NO_NEGO_SYNC;
3053
3054 *configurationPtr = 0;
3055 *requestedPtr = width ? MPI_SCSIDEVPAGE1_RP_WIDE : 0;
3056 *requestedPtr |= (offset << 16) | (factor << 8);
3057
3058 if (width && offset && !nowide && !nosync) {
3059 if (factor < MPT_ULTRA160) {
3060 *requestedPtr |= (MPI_SCSIDEVPAGE1_RP_IU + MPI_SCSIDEVPAGE1_RP_DT);
3061 if ((flags & MPT_TARGET_NO_NEGO_QAS) == 0)
3062 *requestedPtr |= MPI_SCSIDEVPAGE1_RP_QAS;
3063 if (flags & MPT_TAPE_NEGO_IDP)
3064 *requestedPtr |= 0x08000000;
3065 } else if (factor < MPT_ULTRA2) {
3066 *requestedPtr |= MPI_SCSIDEVPAGE1_RP_DT;
3067 }
3068 }
3069
3070 if (nowide)
3071 *configurationPtr |= MPI_SCSIDEVPAGE1_CONF_WDTR_DISALLOWED;
3072
3073 if (nosync)
3074 *configurationPtr |= MPI_SCSIDEVPAGE1_CONF_SDTR_DISALLOWED;
3075
3076 return;
3077}
3078
3079/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3080/* mptscsih_writeSDP1 - write SCSI Device Page 1
3081 * @hd: Pointer to a SCSI Host Strucutre
3082 * @portnum: IOC port number
3083 * @target_id: writeSDP1 for single ID
3084 * @flags: MPT_SCSICFG_ALL_IDS, MPT_SCSICFG_USE_NVRAM, MPT_SCSICFG_BLK_NEGO
3085 *
3086 * Return: -EFAULT if read of config page header fails
3087 * or 0 if success.
3088 *
3089 * Remark: If a target has been found, the settings from the
3090 * target structure are used, else the device is set
3091 * to async/narrow.
3092 *
3093 * Remark: Called during init and after a FW reload.
3094 * Remark: We do not wait for a return, write pages sequentially.
3095 */
3096static int
3097mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags)
3098{
3099 MPT_ADAPTER *ioc = hd->ioc;
3100 Config_t *pReq;
3101 SCSIDevicePage1_t *pData;
3102 VirtTarget *vtarget=NULL;
3103 MPT_FRAME_HDR *mf;
3104 dma_addr_t dataDma;
3105 u16 req_idx;
3106 u32 frameOffset;
3107 u32 requested, configuration, flagsLength;
3108 int ii, nvram;
3109 int id = 0, maxid = 0;
3110 u8 width;
3111 u8 factor;
3112 u8 offset;
3113 u8 bus = 0;
3114 u8 negoFlags;
3115 u8 maxwidth, maxoffset, maxfactor;
3116
3117 if (ioc->spi_data.sdp1length == 0)
3118 return 0;
3119
3120 if (flags & MPT_SCSICFG_ALL_IDS) {
3121 id = 0;
3122 maxid = ioc->sh->max_id - 1;
3123 } else if (ioc->sh) {
3124 id = target_id;
3125 maxid = min_t(int, id, ioc->sh->max_id - 1);
3126 }
3127
3128 for (; id <= maxid; id++) {
3129
3130 if (id == ioc->pfacts[portnum].PortSCSIID)
3131 continue;
3132
3133 /* Use NVRAM to get adapter and target maximums
3134 * Data over-riden by target structure information, if present
3135 */
3136 maxwidth = ioc->spi_data.maxBusWidth;
3137 maxoffset = ioc->spi_data.maxSyncOffset;
3138 maxfactor = ioc->spi_data.minSyncFactor;
3139 if (ioc->spi_data.nvram && (ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
3140 nvram = ioc->spi_data.nvram[id];
3141
3142 if (maxwidth)
3143 maxwidth = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
3144
3145 if (maxoffset > 0) {
3146 maxfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8;
3147 if (maxfactor == 0) {
3148 /* Key for async */
3149 maxfactor = MPT_ASYNC;
3150 maxoffset = 0;
3151 } else if (maxfactor < ioc->spi_data.minSyncFactor) {
3152 maxfactor = ioc->spi_data.minSyncFactor;
3153 }
3154 } else
3155 maxfactor = MPT_ASYNC;
3156 }
3157
3158 /* Set the negotiation flags.
3159 */
3160 negoFlags = ioc->spi_data.noQas;
3161 if (!maxwidth)
3162 negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
3163
3164 if (!maxoffset)
3165 negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
3166
3167 if (flags & MPT_SCSICFG_USE_NVRAM) {
3168 width = maxwidth;
3169 factor = maxfactor;
3170 offset = maxoffset;
3171 } else {
3172 width = 0;
3173 factor = MPT_ASYNC;
3174 offset = 0;
3175 //negoFlags = 0;
3176 //negoFlags = MPT_TARGET_NO_NEGO_SYNC;
3177 }
3178
3179 /* If id is not a raid volume, get the updated
3180 * transmission settings from the target structure.
3181 */
3182 if (hd->Targets && (vtarget = hd->Targets[id]) && !vtarget->raidVolume) {
3183 width = vtarget->maxWidth;
3184 factor = vtarget->minSyncFactor;
3185 offset = vtarget->maxOffset;
3186 negoFlags = vtarget->negoFlags;
3187 }
3188
3189#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
3190 /* Force to async and narrow if DV has not been executed
3191 * for this ID
3192 */
3193 if ((hd->ioc->spi_data.dvStatus[id] & MPT_SCSICFG_DV_NOT_DONE) != 0) {
3194 width = 0;
3195 factor = MPT_ASYNC;
3196 offset = 0;
3197 }
3198#endif
3199
3200 if (flags & MPT_SCSICFG_BLK_NEGO)
3201 negoFlags |= MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC;
3202
3203 mptscsih_setDevicePage1Flags(width, factor, offset,
3204 &requested, &configuration, negoFlags);
3205 dnegoprintk(("writeSDP1: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
3206 target_id, width, factor, offset, negoFlags, requested, configuration));
3207
3208 /* Get a MF for this command.
3209 */
3210 if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) {
3211 dfailprintk((MYIOC_s_WARN_FMT "write SDP1: no msg frames!\n",
3212 ioc->name));
3213 return -EAGAIN;
3214 }
3215
3216 ddvprintk((MYIOC_s_INFO_FMT "WriteSDP1 (mf=%p, id=%d, req=0x%x, cfg=0x%x)\n",
3217 hd->ioc->name, mf, id, requested, configuration));
3218
3219
3220 /* Set the request and the data pointers.
3221 * Request takes: 36 bytes (32 bit SGE)
3222 * SCSI Device Page 1 requires 16 bytes
3223 * 40 + 16 <= size of SCSI IO Request = 56 bytes
3224 * and MF size >= 64 bytes.
3225 * Place data at end of MF.
3226 */
3227 pReq = (Config_t *)mf;
3228
3229 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3230 frameOffset = ioc->req_sz - sizeof(SCSIDevicePage1_t);
3231
3232 pData = (SCSIDevicePage1_t *)((u8 *) mf + frameOffset);
3233 dataDma = ioc->req_frames_dma + (req_idx * ioc->req_sz) + frameOffset;
3234
3235 /* Complete the request frame (same for all requests).
3236 */
3237 pReq->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
3238 pReq->Reserved = 0;
3239 pReq->ChainOffset = 0;
3240 pReq->Function = MPI_FUNCTION_CONFIG;
3241 pReq->ExtPageLength = 0;
3242 pReq->ExtPageType = 0;
3243 pReq->MsgFlags = 0;
3244 for (ii=0; ii < 8; ii++) {
3245 pReq->Reserved2[ii] = 0;
3246 }
3247 pReq->Header.PageVersion = ioc->spi_data.sdp1version;
3248 pReq->Header.PageLength = ioc->spi_data.sdp1length;
3249 pReq->Header.PageNumber = 1;
3250 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
3251 pReq->PageAddress = cpu_to_le32(id | (bus << 8 ));
3252
3253 /* Add a SGE to the config request.
3254 */
3255 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE | ioc->spi_data.sdp1length * 4;
3256
3257 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma);
3258
3259 /* Set up the common data portion
3260 */
3261 pData->Header.PageVersion = pReq->Header.PageVersion;
3262 pData->Header.PageLength = pReq->Header.PageLength;
3263 pData->Header.PageNumber = pReq->Header.PageNumber;
3264 pData->Header.PageType = pReq->Header.PageType;
3265 pData->RequestedParameters = cpu_to_le32(requested);
3266 pData->Reserved = 0;
3267 pData->Configuration = cpu_to_le32(configuration);
3268
3269 dprintk((MYIOC_s_INFO_FMT
3270 "write SDP1: id %d pgaddr 0x%x req 0x%x config 0x%x\n",
3271 ioc->name, id, (id | (bus<<8)),
3272 requested, configuration));
3273
3274 mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
3275 }
3276
3277 return 0;
3278}
3279 2805
3280/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 2806/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3281/* mptscsih_writeIOCPage4 - write IOC Page 4 2807/* mptscsih_writeIOCPage4 - write IOC Page 4
@@ -3465,6 +2991,7 @@ mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
3465 completionCode = MPT_SCANDV_GOOD; 2991 completionCode = MPT_SCANDV_GOOD;
3466 else 2992 else
3467 completionCode = MPT_SCANDV_SOME_ERROR; 2993 completionCode = MPT_SCANDV_SOME_ERROR;
2994 memcpy(hd->pLocal->sense, pr, sizeof(hd->pLocal->sense));
3468 2995
3469 } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID) { 2996 } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID) {
3470 u8 *sense_data; 2997 u8 *sense_data;
@@ -3578,78 +3105,6 @@ mptscsih_timer_expired(unsigned long data)
3578 return; 3105 return;
3579} 3106}
3580 3107
3581#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
3582/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3583/* mptscsih_do_raid - Format and Issue a RAID volume request message.
3584 * @hd: Pointer to scsi host structure
3585 * @action: What do be done.
3586 * @id: Logical target id.
3587 * @bus: Target locations bus.
3588 *
3589 * Returns: < 0 on a fatal error
3590 * 0 on success
3591 *
3592 * Remark: Wait to return until reply processed by the ISR.
3593 */
3594static int
3595mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io)
3596{
3597 MpiRaidActionRequest_t *pReq;
3598 MPT_FRAME_HDR *mf;
3599 int in_isr;
3600
3601 in_isr = in_interrupt();
3602 if (in_isr) {
3603 dprintk((MYIOC_s_WARN_FMT "Internal raid request not allowed in ISR context!\n",
3604 hd->ioc->name));
3605 return -EPERM;
3606 }
3607
3608 /* Get and Populate a free Frame
3609 */
3610 if ((mf = mpt_get_msg_frame(hd->ioc->InternalCtx, hd->ioc)) == NULL) {
3611 ddvprintk((MYIOC_s_WARN_FMT "_do_raid: no msg frames!\n",
3612 hd->ioc->name));
3613 return -EAGAIN;
3614 }
3615 pReq = (MpiRaidActionRequest_t *)mf;
3616 pReq->Action = action;
3617 pReq->Reserved1 = 0;
3618 pReq->ChainOffset = 0;
3619 pReq->Function = MPI_FUNCTION_RAID_ACTION;
3620 pReq->VolumeID = io->id;
3621 pReq->VolumeBus = io->bus;
3622 pReq->PhysDiskNum = io->physDiskNum;
3623 pReq->MsgFlags = 0;
3624 pReq->Reserved2 = 0;
3625 pReq->ActionDataWord = 0; /* Reserved for this action */
3626 //pReq->ActionDataSGE = 0;
3627
3628 mpt_add_sge((char *)&pReq->ActionDataSGE,
3629 MPT_SGE_FLAGS_SSIMPLE_READ | 0, (dma_addr_t) -1);
3630
3631 ddvprintk((MYIOC_s_INFO_FMT "RAID Volume action %x id %d\n",
3632 hd->ioc->name, action, io->id));
3633
3634 hd->pLocal = NULL;
3635 hd->timer.expires = jiffies + HZ*10; /* 10 second timeout */
3636 hd->scandv_wait_done = 0;
3637
3638 /* Save cmd pointer, for resource free if timeout or
3639 * FW reload occurs
3640 */
3641 hd->cmdPtr = mf;
3642
3643 add_timer(&hd->timer);
3644 mpt_put_msg_frame(hd->ioc->InternalCtx, hd->ioc, mf);
3645 wait_event(hd->scandv_waitq, hd->scandv_wait_done);
3646
3647 if ((hd->pLocal == NULL) || (hd->pLocal->completion != MPT_SCANDV_GOOD))
3648 return -1;
3649
3650 return 0;
3651}
3652#endif /* ~MPTSCSIH_ENABLE_DOMAIN_VALIDATION */
3653 3108
3654/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 3109/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3655/** 3110/**
@@ -3903,93 +3358,6 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
3903 3358
3904/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 3359/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3905/** 3360/**
3906 * mptscsih_negotiate_to_asyn_narrow - Restore devices to default state
3907 * @hd: Pointer to a SCSI HOST structure
3908 * @vtarget: per device private data
3909 *
3910 * Uses the ISR, but with special processing.
3911 * MUST be single-threaded.
3912 *
3913 */
3914static void
3915mptscsih_negotiate_to_asyn_narrow(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
3916{
3917 VirtTarget *vtarget = vdevice->vtarget;
3918 MPT_ADAPTER *ioc= hd->ioc;
3919 SCSIDevicePage1_t *pcfg1Data;
3920 CONFIGPARMS cfg;
3921 dma_addr_t cfg1_dma_addr;
3922 ConfigPageHeader_t header;
3923 int id;
3924 int requested, configuration, data,i;
3925 u8 flags, factor;
3926
3927 if ((ioc->bus_type != SPI) ||
3928 (!vdevice->configured_lun))
3929 return;
3930
3931 if (!ioc->spi_data.sdp1length)
3932 return;
3933
3934 pcfg1Data = (SCSIDevicePage1_t *)pci_alloc_consistent(ioc->pcidev,
3935 ioc->spi_data.sdp1length * 4, &cfg1_dma_addr);
3936
3937 if (pcfg1Data == NULL)
3938 return;
3939
3940 header.PageVersion = ioc->spi_data.sdp1version;
3941 header.PageLength = ioc->spi_data.sdp1length;
3942 header.PageNumber = 1;
3943 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
3944 cfg.cfghdr.hdr = &header;
3945 cfg.physAddr = cfg1_dma_addr;
3946 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
3947 cfg.dir = 1;
3948 cfg.timeout = 0;
3949
3950 if (vtarget->raidVolume && ioc->raid_data.pIocPg3) {
3951 for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
3952 id = ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID;
3953 flags = hd->ioc->spi_data.noQas;
3954 if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
3955 data = hd->ioc->spi_data.nvram[id];
3956 if (data & MPT_NVRAM_WIDE_DISABLE)
3957 flags |= MPT_TARGET_NO_NEGO_WIDE;
3958 factor = (data & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT;
3959 if ((factor == 0) || (factor == MPT_ASYNC))
3960 flags |= MPT_TARGET_NO_NEGO_SYNC;
3961 }
3962 mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested,
3963 &configuration, flags);
3964 dnegoprintk(("nego asyn narrow: id=%d width=0 factor=MPT_ASYNC "
3965 "offset=0 negoFlags=%x request=%x config=%x\n",
3966 id, flags, requested, configuration));
3967 pcfg1Data->RequestedParameters = cpu_to_le32(requested);
3968 pcfg1Data->Reserved = 0;
3969 pcfg1Data->Configuration = cpu_to_le32(configuration);
3970 cfg.pageAddr = (vtarget->bus_id<<8) | id;
3971 mpt_config(hd->ioc, &cfg);
3972 }
3973 } else {
3974 flags = vtarget->negoFlags;
3975 mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested,
3976 &configuration, flags);
3977 dnegoprintk(("nego asyn narrow: id=%d width=0 factor=MPT_ASYNC "
3978 "offset=0 negoFlags=%x request=%x config=%x\n",
3979 vtarget->target_id, flags, requested, configuration));
3980 pcfg1Data->RequestedParameters = cpu_to_le32(requested);
3981 pcfg1Data->Reserved = 0;
3982 pcfg1Data->Configuration = cpu_to_le32(configuration);
3983 cfg.pageAddr = (vtarget->bus_id<<8) | vtarget->target_id;
3984 mpt_config(hd->ioc, &cfg);
3985 }
3986
3987 if (pcfg1Data)
3988 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pcfg1Data, cfg1_dma_addr);
3989}
3990
3991/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3992/**
3993 * mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks. 3361 * mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks.
3994 * @hd: Pointer to a SCSI HOST structure 3362 * @hd: Pointer to a SCSI HOST structure
3995 * @vtarget: per device private data 3363 * @vtarget: per device private data
@@ -4014,1637 +3382,15 @@ mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
4014 iocmd.data_dma = -1; 3382 iocmd.data_dma = -1;
4015 iocmd.size = 0; 3383 iocmd.size = 0;
4016 iocmd.rsvd = iocmd.rsvd2 = 0; 3384 iocmd.rsvd = iocmd.rsvd2 = 0;
4017 iocmd.bus = vdevice->bus_id; 3385 iocmd.bus = vdevice->vtarget->bus_id;
4018 iocmd.id = vdevice->target_id; 3386 iocmd.id = vdevice->vtarget->target_id;
4019 iocmd.lun = (u8)vdevice->lun; 3387 iocmd.lun = (u8)vdevice->lun;
4020 3388
4021 if ((vdevice->vtarget->type & TYPE_DISK) && 3389 if ((vdevice->vtarget->type == TYPE_DISK) &&
4022 (vdevice->configured_lun)) 3390 (vdevice->configured_lun))
4023 mptscsih_do_cmd(hd, &iocmd); 3391 mptscsih_do_cmd(hd, &iocmd);
4024} 3392}
4025 3393
4026/* Search IOC page 3 to determine if this is hidden physical disk
4027 */
4028static int
4029mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id)
4030{
4031 int i;
4032
4033 if (!ioc->raid_data.isRaid || !ioc->raid_data.pIocPg3)
4034 return 0;
4035
4036 for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
4037 if (id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID)
4038 return 1;
4039 }
4040
4041 return 0;
4042}
4043
4044#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
4045/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4046/**
4047 * mptscsih_domainValidation - Top level handler for domain validation.
4048 * @hd: Pointer to MPT_SCSI_HOST structure.
4049 *
4050 * Uses the ISR, but with special processing.
4051 * Called from schedule, should not be in interrupt mode.
4052 * While thread alive, do dv for all devices needing dv
4053 *
4054 * Return: None.
4055 */
4056static void
4057mptscsih_domainValidation(void *arg)
4058{
4059 MPT_SCSI_HOST *hd;
4060 MPT_ADAPTER *ioc;
4061 unsigned long flags;
4062 int id, maxid, dvStatus, did;
4063 int ii, isPhysDisk;
4064
4065 spin_lock_irqsave(&dvtaskQ_lock, flags);
4066 dvtaskQ_active = 1;
4067 if (dvtaskQ_release) {
4068 dvtaskQ_active = 0;
4069 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4070 return;
4071 }
4072 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4073
4074 /* For this ioc, loop through all devices and do dv to each device.
4075 * When complete with this ioc, search through the ioc list, and
4076 * for each scsi ioc found, do dv for all devices. Exit when no
4077 * device needs dv.
4078 */
4079 did = 1;
4080 while (did) {
4081 did = 0;
4082 list_for_each_entry(ioc, &ioc_list, list) {
4083 spin_lock_irqsave(&dvtaskQ_lock, flags);
4084 if (dvtaskQ_release) {
4085 dvtaskQ_active = 0;
4086 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4087 return;
4088 }
4089 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4090
4091 msleep(250);
4092
4093 /* DV only to SPI adapters */
4094 if (ioc->bus_type != SPI)
4095 continue;
4096
4097 /* Make sure everything looks ok */
4098 if (ioc->sh == NULL)
4099 continue;
4100
4101 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
4102 if (hd == NULL)
4103 continue;
4104
4105 if ((ioc->spi_data.forceDv & MPT_SCSICFG_RELOAD_IOC_PG3) != 0) {
4106 mpt_read_ioc_pg_3(ioc);
4107 if (ioc->raid_data.pIocPg3) {
4108 Ioc3PhysDisk_t *pPDisk = ioc->raid_data.pIocPg3->PhysDisk;
4109 int numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
4110
4111 while (numPDisk) {
4112 if (ioc->spi_data.dvStatus[pPDisk->PhysDiskID] & MPT_SCSICFG_DV_NOT_DONE)
4113 ioc->spi_data.dvStatus[pPDisk->PhysDiskID] |= MPT_SCSICFG_NEED_DV;
4114
4115 pPDisk++;
4116 numPDisk--;
4117 }
4118 }
4119 ioc->spi_data.forceDv &= ~MPT_SCSICFG_RELOAD_IOC_PG3;
4120 }
4121
4122 maxid = min_t(int, ioc->sh->max_id, MPT_MAX_SCSI_DEVICES);
4123
4124 for (id = 0; id < maxid; id++) {
4125 spin_lock_irqsave(&dvtaskQ_lock, flags);
4126 if (dvtaskQ_release) {
4127 dvtaskQ_active = 0;
4128 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4129 return;
4130 }
4131 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4132 dvStatus = hd->ioc->spi_data.dvStatus[id];
4133
4134 if (dvStatus & MPT_SCSICFG_NEED_DV) {
4135 did++;
4136 hd->ioc->spi_data.dvStatus[id] |= MPT_SCSICFG_DV_PENDING;
4137 hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_NEED_DV;
4138
4139 msleep(250);
4140
4141 /* If hidden phys disk, block IO's to all
4142 * raid volumes
4143 * else, process normally
4144 */
4145 isPhysDisk = mptscsih_is_phys_disk(ioc, id);
4146 if (isPhysDisk) {
4147 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4148 if (hd->ioc->raid_data.isRaid & (1 << ii)) {
4149 hd->ioc->spi_data.dvStatus[ii] |= MPT_SCSICFG_DV_PENDING;
4150 }
4151 }
4152 }
4153
4154 if(mpt_alt_ioc_wait(hd->ioc)!=0) {
4155 ddvprintk((MYIOC_s_WARN_FMT "alt_ioc busy!\n",
4156 hd->ioc->name));
4157 continue;
4158 }
4159
4160 if (mptscsih_doDv(hd, 0, id) == 1) {
4161 /* Untagged device was busy, try again
4162 */
4163 hd->ioc->spi_data.dvStatus[id] |= MPT_SCSICFG_NEED_DV;
4164 hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_DV_PENDING;
4165 } else {
4166 /* DV is complete. Clear flags.
4167 */
4168 hd->ioc->spi_data.dvStatus[id] &= ~(MPT_SCSICFG_DV_NOT_DONE | MPT_SCSICFG_DV_PENDING);
4169 }
4170
4171 spin_lock(&hd->ioc->initializing_hba_lock);
4172 hd->ioc->initializing_hba_lock_flag=0;
4173 spin_unlock(&hd->ioc->initializing_hba_lock);
4174
4175 if (isPhysDisk) {
4176 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4177 if (hd->ioc->raid_data.isRaid & (1 << ii)) {
4178 hd->ioc->spi_data.dvStatus[ii] &= ~MPT_SCSICFG_DV_PENDING;
4179 }
4180 }
4181 }
4182
4183 if (hd->ioc->spi_data.noQas)
4184 mptscsih_qas_check(hd, id);
4185 }
4186 }
4187 }
4188 }
4189
4190 spin_lock_irqsave(&dvtaskQ_lock, flags);
4191 dvtaskQ_active = 0;
4192 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4193
4194 return;
4195}
4196
4197/* Write SDP1 if no QAS has been enabled
4198 */
4199static void
4200mptscsih_qas_check(MPT_SCSI_HOST *hd, int id)
4201{
4202 VirtTarget *vtarget;
4203 int ii;
4204
4205 if (hd->Targets == NULL)
4206 return;
4207
4208 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4209 if (ii == id)
4210 continue;
4211
4212 if ((hd->ioc->spi_data.dvStatus[ii] & MPT_SCSICFG_DV_NOT_DONE) != 0)
4213 continue;
4214
4215 vtarget = hd->Targets[ii];
4216
4217 if ((vtarget != NULL) && (!vtarget->raidVolume)) {
4218 if ((vtarget->negoFlags & hd->ioc->spi_data.noQas) == 0) {
4219 vtarget->negoFlags |= hd->ioc->spi_data.noQas;
4220 dnegoprintk(("writeSDP1: id=%d flags=0\n", id));
4221 mptscsih_writeSDP1(hd, 0, ii, 0);
4222 }
4223 } else {
4224 if (mptscsih_is_phys_disk(hd->ioc, ii) == 1) {
4225 dnegoprintk(("writeSDP1: id=%d SCSICFG_USE_NVRAM\n", id));
4226 mptscsih_writeSDP1(hd, 0, ii, MPT_SCSICFG_USE_NVRAM);
4227 }
4228 }
4229 }
4230 return;
4231}
4232
4233
4234
4235#define MPT_GET_NVRAM_VALS 0x01
4236#define MPT_UPDATE_MAX 0x02
4237#define MPT_SET_MAX 0x04
4238#define MPT_SET_MIN 0x08
4239#define MPT_FALLBACK 0x10
4240#define MPT_SAVE 0x20
4241
4242/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4243/**
4244 * mptscsih_doDv - Perform domain validation to a target.
4245 * @hd: Pointer to MPT_SCSI_HOST structure.
4246 * @portnum: IOC port number.
4247 * @target: Physical ID of this target
4248 *
4249 * Uses the ISR, but with special processing.
4250 * MUST be single-threaded.
4251 * Test will exit if target is at async & narrow.
4252 *
4253 * Return: None.
4254 */
4255static int
4256mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
4257{
4258 MPT_ADAPTER *ioc = hd->ioc;
4259 VirtTarget *vtarget;
4260 SCSIDevicePage1_t *pcfg1Data;
4261 SCSIDevicePage0_t *pcfg0Data;
4262 u8 *pbuf1;
4263 u8 *pbuf2;
4264 u8 *pDvBuf;
4265 dma_addr_t dvbuf_dma = -1;
4266 dma_addr_t buf1_dma = -1;
4267 dma_addr_t buf2_dma = -1;
4268 dma_addr_t cfg1_dma_addr = -1;
4269 dma_addr_t cfg0_dma_addr = -1;
4270 ConfigPageHeader_t header1;
4271 ConfigPageHeader_t header0;
4272 DVPARAMETERS dv;
4273 INTERNAL_CMD iocmd;
4274 CONFIGPARMS cfg;
4275 int dv_alloc = 0;
4276 int rc, sz = 0;
4277 int bufsize = 0;
4278 int dataBufSize = 0;
4279 int echoBufSize = 0;
4280 int notDone;
4281 int patt;
4282 int repeat;
4283 int retcode = 0;
4284 int nfactor = MPT_ULTRA320;
4285 char firstPass = 1;
4286 char doFallback = 0;
4287 char readPage0;
4288 char bus, lun;
4289 char inq0 = 0;
4290
4291 if (ioc->spi_data.sdp1length == 0)
4292 return 0;
4293
4294 if (ioc->spi_data.sdp0length == 0)
4295 return 0;
4296
4297 /* If multiple buses are used, require that the initiator
4298 * id be the same on all buses.
4299 */
4300 if (id == ioc->pfacts[0].PortSCSIID)
4301 return 0;
4302
4303 lun = 0;
4304 bus = (u8) bus_number;
4305 ddvtprintk((MYIOC_s_NOTE_FMT
4306 "DV started: bus=%d, id=%d dv @ %p\n",
4307 ioc->name, bus, id, &dv));
4308
4309 /* Prep DV structure
4310 */
4311 memset (&dv, 0, sizeof(DVPARAMETERS));
4312 dv.id = id;
4313
4314 /* Populate tmax with the current maximum
4315 * transfer parameters for this target.
4316 * Exit if narrow and async.
4317 */
4318 dv.cmd = MPT_GET_NVRAM_VALS;
4319 mptscsih_dv_parms(hd, &dv, NULL);
4320
4321 /* Prep SCSI IO structure
4322 */
4323 iocmd.id = id;
4324 iocmd.bus = bus;
4325 iocmd.lun = lun;
4326 iocmd.flags = 0;
4327 iocmd.physDiskNum = -1;
4328 iocmd.rsvd = iocmd.rsvd2 = 0;
4329
4330 vtarget = hd->Targets[id];
4331
4332 /* Use tagged commands if possible.
4333 */
4334 if (vtarget) {
4335 if (vtarget->tflags & MPT_TARGET_FLAGS_Q_YES)
4336 iocmd.flags |= MPT_ICFLAG_TAGGED_CMD;
4337 else {
4338 if (hd->ioc->facts.FWVersion.Word < 0x01000600)
4339 return 0;
4340
4341 if ((hd->ioc->facts.FWVersion.Word >= 0x01010000) &&
4342 (hd->ioc->facts.FWVersion.Word < 0x01010B00))
4343 return 0;
4344 }
4345 }
4346
4347 /* Prep cfg structure
4348 */
4349 cfg.pageAddr = (bus<<8) | id;
4350 cfg.cfghdr.hdr = NULL;
4351
4352 /* Prep SDP0 header
4353 */
4354 header0.PageVersion = ioc->spi_data.sdp0version;
4355 header0.PageLength = ioc->spi_data.sdp0length;
4356 header0.PageNumber = 0;
4357 header0.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4358
4359 /* Prep SDP1 header
4360 */
4361 header1.PageVersion = ioc->spi_data.sdp1version;
4362 header1.PageLength = ioc->spi_data.sdp1length;
4363 header1.PageNumber = 1;
4364 header1.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4365
4366 if (header0.PageLength & 1)
4367 dv_alloc = (header0.PageLength * 4) + 4;
4368
4369 dv_alloc += (2048 + (header1.PageLength * 4));
4370
4371 pDvBuf = pci_alloc_consistent(ioc->pcidev, dv_alloc, &dvbuf_dma);
4372 if (pDvBuf == NULL)
4373 return 0;
4374
4375 sz = 0;
4376 pbuf1 = (u8 *)pDvBuf;
4377 buf1_dma = dvbuf_dma;
4378 sz +=1024;
4379
4380 pbuf2 = (u8 *) (pDvBuf + sz);
4381 buf2_dma = dvbuf_dma + sz;
4382 sz +=1024;
4383
4384 pcfg0Data = (SCSIDevicePage0_t *) (pDvBuf + sz);
4385 cfg0_dma_addr = dvbuf_dma + sz;
4386 sz += header0.PageLength * 4;
4387
4388 /* 8-byte alignment
4389 */
4390 if (header0.PageLength & 1)
4391 sz += 4;
4392
4393 pcfg1Data = (SCSIDevicePage1_t *) (pDvBuf + sz);
4394 cfg1_dma_addr = dvbuf_dma + sz;
4395
4396 /* Skip this ID? Set cfg.cfghdr.hdr to force config page write
4397 */
4398 {
4399 SpiCfgData *pspi_data = &hd->ioc->spi_data;
4400 if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) {
4401 /* Set the factor from nvram */
4402 nfactor = (pspi_data->nvram[id] & MPT_NVRAM_SYNC_MASK) >> 8;
4403 if (nfactor < pspi_data->minSyncFactor )
4404 nfactor = pspi_data->minSyncFactor;
4405
4406 if (!(pspi_data->nvram[id] & MPT_NVRAM_ID_SCAN_ENABLE) ||
4407 (pspi_data->PortFlags == MPI_SCSIPORTPAGE2_PORT_FLAGS_OFF_DV) ) {
4408
4409 ddvprintk((MYIOC_s_NOTE_FMT "DV Skipped: bus, id, lun (%d, %d, %d)\n",
4410 ioc->name, bus, id, lun));
4411
4412 dv.cmd = MPT_SET_MAX;
4413 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
4414 cfg.cfghdr.hdr = &header1;
4415
4416 /* Save the final negotiated settings to
4417 * SCSI device page 1.
4418 */
4419 cfg.physAddr = cfg1_dma_addr;
4420 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
4421 cfg.dir = 1;
4422 mpt_config(hd->ioc, &cfg);
4423 goto target_done;
4424 }
4425 }
4426 }
4427
4428 /* Finish iocmd inititialization - hidden or visible disk? */
4429 if (ioc->raid_data.pIocPg3) {
4430 /* Search IOC page 3 for matching id
4431 */
4432 Ioc3PhysDisk_t *pPDisk = ioc->raid_data.pIocPg3->PhysDisk;
4433 int numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
4434
4435 while (numPDisk) {
4436 if (pPDisk->PhysDiskID == id) {
4437 /* match */
4438 iocmd.flags |= MPT_ICFLAG_PHYS_DISK;
4439 iocmd.physDiskNum = pPDisk->PhysDiskNum;
4440
4441 /* Quiesce the IM
4442 */
4443 if (mptscsih_do_raid(hd, MPI_RAID_ACTION_QUIESCE_PHYS_IO, &iocmd) < 0) {
4444 ddvprintk((MYIOC_s_ERR_FMT "RAID Queisce FAILED!\n", ioc->name));
4445 goto target_done;
4446 }
4447 break;
4448 }
4449 pPDisk++;
4450 numPDisk--;
4451 }
4452 }
4453
4454 /* RAID Volume ID's may double for a physical device. If RAID but
4455 * not a physical ID as well, skip DV.
4456 */
4457 if ((hd->ioc->raid_data.isRaid & (1 << id)) && !(iocmd.flags & MPT_ICFLAG_PHYS_DISK))
4458 goto target_done;
4459
4460
4461 /* Basic Test.
4462 * Async & Narrow - Inquiry
4463 * Async & Narrow - Inquiry
4464 * Maximum transfer rate - Inquiry
4465 * Compare buffers:
4466 * If compare, test complete.
4467 * If miscompare and first pass, repeat
4468 * If miscompare and not first pass, fall back and repeat
4469 */
4470 hd->pLocal = NULL;
4471 readPage0 = 0;
4472 sz = SCSI_MAX_INQUIRY_BYTES;
4473 rc = MPT_SCANDV_GOOD;
4474 while (1) {
4475 ddvprintk((MYIOC_s_NOTE_FMT "DV: Start Basic test on id=%d\n", ioc->name, id));
4476 retcode = 0;
4477 dv.cmd = MPT_SET_MIN;
4478 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
4479
4480 cfg.cfghdr.hdr = &header1;
4481 cfg.physAddr = cfg1_dma_addr;
4482 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
4483 cfg.dir = 1;
4484 if (mpt_config(hd->ioc, &cfg) != 0)
4485 goto target_done;
4486
4487 /* Wide - narrow - wide workaround case
4488 */
4489 if ((rc == MPT_SCANDV_ISSUE_SENSE) && dv.max.width) {
4490 /* Send an untagged command to reset disk Qs corrupted
4491 * when a parity error occurs on a Request Sense.
4492 */
4493 if ((hd->ioc->facts.FWVersion.Word >= 0x01000600) ||
4494 ((hd->ioc->facts.FWVersion.Word >= 0x01010000) &&
4495 (hd->ioc->facts.FWVersion.Word < 0x01010B00)) ) {
4496
4497 iocmd.cmd = REQUEST_SENSE;
4498 iocmd.data_dma = buf1_dma;
4499 iocmd.data = pbuf1;
4500 iocmd.size = 0x12;
4501 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4502 goto target_done;
4503 else {
4504 if (hd->pLocal == NULL)
4505 goto target_done;
4506 rc = hd->pLocal->completion;
4507 if ((rc == MPT_SCANDV_GOOD) || (rc == MPT_SCANDV_SENSE)) {
4508 dv.max.width = 0;
4509 doFallback = 0;
4510 } else
4511 goto target_done;
4512 }
4513 } else
4514 goto target_done;
4515 }
4516
4517 iocmd.cmd = INQUIRY;
4518 iocmd.data_dma = buf1_dma;
4519 iocmd.data = pbuf1;
4520 iocmd.size = sz;
4521 memset(pbuf1, 0x00, sz);
4522 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4523 goto target_done;
4524 else {
4525 if (hd->pLocal == NULL)
4526 goto target_done;
4527 rc = hd->pLocal->completion;
4528 if (rc == MPT_SCANDV_GOOD) {
4529 if (hd->pLocal->scsiStatus == SAM_STAT_BUSY) {
4530 if ((iocmd.flags & MPT_ICFLAG_TAGGED_CMD) == 0)
4531 retcode = 1;
4532 else
4533 retcode = 0;
4534
4535 goto target_done;
4536 }
4537 } else if (rc == MPT_SCANDV_SENSE) {
4538 ;
4539 } else {
4540 /* If first command doesn't complete
4541 * with a good status or with a check condition,
4542 * exit.
4543 */
4544 goto target_done;
4545 }
4546 }
4547
4548 /* Reset the size for disks
4549 */
4550 inq0 = (*pbuf1) & 0x1F;
4551 if ((inq0 == 0) && vtarget && !vtarget->raidVolume) {
4552 sz = 0x40;
4553 iocmd.size = sz;
4554 }
4555
4556 /* Another GEM workaround. Check peripheral device type,
4557 * if PROCESSOR, quit DV.
4558 */
4559 if (inq0 == TYPE_PROCESSOR) {
4560 mptscsih_initTarget(hd,
4561 vtarget,
4562 lun,
4563 pbuf1,
4564 sz);
4565 goto target_done;
4566 }
4567
4568 if (inq0 > 0x08)
4569 goto target_done;
4570
4571 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4572 goto target_done;
4573
4574 if (sz == 0x40) {
4575 if ((vtarget->maxWidth == 1) && (vtarget->maxOffset) && (nfactor < 0x0A)
4576 && (vtarget->minSyncFactor > 0x09)) {
4577 if ((pbuf1[56] & 0x04) == 0)
4578 ;
4579 else if ((pbuf1[56] & 0x01) == 1) {
4580 vtarget->minSyncFactor =
4581 nfactor > MPT_ULTRA320 ? nfactor : MPT_ULTRA320;
4582 } else {
4583 vtarget->minSyncFactor =
4584 nfactor > MPT_ULTRA160 ? nfactor : MPT_ULTRA160;
4585 }
4586
4587 dv.max.factor = vtarget->minSyncFactor;
4588
4589 if ((pbuf1[56] & 0x02) == 0) {
4590 vtarget->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
4591 hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS;
4592 ddvprintk((MYIOC_s_NOTE_FMT
4593 "DV: Start Basic noQas on id=%d due to pbuf1[56]=%x\n",
4594 ioc->name, id, pbuf1[56]));
4595 }
4596 }
4597 }
4598
4599 if (doFallback)
4600 dv.cmd = MPT_FALLBACK;
4601 else
4602 dv.cmd = MPT_SET_MAX;
4603
4604 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
4605 if (mpt_config(hd->ioc, &cfg) != 0)
4606 goto target_done;
4607
4608 if ((!dv.now.width) && (!dv.now.offset))
4609 goto target_done;
4610
4611 iocmd.cmd = INQUIRY;
4612 iocmd.data_dma = buf2_dma;
4613 iocmd.data = pbuf2;
4614 iocmd.size = sz;
4615 memset(pbuf2, 0x00, sz);
4616 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4617 goto target_done;
4618 else if (hd->pLocal == NULL)
4619 goto target_done;
4620 else {
4621 /* Save the return code.
4622 * If this is the first pass,
4623 * read SCSI Device Page 0
4624 * and update the target max parameters.
4625 */
4626 rc = hd->pLocal->completion;
4627 doFallback = 0;
4628 if (rc == MPT_SCANDV_GOOD) {
4629 if (!readPage0) {
4630 u32 sdp0_info;
4631 u32 sdp0_nego;
4632
4633 cfg.cfghdr.hdr = &header0;
4634 cfg.physAddr = cfg0_dma_addr;
4635 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4636 cfg.dir = 0;
4637
4638 if (mpt_config(hd->ioc, &cfg) != 0)
4639 goto target_done;
4640
4641 sdp0_info = le32_to_cpu(pcfg0Data->Information) & 0x0E;
4642 sdp0_nego = (le32_to_cpu(pcfg0Data->NegotiatedParameters) & 0xFF00 ) >> 8;
4643
4644 /* Quantum and Fujitsu workarounds.
4645 * Quantum: PPR U320 -> PPR reply with Ultra2 and wide
4646 * Fujitsu: PPR U320 -> Msg Reject and Ultra2 and wide
4647 * Resetart with a request for U160.
4648 */
4649 if ((dv.now.factor == MPT_ULTRA320) && (sdp0_nego == MPT_ULTRA2)) {
4650 doFallback = 1;
4651 } else {
4652 dv.cmd = MPT_UPDATE_MAX;
4653 mptscsih_dv_parms(hd, &dv, (void *)pcfg0Data);
4654 /* Update the SCSI device page 1 area
4655 */
4656 pcfg1Data->RequestedParameters = pcfg0Data->NegotiatedParameters;
4657 readPage0 = 1;
4658 }
4659 }
4660
4661 /* Quantum workaround. Restart this test will the fallback
4662 * flag set.
4663 */
4664 if (doFallback == 0) {
4665 if (memcmp(pbuf1, pbuf2, sz) != 0) {
4666 if (!firstPass)
4667 doFallback = 1;
4668 } else {
4669 ddvprintk((MYIOC_s_NOTE_FMT
4670 "DV:Inquiry compared id=%d, calling initTarget\n", ioc->name, id));
4671 hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_DV_NOT_DONE;
4672 mptscsih_initTarget(hd,
4673 vtarget,
4674 lun,
4675 pbuf1,
4676 sz);
4677 break; /* test complete */
4678 }
4679 }
4680
4681
4682 } else if (rc == MPT_SCANDV_ISSUE_SENSE)
4683 doFallback = 1; /* set fallback flag */
4684 else if ((rc == MPT_SCANDV_DID_RESET) ||
4685 (rc == MPT_SCANDV_SENSE) ||
4686 (rc == MPT_SCANDV_FALLBACK))
4687 doFallback = 1; /* set fallback flag */
4688 else
4689 goto target_done;
4690
4691 firstPass = 0;
4692 }
4693 }
4694 ddvprintk((MYIOC_s_NOTE_FMT "DV: Basic test on id=%d completed OK.\n", ioc->name, id));
4695
4696 if (ioc->spi_data.mpt_dv == 0)
4697 goto target_done;
4698
4699 inq0 = (*pbuf1) & 0x1F;
4700
4701 /* Continue only for disks
4702 */
4703 if (inq0 != 0)
4704 goto target_done;
4705
4706 if ( ioc->spi_data.PortFlags == MPI_SCSIPORTPAGE2_PORT_FLAGS_BASIC_DV_ONLY )
4707 goto target_done;
4708
4709 /* Start the Enhanced Test.
4710 * 0) issue TUR to clear out check conditions
4711 * 1) read capacity of echo (regular) buffer
4712 * 2) reserve device
4713 * 3) do write-read-compare data pattern test
4714 * 4) release
4715 * 5) update nego parms to target struct
4716 */
4717 cfg.cfghdr.hdr = &header1;
4718 cfg.physAddr = cfg1_dma_addr;
4719 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
4720 cfg.dir = 1;
4721
4722 iocmd.cmd = TEST_UNIT_READY;
4723 iocmd.data_dma = -1;
4724 iocmd.data = NULL;
4725 iocmd.size = 0;
4726 notDone = 1;
4727 while (notDone) {
4728 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4729 goto target_done;
4730
4731 if (hd->pLocal == NULL)
4732 goto target_done;
4733
4734 rc = hd->pLocal->completion;
4735 if (rc == MPT_SCANDV_GOOD)
4736 notDone = 0;
4737 else if (rc == MPT_SCANDV_SENSE) {
4738 u8 skey = hd->pLocal->sense[2] & 0x0F;
4739 u8 asc = hd->pLocal->sense[12];
4740 u8 ascq = hd->pLocal->sense[13];
4741 ddvprintk((MYIOC_s_INFO_FMT
4742 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n",
4743 ioc->name, skey, asc, ascq));
4744
4745 if (skey == UNIT_ATTENTION)
4746 notDone++; /* repeat */
4747 else if ((skey == NOT_READY) &&
4748 (asc == 0x04)&&(ascq == 0x01)) {
4749 /* wait then repeat */
4750 mdelay (2000);
4751 notDone++;
4752 } else if ((skey == NOT_READY) && (asc == 0x3A)) {
4753 /* no medium, try read test anyway */
4754 notDone = 0;
4755 } else {
4756 /* All other errors are fatal.
4757 */
4758 ddvprintk((MYIOC_s_INFO_FMT "DV: fatal error.",
4759 ioc->name));
4760 goto target_done;
4761 }
4762 } else
4763 goto target_done;
4764 }
4765
4766 iocmd.cmd = READ_BUFFER;
4767 iocmd.data_dma = buf1_dma;
4768 iocmd.data = pbuf1;
4769 iocmd.size = 4;
4770 iocmd.flags |= MPT_ICFLAG_BUF_CAP;
4771
4772 dataBufSize = 0;
4773 echoBufSize = 0;
4774 for (patt = 0; patt < 2; patt++) {
4775 if (patt == 0)
4776 iocmd.flags |= MPT_ICFLAG_ECHO;
4777 else
4778 iocmd.flags &= ~MPT_ICFLAG_ECHO;
4779
4780 notDone = 1;
4781 while (notDone) {
4782 bufsize = 0;
4783
4784 /* If not ready after 8 trials,
4785 * give up on this device.
4786 */
4787 if (notDone > 8)
4788 goto target_done;
4789
4790 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4791 goto target_done;
4792 else if (hd->pLocal == NULL)
4793 goto target_done;
4794 else {
4795 rc = hd->pLocal->completion;
4796 ddvprintk(("ReadBuffer Comp Code %d", rc));
4797 ddvprintk((" buff: %0x %0x %0x %0x\n",
4798 pbuf1[0], pbuf1[1], pbuf1[2], pbuf1[3]));
4799
4800 if (rc == MPT_SCANDV_GOOD) {
4801 notDone = 0;
4802 if (iocmd.flags & MPT_ICFLAG_ECHO) {
4803 bufsize = ((pbuf1[2] & 0x1F) <<8) | pbuf1[3];
4804 if (pbuf1[0] & 0x01)
4805 iocmd.flags |= MPT_ICFLAG_EBOS;
4806 } else {
4807 bufsize = pbuf1[1]<<16 | pbuf1[2]<<8 | pbuf1[3];
4808 }
4809 } else if (rc == MPT_SCANDV_SENSE) {
4810 u8 skey = hd->pLocal->sense[2] & 0x0F;
4811 u8 asc = hd->pLocal->sense[12];
4812 u8 ascq = hd->pLocal->sense[13];
4813 ddvprintk((MYIOC_s_INFO_FMT
4814 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n",
4815 ioc->name, skey, asc, ascq));
4816 if (skey == ILLEGAL_REQUEST) {
4817 notDone = 0;
4818 } else if (skey == UNIT_ATTENTION) {
4819 notDone++; /* repeat */
4820 } else if ((skey == NOT_READY) &&
4821 (asc == 0x04)&&(ascq == 0x01)) {
4822 /* wait then repeat */
4823 mdelay (2000);
4824 notDone++;
4825 } else {
4826 /* All other errors are fatal.
4827 */
4828 ddvprintk((MYIOC_s_INFO_FMT "DV: fatal error.",
4829 ioc->name));
4830 goto target_done;
4831 }
4832 } else {
4833 /* All other errors are fatal
4834 */
4835 goto target_done;
4836 }
4837 }
4838 }
4839
4840 if (iocmd.flags & MPT_ICFLAG_ECHO)
4841 echoBufSize = bufsize;
4842 else
4843 dataBufSize = bufsize;
4844 }
4845 sz = 0;
4846 iocmd.flags &= ~MPT_ICFLAG_BUF_CAP;
4847
4848 /* Use echo buffers if possible,
4849 * Exit if both buffers are 0.
4850 */
4851 if (echoBufSize > 0) {
4852 iocmd.flags |= MPT_ICFLAG_ECHO;
4853 if (dataBufSize > 0)
4854 bufsize = min(echoBufSize, dataBufSize);
4855 else
4856 bufsize = echoBufSize;
4857 } else if (dataBufSize == 0)
4858 goto target_done;
4859
4860 ddvprintk((MYIOC_s_INFO_FMT "%s Buffer Capacity %d\n", ioc->name,
4861 (iocmd.flags & MPT_ICFLAG_ECHO) ? "Echo" : " ", bufsize));
4862
4863 /* Data buffers for write-read-compare test max 1K.
4864 */
4865 sz = min(bufsize, 1024);
4866
4867 /* --- loop ----
4868 * On first pass, always issue a reserve.
4869 * On additional loops, only if a reset has occurred.
4870 * iocmd.flags indicates if echo or regular buffer
4871 */
4872 for (patt = 0; patt < 4; patt++) {
4873 ddvprintk(("Pattern %d\n", patt));
4874 if ((iocmd.flags & MPT_ICFLAG_RESERVED) && (iocmd.flags & MPT_ICFLAG_DID_RESET)) {
4875 iocmd.cmd = TEST_UNIT_READY;
4876 iocmd.data_dma = -1;
4877 iocmd.data = NULL;
4878 iocmd.size = 0;
4879 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4880 goto target_done;
4881
4882 iocmd.cmd = RELEASE;
4883 iocmd.data_dma = -1;
4884 iocmd.data = NULL;
4885 iocmd.size = 0;
4886 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4887 goto target_done;
4888 else if (hd->pLocal == NULL)
4889 goto target_done;
4890 else {
4891 rc = hd->pLocal->completion;
4892 ddvprintk(("Release rc %d\n", rc));
4893 if (rc == MPT_SCANDV_GOOD)
4894 iocmd.flags &= ~MPT_ICFLAG_RESERVED;
4895 else
4896 goto target_done;
4897 }
4898 iocmd.flags &= ~MPT_ICFLAG_RESERVED;
4899 }
4900 iocmd.flags &= ~MPT_ICFLAG_DID_RESET;
4901
4902 if (iocmd.flags & MPT_ICFLAG_EBOS)
4903 goto skip_Reserve;
4904
4905 repeat = 5;
4906 while (repeat && (!(iocmd.flags & MPT_ICFLAG_RESERVED))) {
4907 iocmd.cmd = RESERVE;
4908 iocmd.data_dma = -1;
4909 iocmd.data = NULL;
4910 iocmd.size = 0;
4911 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4912 goto target_done;
4913 else if (hd->pLocal == NULL)
4914 goto target_done;
4915 else {
4916 rc = hd->pLocal->completion;
4917 if (rc == MPT_SCANDV_GOOD) {
4918 iocmd.flags |= MPT_ICFLAG_RESERVED;
4919 } else if (rc == MPT_SCANDV_SENSE) {
4920 /* Wait if coming ready
4921 */
4922 u8 skey = hd->pLocal->sense[2] & 0x0F;
4923 u8 asc = hd->pLocal->sense[12];
4924 u8 ascq = hd->pLocal->sense[13];
4925 ddvprintk((MYIOC_s_INFO_FMT
4926 "DV: Reserve Failed: ", ioc->name));
4927 ddvprintk(("SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n",
4928 skey, asc, ascq));
4929
4930 if ((skey == NOT_READY) && (asc == 0x04)&&
4931 (ascq == 0x01)) {
4932 /* wait then repeat */
4933 mdelay (2000);
4934 notDone++;
4935 } else {
4936 ddvprintk((MYIOC_s_INFO_FMT
4937 "DV: Reserved Failed.", ioc->name));
4938 goto target_done;
4939 }
4940 } else {
4941 ddvprintk((MYIOC_s_INFO_FMT "DV: Reserved Failed.",
4942 ioc->name));
4943 goto target_done;
4944 }
4945 }
4946 }
4947
4948skip_Reserve:
4949 mptscsih_fillbuf(pbuf1, sz, patt, 1);
4950 iocmd.cmd = WRITE_BUFFER;
4951 iocmd.data_dma = buf1_dma;
4952 iocmd.data = pbuf1;
4953 iocmd.size = sz;
4954 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4955 goto target_done;
4956 else if (hd->pLocal == NULL)
4957 goto target_done;
4958 else {
4959 rc = hd->pLocal->completion;
4960 if (rc == MPT_SCANDV_GOOD)
4961 ; /* Issue read buffer */
4962 else if (rc == MPT_SCANDV_DID_RESET) {
4963 /* If using echo buffers, reset to data buffers.
4964 * Else do Fallback and restart
4965 * this test (re-issue reserve
4966 * because of bus reset).
4967 */
4968 if ((iocmd.flags & MPT_ICFLAG_ECHO) && (dataBufSize >= bufsize)) {
4969 iocmd.flags &= ~MPT_ICFLAG_ECHO;
4970 } else {
4971 dv.cmd = MPT_FALLBACK;
4972 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
4973
4974 if (mpt_config(hd->ioc, &cfg) != 0)
4975 goto target_done;
4976
4977 if ((!dv.now.width) && (!dv.now.offset))
4978 goto target_done;
4979 }
4980
4981 iocmd.flags |= MPT_ICFLAG_DID_RESET;
4982 patt = -1;
4983 continue;
4984 } else if (rc == MPT_SCANDV_SENSE) {
4985 /* Restart data test if UA, else quit.
4986 */
4987 u8 skey = hd->pLocal->sense[2] & 0x0F;
4988 ddvprintk((MYIOC_s_INFO_FMT
4989 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n", ioc->name, skey,
4990 hd->pLocal->sense[12], hd->pLocal->sense[13]));
4991 if (skey == UNIT_ATTENTION) {
4992 patt = -1;
4993 continue;
4994 } else if (skey == ILLEGAL_REQUEST) {
4995 if (iocmd.flags & MPT_ICFLAG_ECHO) {
4996 if (dataBufSize >= bufsize) {
4997 iocmd.flags &= ~MPT_ICFLAG_ECHO;
4998 patt = -1;
4999 continue;
5000 }
5001 }
5002 goto target_done;
5003 }
5004 else
5005 goto target_done;
5006 } else {
5007 /* fatal error */
5008 goto target_done;
5009 }
5010 }
5011
5012 iocmd.cmd = READ_BUFFER;
5013 iocmd.data_dma = buf2_dma;
5014 iocmd.data = pbuf2;
5015 iocmd.size = sz;
5016 if (mptscsih_do_cmd(hd, &iocmd) < 0)
5017 goto target_done;
5018 else if (hd->pLocal == NULL)
5019 goto target_done;
5020 else {
5021 rc = hd->pLocal->completion;
5022 if (rc == MPT_SCANDV_GOOD) {
5023 /* If buffers compare,
5024 * go to next pattern,
5025 * else, do a fallback and restart
5026 * data transfer test.
5027 */
5028 if (memcmp (pbuf1, pbuf2, sz) == 0) {
5029 ; /* goto next pattern */
5030 } else {
5031 /* Miscompare with Echo buffer, go to data buffer,
5032 * if that buffer exists.
5033 * Miscompare with Data buffer, check first 4 bytes,
5034 * some devices return capacity. Exit in this case.
5035 */
5036 if (iocmd.flags & MPT_ICFLAG_ECHO) {
5037 if (dataBufSize >= bufsize)
5038 iocmd.flags &= ~MPT_ICFLAG_ECHO;
5039 else
5040 goto target_done;
5041 } else {
5042 if (dataBufSize == (pbuf2[1]<<16 | pbuf2[2]<<8 | pbuf2[3])) {
5043 /* Argh. Device returning wrong data.
5044 * Quit DV for this device.
5045 */
5046 goto target_done;
5047 }
5048
5049 /* Had an actual miscompare. Slow down.*/
5050 dv.cmd = MPT_FALLBACK;
5051 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
5052
5053 if (mpt_config(hd->ioc, &cfg) != 0)
5054 goto target_done;
5055
5056 if ((!dv.now.width) && (!dv.now.offset))
5057 goto target_done;
5058 }
5059
5060 patt = -1;
5061 continue;
5062 }
5063 } else if (rc == MPT_SCANDV_DID_RESET) {
5064 /* Do Fallback and restart
5065 * this test (re-issue reserve
5066 * because of bus reset).
5067 */
5068 dv.cmd = MPT_FALLBACK;
5069 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
5070
5071 if (mpt_config(hd->ioc, &cfg) != 0)
5072 goto target_done;
5073
5074 if ((!dv.now.width) && (!dv.now.offset))
5075 goto target_done;
5076
5077 iocmd.flags |= MPT_ICFLAG_DID_RESET;
5078 patt = -1;
5079 continue;
5080 } else if (rc == MPT_SCANDV_SENSE) {
5081 /* Restart data test if UA, else quit.
5082 */
5083 u8 skey = hd->pLocal->sense[2] & 0x0F;
5084 ddvprintk((MYIOC_s_INFO_FMT
5085 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n", ioc->name, skey,
5086 hd->pLocal->sense[12], hd->pLocal->sense[13]));
5087 if (skey == UNIT_ATTENTION) {
5088 patt = -1;
5089 continue;
5090 }
5091 else
5092 goto target_done;
5093 } else {
5094 /* fatal error */
5095 goto target_done;
5096 }
5097 }
5098
5099 } /* --- end of patt loop ---- */
5100
5101target_done:
5102 if (iocmd.flags & MPT_ICFLAG_RESERVED) {
5103 iocmd.cmd = RELEASE;
5104 iocmd.data_dma = -1;
5105 iocmd.data = NULL;
5106 iocmd.size = 0;
5107 if (mptscsih_do_cmd(hd, &iocmd) < 0)
5108 printk(MYIOC_s_INFO_FMT "DV: Release failed. id %d",
5109 ioc->name, id);
5110 else if (hd->pLocal) {
5111 if (hd->pLocal->completion == MPT_SCANDV_GOOD)
5112 iocmd.flags &= ~MPT_ICFLAG_RESERVED;
5113 } else {
5114 printk(MYIOC_s_INFO_FMT "DV: Release failed. id %d",
5115 ioc->name, id);
5116 }
5117 }
5118
5119
5120 /* Set if cfg1_dma_addr contents is valid
5121 */
5122 if ((cfg.cfghdr.hdr != NULL) && (retcode == 0)){
5123 /* If disk, not U320, disable QAS
5124 */
5125 if ((inq0 == 0) && (dv.now.factor > MPT_ULTRA320)) {
5126 hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS;
5127 ddvprintk((MYIOC_s_NOTE_FMT
5128 "noQas set due to id=%d has factor=%x\n", ioc->name, id, dv.now.factor));
5129 }
5130
5131 dv.cmd = MPT_SAVE;
5132 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
5133
5134 /* Double writes to SDP1 can cause problems,
5135 * skip save of the final negotiated settings to
5136 * SCSI device page 1.
5137 *
5138 cfg.cfghdr.hdr = &header1;
5139 cfg.physAddr = cfg1_dma_addr;
5140 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
5141 cfg.dir = 1;
5142 mpt_config(hd->ioc, &cfg);
5143 */
5144 }
5145
5146 /* If this is a RAID Passthrough, enable internal IOs
5147 */
5148 if (iocmd.flags & MPT_ICFLAG_PHYS_DISK) {
5149 if (mptscsih_do_raid(hd, MPI_RAID_ACTION_ENABLE_PHYS_IO, &iocmd) < 0)
5150 ddvprintk((MYIOC_s_ERR_FMT "RAID Enable FAILED!\n", ioc->name));
5151 }
5152
5153 /* Done with the DV scan of the current target
5154 */
5155 if (pDvBuf)
5156 pci_free_consistent(ioc->pcidev, dv_alloc, pDvBuf, dvbuf_dma);
5157
5158 ddvtprintk((MYIOC_s_INFO_FMT "DV Done id=%d\n",
5159 ioc->name, id));
5160
5161 return retcode;
5162}
5163
5164/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5165/* mptscsih_dv_parms - perform a variety of operations on the
5166 * parameters used for negotiation.
5167 * @hd: Pointer to a SCSI host.
5168 * @dv: Pointer to a structure that contains the maximum and current
5169 * negotiated parameters.
5170 */
5171static void
5172mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
5173{
5174 VirtTarget *vtarget;
5175 SCSIDevicePage0_t *pPage0;
5176 SCSIDevicePage1_t *pPage1;
5177 int val = 0, data, configuration;
5178 u8 width = 0;
5179 u8 offset = 0;
5180 u8 factor = 0;
5181 u8 negoFlags = 0;
5182 u8 cmd = dv->cmd;
5183 u8 id = dv->id;
5184
5185 switch (cmd) {
5186 case MPT_GET_NVRAM_VALS:
5187 ddvprintk((MYIOC_s_NOTE_FMT "Getting NVRAM: ",
5188 hd->ioc->name));
5189 /* Get the NVRAM values and save in tmax
5190 * If not an LVD bus, the adapter minSyncFactor has been
5191 * already throttled back.
5192 */
5193 negoFlags = hd->ioc->spi_data.noQas;
5194 if ((hd->Targets)&&((vtarget = hd->Targets[(int)id]) != NULL) && !vtarget->raidVolume) {
5195 width = vtarget->maxWidth;
5196 offset = vtarget->maxOffset;
5197 factor = vtarget->minSyncFactor;
5198 negoFlags |= vtarget->negoFlags;
5199 } else {
5200 if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
5201 data = hd->ioc->spi_data.nvram[id];
5202 width = data & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
5203 if ((offset = hd->ioc->spi_data.maxSyncOffset) == 0)
5204 factor = MPT_ASYNC;
5205 else {
5206 factor = (data & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT;
5207 if ((factor == 0) || (factor == MPT_ASYNC)){
5208 factor = MPT_ASYNC;
5209 offset = 0;
5210 }
5211 }
5212 } else {
5213 width = MPT_NARROW;
5214 offset = 0;
5215 factor = MPT_ASYNC;
5216 }
5217
5218 /* Set the negotiation flags */
5219 if (!width)
5220 negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
5221
5222 if (!offset)
5223 negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
5224 }
5225
5226 /* limit by adapter capabilities */
5227 width = min(width, hd->ioc->spi_data.maxBusWidth);
5228 offset = min(offset, hd->ioc->spi_data.maxSyncOffset);
5229 factor = max(factor, hd->ioc->spi_data.minSyncFactor);
5230
5231 /* Check Consistency */
5232 if (offset && (factor < MPT_ULTRA2) && !width)
5233 factor = MPT_ULTRA2;
5234
5235 dv->max.width = width;
5236 dv->max.offset = offset;
5237 dv->max.factor = factor;
5238 dv->max.flags = negoFlags;
5239 ddvprintk((" id=%d width=%d factor=%x offset=%x flags=%x\n",
5240 id, width, factor, offset, negoFlags));
5241 break;
5242
5243 case MPT_UPDATE_MAX:
5244 ddvprintk((MYIOC_s_NOTE_FMT
5245 "Updating with SDP0 Data: ", hd->ioc->name));
5246 /* Update tmax values with those from Device Page 0.*/
5247 pPage0 = (SCSIDevicePage0_t *) pPage;
5248 if (pPage0) {
5249 val = le32_to_cpu(pPage0->NegotiatedParameters);
5250 dv->max.width = val & MPI_SCSIDEVPAGE0_NP_WIDE ? 1 : 0;
5251 dv->max.offset = (val&MPI_SCSIDEVPAGE0_NP_NEG_SYNC_OFFSET_MASK) >> 16;
5252 dv->max.factor = (val&MPI_SCSIDEVPAGE0_NP_NEG_SYNC_PERIOD_MASK) >> 8;
5253 }
5254
5255 dv->now.width = dv->max.width;
5256 dv->now.offset = dv->max.offset;
5257 dv->now.factor = dv->max.factor;
5258 ddvprintk(("id=%d width=%d factor=%x offset=%x flags=%x\n",
5259 id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags));
5260 break;
5261
5262 case MPT_SET_MAX:
5263 ddvprintk((MYIOC_s_NOTE_FMT "Setting Max: ",
5264 hd->ioc->name));
5265 /* Set current to the max values. Update the config page.*/
5266 dv->now.width = dv->max.width;
5267 dv->now.offset = dv->max.offset;
5268 dv->now.factor = dv->max.factor;
5269 dv->now.flags = dv->max.flags;
5270
5271 pPage1 = (SCSIDevicePage1_t *)pPage;
5272 if (pPage1) {
5273 mptscsih_setDevicePage1Flags (dv->now.width, dv->now.factor,
5274 dv->now.offset, &val, &configuration, dv->now.flags);
5275 dnegoprintk(("Setting Max: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
5276 id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags, val, configuration));
5277 pPage1->RequestedParameters = cpu_to_le32(val);
5278 pPage1->Reserved = 0;
5279 pPage1->Configuration = cpu_to_le32(configuration);
5280 }
5281
5282 ddvprintk(("id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x configuration=%x\n",
5283 id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags, val, configuration));
5284 break;
5285
5286 case MPT_SET_MIN:
5287 ddvprintk((MYIOC_s_NOTE_FMT "Setting Min: ",
5288 hd->ioc->name));
5289 /* Set page to asynchronous and narrow
5290 * Do not update now, breaks fallback routine. */
5291 width = MPT_NARROW;
5292 offset = 0;
5293 factor = MPT_ASYNC;
5294 negoFlags = dv->max.flags;
5295
5296 pPage1 = (SCSIDevicePage1_t *)pPage;
5297 if (pPage1) {
5298 mptscsih_setDevicePage1Flags (width, factor,
5299 offset, &val, &configuration, negoFlags);
5300 dnegoprintk(("Setting Min: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
5301 id, width, factor, offset, negoFlags, val, configuration));
5302 pPage1->RequestedParameters = cpu_to_le32(val);
5303 pPage1->Reserved = 0;
5304 pPage1->Configuration = cpu_to_le32(configuration);
5305 }
5306 ddvprintk(("id=%d width=%d factor=%x offset=%x request=%x config=%x negoFlags=%x\n",
5307 id, width, factor, offset, val, configuration, negoFlags));
5308 break;
5309
5310 case MPT_FALLBACK:
5311 ddvprintk((MYIOC_s_NOTE_FMT
5312 "Fallback: Start: offset %d, factor %x, width %d \n",
5313 hd->ioc->name, dv->now.offset,
5314 dv->now.factor, dv->now.width));
5315 width = dv->now.width;
5316 offset = dv->now.offset;
5317 factor = dv->now.factor;
5318 if ((offset) && (dv->max.width)) {
5319 if (factor < MPT_ULTRA160)
5320 factor = MPT_ULTRA160;
5321 else if (factor < MPT_ULTRA2) {
5322 factor = MPT_ULTRA2;
5323 width = MPT_WIDE;
5324 } else if ((factor == MPT_ULTRA2) && width) {
5325 factor = MPT_ULTRA2;
5326 width = MPT_NARROW;
5327 } else if (factor < MPT_ULTRA) {
5328 factor = MPT_ULTRA;
5329 width = MPT_WIDE;
5330 } else if ((factor == MPT_ULTRA) && width) {
5331 width = MPT_NARROW;
5332 } else if (factor < MPT_FAST) {
5333 factor = MPT_FAST;
5334 width = MPT_WIDE;
5335 } else if ((factor == MPT_FAST) && width) {
5336 factor = MPT_FAST;
5337 width = MPT_NARROW;
5338 } else if (factor < MPT_SCSI) {
5339 factor = MPT_SCSI;
5340 width = MPT_WIDE;
5341 } else if ((factor == MPT_SCSI) && width) {
5342 factor = MPT_SCSI;
5343 width = MPT_NARROW;
5344 } else {
5345 factor = MPT_ASYNC;
5346 offset = 0;
5347 }
5348
5349 } else if (offset) {
5350 width = MPT_NARROW;
5351 if (factor < MPT_ULTRA)
5352 factor = MPT_ULTRA;
5353 else if (factor < MPT_FAST)
5354 factor = MPT_FAST;
5355 else if (factor < MPT_SCSI)
5356 factor = MPT_SCSI;
5357 else {
5358 factor = MPT_ASYNC;
5359 offset = 0;
5360 }
5361
5362 } else {
5363 width = MPT_NARROW;
5364 factor = MPT_ASYNC;
5365 }
5366 dv->max.flags |= MPT_TARGET_NO_NEGO_QAS;
5367 dv->max.flags &= ~MPT_TAPE_NEGO_IDP;
5368
5369 dv->now.width = width;
5370 dv->now.offset = offset;
5371 dv->now.factor = factor;
5372 dv->now.flags = dv->max.flags;
5373
5374 pPage1 = (SCSIDevicePage1_t *)pPage;
5375 if (pPage1) {
5376 mptscsih_setDevicePage1Flags (width, factor, offset, &val,
5377 &configuration, dv->now.flags);
5378 dnegoprintk(("Finish: id=%d width=%d offset=%d factor=%x negoFlags=%x request=%x config=%x\n",
5379 id, width, offset, factor, dv->now.flags, val, configuration));
5380
5381 pPage1->RequestedParameters = cpu_to_le32(val);
5382 pPage1->Reserved = 0;
5383 pPage1->Configuration = cpu_to_le32(configuration);
5384 }
5385
5386 ddvprintk(("Finish: id=%d offset=%d factor=%x width=%d request=%x config=%x\n",
5387 id, dv->now.offset, dv->now.factor, dv->now.width, val, configuration));
5388 break;
5389
5390 case MPT_SAVE:
5391 ddvprintk((MYIOC_s_NOTE_FMT
5392 "Saving to Target structure: ", hd->ioc->name));
5393 ddvprintk(("id=%d width=%x factor=%x offset=%d flags=%x\n",
5394 id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags));
5395
5396 /* Save these values to target structures
5397 * or overwrite nvram (phys disks only).
5398 */
5399
5400 if ((hd->Targets)&&((vtarget = hd->Targets[(int)id]) != NULL) && !vtarget->raidVolume ) {
5401 vtarget->maxWidth = dv->now.width;
5402 vtarget->maxOffset = dv->now.offset;
5403 vtarget->minSyncFactor = dv->now.factor;
5404 vtarget->negoFlags = dv->now.flags;
5405 } else {
5406 /* Preserv all flags, use
5407 * read-modify-write algorithm
5408 */
5409 if (hd->ioc->spi_data.nvram) {
5410 data = hd->ioc->spi_data.nvram[id];
5411
5412 if (dv->now.width)
5413 data &= ~MPT_NVRAM_WIDE_DISABLE;
5414 else
5415 data |= MPT_NVRAM_WIDE_DISABLE;
5416
5417 if (!dv->now.offset)
5418 factor = MPT_ASYNC;
5419
5420 data &= ~MPT_NVRAM_SYNC_MASK;
5421 data |= (dv->now.factor << MPT_NVRAM_SYNC_SHIFT) & MPT_NVRAM_SYNC_MASK;
5422
5423 hd->ioc->spi_data.nvram[id] = data;
5424 }
5425 }
5426 break;
5427 }
5428}
5429
5430/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5431/* mptscsih_fillbuf - fill a buffer with a special data pattern
5432 * cleanup. For bus scan only.
5433 *
5434 * @buffer: Pointer to data buffer to be filled.
5435 * @size: Number of bytes to fill
5436 * @index: Pattern index
5437 * @width: bus width, 0 (8 bits) or 1 (16 bits)
5438 */
5439static void
5440mptscsih_fillbuf(char *buffer, int size, int index, int width)
5441{
5442 char *ptr = buffer;
5443 int ii;
5444 char byte;
5445 short val;
5446
5447 switch (index) {
5448 case 0:
5449
5450 if (width) {
5451 /* Pattern: 0000 FFFF 0000 FFFF
5452 */
5453 for (ii=0; ii < size; ii++, ptr++) {
5454 if (ii & 0x02)
5455 *ptr = 0xFF;
5456 else
5457 *ptr = 0x00;
5458 }
5459 } else {
5460 /* Pattern: 00 FF 00 FF
5461 */
5462 for (ii=0; ii < size; ii++, ptr++) {
5463 if (ii & 0x01)
5464 *ptr = 0xFF;
5465 else
5466 *ptr = 0x00;
5467 }
5468 }
5469 break;
5470
5471 case 1:
5472 if (width) {
5473 /* Pattern: 5555 AAAA 5555 AAAA 5555
5474 */
5475 for (ii=0; ii < size; ii++, ptr++) {
5476 if (ii & 0x02)
5477 *ptr = 0xAA;
5478 else
5479 *ptr = 0x55;
5480 }
5481 } else {
5482 /* Pattern: 55 AA 55 AA 55
5483 */
5484 for (ii=0; ii < size; ii++, ptr++) {
5485 if (ii & 0x01)
5486 *ptr = 0xAA;
5487 else
5488 *ptr = 0x55;
5489 }
5490 }
5491 break;
5492
5493 case 2:
5494 /* Pattern: 00 01 02 03 04 05
5495 * ... FE FF 00 01..
5496 */
5497 for (ii=0; ii < size; ii++, ptr++)
5498 *ptr = (char) ii;
5499 break;
5500
5501 case 3:
5502 if (width) {
5503 /* Wide Pattern: FFFE 0001 FFFD 0002
5504 * ... 4000 DFFF 8000 EFFF
5505 */
5506 byte = 0;
5507 for (ii=0; ii < size/2; ii++) {
5508 /* Create the base pattern
5509 */
5510 val = (1 << byte);
5511 /* every 64 (0x40) bytes flip the pattern
5512 * since we fill 2 bytes / iteration,
5513 * test for ii = 0x20
5514 */
5515 if (ii & 0x20)
5516 val = ~(val);
5517
5518 if (ii & 0x01) {
5519 *ptr = (char)( (val & 0xFF00) >> 8);
5520 ptr++;
5521 *ptr = (char)(val & 0xFF);
5522 byte++;
5523 byte &= 0x0F;
5524 } else {
5525 val = ~val;
5526 *ptr = (char)( (val & 0xFF00) >> 8);
5527 ptr++;
5528 *ptr = (char)(val & 0xFF);
5529 }
5530
5531 ptr++;
5532 }
5533 } else {
5534 /* Narrow Pattern: FE 01 FD 02 FB 04
5535 * .. 7F 80 01 FE 02 FD ... 80 7F
5536 */
5537 byte = 0;
5538 for (ii=0; ii < size; ii++, ptr++) {
5539 /* Base pattern - first 32 bytes
5540 */
5541 if (ii & 0x01) {
5542 *ptr = (1 << byte);
5543 byte++;
5544 byte &= 0x07;
5545 } else {
5546 *ptr = (char) (~(1 << byte));
5547 }
5548
5549 /* Flip the pattern every 32 bytes
5550 */
5551 if (ii & 0x20)
5552 *ptr = ~(*ptr);
5553 }
5554 }
5555 break;
5556 }
5557}
5558
5559/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5560/* If DV disabled (negoNvram set to USE_NVARM) or if not LUN 0, return.
5561 * Else set the NEED_DV flag after Read Capacity Issued (disks)
5562 * or Mode Sense (cdroms).
5563 *
5564 * Tapes, initTarget will set this flag on completion of Inquiry command.
5565 * Called only if DV_NOT_DONE flag is set
5566 */
5567static void
5568mptscsih_set_dvflags(MPT_SCSI_HOST *hd, struct scsi_cmnd *sc)
5569{
5570 MPT_ADAPTER *ioc = hd->ioc;
5571 u8 cmd;
5572 SpiCfgData *pSpi;
5573
5574 ddvtprintk((MYIOC_s_NOTE_FMT
5575 " set_dvflags: id=%d lun=%d negoNvram=%x cmd=%x\n",
5576 hd->ioc->name, sc->device->id, sc->device->lun , hd->negoNvram, sc->cmnd[0]));
5577
5578 if ((sc->device->lun != 0) || (hd->negoNvram != 0))
5579 return;
5580
5581 cmd = sc->cmnd[0];
5582
5583 if ((cmd == READ_CAPACITY) || (cmd == MODE_SENSE)) {
5584 pSpi = &ioc->spi_data;
5585 if ((ioc->raid_data.isRaid & (1 << sc->device->id)) && ioc->raid_data.pIocPg3) {
5586 /* Set NEED_DV for all hidden disks
5587 */
5588 Ioc3PhysDisk_t *pPDisk = ioc->raid_data.pIocPg3->PhysDisk;
5589 int numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
5590
5591 while (numPDisk) {
5592 pSpi->dvStatus[pPDisk->PhysDiskID] |= MPT_SCSICFG_NEED_DV;
5593 ddvtprintk(("NEED_DV set for phys disk id %d\n", pPDisk->PhysDiskID));
5594 pPDisk++;
5595 numPDisk--;
5596 }
5597 }
5598 pSpi->dvStatus[sc->device->id] |= MPT_SCSICFG_NEED_DV;
5599 ddvtprintk(("NEED_DV set for visible disk id %d\n", sc->device->id));
5600 }
5601}
5602
5603/* mptscsih_raid_set_dv_flags()
5604 *
5605 * New or replaced disk. Set DV flag and schedule DV.
5606 */
5607static void
5608mptscsih_set_dvflags_raid(MPT_SCSI_HOST *hd, int id)
5609{
5610 MPT_ADAPTER *ioc = hd->ioc;
5611 SpiCfgData *pSpi = &ioc->spi_data;
5612 Ioc3PhysDisk_t *pPDisk;
5613 int numPDisk;
5614
5615 if (hd->negoNvram != 0)
5616 return;
5617
5618 ddvtprintk(("DV requested for phys disk id %d\n", id));
5619 if (ioc->raid_data.pIocPg3) {
5620 pPDisk = ioc->raid_data.pIocPg3->PhysDisk;
5621 numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
5622 while (numPDisk) {
5623 if (id == pPDisk->PhysDiskNum) {
5624 pSpi->dvStatus[pPDisk->PhysDiskID] =
5625 (MPT_SCSICFG_NEED_DV | MPT_SCSICFG_DV_NOT_DONE);
5626 pSpi->forceDv = MPT_SCSICFG_NEED_DV;
5627 ddvtprintk(("NEED_DV set for phys disk id %d\n",
5628 pPDisk->PhysDiskID));
5629 break;
5630 }
5631 pPDisk++;
5632 numPDisk--;
5633 }
5634
5635 if (numPDisk == 0) {
5636 /* The physical disk that needs DV was not found
5637 * in the stored IOC Page 3. The driver must reload
5638 * this page. DV routine will set the NEED_DV flag for
5639 * all phys disks that have DV_NOT_DONE set.
5640 */
5641 pSpi->forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
5642 ddvtprintk(("phys disk %d not found. Setting reload IOC Pg3 Flag\n",id));
5643 }
5644 }
5645}
5646#endif /* ~MPTSCSIH_ENABLE_DOMAIN_VALIDATION */
5647
5648EXPORT_SYMBOL(mptscsih_remove); 3394EXPORT_SYMBOL(mptscsih_remove);
5649EXPORT_SYMBOL(mptscsih_shutdown); 3395EXPORT_SYMBOL(mptscsih_shutdown);
5650#ifdef CONFIG_PM 3396#ifdef CONFIG_PM
diff --git a/drivers/message/fusion/mptscsih.h b/drivers/message/fusion/mptscsih.h
index 44b248d51ea3..14a5b6c2e2bd 100644
--- a/drivers/message/fusion/mptscsih.h
+++ b/drivers/message/fusion/mptscsih.h
@@ -60,16 +60,6 @@
60 60
61#define MPT_SCSI_MAX_SECTORS 8192 61#define MPT_SCSI_MAX_SECTORS 8192
62 62
63/* To disable domain validation, uncomment the
64 * following line. No effect for FC devices.
65 * For SCSI devices, driver will negotiate to
66 * NVRAM settings (if available) or to maximum adapter
67 * capabilities.
68 */
69
70#define MPTSCSIH_ENABLE_DOMAIN_VALIDATION
71
72
73/* SCSI driver setup structure. Settings can be overridden 63/* SCSI driver setup structure. Settings can be overridden
74 * by command line options. 64 * by command line options.
75 */ 65 */
@@ -109,3 +99,5 @@ extern int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
109extern int mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth); 99extern int mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth);
110extern void mptscsih_timer_expired(unsigned long data); 100extern void mptscsih_timer_expired(unsigned long data);
111extern int mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout); 101extern int mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout);
102extern int mptscsih_raid_id_to_num(MPT_SCSI_HOST *hd, uint physdiskid);
103extern int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id);
diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c
index f148dfa39117..09c745b19cc8 100644
--- a/drivers/message/fusion/mptspi.c
+++ b/drivers/message/fusion/mptspi.c
@@ -56,12 +56,15 @@
56#include <linux/reboot.h> /* notifier code */ 56#include <linux/reboot.h> /* notifier code */
57#include <linux/sched.h> 57#include <linux/sched.h>
58#include <linux/workqueue.h> 58#include <linux/workqueue.h>
59#include <linux/raid_class.h>
59 60
60#include <scsi/scsi.h> 61#include <scsi/scsi.h>
61#include <scsi/scsi_cmnd.h> 62#include <scsi/scsi_cmnd.h>
62#include <scsi/scsi_device.h> 63#include <scsi/scsi_device.h>
63#include <scsi/scsi_host.h> 64#include <scsi/scsi_host.h>
64#include <scsi/scsi_tcq.h> 65#include <scsi/scsi_tcq.h>
66#include <scsi/scsi_transport.h>
67#include <scsi/scsi_transport_spi.h>
65 68
66#include "mptbase.h" 69#include "mptbase.h"
67#include "mptscsih.h" 70#include "mptscsih.h"
@@ -76,20 +79,6 @@ MODULE_DESCRIPTION(my_NAME);
76MODULE_LICENSE("GPL"); 79MODULE_LICENSE("GPL");
77 80
78/* Command line args */ 81/* Command line args */
79#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
80static int mpt_dv = MPTSCSIH_DOMAIN_VALIDATION;
81module_param(mpt_dv, int, 0);
82MODULE_PARM_DESC(mpt_dv, " DV Algorithm: enhanced=1, basic=0 (default=MPTSCSIH_DOMAIN_VALIDATION=1)");
83
84static int mpt_width = MPTSCSIH_MAX_WIDTH;
85module_param(mpt_width, int, 0);
86MODULE_PARM_DESC(mpt_width, " Max Bus Width: wide=1, narrow=0 (default=MPTSCSIH_MAX_WIDTH=1)");
87
88static ushort mpt_factor = MPTSCSIH_MIN_SYNC;
89module_param(mpt_factor, ushort, 0);
90MODULE_PARM_DESC(mpt_factor, " Min Sync Factor (default=MPTSCSIH_MIN_SYNC=0x08)");
91#endif
92
93static int mpt_saf_te = MPTSCSIH_SAF_TE; 82static int mpt_saf_te = MPTSCSIH_SAF_TE;
94module_param(mpt_saf_te, int, 0); 83module_param(mpt_saf_te, int, 0);
95MODULE_PARM_DESC(mpt_saf_te, " Force enabling SEP Processor: enable=1 (default=MPTSCSIH_SAF_TE=0)"); 84MODULE_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;
98module_param(mpt_pq_filter, int, 0); 87module_param(mpt_pq_filter, int, 0);
99MODULE_PARM_DESC(mpt_pq_filter, " Enable peripheral qualifier filter: enable=1 (default=0)"); 88MODULE_PARM_DESC(mpt_pq_filter, " Enable peripheral qualifier filter: enable=1 (default=0)");
100 89
90static void mptspi_write_offset(struct scsi_target *, int);
91static void mptspi_write_width(struct scsi_target *, int);
92static int mptspi_write_spi_device_pg1(struct scsi_target *,
93 struct _CONFIG_PAGE_SCSI_DEVICE_1 *);
94
95static struct scsi_transport_template *mptspi_transport_template = NULL;
96
101static int mptspiDoneCtx = -1; 97static int mptspiDoneCtx = -1;
102static int mptspiTaskCtx = -1; 98static int mptspiTaskCtx = -1;
103static int mptspiInternalCtx = -1; /* Used only for internal commands */ 99static int mptspiInternalCtx = -1; /* Used only for internal commands */
104 100
101static int mptspi_target_alloc(struct scsi_target *starget)
102{
103 struct Scsi_Host *shost = dev_to_shost(&starget->dev);
104 struct _MPT_SCSI_HOST *hd = (struct _MPT_SCSI_HOST *)shost->hostdata;
105 int ret;
106
107 if (hd == NULL)
108 return -ENODEV;
109
110 ret = mptscsih_target_alloc(starget);
111 if (ret)
112 return ret;
113
114 /* if we're a device on virtual channel 1 and we're not part
115 * of an array, just return here (otherwise the setup below
116 * may actually affect a real physical device on channel 0 */
117 if (starget->channel == 1 &&
118 mptscsih_raid_id_to_num(hd, starget->id) < 0)
119 return 0;
120
121 if (hd->ioc->spi_data.nvram &&
122 hd->ioc->spi_data.nvram[starget->id] != MPT_HOST_NVRAM_INVALID) {
123 u32 nvram = hd->ioc->spi_data.nvram[starget->id];
124 spi_min_period(starget) = (nvram & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT;
125 spi_max_width(starget) = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
126 } else {
127 spi_min_period(starget) = hd->ioc->spi_data.minSyncFactor;
128 spi_max_width(starget) = hd->ioc->spi_data.maxBusWidth;
129 }
130 spi_max_offset(starget) = hd->ioc->spi_data.maxSyncOffset;
131
132 spi_offset(starget) = 0;
133 mptspi_write_width(starget, 0);
134
135 return 0;
136}
137
138static int mptspi_read_spi_device_pg0(struct scsi_target *starget,
139 struct _CONFIG_PAGE_SCSI_DEVICE_0 *pass_pg0)
140{
141 struct Scsi_Host *shost = dev_to_shost(&starget->dev);
142 struct _MPT_SCSI_HOST *hd = (struct _MPT_SCSI_HOST *)shost->hostdata;
143 struct _MPT_ADAPTER *ioc = hd->ioc;
144 struct _CONFIG_PAGE_SCSI_DEVICE_0 *pg0;
145 dma_addr_t pg0_dma;
146 int size;
147 struct _x_config_parms cfg;
148 struct _CONFIG_PAGE_HEADER hdr;
149 int err = -EBUSY;
150
151 /* No SPI parameters for RAID devices */
152 if (starget->channel == 0 &&
153 (hd->ioc->raid_data.isRaid & (1 << starget->id)))
154 return -1;
155
156 size = ioc->spi_data.sdp0length * 4;
157 /*
158 if (ioc->spi_data.sdp0length & 1)
159 size += size + 4;
160 size += 2048;
161 */
162
163 pg0 = dma_alloc_coherent(&ioc->pcidev->dev, size, &pg0_dma, GFP_KERNEL);
164 if (pg0 == NULL) {
165 starget_printk(KERN_ERR, starget, "dma_alloc_coherent for parameters failed\n");
166 return -EINVAL;
167 }
168
169 memset(&hdr, 0, sizeof(hdr));
170
171 hdr.PageVersion = ioc->spi_data.sdp0version;
172 hdr.PageLength = ioc->spi_data.sdp0length;
173 hdr.PageNumber = 0;
174 hdr.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
175
176 memset(&cfg, 0, sizeof(cfg));
177
178 cfg.cfghdr.hdr = &hdr;
179 cfg.physAddr = pg0_dma;
180 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
181 cfg.dir = 0;
182 cfg.pageAddr = starget->id;
183
184 if (mpt_config(ioc, &cfg)) {
185 starget_printk(KERN_ERR, starget, "mpt_config failed\n");
186 goto out_free;
187 }
188 err = 0;
189 memcpy(pass_pg0, pg0, size);
190
191 out_free:
192 dma_free_coherent(&ioc->pcidev->dev, size, pg0, pg0_dma);
193 return err;
194}
195
196static u32 mptspi_getRP(struct scsi_target *starget)
197{
198 u32 nego = 0;
199
200 nego |= spi_iu(starget) ? MPI_SCSIDEVPAGE1_RP_IU : 0;
201 nego |= spi_dt(starget) ? MPI_SCSIDEVPAGE1_RP_DT : 0;
202 nego |= spi_qas(starget) ? MPI_SCSIDEVPAGE1_RP_QAS : 0;
203 nego |= spi_hold_mcs(starget) ? MPI_SCSIDEVPAGE1_RP_HOLD_MCS : 0;
204 nego |= spi_wr_flow(starget) ? MPI_SCSIDEVPAGE1_RP_WR_FLOW : 0;
205 nego |= spi_rd_strm(starget) ? MPI_SCSIDEVPAGE1_RP_RD_STRM : 0;
206 nego |= spi_rti(starget) ? MPI_SCSIDEVPAGE1_RP_RTI : 0;
207 nego |= spi_pcomp_en(starget) ? MPI_SCSIDEVPAGE1_RP_PCOMP_EN : 0;
208
209 nego |= (spi_period(starget) << MPI_SCSIDEVPAGE1_RP_SHIFT_MIN_SYNC_PERIOD) & MPI_SCSIDEVPAGE1_RP_MIN_SYNC_PERIOD_MASK;
210 nego |= (spi_offset(starget) << MPI_SCSIDEVPAGE1_RP_SHIFT_MAX_SYNC_OFFSET) & MPI_SCSIDEVPAGE1_RP_MAX_SYNC_OFFSET_MASK;
211 nego |= spi_width(starget) ? MPI_SCSIDEVPAGE1_RP_WIDE : 0;
212
213 return nego;
214}
215
216static void mptspi_read_parameters(struct scsi_target *starget)
217{
218 int nego;
219 struct _CONFIG_PAGE_SCSI_DEVICE_0 pg0;
220
221 mptspi_read_spi_device_pg0(starget, &pg0);
222
223 nego = le32_to_cpu(pg0.NegotiatedParameters);
224
225 spi_iu(starget) = (nego & MPI_SCSIDEVPAGE0_NP_IU) ? 1 : 0;
226 spi_dt(starget) = (nego & MPI_SCSIDEVPAGE0_NP_DT) ? 1 : 0;
227 spi_qas(starget) = (nego & MPI_SCSIDEVPAGE0_NP_QAS) ? 1 : 0;
228 spi_wr_flow(starget) = (nego & MPI_SCSIDEVPAGE0_NP_WR_FLOW) ? 1 : 0;
229 spi_rd_strm(starget) = (nego & MPI_SCSIDEVPAGE0_NP_RD_STRM) ? 1 : 0;
230 spi_rti(starget) = (nego & MPI_SCSIDEVPAGE0_NP_RTI) ? 1 : 0;
231 spi_pcomp_en(starget) = (nego & MPI_SCSIDEVPAGE0_NP_PCOMP_EN) ? 1 : 0;
232 spi_hold_mcs(starget) = (nego & MPI_SCSIDEVPAGE0_NP_HOLD_MCS) ? 1 : 0;
233 spi_period(starget) = (nego & MPI_SCSIDEVPAGE0_NP_NEG_SYNC_PERIOD_MASK) >> MPI_SCSIDEVPAGE0_NP_SHIFT_SYNC_PERIOD;
234 spi_offset(starget) = (nego & MPI_SCSIDEVPAGE0_NP_NEG_SYNC_OFFSET_MASK) >> MPI_SCSIDEVPAGE0_NP_SHIFT_SYNC_OFFSET;
235 spi_width(starget) = (nego & MPI_SCSIDEVPAGE0_NP_WIDE) ? 1 : 0;
236}
237
238static int
239mptscsih_quiesce_raid(MPT_SCSI_HOST *hd, int quiesce, int disk)
240{
241 MpiRaidActionRequest_t *pReq;
242 MPT_FRAME_HDR *mf;
243
244 /* Get and Populate a free Frame
245 */
246 if ((mf = mpt_get_msg_frame(hd->ioc->InternalCtx, hd->ioc)) == NULL) {
247 ddvprintk((MYIOC_s_WARN_FMT "_do_raid: no msg frames!\n",
248 hd->ioc->name));
249 return -EAGAIN;
250 }
251 pReq = (MpiRaidActionRequest_t *)mf;
252 if (quiesce)
253 pReq->Action = MPI_RAID_ACTION_QUIESCE_PHYS_IO;
254 else
255 pReq->Action = MPI_RAID_ACTION_ENABLE_PHYS_IO;
256 pReq->Reserved1 = 0;
257 pReq->ChainOffset = 0;
258 pReq->Function = MPI_FUNCTION_RAID_ACTION;
259 pReq->VolumeID = disk;
260 pReq->VolumeBus = 0;
261 pReq->PhysDiskNum = 0;
262 pReq->MsgFlags = 0;
263 pReq->Reserved2 = 0;
264 pReq->ActionDataWord = 0; /* Reserved for this action */
265
266 mpt_add_sge((char *)&pReq->ActionDataSGE,
267 MPT_SGE_FLAGS_SSIMPLE_READ | 0, (dma_addr_t) -1);
268
269 ddvprintk((MYIOC_s_INFO_FMT "RAID Volume action %x id %d\n",
270 hd->ioc->name, action, io->id));
271
272 hd->pLocal = NULL;
273 hd->timer.expires = jiffies + HZ*10; /* 10 second timeout */
274 hd->scandv_wait_done = 0;
275
276 /* Save cmd pointer, for resource free if timeout or
277 * FW reload occurs
278 */
279 hd->cmdPtr = mf;
280
281 add_timer(&hd->timer);
282 mpt_put_msg_frame(hd->ioc->InternalCtx, hd->ioc, mf);
283 wait_event(hd->scandv_waitq, hd->scandv_wait_done);
284
285 if ((hd->pLocal == NULL) || (hd->pLocal->completion != 0))
286 return -1;
287
288 return 0;
289}
290
291static void mptspi_dv_device(struct _MPT_SCSI_HOST *hd,
292 struct scsi_device *sdev)
293{
294 VirtTarget *vtarget = scsi_target(sdev)->hostdata;
295
296 /* no DV on RAID devices */
297 if (sdev->channel == 0 &&
298 (hd->ioc->raid_data.isRaid & (1 << sdev->id)))
299 return;
300
301 /* If this is a piece of a RAID, then quiesce first */
302 if (sdev->channel == 1 &&
303 mptscsih_quiesce_raid(hd, 1, vtarget->target_id) < 0) {
304 starget_printk(KERN_ERR, scsi_target(sdev),
305 "Integrated RAID quiesce failed\n");
306 return;
307 }
308
309 spi_dv_device(sdev);
310
311 if (sdev->channel == 1 &&
312 mptscsih_quiesce_raid(hd, 0, vtarget->target_id) < 0)
313 starget_printk(KERN_ERR, scsi_target(sdev),
314 "Integrated RAID resume failed\n");
315
316 mptspi_read_parameters(sdev->sdev_target);
317 spi_display_xfer_agreement(sdev->sdev_target);
318 mptspi_read_parameters(sdev->sdev_target);
319}
320
321static int mptspi_slave_alloc(struct scsi_device *sdev)
322{
323 int ret;
324 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sdev->host->hostdata;
325 /* gcc doesn't see that all uses of this variable occur within
326 * the if() statements, so stop it from whining */
327 int physdisknum = 0;
328
329 if (sdev->channel == 1) {
330 physdisknum = mptscsih_raid_id_to_num(hd, sdev->id);
331
332 if (physdisknum < 0)
333 return physdisknum;
334 }
335
336 ret = mptscsih_slave_alloc(sdev);
337
338 if (ret)
339 return ret;
340
341 if (sdev->channel == 1) {
342 VirtDevice *vdev = sdev->hostdata;
343 sdev->no_uld_attach = 1;
344 vdev->vtarget->tflags |= MPT_TARGET_FLAGS_RAID_COMPONENT;
345 /* The real channel for this device is zero */
346 vdev->vtarget->bus_id = 0;
347 /* The actual physdisknum (for RAID passthrough) */
348 vdev->vtarget->target_id = physdisknum;
349 }
350
351 return 0;
352}
353
354static int mptspi_slave_configure(struct scsi_device *sdev)
355{
356 int ret = mptscsih_slave_configure(sdev);
357 struct _MPT_SCSI_HOST *hd =
358 (struct _MPT_SCSI_HOST *)sdev->host->hostdata;
359
360 if (ret)
361 return ret;
362
363 if ((sdev->channel == 1 ||
364 !(hd->ioc->raid_data.isRaid & (1 << sdev->id))) &&
365 !spi_initial_dv(sdev->sdev_target))
366 mptspi_dv_device(hd, sdev);
367
368 return 0;
369}
370
371static void mptspi_slave_destroy(struct scsi_device *sdev)
372{
373 struct scsi_target *starget = scsi_target(sdev);
374 VirtTarget *vtarget = starget->hostdata;
375 VirtDevice *vdevice = sdev->hostdata;
376
377 /* Will this be the last lun on a non-raid device? */
378 if (vtarget->num_luns == 1 && vdevice->configured_lun) {
379 struct _CONFIG_PAGE_SCSI_DEVICE_1 pg1;
380
381 /* Async Narrow */
382 pg1.RequestedParameters = 0;
383 pg1.Reserved = 0;
384 pg1.Configuration = 0;
385
386 mptspi_write_spi_device_pg1(starget, &pg1);
387 }
388
389 mptscsih_slave_destroy(sdev);
390}
391
105static struct scsi_host_template mptspi_driver_template = { 392static struct scsi_host_template mptspi_driver_template = {
106 .module = THIS_MODULE, 393 .module = THIS_MODULE,
107 .proc_name = "mptspi", 394 .proc_name = "mptspi",
@@ -109,11 +396,11 @@ static struct scsi_host_template mptspi_driver_template = {
109 .name = "MPT SPI Host", 396 .name = "MPT SPI Host",
110 .info = mptscsih_info, 397 .info = mptscsih_info,
111 .queuecommand = mptscsih_qcmd, 398 .queuecommand = mptscsih_qcmd,
112 .target_alloc = mptscsih_target_alloc, 399 .target_alloc = mptspi_target_alloc,
113 .slave_alloc = mptscsih_slave_alloc, 400 .slave_alloc = mptspi_slave_alloc,
114 .slave_configure = mptscsih_slave_configure, 401 .slave_configure = mptspi_slave_configure,
115 .target_destroy = mptscsih_target_destroy, 402 .target_destroy = mptscsih_target_destroy,
116 .slave_destroy = mptscsih_slave_destroy, 403 .slave_destroy = mptspi_slave_destroy,
117 .change_queue_depth = mptscsih_change_queue_depth, 404 .change_queue_depth = mptscsih_change_queue_depth,
118 .eh_abort_handler = mptscsih_abort, 405 .eh_abort_handler = mptscsih_abort,
119 .eh_device_reset_handler = mptscsih_dev_reset, 406 .eh_device_reset_handler = mptscsih_dev_reset,
@@ -128,6 +415,360 @@ static struct scsi_host_template mptspi_driver_template = {
128 .use_clustering = ENABLE_CLUSTERING, 415 .use_clustering = ENABLE_CLUSTERING,
129}; 416};
130 417
418static int mptspi_write_spi_device_pg1(struct scsi_target *starget,
419 struct _CONFIG_PAGE_SCSI_DEVICE_1 *pass_pg1)
420{
421 struct Scsi_Host *shost = dev_to_shost(&starget->dev);
422 struct _MPT_SCSI_HOST *hd = (struct _MPT_SCSI_HOST *)shost->hostdata;
423 struct _MPT_ADAPTER *ioc = hd->ioc;
424 struct _CONFIG_PAGE_SCSI_DEVICE_1 *pg1;
425 dma_addr_t pg1_dma;
426 int size;
427 struct _x_config_parms cfg;
428 struct _CONFIG_PAGE_HEADER hdr;
429 int err = -EBUSY;
430
431 /* don't allow updating nego parameters on RAID devices */
432 if (starget->channel == 0 &&
433 (hd->ioc->raid_data.isRaid & (1 << starget->id)))
434 return -1;
435
436 size = ioc->spi_data.sdp1length * 4;
437
438 pg1 = dma_alloc_coherent(&ioc->pcidev->dev, size, &pg1_dma, GFP_KERNEL);
439 if (pg1 == NULL) {
440 starget_printk(KERN_ERR, starget, "dma_alloc_coherent for parameters failed\n");
441 return -EINVAL;
442 }
443
444 memset(&hdr, 0, sizeof(hdr));
445
446 hdr.PageVersion = ioc->spi_data.sdp1version;
447 hdr.PageLength = ioc->spi_data.sdp1length;
448 hdr.PageNumber = 1;
449 hdr.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
450
451 memset(&cfg, 0, sizeof(cfg));
452
453 cfg.cfghdr.hdr = &hdr;
454 cfg.physAddr = pg1_dma;
455 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
456 cfg.dir = 1;
457 cfg.pageAddr = starget->id;
458
459 memcpy(pg1, pass_pg1, size);
460
461 pg1->Header.PageVersion = hdr.PageVersion;
462 pg1->Header.PageLength = hdr.PageLength;
463 pg1->Header.PageNumber = hdr.PageNumber;
464 pg1->Header.PageType = hdr.PageType;
465
466 if (mpt_config(ioc, &cfg)) {
467 starget_printk(KERN_ERR, starget, "mpt_config failed\n");
468 goto out_free;
469 }
470 err = 0;
471
472 out_free:
473 dma_free_coherent(&ioc->pcidev->dev, size, pg1, pg1_dma);
474 return err;
475}
476
477static void mptspi_write_offset(struct scsi_target *starget, int offset)
478{
479 struct _CONFIG_PAGE_SCSI_DEVICE_1 pg1;
480 u32 nego;
481
482 if (offset < 0)
483 offset = 0;
484
485 if (offset > 255)
486 offset = 255;
487
488 if (spi_offset(starget) == -1)
489 mptspi_read_parameters(starget);
490
491 spi_offset(starget) = offset;
492
493 nego = mptspi_getRP(starget);
494
495 pg1.RequestedParameters = cpu_to_le32(nego);
496 pg1.Reserved = 0;
497 pg1.Configuration = 0;
498
499 mptspi_write_spi_device_pg1(starget, &pg1);
500}
501
502static void mptspi_write_period(struct scsi_target *starget, int period)
503{
504 struct _CONFIG_PAGE_SCSI_DEVICE_1 pg1;
505 u32 nego;
506
507 if (period < 8)
508 period = 8;
509
510 if (period > 255)
511 period = 255;
512
513 if (spi_period(starget) == -1)
514 mptspi_read_parameters(starget);
515
516 if (period == 8) {
517 spi_iu(starget) = 1;
518 spi_dt(starget) = 1;
519 } else if (period == 9) {
520 spi_dt(starget) = 1;
521 }
522
523 spi_period(starget) = period;
524
525 nego = mptspi_getRP(starget);
526
527 pg1.RequestedParameters = cpu_to_le32(nego);
528 pg1.Reserved = 0;
529 pg1.Configuration = 0;
530
531 mptspi_write_spi_device_pg1(starget, &pg1);
532}
533
534static void mptspi_write_dt(struct scsi_target *starget, int dt)
535{
536 struct _CONFIG_PAGE_SCSI_DEVICE_1 pg1;
537 u32 nego;
538
539 if (spi_period(starget) == -1)
540 mptspi_read_parameters(starget);
541
542 if (!dt && spi_period(starget) < 10)
543 spi_period(starget) = 10;
544
545 spi_dt(starget) = dt;
546
547 nego = mptspi_getRP(starget);
548
549
550 pg1.RequestedParameters = cpu_to_le32(nego);
551 pg1.Reserved = 0;
552 pg1.Configuration = 0;
553
554 mptspi_write_spi_device_pg1(starget, &pg1);
555}
556
557static void mptspi_write_iu(struct scsi_target *starget, int iu)
558{
559 struct _CONFIG_PAGE_SCSI_DEVICE_1 pg1;
560 u32 nego;
561
562 if (spi_period(starget) == -1)
563 mptspi_read_parameters(starget);
564
565 if (!iu && spi_period(starget) < 9)
566 spi_period(starget) = 9;
567
568 spi_iu(starget) = iu;
569
570 nego = mptspi_getRP(starget);
571
572 pg1.RequestedParameters = cpu_to_le32(nego);
573 pg1.Reserved = 0;
574 pg1.Configuration = 0;
575
576 mptspi_write_spi_device_pg1(starget, &pg1);
577}
578
579#define MPTSPI_SIMPLE_TRANSPORT_PARM(parm) \
580static void mptspi_write_##parm(struct scsi_target *starget, int parm)\
581{ \
582 struct _CONFIG_PAGE_SCSI_DEVICE_1 pg1; \
583 u32 nego; \
584 \
585 spi_##parm(starget) = parm; \
586 \
587 nego = mptspi_getRP(starget); \
588 \
589 pg1.RequestedParameters = cpu_to_le32(nego); \
590 pg1.Reserved = 0; \
591 pg1.Configuration = 0; \
592 \
593 mptspi_write_spi_device_pg1(starget, &pg1); \
594}
595
596MPTSPI_SIMPLE_TRANSPORT_PARM(rd_strm)
597MPTSPI_SIMPLE_TRANSPORT_PARM(wr_flow)
598MPTSPI_SIMPLE_TRANSPORT_PARM(rti)
599MPTSPI_SIMPLE_TRANSPORT_PARM(hold_mcs)
600MPTSPI_SIMPLE_TRANSPORT_PARM(pcomp_en)
601
602static void mptspi_write_qas(struct scsi_target *starget, int qas)
603{
604 struct _CONFIG_PAGE_SCSI_DEVICE_1 pg1;
605 struct Scsi_Host *shost = dev_to_shost(&starget->dev);
606 struct _MPT_SCSI_HOST *hd = (struct _MPT_SCSI_HOST *)shost->hostdata;
607 VirtTarget *vtarget = starget->hostdata;
608 u32 nego;
609
610 if ((vtarget->negoFlags & MPT_TARGET_NO_NEGO_QAS) ||
611 hd->ioc->spi_data.noQas)
612 spi_qas(starget) = 0;
613 else
614 spi_qas(starget) = qas;
615
616 nego = mptspi_getRP(starget);
617
618 pg1.RequestedParameters = cpu_to_le32(nego);
619 pg1.Reserved = 0;
620 pg1.Configuration = 0;
621
622 mptspi_write_spi_device_pg1(starget, &pg1);
623}
624
625static void mptspi_write_width(struct scsi_target *starget, int width)
626{
627 struct _CONFIG_PAGE_SCSI_DEVICE_1 pg1;
628 u32 nego;
629
630 if (!width) {
631 spi_dt(starget) = 0;
632 if (spi_period(starget) < 10)
633 spi_period(starget) = 10;
634 }
635
636 spi_width(starget) = width;
637
638 nego = mptspi_getRP(starget);
639
640 pg1.RequestedParameters = cpu_to_le32(nego);
641 pg1.Reserved = 0;
642 pg1.Configuration = 0;
643
644 mptspi_write_spi_device_pg1(starget, &pg1);
645}
646
647struct work_queue_wrapper {
648 struct work_struct work;
649 struct _MPT_SCSI_HOST *hd;
650 int disk;
651};
652
653static void mpt_work_wrapper(void *data)
654{
655 struct work_queue_wrapper *wqw = (struct work_queue_wrapper *)data;
656 struct _MPT_SCSI_HOST *hd = wqw->hd;
657 struct Scsi_Host *shost = hd->ioc->sh;
658 struct scsi_device *sdev;
659 int disk = wqw->disk;
660 struct _CONFIG_PAGE_IOC_3 *pg3;
661
662 kfree(wqw);
663
664 mpt_findImVolumes(hd->ioc);
665 pg3 = hd->ioc->raid_data.pIocPg3;
666 if (!pg3)
667 return;
668
669 shost_for_each_device(sdev,shost) {
670 struct scsi_target *starget = scsi_target(sdev);
671 VirtTarget *vtarget = starget->hostdata;
672
673 /* only want to search RAID components */
674 if (sdev->channel != 1)
675 continue;
676
677 /* The target_id is the raid PhysDiskNum, even if
678 * starget->id is the actual target address */
679 if(vtarget->target_id != disk)
680 continue;
681
682 starget_printk(KERN_INFO, vtarget->starget,
683 "Integrated RAID requests DV of new device\n");
684 mptspi_dv_device(hd, sdev);
685 }
686 shost_printk(KERN_INFO, shost,
687 "Integrated RAID detects new device %d\n", disk);
688 scsi_scan_target(&hd->ioc->sh->shost_gendev, 1, disk, 0, 1);
689}
690
691
692static void mpt_dv_raid(struct _MPT_SCSI_HOST *hd, int disk)
693{
694 struct work_queue_wrapper *wqw = kmalloc(sizeof(*wqw), GFP_ATOMIC);
695
696 if (!wqw) {
697 shost_printk(KERN_ERR, hd->ioc->sh,
698 "Failed to act on RAID event for physical disk %d\n",
699 disk);
700 return;
701 }
702 INIT_WORK(&wqw->work, mpt_work_wrapper, wqw);
703 wqw->hd = hd;
704 wqw->disk = disk;
705
706 schedule_work(&wqw->work);
707}
708
709static int
710mptspi_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
711{
712 u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
713 struct _MPT_SCSI_HOST *hd = (struct _MPT_SCSI_HOST *)ioc->sh->hostdata;
714
715 if (hd && event == MPI_EVENT_INTEGRATED_RAID) {
716 int reason
717 = (le32_to_cpu(pEvReply->Data[0]) & 0x00FF0000) >> 16;
718
719 if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
720 int disk = (le32_to_cpu(pEvReply->Data[0]) & 0xFF000000) >> 24;
721 mpt_dv_raid(hd, disk);
722 }
723 }
724 return mptscsih_event_process(ioc, pEvReply);
725}
726
727static int
728mptspi_deny_binding(struct scsi_target *starget)
729{
730 struct _MPT_SCSI_HOST *hd =
731 (struct _MPT_SCSI_HOST *)dev_to_shost(starget->dev.parent)->hostdata;
732 return ((hd->ioc->raid_data.isRaid & (1 << starget->id)) &&
733 starget->channel == 0) ? 1 : 0;
734}
735
736static struct spi_function_template mptspi_transport_functions = {
737 .get_offset = mptspi_read_parameters,
738 .set_offset = mptspi_write_offset,
739 .show_offset = 1,
740 .get_period = mptspi_read_parameters,
741 .set_period = mptspi_write_period,
742 .show_period = 1,
743 .get_width = mptspi_read_parameters,
744 .set_width = mptspi_write_width,
745 .show_width = 1,
746 .get_iu = mptspi_read_parameters,
747 .set_iu = mptspi_write_iu,
748 .show_iu = 1,
749 .get_dt = mptspi_read_parameters,
750 .set_dt = mptspi_write_dt,
751 .show_dt = 1,
752 .get_qas = mptspi_read_parameters,
753 .set_qas = mptspi_write_qas,
754 .show_qas = 1,
755 .get_wr_flow = mptspi_read_parameters,
756 .set_wr_flow = mptspi_write_wr_flow,
757 .show_wr_flow = 1,
758 .get_rd_strm = mptspi_read_parameters,
759 .set_rd_strm = mptspi_write_rd_strm,
760 .show_rd_strm = 1,
761 .get_rti = mptspi_read_parameters,
762 .set_rti = mptspi_write_rti,
763 .show_rti = 1,
764 .get_pcomp_en = mptspi_read_parameters,
765 .set_pcomp_en = mptspi_write_pcomp_en,
766 .show_pcomp_en = 1,
767 .get_hold_mcs = mptspi_read_parameters,
768 .set_hold_mcs = mptspi_write_hold_mcs,
769 .show_hold_mcs = 1,
770 .deny_binding = mptspi_deny_binding,
771};
131 772
132/**************************************************************************** 773/****************************************************************************
133 * Supported hardware 774 * Supported hardware
@@ -242,7 +883,14 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
242 sh->max_id = MPT_MAX_SCSI_DEVICES; 883 sh->max_id = MPT_MAX_SCSI_DEVICES;
243 884
244 sh->max_lun = MPT_LAST_LUN + 1; 885 sh->max_lun = MPT_LAST_LUN + 1;
245 sh->max_channel = 0; 886 /*
887 * If RAID Firmware Detected, setup virtual channel
888 */
889 if ((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
890 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI)
891 sh->max_channel = 1;
892 else
893 sh->max_channel = 0;
246 sh->this_id = ioc->pfacts[0].PortSCSIID; 894 sh->this_id = ioc->pfacts[0].PortSCSIID;
247 895
248 /* Required entry. 896 /* Required entry.
@@ -301,7 +949,8 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
301 * indicates a device exists. 949 * indicates a device exists.
302 * max_id = 1 + maximum id (hosts.h) 950 * max_id = 1 + maximum id (hosts.h)
303 */ 951 */
304 hd->Targets = kcalloc(sh->max_id, sizeof(void *), GFP_ATOMIC); 952 hd->Targets = kcalloc(sh->max_id * (sh->max_channel + 1),
953 sizeof(void *), GFP_ATOMIC);
305 if (!hd->Targets) { 954 if (!hd->Targets) {
306 error = -ENOMEM; 955 error = -ENOMEM;
307 goto out_mptspi_probe; 956 goto out_mptspi_probe;
@@ -334,49 +983,23 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
334 ioc->spi_data.Saf_Te = mpt_saf_te; 983 ioc->spi_data.Saf_Te = mpt_saf_te;
335 hd->mpt_pq_filter = mpt_pq_filter; 984 hd->mpt_pq_filter = mpt_pq_filter;
336 985
337#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
338 if (ioc->spi_data.maxBusWidth > mpt_width)
339 ioc->spi_data.maxBusWidth = mpt_width;
340 if (ioc->spi_data.minSyncFactor < mpt_factor)
341 ioc->spi_data.minSyncFactor = mpt_factor;
342 if (ioc->spi_data.minSyncFactor == MPT_ASYNC) {
343 ioc->spi_data.maxSyncOffset = 0;
344 }
345 ioc->spi_data.mpt_dv = mpt_dv;
346 hd->negoNvram = 0;
347
348 ddvprintk((MYIOC_s_INFO_FMT
349 "dv %x width %x factor %x saf_te %x mpt_pq_filter %x\n",
350 ioc->name,
351 mpt_dv,
352 mpt_width,
353 mpt_factor,
354 mpt_saf_te,
355 mpt_pq_filter));
356#else
357 hd->negoNvram = MPT_SCSICFG_USE_NVRAM; 986 hd->negoNvram = MPT_SCSICFG_USE_NVRAM;
358 ddvprintk((MYIOC_s_INFO_FMT 987 ddvprintk((MYIOC_s_INFO_FMT
359 "saf_te %x mpt_pq_filter %x\n", 988 "saf_te %x mpt_pq_filter %x\n",
360 ioc->name, 989 ioc->name,
361 mpt_saf_te, 990 mpt_saf_te,
362 mpt_pq_filter)); 991 mpt_pq_filter));
363#endif
364
365 ioc->spi_data.forceDv = 0;
366 ioc->spi_data.noQas = 0; 992 ioc->spi_data.noQas = 0;
367 993
368 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++)
369 ioc->spi_data.dvStatus[ii] =
370 MPT_SCSICFG_NEGOTIATE;
371
372 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++)
373 ioc->spi_data.dvStatus[ii] |=
374 MPT_SCSICFG_DV_NOT_DONE;
375
376 init_waitqueue_head(&hd->scandv_waitq); 994 init_waitqueue_head(&hd->scandv_waitq);
377 hd->scandv_wait_done = 0; 995 hd->scandv_wait_done = 0;
378 hd->last_queue_full = 0; 996 hd->last_queue_full = 0;
379 997
998 /* Some versions of the firmware don't support page 0; without
999 * that we can't get the parameters */
1000 if (hd->ioc->spi_data.sdp0length != 0)
1001 sh->transportt = mptspi_transport_template;
1002
380 error = scsi_add_host (sh, &ioc->pcidev->dev); 1003 error = scsi_add_host (sh, &ioc->pcidev->dev);
381 if(error) { 1004 if(error) {
382 dprintk((KERN_ERR MYNAM 1005 dprintk((KERN_ERR MYNAM
@@ -423,15 +1046,18 @@ static struct pci_driver mptspi_driver = {
423static int __init 1046static int __init
424mptspi_init(void) 1047mptspi_init(void)
425{ 1048{
426
427 show_mptmod_ver(my_NAME, my_VERSION); 1049 show_mptmod_ver(my_NAME, my_VERSION);
428 1050
1051 mptspi_transport_template = spi_attach_transport(&mptspi_transport_functions);
1052 if (!mptspi_transport_template)
1053 return -ENODEV;
1054
429 mptspiDoneCtx = mpt_register(mptscsih_io_done, MPTSPI_DRIVER); 1055 mptspiDoneCtx = mpt_register(mptscsih_io_done, MPTSPI_DRIVER);
430 mptspiTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSPI_DRIVER); 1056 mptspiTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSPI_DRIVER);
431 mptspiInternalCtx = mpt_register(mptscsih_scandv_complete, MPTSPI_DRIVER); 1057 mptspiInternalCtx = mpt_register(mptscsih_scandv_complete, MPTSPI_DRIVER);
432 1058
433 if (mpt_event_register(mptspiDoneCtx, mptscsih_event_process) == 0) { 1059 if (mpt_event_register(mptspiDoneCtx, mptspi_event_process) == 0) {
434 devtprintk((KERN_INFO MYNAM 1060 devtverboseprintk((KERN_INFO MYNAM
435 ": Registered for IOC event notifications\n")); 1061 ": Registered for IOC event notifications\n"));
436 } 1062 }
437 1063
@@ -465,6 +1091,7 @@ mptspi_exit(void)
465 mpt_deregister(mptspiInternalCtx); 1091 mpt_deregister(mptspiInternalCtx);
466 mpt_deregister(mptspiTaskCtx); 1092 mpt_deregister(mptspiTaskCtx);
467 mpt_deregister(mptspiDoneCtx); 1093 mpt_deregister(mptspiDoneCtx);
1094 spi_release_transport(mptspi_transport_template);
468} 1095}
469 1096
470module_init(mptspi_init); 1097module_init(mptspi_init);