File Index
Files and directories
Sign in
FILE

mptbase.c

File preview with syntax highlighting.

linux-6.19.14/drivers/message/fusion/mptbase.c C
   1/*
   2 *  linux/drivers/message/fusion/mptbase.c
   3 *      This is the Fusion MPT base driver which supports multiple
   4 *      (SCSI + LAN) specialized protocol drivers.
   5 *      For use with LSI PCI chip/adapter(s)
   6 *      running LSI Fusion MPT (Message Passing Technology) firmware.
   7 *
   8 *  Copyright (c) 1999-2008 LSI Corporation
   9 *  (mailto:DL-MPTFusionLinux@lsi.com)
  10 *
  11 */
  12/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  13/*
  14    This program is free software; you can redistribute it and/or modify
  15    it under the terms of the GNU General Public License as published by
  16    the Free Software Foundation; version 2 of the License.
  17
  18    This program is distributed in the hope that it will be useful,
  19    but WITHOUT ANY WARRANTY; without even the implied warranty of
  20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21    GNU General Public License for more details.
  22
  23    NO WARRANTY
  24    THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
  25    CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
  26    LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
  27    MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
  28    solely responsible for determining the appropriateness of using and
  29    distributing the Program and assumes all risks associated with its
  30    exercise of rights under this Agreement, including but not limited to
  31    the risks and costs of program errors, damage to or loss of data,
  32    programs or equipment, and unavailability or interruption of operations.
  33
  34    DISCLAIMER OF LIABILITY
  35    NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
  36    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  37    DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
  38    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
  39    TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
  40    USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
  41    HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
  42
  43    You should have received a copy of the GNU General Public License
  44    along with this program; if not, write to the Free Software
  45    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  46*/
  47/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  48
  49#include <linux/kernel.h>
  50#include <linux/module.h>
  51#include <linux/errno.h>
  52#include <linux/init.h>
  53#include <linux/seq_file.h>
  54#include <linux/slab.h>
  55#include <linux/types.h>
  56#include <linux/pci.h>
  57#include <linux/kdev_t.h>
  58#include <linux/blkdev.h>
  59#include <linux/delay.h>
  60#include <linux/interrupt.h>
  61#include <linux/dma-mapping.h>
  62#include <linux/kthread.h>
  63#include <scsi/scsi_host.h>
  64
  65#include "mptbase.h"
  66#include "lsi/mpi_log_fc.h"
  67
  68/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  69#define my_NAME		"Fusion MPT base driver"
  70#define my_VERSION	MPT_LINUX_VERSION_COMMON
  71#define MYNAM		"mptbase"
  72
  73MODULE_AUTHOR(MODULEAUTHOR);
  74MODULE_DESCRIPTION(my_NAME);
  75MODULE_LICENSE("GPL");
  76MODULE_VERSION(my_VERSION);
  77
  78/*
  79 *  cmd line parameters
  80 */
  81
  82static int mpt_msi_enable_spi;
  83module_param(mpt_msi_enable_spi, int, 0);
  84MODULE_PARM_DESC(mpt_msi_enable_spi,
  85		 " Enable MSI Support for SPI controllers (default=0)");
  86
  87static int mpt_msi_enable_fc;
  88module_param(mpt_msi_enable_fc, int, 0);
  89MODULE_PARM_DESC(mpt_msi_enable_fc,
  90		 " Enable MSI Support for FC controllers (default=0)");
  91
  92static int mpt_msi_enable_sas;
  93module_param(mpt_msi_enable_sas, int, 0);
  94MODULE_PARM_DESC(mpt_msi_enable_sas,
  95		 " Enable MSI Support for SAS controllers (default=0)");
  96
  97static int mpt_channel_mapping;
  98module_param(mpt_channel_mapping, int, 0);
  99MODULE_PARM_DESC(mpt_channel_mapping, " Mapping id's to channels (default=0)");
 100
 101static int mpt_debug_level;
 102static int mpt_set_debug_level(const char *val, const struct kernel_param *kp);
 103module_param_call(mpt_debug_level, mpt_set_debug_level, param_get_int,
 104		  &mpt_debug_level, 0600);
 105MODULE_PARM_DESC(mpt_debug_level,
 106		 " debug level - refer to mptdebug.h - (default=0)");
 107
 108int mpt_fwfault_debug;
 109EXPORT_SYMBOL(mpt_fwfault_debug);
 110module_param(mpt_fwfault_debug, int, 0600);
 111MODULE_PARM_DESC(mpt_fwfault_debug,
 112		 "Enable detection of Firmware fault and halt Firmware on fault - (default=0)");
 113
 114static char	MptCallbacksName[MPT_MAX_PROTOCOL_DRIVERS]
 115				[MPT_MAX_CALLBACKNAME_LEN+1];
 116
 117#ifdef MFCNT
 118static int mfcounter = 0;
 119#define PRINT_MF_COUNT 20000
 120#endif
 121
 122/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 123/*
 124 *  Public data...
 125 */
 126
 127#define WHOINIT_UNKNOWN		0xAA
 128
 129/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 130/*
 131 *  Private data...
 132 */
 133					/* Adapter link list */
 134LIST_HEAD(ioc_list);
 135					/* Callback lookup table */
 136static MPT_CALLBACK		 MptCallbacks[MPT_MAX_PROTOCOL_DRIVERS];
 137					/* Protocol driver class lookup table */
 138static int			 MptDriverClass[MPT_MAX_PROTOCOL_DRIVERS];
 139					/* Event handler lookup table */
 140static MPT_EVHANDLER		 MptEvHandlers[MPT_MAX_PROTOCOL_DRIVERS];
 141					/* Reset handler lookup table */
 142static MPT_RESETHANDLER		 MptResetHandlers[MPT_MAX_PROTOCOL_DRIVERS];
 143static struct mpt_pci_driver 	*MptDeviceDriverHandlers[MPT_MAX_PROTOCOL_DRIVERS];
 144
 145#ifdef CONFIG_PROC_FS
 146static struct proc_dir_entry 	*mpt_proc_root_dir;
 147#endif
 148
 149/*
 150 *  Driver Callback Index's
 151 */
 152static u8 mpt_base_index = MPT_MAX_PROTOCOL_DRIVERS;
 153static u8 last_drv_idx;
 154
 155/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 156/*
 157 *  Forward protos...
 158 */
 159static irqreturn_t mpt_interrupt(int irq, void *bus_id);
 160static int	mptbase_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
 161		MPT_FRAME_HDR *reply);
 162static int	mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes,
 163			u32 *req, int replyBytes, u16 *u16reply, int maxwait,
 164			int sleepFlag);
 165static int	mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag);
 166static void	mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev);
 167static void	mpt_adapter_disable(MPT_ADAPTER *ioc);
 168static void	mpt_adapter_dispose(MPT_ADAPTER *ioc);
 169
 170static void	MptDisplayIocCapabilities(MPT_ADAPTER *ioc);
 171static int	MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag);
 172static int	GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason);
 173static int	GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
 174static int	SendIocInit(MPT_ADAPTER *ioc, int sleepFlag);
 175static int	SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
 176static int	mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag);
 177static int	mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag);
 178static int	mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
 179static int	KickStart(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
 180static int	SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag);
 181static int	PrimeIocFifos(MPT_ADAPTER *ioc);
 182static int	WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
 183static int	WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
 184static int	WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
 185static int	GetLanConfigPages(MPT_ADAPTER *ioc);
 186static int	GetIoUnitPage2(MPT_ADAPTER *ioc);
 187int		mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
 188static int	mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum);
 189static int	mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum);
 190static void 	mpt_read_ioc_pg_1(MPT_ADAPTER *ioc);
 191static void 	mpt_read_ioc_pg_4(MPT_ADAPTER *ioc);
 192static void	mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc);
 193static int	SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch,
 194	int sleepFlag);
 195static int	SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp);
 196static int	mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag);
 197static int	mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init);
 198
 199#ifdef CONFIG_PROC_FS
 200static int mpt_summary_proc_show(struct seq_file *m, void *v);
 201static int mpt_version_proc_show(struct seq_file *m, void *v);
 202static int mpt_iocinfo_proc_show(struct seq_file *m, void *v);
 203#endif
 204static void	mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc);
 205
 206static int	ProcessEventNotification(MPT_ADAPTER *ioc,
 207		EventNotificationReply_t *evReply, int *evHandlers);
 208static void	mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf);
 209static void	mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info);
 210static void	mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info);
 211static void	mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info , u8 cb_idx);
 212static int	mpt_read_ioc_pg_3(MPT_ADAPTER *ioc);
 213static void	mpt_inactive_raid_list_free(MPT_ADAPTER *ioc);
 214
 215/* module entry point */
 216static int  __init    fusion_init  (void);
 217static void __exit    fusion_exit  (void);
 218
 219#define CHIPREG_READ32(addr) 		readl_relaxed(addr)
 220#define CHIPREG_READ32_dmasync(addr)	readl(addr)
 221#define CHIPREG_WRITE32(addr,val) 	writel(val, addr)
 222#define CHIPREG_PIO_WRITE32(addr,val)	outl(val, (unsigned long)addr)
 223#define CHIPREG_PIO_READ32(addr) 	inl((unsigned long)addr)
 224
 225static void
 226pci_disable_io_access(struct pci_dev *pdev)
 227{
 228	u16 command_reg;
 229
 230	pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
 231	command_reg &= ~1;
 232	pci_write_config_word(pdev, PCI_COMMAND, command_reg);
 233}
 234
 235static void
 236pci_enable_io_access(struct pci_dev *pdev)
 237{
 238	u16 command_reg;
 239
 240	pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
 241	command_reg |= 1;
 242	pci_write_config_word(pdev, PCI_COMMAND, command_reg);
 243}
 244
 245static int mpt_set_debug_level(const char *val, const struct kernel_param *kp)
 246{
 247	int ret = param_set_int(val, kp);
 248	MPT_ADAPTER *ioc;
 249
 250	if (ret)
 251		return ret;
 252
 253	list_for_each_entry(ioc, &ioc_list, list)
 254		ioc->debug_level = mpt_debug_level;
 255	return 0;
 256}
 257
 258/**
 259 *	mpt_get_cb_idx - obtain cb_idx for registered driver
 260 *	@dclass: class driver enum
 261 *
 262 *	Returns cb_idx, or zero means it wasn't found
 263 **/
 264static u8
 265mpt_get_cb_idx(MPT_DRIVER_CLASS dclass)
 266{
 267	u8 cb_idx;
 268
 269	for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--)
 270		if (MptDriverClass[cb_idx] == dclass)
 271			return cb_idx;
 272	return 0;
 273}
 274
 275/**
 276 * mpt_is_discovery_complete - determine if discovery has completed
 277 * @ioc: per adatper instance
 278 *
 279 * Returns 1 when discovery completed, else zero.
 280 */
 281static int
 282mpt_is_discovery_complete(MPT_ADAPTER *ioc)
 283{
 284	ConfigExtendedPageHeader_t hdr;
 285	CONFIGPARMS cfg;
 286	SasIOUnitPage0_t *buffer;
 287	dma_addr_t dma_handle;
 288	int rc = 0;
 289
 290	memset(&hdr, 0, sizeof(ConfigExtendedPageHeader_t));
 291	memset(&cfg, 0, sizeof(CONFIGPARMS));
 292	hdr.PageVersion = MPI_SASIOUNITPAGE0_PAGEVERSION;
 293	hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
 294	hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
 295	cfg.cfghdr.ehdr = &hdr;
 296	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
 297
 298	if ((mpt_config(ioc, &cfg)))
 299		goto out;
 300	if (!hdr.ExtPageLength)
 301		goto out;
 302
 303	buffer = dma_alloc_coherent(&ioc->pcidev->dev, hdr.ExtPageLength * 4,
 304				    &dma_handle, GFP_KERNEL);
 305	if (!buffer)
 306		goto out;
 307
 308	cfg.physAddr = dma_handle;
 309	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
 310
 311	if ((mpt_config(ioc, &cfg)))
 312		goto out_free_consistent;
 313
 314	if (!(buffer->PhyData[0].PortFlags &
 315	    MPI_SAS_IOUNIT0_PORT_FLAGS_DISCOVERY_IN_PROGRESS))
 316		rc = 1;
 317
 318 out_free_consistent:
 319	dma_free_coherent(&ioc->pcidev->dev, hdr.ExtPageLength * 4, buffer,
 320			  dma_handle);
 321 out:
 322	return rc;
 323}
 324
 325
 326/**
 327 *  mpt_remove_dead_ioc_func - kthread context to remove dead ioc
 328 * @arg: input argument, used to derive ioc
 329 *
 330 * Return 0 if controller is removed from pci subsystem.
 331 * Return -1 for other case.
 332 */
 333static int mpt_remove_dead_ioc_func(void *arg)
 334{
 335	MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg;
 336	struct pci_dev *pdev;
 337
 338	if (!ioc)
 339		return -1;
 340
 341	pdev = ioc->pcidev;
 342	if (!pdev)
 343		return -1;
 344
 345	pci_stop_and_remove_bus_device_locked(pdev);
 346	return 0;
 347}
 348
 349
 350
 351/**
 352 *	mpt_fault_reset_work - work performed on workq after ioc fault
 353 *	@work: input argument, used to derive ioc
 354 *
 355**/
 356static void
 357mpt_fault_reset_work(struct work_struct *work)
 358{
 359	MPT_ADAPTER	*ioc =
 360	    container_of(work, MPT_ADAPTER, fault_reset_work.work);
 361	u32		 ioc_raw_state;
 362	int		 rc;
 363	unsigned long	 flags;
 364	MPT_SCSI_HOST	*hd;
 365	struct task_struct *p;
 366
 367	if (ioc->ioc_reset_in_progress || !ioc->active)
 368		goto out;
 369
 370
 371	ioc_raw_state = mpt_GetIocState(ioc, 0);
 372	if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_MASK) {
 373		printk(MYIOC_s_INFO_FMT "%s: IOC is non-operational !!!!\n",
 374		    ioc->name, __func__);
 375
 376		/*
 377		 * Call mptscsih_flush_pending_cmds callback so that we
 378		 * flush all pending commands back to OS.
 379		 * This call is required to aovid deadlock at block layer.
 380		 * Dead IOC will fail to do diag reset,and this call is safe
 381		 * since dead ioc will never return any command back from HW.
 382		 */
 383		hd = shost_priv(ioc->sh);
 384		ioc->schedule_dead_ioc_flush_running_cmds(hd);
 385
 386		/*Remove the Dead Host */
 387		p = kthread_run(mpt_remove_dead_ioc_func, ioc,
 388				"mpt_dead_ioc_%d", ioc->id);
 389		if (IS_ERR(p))	{
 390			printk(MYIOC_s_ERR_FMT
 391				"%s: Running mpt_dead_ioc thread failed !\n",
 392				ioc->name, __func__);
 393		} else {
 394			printk(MYIOC_s_WARN_FMT
 395				"%s: Running mpt_dead_ioc thread success !\n",
 396				ioc->name, __func__);
 397		}
 398		return; /* don't rearm timer */
 399	}
 400
 401	if ((ioc_raw_state & MPI_IOC_STATE_MASK)
 402			== MPI_IOC_STATE_FAULT) {
 403		printk(MYIOC_s_WARN_FMT "IOC is in FAULT state (%04xh)!!!\n",
 404		       ioc->name, ioc_raw_state & MPI_DOORBELL_DATA_MASK);
 405		printk(MYIOC_s_WARN_FMT "Issuing HardReset from %s!!\n",
 406		       ioc->name, __func__);
 407		rc = mpt_HardResetHandler(ioc, CAN_SLEEP);
 408		printk(MYIOC_s_WARN_FMT "%s: HardReset: %s\n", ioc->name,
 409		       __func__, (rc == 0) ? "success" : "failed");
 410		ioc_raw_state = mpt_GetIocState(ioc, 0);
 411		if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT)
 412			printk(MYIOC_s_WARN_FMT "IOC is in FAULT state after "
 413			    "reset (%04xh)\n", ioc->name, ioc_raw_state &
 414			    MPI_DOORBELL_DATA_MASK);
 415	} else if (ioc->bus_type == SAS && ioc->sas_discovery_quiesce_io) {
 416		if ((mpt_is_discovery_complete(ioc))) {
 417			devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "clearing "
 418			    "discovery_quiesce_io flag\n", ioc->name));
 419			ioc->sas_discovery_quiesce_io = 0;
 420		}
 421	}
 422
 423 out:
 424	/*
 425	 * Take turns polling alternate controller
 426	 */
 427	if (ioc->alt_ioc)
 428		ioc = ioc->alt_ioc;
 429
 430	/* rearm the timer */
 431	spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
 432	if (ioc->reset_work_q)
 433		queue_delayed_work(ioc->reset_work_q, &ioc->fault_reset_work,
 434			msecs_to_jiffies(MPT_POLLING_INTERVAL));
 435	spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
 436}
 437
 438
 439/*
 440 *  Process turbo (context) reply...
 441 */
 442static void
 443mpt_turbo_reply(MPT_ADAPTER *ioc, u32 pa)
 444{
 445	MPT_FRAME_HDR *mf = NULL;
 446	MPT_FRAME_HDR *mr = NULL;
 447	u16 req_idx = 0;
 448	u8 cb_idx;
 449
 450	dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got TURBO reply req_idx=%08x\n",
 451				ioc->name, pa));
 452
 453	switch (pa >> MPI_CONTEXT_REPLY_TYPE_SHIFT) {
 454	case MPI_CONTEXT_REPLY_TYPE_SCSI_INIT:
 455		req_idx = pa & 0x0000FFFF;
 456		cb_idx = (pa & 0x00FF0000) >> 16;
 457		mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
 458		break;
 459	case MPI_CONTEXT_REPLY_TYPE_LAN:
 460		cb_idx = mpt_get_cb_idx(MPTLAN_DRIVER);
 461		/*
 462		 *  Blind set of mf to NULL here was fatal
 463		 *  after lan_reply says "freeme"
 464		 *  Fix sort of combined with an optimization here;
 465		 *  added explicit check for case where lan_reply
 466		 *  was just returning 1 and doing nothing else.
 467		 *  For this case skip the callback, but set up
 468		 *  proper mf value first here:-)
 469		 */
 470		if ((pa & 0x58000000) == 0x58000000) {
 471			req_idx = pa & 0x0000FFFF;
 472			mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
 473			mpt_free_msg_frame(ioc, mf);
 474			mb();
 475			return;
 476		}
 477		mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
 478		break;
 479	case MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET:
 480		cb_idx = mpt_get_cb_idx(MPTSTM_DRIVER);
 481		mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
 482		break;
 483	default:
 484		cb_idx = 0;
 485		BUG();
 486	}
 487
 488	/*  Check for (valid) IO callback!  */
 489	if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
 490		MptCallbacks[cb_idx] == NULL) {
 491		printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
 492				__func__, ioc->name, cb_idx);
 493		goto out;
 494	}
 495
 496	if (MptCallbacks[cb_idx](ioc, mf, mr))
 497		mpt_free_msg_frame(ioc, mf);
 498 out:
 499	mb();
 500}
 501
 502static void
 503mpt_reply(MPT_ADAPTER *ioc, u32 pa)
 504{
 505	MPT_FRAME_HDR	*mf;
 506	MPT_FRAME_HDR	*mr;
 507	u16		 req_idx;
 508	u8		 cb_idx;
 509	int		 freeme;
 510
 511	u32 reply_dma_low;
 512	u16 ioc_stat;
 513
 514	/* non-TURBO reply!  Hmmm, something may be up...
 515	 *  Newest turbo reply mechanism; get address
 516	 *  via left shift 1 (get rid of MPI_ADDRESS_REPLY_A_BIT)!
 517	 */
 518
 519	/* Map DMA address of reply header to cpu address.
 520	 * pa is 32 bits - but the dma address may be 32 or 64 bits
 521	 * get offset based only only the low addresses
 522	 */
 523
 524	reply_dma_low = (pa <<= 1);
 525	mr = (MPT_FRAME_HDR *)((u8 *)ioc->reply_frames +
 526			 (reply_dma_low - ioc->reply_frames_low_dma));
 527
 528	req_idx = le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx);
 529	cb_idx = mr->u.frame.hwhdr.msgctxu.fld.cb_idx;
 530	mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
 531
 532	dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got non-TURBO reply=%p req_idx=%x cb_idx=%x Function=%x\n",
 533			ioc->name, mr, req_idx, cb_idx, mr->u.hdr.Function));
 534	DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mr);
 535
 536	 /*  Check/log IOC log info
 537	 */
 538	ioc_stat = le16_to_cpu(mr->u.reply.IOCStatus);
 539	if (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
 540		u32	 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo);
 541		if (ioc->bus_type == FC)
 542			mpt_fc_log_info(ioc, log_info);
 543		else if (ioc->bus_type == SPI)
 544			mpt_spi_log_info(ioc, log_info);
 545		else if (ioc->bus_type == SAS)
 546			mpt_sas_log_info(ioc, log_info, cb_idx);
 547	}
 548
 549	if (ioc_stat & MPI_IOCSTATUS_MASK)
 550		mpt_iocstatus_info(ioc, (u32)ioc_stat, mf);
 551
 552	/*  Check for (valid) IO callback!  */
 553	if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
 554		MptCallbacks[cb_idx] == NULL) {
 555		printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
 556				__func__, ioc->name, cb_idx);
 557		freeme = 0;
 558		goto out;
 559	}
 560
 561	freeme = MptCallbacks[cb_idx](ioc, mf, mr);
 562
 563 out:
 564	/*  Flush (non-TURBO) reply with a WRITE!  */
 565	CHIPREG_WRITE32(&ioc->chip->ReplyFifo, pa);
 566
 567	if (freeme)
 568		mpt_free_msg_frame(ioc, mf);
 569	mb();
 570}
 571
 572/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 573/**
 574 *	mpt_interrupt - MPT adapter (IOC) specific interrupt handler.
 575 *	@irq: irq number (not used)
 576 *	@bus_id: bus identifier cookie == pointer to MPT_ADAPTER structure
 577 *
 578 *	This routine is registered via the request_irq() kernel API call,
 579 *	and handles all interrupts generated from a specific MPT adapter
 580 *	(also referred to as a IO Controller or IOC).
 581 *	This routine must clear the interrupt from the adapter and does
 582 *	so by reading the reply FIFO.  Multiple replies may be processed
 583 *	per single call to this routine.
 584 *
 585 *	This routine handles register-level access of the adapter but
 586 *	dispatches (calls) a protocol-specific callback routine to handle
 587 *	the protocol-specific details of the MPT request completion.
 588 */
 589static irqreturn_t
 590mpt_interrupt(int irq, void *bus_id)
 591{
 592	MPT_ADAPTER *ioc = bus_id;
 593	u32 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
 594
 595	if (pa == 0xFFFFFFFF)
 596		return IRQ_NONE;
 597
 598	/*
 599	 *  Drain the reply FIFO!
 600	 */
 601	do {
 602		if (pa & MPI_ADDRESS_REPLY_A_BIT)
 603			mpt_reply(ioc, pa);
 604		else
 605			mpt_turbo_reply(ioc, pa);
 606		pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
 607	} while (pa != 0xFFFFFFFF);
 608
 609	return IRQ_HANDLED;
 610}
 611
 612/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 613/**
 614 *	mptbase_reply - MPT base driver's callback routine
 615 *	@ioc: Pointer to MPT_ADAPTER structure
 616 *	@req: Pointer to original MPT request frame
 617 *	@reply: Pointer to MPT reply frame (NULL if TurboReply)
 618 *
 619 *	MPT base driver's callback routine; all base driver
 620 *	"internal" request/reply processing is routed here.
 621 *	Currently used for EventNotification and EventAck handling.
 622 *
 623 *	Returns 1 indicating original alloc'd request frame ptr
 624 *	should be freed, or 0 if it shouldn't.
 625 */
 626static int
 627mptbase_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply)
 628{
 629	EventNotificationReply_t *pEventReply;
 630	u8 event;
 631	int evHandlers;
 632	int freereq = 1;
 633
 634	switch (reply->u.hdr.Function) {
 635	case MPI_FUNCTION_EVENT_NOTIFICATION:
 636		pEventReply = (EventNotificationReply_t *)reply;
 637		evHandlers = 0;
 638		ProcessEventNotification(ioc, pEventReply, &evHandlers);
 639		event = le32_to_cpu(pEventReply->Event) & 0xFF;
 640		if (pEventReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)
 641			freereq = 0;
 642		if (event != MPI_EVENT_EVENT_CHANGE)
 643			break;
 644		fallthrough;
 645	case MPI_FUNCTION_CONFIG:
 646	case MPI_FUNCTION_SAS_IO_UNIT_CONTROL:
 647		ioc->mptbase_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
 648		ioc->mptbase_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
 649		memcpy(ioc->mptbase_cmds.reply, reply,
 650		    min(MPT_DEFAULT_FRAME_SIZE,
 651			4 * reply->u.reply.MsgLength));
 652		if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_PENDING) {
 653			ioc->mptbase_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
 654			complete(&ioc->mptbase_cmds.done);
 655		} else
 656			freereq = 0;
 657		if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_FREE_MF)
 658			freereq = 1;
 659		break;
 660	case MPI_FUNCTION_EVENT_ACK:
 661		devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 662		    "EventAck reply received\n", ioc->name));
 663		break;
 664	default:
 665		printk(MYIOC_s_ERR_FMT
 666		    "Unexpected msg function (=%02Xh) reply received!\n",
 667		    ioc->name, reply->u.hdr.Function);
 668		break;
 669	}
 670
 671	/*
 672	 *	Conditionally tell caller to free the original
 673	 *	EventNotification/EventAck/unexpected request frame!
 674	 */
 675	return freereq;
 676}
 677
 678/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 679/**
 680 *	mpt_register - Register protocol-specific main callback handler.
 681 *	@cbfunc: callback function pointer
 682 *	@dclass: Protocol driver's class (%MPT_DRIVER_CLASS enum value)
 683 *	@func_name: call function's name
 684 *
 685 *	This routine is called by a protocol-specific driver (SCSI host,
 686 *	LAN, SCSI target) to register its reply callback routine.  Each
 687 *	protocol-specific driver must do this before it will be able to
 688 *	use any IOC resources, such as obtaining request frames.
 689 *
 690 *	NOTES: The SCSI protocol driver currently calls this routine thrice
 691 *	in order to register separate callbacks; one for "normal" SCSI IO;
 692 *	one for MptScsiTaskMgmt requests; one for Scan/DV requests.
 693 *
 694 *	Returns u8 valued "handle" in the range (and S.O.D. order)
 695 *	{N,...,7,6,5,...,1} if successful.
 696 *	A return value of MPT_MAX_PROTOCOL_DRIVERS (including zero!) should be
 697 *	considered an error by the caller.
 698 */
 699u8
 700mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass, char *func_name)
 701{
 702	u8 cb_idx;
 703	last_drv_idx = MPT_MAX_PROTOCOL_DRIVERS;
 704
 705	/*
 706	 *  Search for empty callback slot in this order: {N,...,7,6,5,...,1}
 707	 *  (slot/handle 0 is reserved!)
 708	 */
 709	for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
 710		if (MptCallbacks[cb_idx] == NULL) {
 711			MptCallbacks[cb_idx] = cbfunc;
 712			MptDriverClass[cb_idx] = dclass;
 713			MptEvHandlers[cb_idx] = NULL;
 714			last_drv_idx = cb_idx;
 715			strscpy(MptCallbacksName[cb_idx], func_name,
 716				MPT_MAX_CALLBACKNAME_LEN+1);
 717			break;
 718		}
 719	}
 720
 721	return last_drv_idx;
 722}
 723
 724/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 725/**
 726 *	mpt_deregister - Deregister a protocol drivers resources.
 727 *	@cb_idx: previously registered callback handle
 728 *
 729 *	Each protocol-specific driver should call this routine when its
 730 *	module is unloaded.
 731 */
 732void
 733mpt_deregister(u8 cb_idx)
 734{
 735	if (cb_idx && (cb_idx < MPT_MAX_PROTOCOL_DRIVERS)) {
 736		MptCallbacks[cb_idx] = NULL;
 737		MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
 738		MptEvHandlers[cb_idx] = NULL;
 739
 740		last_drv_idx++;
 741	}
 742}
 743
 744/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 745/**
 746 *	mpt_event_register - Register protocol-specific event callback handler.
 747 *	@cb_idx: previously registered (via mpt_register) callback handle
 748 *	@ev_cbfunc: callback function
 749 *
 750 *	This routine can be called by one or more protocol-specific drivers
 751 *	if/when they choose to be notified of MPT events.
 752 *
 753 *	Returns 0 for success.
 754 */
 755int
 756mpt_event_register(u8 cb_idx, MPT_EVHANDLER ev_cbfunc)
 757{
 758	if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
 759		return -1;
 760
 761	MptEvHandlers[cb_idx] = ev_cbfunc;
 762	return 0;
 763}
 764
 765/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 766/**
 767 *	mpt_event_deregister - Deregister protocol-specific event callback handler
 768 *	@cb_idx: previously registered callback handle
 769 *
 770 *	Each protocol-specific driver should call this routine
 771 *	when it does not (or can no longer) handle events,
 772 *	or when its module is unloaded.
 773 */
 774void
 775mpt_event_deregister(u8 cb_idx)
 776{
 777	if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
 778		return;
 779
 780	MptEvHandlers[cb_idx] = NULL;
 781}
 782
 783/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 784/**
 785 *	mpt_reset_register - Register protocol-specific IOC reset handler.
 786 *	@cb_idx: previously registered (via mpt_register) callback handle
 787 *	@reset_func: reset function
 788 *
 789 *	This routine can be called by one or more protocol-specific drivers
 790 *	if/when they choose to be notified of IOC resets.
 791 *
 792 *	Returns 0 for success.
 793 */
 794int
 795mpt_reset_register(u8 cb_idx, MPT_RESETHANDLER reset_func)
 796{
 797	if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
 798		return -1;
 799
 800	MptResetHandlers[cb_idx] = reset_func;
 801	return 0;
 802}
 803
 804/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 805/**
 806 *	mpt_reset_deregister - Deregister protocol-specific IOC reset handler.
 807 *	@cb_idx: previously registered callback handle
 808 *
 809 *	Each protocol-specific driver should call this routine
 810 *	when it does not (or can no longer) handle IOC reset handling,
 811 *	or when its module is unloaded.
 812 */
 813void
 814mpt_reset_deregister(u8 cb_idx)
 815{
 816	if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
 817		return;
 818
 819	MptResetHandlers[cb_idx] = NULL;
 820}
 821
 822/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 823/**
 824 *	mpt_device_driver_register - Register device driver hooks
 825 *	@dd_cbfunc: driver callbacks struct
 826 *	@cb_idx: MPT protocol driver index
 827 */
 828int
 829mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, u8 cb_idx)
 830{
 831	MPT_ADAPTER	*ioc;
 832
 833	if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
 834		return -EINVAL;
 835
 836	MptDeviceDriverHandlers[cb_idx] = dd_cbfunc;
 837
 838	/* call per pci device probe entry point */
 839	list_for_each_entry(ioc, &ioc_list, list) {
 840		if (dd_cbfunc->probe)
 841			dd_cbfunc->probe(ioc->pcidev);
 842	 }
 843
 844	return 0;
 845}
 846
 847/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 848/**
 849 *	mpt_device_driver_deregister - DeRegister device driver hooks
 850 *	@cb_idx: MPT protocol driver index
 851 */
 852void
 853mpt_device_driver_deregister(u8 cb_idx)
 854{
 855	struct mpt_pci_driver *dd_cbfunc;
 856	MPT_ADAPTER	*ioc;
 857
 858	if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
 859		return;
 860
 861	dd_cbfunc = MptDeviceDriverHandlers[cb_idx];
 862
 863	list_for_each_entry(ioc, &ioc_list, list) {
 864		if (dd_cbfunc->remove)
 865			dd_cbfunc->remove(ioc->pcidev);
 866	}
 867
 868	MptDeviceDriverHandlers[cb_idx] = NULL;
 869}
 870
 871
 872/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 873/**
 874 *	mpt_get_msg_frame - Obtain an MPT request frame from the pool
 875 *	@cb_idx: Handle of registered MPT protocol driver
 876 *	@ioc: Pointer to MPT adapter structure
 877 *
 878 *	Obtain an MPT request frame from the pool (of 1024) that are
 879 *	allocated per MPT adapter.
 880 *
 881 *	Returns pointer to a MPT request frame or %NULL if none are available
 882 *	or IOC is not active.
 883 */
 884MPT_FRAME_HDR*
 885mpt_get_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc)
 886{
 887	MPT_FRAME_HDR *mf;
 888	unsigned long flags;
 889	u16	 req_idx;	/* Request index */
 890
 891	/* validate handle and ioc identifier */
 892
 893#ifdef MFCNT
 894	if (!ioc->active)
 895		printk(MYIOC_s_WARN_FMT "IOC Not Active! mpt_get_msg_frame "
 896		    "returning NULL!\n", ioc->name);
 897#endif
 898
 899	/* If interrupts are not attached, do not return a request frame */
 900	if (!ioc->active)
 901		return NULL;
 902
 903	spin_lock_irqsave(&ioc->FreeQlock, flags);
 904	if (!list_empty(&ioc->FreeQ)) {
 905		int req_offset;
 906
 907		mf = list_entry(ioc->FreeQ.next, MPT_FRAME_HDR,
 908				u.frame.linkage.list);
 909		list_del(&mf->u.frame.linkage.list);
 910		mf->u.frame.linkage.arg1 = 0;
 911		mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx;	/* byte */
 912		req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
 913								/* u16! */
 914		req_idx = req_offset / ioc->req_sz;
 915		mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
 916		mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
 917		/* Default, will be changed if necessary in SG generation */
 918		ioc->RequestNB[req_idx] = ioc->NB_for_64_byte_frame;
 919#ifdef MFCNT
 920		ioc->mfcnt++;
 921#endif
 922	}
 923	else
 924		mf = NULL;
 925	spin_unlock_irqrestore(&ioc->FreeQlock, flags);
 926
 927#ifdef MFCNT
 928	if (mf == NULL)
 929		printk(MYIOC_s_WARN_FMT "IOC Active. No free Msg Frames! "
 930		    "Count 0x%x Max 0x%x\n", ioc->name, ioc->mfcnt,
 931		    ioc->req_depth);
 932	mfcounter++;
 933	if (mfcounter == PRINT_MF_COUNT)
 934		printk(MYIOC_s_INFO_FMT "MF Count 0x%x Max 0x%x \n", ioc->name,
 935		    ioc->mfcnt, ioc->req_depth);
 936#endif
 937
 938	dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_get_msg_frame(%d,%d), got mf=%p\n",
 939	    ioc->name, cb_idx, ioc->id, mf));
 940	return mf;
 941}
 942
 943/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 944/**
 945 *	mpt_put_msg_frame - Send a protocol-specific MPT request frame to an IOC
 946 *	@cb_idx: Handle of registered MPT protocol driver
 947 *	@ioc: Pointer to MPT adapter structure
 948 *	@mf: Pointer to MPT request frame
 949 *
 950 *	This routine posts an MPT request frame to the request post FIFO of a
 951 *	specific MPT adapter.
 952 */
 953void
 954mpt_put_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
 955{
 956	u32 mf_dma_addr;
 957	int req_offset;
 958	u16 req_idx;	/* Request index */
 959
 960	/* ensure values are reset properly! */
 961	mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx;		/* byte */
 962	req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
 963								/* u16! */
 964	req_idx = req_offset / ioc->req_sz;
 965	mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
 966	mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
 967
 968	DBG_DUMP_PUT_MSG_FRAME(ioc, (u32 *)mf);
 969
 970	mf_dma_addr = (ioc->req_frames_low_dma + req_offset) | ioc->RequestNB[req_idx];
 971	dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mf_dma_addr=%x req_idx=%d "
 972	    "RequestNB=%x\n", ioc->name, mf_dma_addr, req_idx,
 973	    ioc->RequestNB[req_idx]));
 974	CHIPREG_WRITE32(&ioc->chip->RequestFifo, mf_dma_addr);
 975}
 976
 977/**
 978 *	mpt_put_msg_frame_hi_pri - Send a hi-pri protocol-specific MPT request frame
 979 *	@cb_idx: Handle of registered MPT protocol driver
 980 *	@ioc: Pointer to MPT adapter structure
 981 *	@mf: Pointer to MPT request frame
 982 *
 983 *	Send a protocol-specific MPT request frame to an IOC using
 984 *	hi-priority request queue.
 985 *
 986 *	This routine posts an MPT request frame to the request post FIFO of a
 987 *	specific MPT adapter.
 988 **/
 989void
 990mpt_put_msg_frame_hi_pri(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
 991{
 992	u32 mf_dma_addr;
 993	int req_offset;
 994	u16 req_idx;	/* Request index */
 995
 996	/* ensure values are reset properly! */
 997	mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx;
 998	req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
 999	req_idx = req_offset / ioc->req_sz;
1000	mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
1001	mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
1002
1003	DBG_DUMP_PUT_MSG_FRAME(ioc, (u32 *)mf);
1004
1005	mf_dma_addr = (ioc->req_frames_low_dma + req_offset);
1006	dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mf_dma_addr=%x req_idx=%d\n",
1007		ioc->name, mf_dma_addr, req_idx));
1008	CHIPREG_WRITE32(&ioc->chip->RequestHiPriFifo, mf_dma_addr);
1009}
1010
1011/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1012/**
1013 *	mpt_free_msg_frame - Place MPT request frame back on FreeQ.
1014 *	@ioc: Pointer to MPT adapter structure
1015 *	@mf: Pointer to MPT request frame
1016 *
1017 *	This routine places a MPT request frame back on the MPT adapter's
1018 *	FreeQ.
1019 */
1020void
1021mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
1022{
1023	unsigned long flags;
1024
1025	/*  Put Request back on FreeQ!  */
1026	spin_lock_irqsave(&ioc->FreeQlock, flags);
1027	if (cpu_to_le32(mf->u.frame.linkage.arg1) == 0xdeadbeaf)
1028		goto out;
1029	/* signature to know if this mf is freed */
1030	mf->u.frame.linkage.arg1 = cpu_to_le32(0xdeadbeaf);
1031	list_add(&mf->u.frame.linkage.list, &ioc->FreeQ);
1032#ifdef MFCNT
1033	ioc->mfcnt--;
1034#endif
1035 out:
1036	spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1037}
1038
1039/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1040/**
1041 *	mpt_add_sge - Place a simple 32 bit SGE at address pAddr.
1042 *	@pAddr: virtual address for SGE
1043 *	@flagslength: SGE flags and data transfer length
1044 *	@dma_addr: Physical address
1045 *
1046 *	This routine places a MPT request frame back on the MPT adapter's
1047 *	FreeQ.
1048 */
1049static void
1050mpt_add_sge(void *pAddr, u32 flagslength, dma_addr_t dma_addr)
1051{
1052	SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
1053	pSge->FlagsLength = cpu_to_le32(flagslength);
1054	pSge->Address = cpu_to_le32(dma_addr);
1055}
1056
1057/**
1058 *	mpt_add_sge_64bit - Place a simple 64 bit SGE at address pAddr.
1059 *	@pAddr: virtual address for SGE
1060 *	@flagslength: SGE flags and data transfer length
1061 *	@dma_addr: Physical address
1062 *
1063 *	This routine places a MPT request frame back on the MPT adapter's
1064 *	FreeQ.
1065 **/
1066static void
1067mpt_add_sge_64bit(void *pAddr, u32 flagslength, dma_addr_t dma_addr)
1068{
1069	SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
1070	pSge->Address.Low = cpu_to_le32
1071			(lower_32_bits(dma_addr));
1072	pSge->Address.High = cpu_to_le32
1073			(upper_32_bits(dma_addr));
1074	pSge->FlagsLength = cpu_to_le32
1075			((flagslength | MPT_SGE_FLAGS_64_BIT_ADDRESSING));
1076}
1077
1078/**
1079 *	mpt_add_sge_64bit_1078 - Place a simple 64 bit SGE at address pAddr (1078 workaround).
1080 *	@pAddr: virtual address for SGE
1081 *	@flagslength: SGE flags and data transfer length
1082 *	@dma_addr: Physical address
1083 *
1084 *	This routine places a MPT request frame back on the MPT adapter's
1085 *	FreeQ.
1086 **/
1087static void
1088mpt_add_sge_64bit_1078(void *pAddr, u32 flagslength, dma_addr_t dma_addr)
1089{
1090	SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
1091	u32 tmp;
1092
1093	pSge->Address.Low = cpu_to_le32
1094			(lower_32_bits(dma_addr));
1095	tmp = (u32)(upper_32_bits(dma_addr));
1096
1097	/*
1098	 * 1078 errata workaround for the 36GB limitation
1099	 */
1100	if ((((u64)dma_addr + MPI_SGE_LENGTH(flagslength)) >> 32)  == 9) {
1101		flagslength |=
1102		    MPI_SGE_SET_FLAGS(MPI_SGE_FLAGS_LOCAL_ADDRESS);
1103		tmp |= (1<<31);
1104		if (mpt_debug_level & MPT_DEBUG_36GB_MEM)
1105			printk(KERN_DEBUG "1078 P0M2 addressing for "
1106			    "addr = 0x%llx len = %d\n",
1107			    (unsigned long long)dma_addr,
1108			    MPI_SGE_LENGTH(flagslength));
1109	}
1110
1111	pSge->Address.High = cpu_to_le32(tmp);
1112	pSge->FlagsLength = cpu_to_le32(
1113		(flagslength | MPT_SGE_FLAGS_64_BIT_ADDRESSING));
1114}
1115
1116/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1117/**
1118 *	mpt_add_chain - Place a 32 bit chain SGE at address pAddr.
1119 *	@pAddr: virtual address for SGE
1120 *	@next: nextChainOffset value (u32's)
1121 *	@length: length of next SGL segment
1122 *	@dma_addr: Physical address
1123 *
1124 */
1125static void
1126mpt_add_chain(void *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
1127{
1128	SGEChain32_t *pChain = (SGEChain32_t *) pAddr;
1129
1130	pChain->Length = cpu_to_le16(length);
1131	pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT;
1132	pChain->NextChainOffset = next;
1133	pChain->Address = cpu_to_le32(dma_addr);
1134}
1135
1136/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1137/**
1138 *	mpt_add_chain_64bit - Place a 64 bit chain SGE at address pAddr.
1139 *	@pAddr: virtual address for SGE
1140 *	@next: nextChainOffset value (u32's)
1141 *	@length: length of next SGL segment
1142 *	@dma_addr: Physical address
1143 *
1144 */
1145static void
1146mpt_add_chain_64bit(void *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
1147{
1148	SGEChain64_t *pChain = (SGEChain64_t *) pAddr;
1149	u32 tmp = dma_addr & 0xFFFFFFFF;
1150
1151	pChain->Length = cpu_to_le16(length);
1152	pChain->Flags = (MPI_SGE_FLAGS_CHAIN_ELEMENT |
1153			 MPI_SGE_FLAGS_64_BIT_ADDRESSING);
1154
1155	pChain->NextChainOffset = next;
1156
1157	pChain->Address.Low = cpu_to_le32(tmp);
1158	tmp = (u32)(upper_32_bits(dma_addr));
1159	pChain->Address.High = cpu_to_le32(tmp);
1160}
1161
1162/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1163/**
1164 *	mpt_send_handshake_request - Send MPT request via doorbell handshake method.
1165 *	@cb_idx: Handle of registered MPT protocol driver
1166 *	@ioc: Pointer to MPT adapter structure
1167 *	@reqBytes: Size of the request in bytes
1168 *	@req: Pointer to MPT request frame
1169 *	@sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1170 *
1171 *	This routine is used exclusively to send MptScsiTaskMgmt
1172 *	requests since they are required to be sent via doorbell handshake.
1173 *
1174 *	NOTE: It is the callers responsibility to byte-swap fields in the
1175 *	request which are greater than 1 byte in size.
1176 *
1177 *	Returns 0 for success, non-zero for failure.
1178 */
1179int
1180mpt_send_handshake_request(u8 cb_idx, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag)
1181{
1182	int	r = 0;
1183	u8	*req_as_bytes;
1184	int	 ii;
1185
1186	/* State is known to be good upon entering
1187	 * this function so issue the bus reset
1188	 * request.
1189	 */
1190
1191	/*
1192	 * Emulate what mpt_put_msg_frame() does /wrt to sanity
1193	 * setting cb_idx/req_idx.  But ONLY if this request
1194	 * is in proper (pre-alloc'd) request buffer range...
1195	 */
1196	ii = MFPTR_2_MPT_INDEX(ioc,(MPT_FRAME_HDR*)req);
1197	if (reqBytes >= 12 && ii >= 0 && ii < ioc->req_depth) {
1198		MPT_FRAME_HDR *mf = (MPT_FRAME_HDR*)req;
1199		mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(ii);
1200		mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx;
1201	}
1202
1203	/* Make sure there are no doorbells */
1204	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1205
1206	CHIPREG_WRITE32(&ioc->chip->Doorbell,
1207			((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
1208			 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
1209
1210	/* Wait for IOC doorbell int */
1211	if ((ii = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) {
1212		return ii;
1213	}
1214
1215	/* Read doorbell and check for active bit */
1216	if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
1217		return -5;
1218
1219	dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_send_handshake_request start, WaitCnt=%d\n",
1220		ioc->name, ii));
1221
1222	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1223
1224	if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1225		return -2;
1226	}
1227
1228	/* Send request via doorbell handshake */
1229	req_as_bytes = (u8 *) req;
1230	for (ii = 0; ii < reqBytes/4; ii++) {
1231		u32 word;
1232
1233		word = ((req_as_bytes[(ii*4) + 0] <<  0) |
1234			(req_as_bytes[(ii*4) + 1] <<  8) |
1235			(req_as_bytes[(ii*4) + 2] << 16) |
1236			(req_as_bytes[(ii*4) + 3] << 24));
1237		CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
1238		if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1239			r = -3;
1240			break;
1241		}
1242	}
1243
1244	if (r >= 0 && WaitForDoorbellInt(ioc, 10, sleepFlag) >= 0)
1245		r = 0;
1246	else
1247		r = -4;
1248
1249	/* Make sure there are no doorbells */
1250	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1251
1252	return r;
1253}
1254
1255/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1256/**
1257 * mpt_host_page_access_control - control the IOC's Host Page Buffer access
1258 * @ioc: Pointer to MPT adapter structure
1259 * @access_control_value: define bits below
1260 * @sleepFlag: Specifies whether the process can sleep
1261 *
1262 * Provides mechanism for the host driver to control the IOC's
1263 * Host Page Buffer access.
1264 *
1265 * Access Control Value - bits[15:12]
1266 * 0h Reserved
1267 * 1h Enable Access { MPI_DB_HPBAC_ENABLE_ACCESS }
1268 * 2h Disable Access { MPI_DB_HPBAC_DISABLE_ACCESS }
1269 * 3h Free Buffer { MPI_DB_HPBAC_FREE_BUFFER }
1270 *
1271 * Returns 0 for success, non-zero for failure.
1272 */
1273
1274static int
1275mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag)
1276{
1277	/* return if in use */
1278	if (CHIPREG_READ32(&ioc->chip->Doorbell)
1279	    & MPI_DOORBELL_ACTIVE)
1280	    return -1;
1281
1282	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1283
1284	CHIPREG_WRITE32(&ioc->chip->Doorbell,
1285		((MPI_FUNCTION_HOST_PAGEBUF_ACCESS_CONTROL
1286		 <<MPI_DOORBELL_FUNCTION_SHIFT) |
1287		 (access_control_value<<12)));
1288
1289	/* Wait for IOC to clear Doorbell Status bit */
1290	if (WaitForDoorbellAck(ioc, 5, sleepFlag) < 0)
1291		return -2;
1292	else
1293		return 0;
1294}
1295
1296/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1297/**
1298 *	mpt_host_page_alloc - allocate system memory for the fw
1299 *	@ioc: Pointer to pointer to IOC adapter
1300 *	@ioc_init: Pointer to ioc init config page
1301 *
1302 *	If we already allocated memory in past, then resend the same pointer.
1303 *	Returns 0 for success, non-zero for failure.
1304 */
1305static int
1306mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init)
1307{
1308	char	*psge;
1309	int	flags_length;
1310	u32	host_page_buffer_sz=0;
1311
1312	if(!ioc->HostPageBuffer) {
1313
1314		host_page_buffer_sz =
1315		    le32_to_cpu(ioc->facts.HostPageBufferSGE.FlagsLength) & 0xFFFFFF;
1316
1317		if(!host_page_buffer_sz)
1318			return 0; /* fw doesn't need any host buffers */
1319
1320		/* spin till we get enough memory */
1321		while (host_page_buffer_sz > 0) {
1322			ioc->HostPageBuffer =
1323				dma_alloc_coherent(&ioc->pcidev->dev,
1324						host_page_buffer_sz,
1325						&ioc->HostPageBuffer_dma,
1326						GFP_KERNEL);
1327			if (ioc->HostPageBuffer) {
1328				dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1329				    "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n",
1330				    ioc->name, ioc->HostPageBuffer,
1331				    (u32)ioc->HostPageBuffer_dma,
1332				    host_page_buffer_sz));
1333				ioc->alloc_total += host_page_buffer_sz;
1334				ioc->HostPageBuffer_sz = host_page_buffer_sz;
1335				break;
1336			}
1337
1338			host_page_buffer_sz -= (4*1024);
1339		}
1340	}
1341
1342	if(!ioc->HostPageBuffer) {
1343		printk(MYIOC_s_ERR_FMT
1344		    "Failed to alloc memory for host_page_buffer!\n",
1345		    ioc->name);
1346		return -999;
1347	}
1348
1349	psge = (char *)&ioc_init->HostPageBufferSGE;
1350	flags_length = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
1351	    MPI_SGE_FLAGS_SYSTEM_ADDRESS |
1352	    MPI_SGE_FLAGS_HOST_TO_IOC |
1353	    MPI_SGE_FLAGS_END_OF_BUFFER;
1354	flags_length = flags_length << MPI_SGE_FLAGS_SHIFT;
1355	flags_length |= ioc->HostPageBuffer_sz;
1356	ioc->add_sge(psge, flags_length, ioc->HostPageBuffer_dma);
1357	ioc->facts.HostPageBufferSGE = ioc_init->HostPageBufferSGE;
1358
1359	return 0;
1360}
1361
1362/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1363/**
1364 *	mpt_verify_adapter - Given IOC identifier, set pointer to its adapter structure.
1365 *	@iocid: IOC unique identifier (integer)
1366 *	@iocpp: Pointer to pointer to IOC adapter
1367 *
1368 *	Given a unique IOC identifier, set pointer to the associated MPT
1369 *	adapter structure.
1370 *
1371 *	Returns iocid and sets iocpp if iocid is found.
1372 *	Returns -1 if iocid is not found.
1373 */
1374int
1375mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
1376{
1377	MPT_ADAPTER *ioc;
1378
1379	list_for_each_entry(ioc,&ioc_list,list) {
1380		if (ioc->id == iocid) {
1381			*iocpp =ioc;
1382			return iocid;
1383		}
1384	}
1385
1386	*iocpp = NULL;
1387	return -1;
1388}
1389
1390/**
1391 *	mpt_get_product_name - returns product string
1392 *	@vendor: pci vendor id
1393 *	@device: pci device id
1394 *	@revision: pci revision id
1395 *
1396 *	Returns product string displayed when driver loads,
1397 *	in /proc/mpt/summary and /sysfs/class/scsi_host/host<X>/version_product
1398 *
1399 **/
1400static const char*
1401mpt_get_product_name(u16 vendor, u16 device, u8 revision)
1402{
1403	char *product_str = NULL;
1404
1405	if (vendor == PCI_VENDOR_ID_BROCADE) {
1406		switch (device)
1407		{
1408		case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1409			switch (revision)
1410			{
1411			case 0x00:
1412				product_str = "BRE040 A0";
1413				break;
1414			case 0x01:
1415				product_str = "BRE040 A1";
1416				break;
1417			default:
1418				product_str = "BRE040";
1419				break;
1420			}
1421			break;
1422		}
1423		goto out;
1424	}
1425
1426	switch (device)
1427	{
1428	case MPI_MANUFACTPAGE_DEVICEID_FC909:
1429		product_str = "LSIFC909 B1";
1430		break;
1431	case MPI_MANUFACTPAGE_DEVICEID_FC919:
1432		product_str = "LSIFC919 B0";
1433		break;
1434	case MPI_MANUFACTPAGE_DEVICEID_FC929:
1435		product_str = "LSIFC929 B0";
1436		break;
1437	case MPI_MANUFACTPAGE_DEVICEID_FC919X:
1438		if (revision < 0x80)
1439			product_str = "LSIFC919X A0";
1440		else
1441			product_str = "LSIFC919XL A1";
1442		break;
1443	case MPI_MANUFACTPAGE_DEVICEID_FC929X:
1444		if (revision < 0x80)
1445			product_str = "LSIFC929X A0";
1446		else
1447			product_str = "LSIFC929XL A1";
1448		break;
1449	case MPI_MANUFACTPAGE_DEVICEID_FC939X:
1450		product_str = "LSIFC939X A1";
1451		break;
1452	case MPI_MANUFACTPAGE_DEVICEID_FC949X:
1453		product_str = "LSIFC949X A1";
1454		break;
1455	case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1456		switch (revision)
1457		{
1458		case 0x00:
1459			product_str = "LSIFC949E A0";
1460			break;
1461		case 0x01:
1462			product_str = "LSIFC949E A1";
1463			break;
1464		default:
1465			product_str = "LSIFC949E";
1466			break;
1467		}
1468		break;
1469	case MPI_MANUFACTPAGE_DEVID_53C1030:
1470		switch (revision)
1471		{
1472		case 0x00:
1473			product_str = "LSI53C1030 A0";
1474			break;
1475		case 0x01:
1476			product_str = "LSI53C1030 B0";
1477			break;
1478		case 0x03:
1479			product_str = "LSI53C1030 B1";
1480			break;
1481		case 0x07:
1482			product_str = "LSI53C1030 B2";
1483			break;
1484		case 0x08:
1485			product_str = "LSI53C1030 C0";
1486			break;
1487		case 0x80:
1488			product_str = "LSI53C1030T A0";
1489			break;
1490		case 0x83:
1491			product_str = "LSI53C1030T A2";
1492			break;
1493		case 0x87:
1494			product_str = "LSI53C1030T A3";
1495			break;
1496		case 0xc1:
1497			product_str = "LSI53C1020A A1";
1498			break;
1499		default:
1500			product_str = "LSI53C1030";
1501			break;
1502		}
1503		break;
1504	case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
1505		switch (revision)
1506		{
1507		case 0x03:
1508			product_str = "LSI53C1035 A2";
1509			break;
1510		case 0x04:
1511			product_str = "LSI53C1035 B0";
1512			break;
1513		default:
1514			product_str = "LSI53C1035";
1515			break;
1516		}
1517		break;
1518	case MPI_MANUFACTPAGE_DEVID_SAS1064:
1519		switch (revision)
1520		{
1521		case 0x00:
1522			product_str = "LSISAS1064 A1";
1523			break;
1524		case 0x01:
1525			product_str = "LSISAS1064 A2";
1526			break;
1527		case 0x02:
1528			product_str = "LSISAS1064 A3";
1529			break;
1530		case 0x03:
1531			product_str = "LSISAS1064 A4";
1532			break;
1533		default:
1534			product_str = "LSISAS1064";
1535			break;
1536		}
1537		break;
1538	case MPI_MANUFACTPAGE_DEVID_SAS1064E:
1539		switch (revision)
1540		{
1541		case 0x00:
1542			product_str = "LSISAS1064E A0";
1543			break;
1544		case 0x01:
1545			product_str = "LSISAS1064E B0";
1546			break;
1547		case 0x02:
1548			product_str = "LSISAS1064E B1";
1549			break;
1550		case 0x04:
1551			product_str = "LSISAS1064E B2";
1552			break;
1553		case 0x08:
1554			product_str = "LSISAS1064E B3";
1555			break;
1556		default:
1557			product_str = "LSISAS1064E";
1558			break;
1559		}
1560		break;
1561	case MPI_MANUFACTPAGE_DEVID_SAS1068:
1562		switch (revision)
1563		{
1564		case 0x00:
1565			product_str = "LSISAS1068 A0";
1566			break;
1567		case 0x01:
1568			product_str = "LSISAS1068 B0";
1569			break;
1570		case 0x02:
1571			product_str = "LSISAS1068 B1";
1572			break;
1573		default:
1574			product_str = "LSISAS1068";
1575			break;
1576		}
1577		break;
1578	case MPI_MANUFACTPAGE_DEVID_SAS1068E:
1579		switch (revision)
1580		{
1581		case 0x00:
1582			product_str = "LSISAS1068E A0";
1583			break;
1584		case 0x01:
1585			product_str = "LSISAS1068E B0";
1586			break;
1587		case 0x02:
1588			product_str = "LSISAS1068E B1";
1589			break;
1590		case 0x04:
1591			product_str = "LSISAS1068E B2";
1592			break;
1593		case 0x08:
1594			product_str = "LSISAS1068E B3";
1595			break;
1596		default:
1597			product_str = "LSISAS1068E";
1598			break;
1599		}
1600		break;
1601	case MPI_MANUFACTPAGE_DEVID_SAS1078:
1602		switch (revision)
1603		{
1604		case 0x00:
1605			product_str = "LSISAS1078 A0";
1606			break;
1607		case 0x01:
1608			product_str = "LSISAS1078 B0";
1609			break;
1610		case 0x02:
1611			product_str = "LSISAS1078 C0";
1612			break;
1613		case 0x03:
1614			product_str = "LSISAS1078 C1";
1615			break;
1616		case 0x04:
1617			product_str = "LSISAS1078 C2";
1618			break;
1619		default:
1620			product_str = "LSISAS1078";
1621			break;
1622		}
1623		break;
1624	}
1625
1626 out:
1627	return product_str;
1628}
1629
1630/**
1631 *	mpt_mapresources - map in memory mapped io
1632 *	@ioc: Pointer to pointer to IOC adapter
1633 *
1634 **/
1635static int
1636mpt_mapresources(MPT_ADAPTER *ioc)
1637{
1638	u8		__iomem *mem;
1639	int		 ii;
1640	resource_size_t	 mem_phys;
1641	unsigned long	 port;
1642	u32		 msize;
1643	u32		 psize;
1644	int		 r = -ENODEV;
1645	struct pci_dev *pdev;
1646
1647	pdev = ioc->pcidev;
1648	ioc->bars = pci_select_bars(pdev, IORESOURCE_MEM);
1649	if (pci_enable_device_mem(pdev)) {
1650		printk(MYIOC_s_ERR_FMT "pci_enable_device_mem() "
1651		    "failed\n", ioc->name);
1652		return r;
1653	}
1654	if (pci_request_selected_regions(pdev, ioc->bars, "mpt")) {
1655		printk(MYIOC_s_ERR_FMT "pci_request_selected_regions() with "
1656		    "MEM failed\n", ioc->name);
1657		goto out_pci_disable_device;
1658	}
1659
1660	if (sizeof(dma_addr_t) > 4) {
1661		const uint64_t required_mask = dma_get_required_mask
1662		    (&pdev->dev);
1663		if (required_mask > DMA_BIT_MASK(32)
1664			&& !dma_set_mask(&pdev->dev, DMA_BIT_MASK(64))
1665			&& !dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64))) {
1666			ioc->dma_mask = DMA_BIT_MASK(64);
1667			dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1668				": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1669				ioc->name));
1670		} else if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(32))
1671			   && !dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32))) {
1672			ioc->dma_mask = DMA_BIT_MASK(32);
1673			dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1674				": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1675				ioc->name));
1676		} else {
1677			printk(MYIOC_s_WARN_FMT "no suitable DMA mask for %s\n",
1678			    ioc->name, pci_name(pdev));
1679			goto out_pci_release_region;
1680		}
1681	} else {
1682		if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(32))
1683			&& !dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32))) {
1684			ioc->dma_mask = DMA_BIT_MASK(32);
1685			dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1686				": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1687				ioc->name));
1688		} else {
1689			printk(MYIOC_s_WARN_FMT "no suitable DMA mask for %s\n",
1690			    ioc->name, pci_name(pdev));
1691			goto out_pci_release_region;
1692		}
1693	}
1694
1695	mem_phys = msize = 0;
1696	port = psize = 0;
1697	for (ii = 0; ii < DEVICE_COUNT_RESOURCE; ii++) {
1698		if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) {
1699			if (psize)
1700				continue;
1701			/* Get I/O space! */
1702			port = pci_resource_start(pdev, ii);
1703			psize = pci_resource_len(pdev, ii);
1704		} else {
1705			if (msize)
1706				continue;
1707			/* Get memmap */
1708			mem_phys = pci_resource_start(pdev, ii);
1709			msize = pci_resource_len(pdev, ii);
1710		}
1711	}
1712	ioc->mem_size = msize;
1713
1714	mem = NULL;
1715	/* Get logical ptr for PciMem0 space */
1716	/*mem = ioremap(mem_phys, msize);*/
1717	mem = ioremap(mem_phys, msize);
1718	if (mem == NULL) {
1719		printk(MYIOC_s_ERR_FMT ": ERROR - Unable to map adapter"
1720			" memory!\n", ioc->name);
1721		r = -EINVAL;
1722		goto out_pci_release_region;
1723	}
1724	ioc->memmap = mem;
1725	dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "mem = %p, mem_phys = %llx\n",
1726	    ioc->name, mem, (unsigned long long)mem_phys));
1727
1728	ioc->mem_phys = mem_phys;
1729	ioc->chip = (SYSIF_REGS __iomem *)mem;
1730
1731	/* Save Port IO values in case we need to do downloadboot */
1732	ioc->pio_mem_phys = port;
1733	ioc->pio_chip = (SYSIF_REGS __iomem *)port;
1734
1735	return 0;
1736
1737out_pci_release_region:
1738	pci_release_selected_regions(pdev, ioc->bars);
1739out_pci_disable_device:
1740	pci_disable_device(pdev);
1741	return r;
1742}
1743
1744/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1745/**
1746 *	mpt_attach - Install a PCI intelligent MPT adapter.
1747 *	@pdev: Pointer to pci_dev structure
1748 *	@id: PCI device ID information
1749 *
1750 *	This routine performs all the steps necessary to bring the IOC of
1751 *	a MPT adapter to a OPERATIONAL state.  This includes registering
1752 *	memory regions, registering the interrupt, and allocating request
1753 *	and reply memory pools.
1754 *
1755 *	This routine also pre-fetches the LAN MAC address of a Fibre Channel
1756 *	MPT adapter.
1757 *
1758 *	Returns 0 for success, non-zero for failure.
1759 *
1760 *	TODO: Add support for polled controllers
1761 */
1762int
1763mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1764{
1765	MPT_ADAPTER	*ioc;
1766	u8		 cb_idx;
1767	int		 r = -ENODEV;
1768	u8		 pcixcmd;
1769	static int	 mpt_ids = 0;
1770#ifdef CONFIG_PROC_FS
1771	struct proc_dir_entry *dent;
1772#endif
1773
1774	ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_KERNEL);
1775	if (ioc == NULL) {
1776		printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
1777		return -ENOMEM;
1778	}
1779
1780	ioc->id = mpt_ids++;
1781	sprintf(ioc->name, "ioc%d", ioc->id);
1782	dinitprintk(ioc, printk(KERN_WARNING MYNAM ": mpt_adapter_install\n"));
1783
1784	/*
1785	 * set initial debug level
1786	 * (refer to mptdebug.h)
1787	 *
1788	 */
1789	ioc->debug_level = mpt_debug_level;
1790	if (mpt_debug_level)
1791		printk(KERN_INFO "mpt_debug_level=%xh\n", mpt_debug_level);
1792
1793	dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": mpt_adapter_install\n", ioc->name));
1794
1795	ioc->pcidev = pdev;
1796	if (mpt_mapresources(ioc)) {
1797		goto out_free_ioc;
1798	}
1799
1800	/*
1801	 * Setting up proper handlers for scatter gather handling
1802	 */
1803	if (ioc->dma_mask == DMA_BIT_MASK(64)) {
1804		if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1078)
1805			ioc->add_sge = &mpt_add_sge_64bit_1078;
1806		else
1807			ioc->add_sge = &mpt_add_sge_64bit;
1808		ioc->add_chain = &mpt_add_chain_64bit;
1809		ioc->sg_addr_size = 8;
1810	} else {
1811		ioc->add_sge = &mpt_add_sge;
1812		ioc->add_chain = &mpt_add_chain;
1813		ioc->sg_addr_size = 4;
1814	}
1815	ioc->SGE_size = sizeof(u32) + ioc->sg_addr_size;
1816
1817	ioc->alloc_total = sizeof(MPT_ADAPTER);
1818	ioc->req_sz = MPT_DEFAULT_FRAME_SIZE;		/* avoid div by zero! */
1819	ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
1820
1821
1822	spin_lock_init(&ioc->taskmgmt_lock);
1823	mutex_init(&ioc->internal_cmds.mutex);
1824	init_completion(&ioc->internal_cmds.done);
1825	mutex_init(&ioc->mptbase_cmds.mutex);
1826	init_completion(&ioc->mptbase_cmds.done);
1827	mutex_init(&ioc->taskmgmt_cmds.mutex);
1828	init_completion(&ioc->taskmgmt_cmds.done);
1829
1830	/* Initialize the event logging.
1831	 */
1832	ioc->eventTypes = 0;	/* None */
1833	ioc->eventContext = 0;
1834	ioc->eventLogSize = 0;
1835	ioc->events = NULL;
1836
1837#ifdef MFCNT
1838	ioc->mfcnt = 0;
1839#endif
1840
1841	ioc->sh = NULL;
1842	ioc->cached_fw = NULL;
1843
1844	/* Initialize SCSI Config Data structure
1845	 */
1846	memset(&ioc->spi_data, 0, sizeof(SpiCfgData));
1847
1848	/* Initialize the fc rport list head.
1849	 */
1850	INIT_LIST_HEAD(&ioc->fc_rports);
1851
1852	/* Find lookup slot. */
1853	INIT_LIST_HEAD(&ioc->list);
1854
1855
1856	/* Initialize workqueue */
1857	INIT_DELAYED_WORK(&ioc->fault_reset_work, mpt_fault_reset_work);
1858
1859	ioc->reset_work_q =
1860		alloc_workqueue("mpt_poll_%d", WQ_MEM_RECLAIM | WQ_PERCPU, 0,
1861				ioc->id);
1862	if (!ioc->reset_work_q) {
1863		printk(MYIOC_s_ERR_FMT "Insufficient memory to add adapter!\n",
1864		    ioc->name);
1865		r = -ENOMEM;
1866		goto out_unmap_resources;
1867	}
1868
1869	dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "facts @ %p, pfacts[0] @ %p\n",
1870	    ioc->name, &ioc->facts, &ioc->pfacts[0]));
1871
1872	ioc->prod_name = mpt_get_product_name(pdev->vendor, pdev->device,
1873					      pdev->revision);
1874
1875	switch (pdev->device)
1876	{
1877	case MPI_MANUFACTPAGE_DEVICEID_FC939X:
1878	case MPI_MANUFACTPAGE_DEVICEID_FC949X:
1879		ioc->errata_flag_1064 = 1;
1880		fallthrough;
1881	case MPI_MANUFACTPAGE_DEVICEID_FC909:
1882	case MPI_MANUFACTPAGE_DEVICEID_FC929:
1883	case MPI_MANUFACTPAGE_DEVICEID_FC919:
1884	case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1885		ioc->bus_type = FC;
1886		break;
1887
1888	case MPI_MANUFACTPAGE_DEVICEID_FC929X:
1889		if (pdev->revision < XL_929) {
1890			/* 929X Chip Fix. Set Split transactions level
1891		 	* for PCIX. Set MOST bits to zero.
1892		 	*/
1893			pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1894			pcixcmd &= 0x8F;
1895			pci_write_config_byte(pdev, 0x6a, pcixcmd);
1896		} else {
1897			/* 929XL Chip Fix. Set MMRBC to 0x08.
1898		 	*/
1899			pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1900			pcixcmd |= 0x08;
1901			pci_write_config_byte(pdev, 0x6a, pcixcmd);
1902		}
1903		ioc->bus_type = FC;
1904		break;
1905
1906	case MPI_MANUFACTPAGE_DEVICEID_FC919X:
1907		/* 919X Chip Fix. Set Split transactions level
1908		 * for PCIX. Set MOST bits to zero.
1909		 */
1910		pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1911		pcixcmd &= 0x8F;
1912		pci_write_config_byte(pdev, 0x6a, pcixcmd);
1913		ioc->bus_type = FC;
1914		break;
1915
1916	case MPI_MANUFACTPAGE_DEVID_53C1030:
1917		/* 1030 Chip Fix. Disable Split transactions
1918		 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
1919		 */
1920		if (pdev->revision < C0_1030) {
1921			pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1922			pcixcmd &= 0x8F;
1923			pci_write_config_byte(pdev, 0x6a, pcixcmd);
1924		}
1925		fallthrough;
1926
1927	case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
1928		ioc->bus_type = SPI;
1929		break;
1930
1931	case MPI_MANUFACTPAGE_DEVID_SAS1064:
1932	case MPI_MANUFACTPAGE_DEVID_SAS1068:
1933		ioc->errata_flag_1064 = 1;
1934		ioc->bus_type = SAS;
1935		break;
1936
1937	case MPI_MANUFACTPAGE_DEVID_SAS1064E:
1938	case MPI_MANUFACTPAGE_DEVID_SAS1068E:
1939	case MPI_MANUFACTPAGE_DEVID_SAS1078:
1940		ioc->bus_type = SAS;
1941		break;
1942	}
1943
1944
1945	switch (ioc->bus_type) {
1946
1947	case SAS:
1948		ioc->msi_enable = mpt_msi_enable_sas;
1949		break;
1950
1951	case SPI:
1952		ioc->msi_enable = mpt_msi_enable_spi;
1953		break;
1954
1955	case FC:
1956		ioc->msi_enable = mpt_msi_enable_fc;
1957		break;
1958
1959	default:
1960		ioc->msi_enable = 0;
1961		break;
1962	}
1963
1964	ioc->fw_events_off = 1;
1965
1966	if (ioc->errata_flag_1064)
1967		pci_disable_io_access(pdev);
1968
1969	spin_lock_init(&ioc->FreeQlock);
1970
1971	/* Disable all! */
1972	CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1973	ioc->active = 0;
1974	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1975
1976	/* Set IOC ptr in the pcidev's driver data. */
1977	pci_set_drvdata(ioc->pcidev, ioc);
1978
1979	/* Set lookup ptr. */
1980	list_add_tail(&ioc->list, &ioc_list);
1981
1982	/* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1983	 */
1984	mpt_detect_bound_ports(ioc, pdev);
1985
1986	INIT_LIST_HEAD(&ioc->fw_event_list);
1987	spin_lock_init(&ioc->fw_event_lock);
1988	ioc->fw_event_q = alloc_workqueue("mpt/%d",
1989					  WQ_MEM_RECLAIM | WQ_PERCPU, 0,
1990					  ioc->id);
1991	if (!ioc->fw_event_q) {
1992		printk(MYIOC_s_ERR_FMT "Insufficient memory to add adapter!\n",
1993		    ioc->name);
1994		r = -ENOMEM;
1995		goto out_remove_ioc;
1996	}
1997
1998	if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
1999	    CAN_SLEEP)) != 0){
2000		printk(MYIOC_s_ERR_FMT "didn't initialize properly! (%d)\n",
2001		    ioc->name, r);
2002
2003		destroy_workqueue(ioc->fw_event_q);
2004		ioc->fw_event_q = NULL;
2005
2006		list_del(&ioc->list);
2007		if (ioc->alt_ioc)
2008			ioc->alt_ioc->alt_ioc = NULL;
2009		iounmap(ioc->memmap);
2010		if (pci_is_enabled(pdev))
2011			pci_disable_device(pdev);
2012		if (r != -5)
2013			pci_release_selected_regions(pdev, ioc->bars);
2014
2015		destroy_workqueue(ioc->reset_work_q);
2016		ioc->reset_work_q = NULL;
2017
2018		kfree(ioc);
2019		return r;
2020	}
2021
2022	/* call per device driver probe entry point */
2023	for(cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
2024		if(MptDeviceDriverHandlers[cb_idx] &&
2025		  MptDeviceDriverHandlers[cb_idx]->probe) {
2026			MptDeviceDriverHandlers[cb_idx]->probe(pdev);
2027		}
2028	}
2029
2030#ifdef CONFIG_PROC_FS
2031	/*
2032	 *  Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
2033	 */
2034	dent = proc_mkdir(ioc->name, mpt_proc_root_dir);
2035	if (dent) {
2036		proc_create_single_data("info", S_IRUGO, dent,
2037				mpt_iocinfo_proc_show, ioc);
2038		proc_create_single_data("summary", S_IRUGO, dent,
2039				mpt_summary_proc_show, ioc);
2040	}
2041#endif
2042
2043	if (!ioc->alt_ioc)
2044		queue_delayed_work(ioc->reset_work_q, &ioc->fault_reset_work,
2045			msecs_to_jiffies(MPT_POLLING_INTERVAL));
2046
2047	return 0;
2048
2049out_remove_ioc:
2050	list_del(&ioc->list);
2051	if (ioc->alt_ioc)
2052		ioc->alt_ioc->alt_ioc = NULL;
2053
2054	destroy_workqueue(ioc->reset_work_q);
2055	ioc->reset_work_q = NULL;
2056
2057out_unmap_resources:
2058	iounmap(ioc->memmap);
2059	pci_disable_device(pdev);
2060	pci_release_selected_regions(pdev, ioc->bars);
2061
2062out_free_ioc:
2063	kfree(ioc);
2064
2065	return r;
2066}
2067
2068/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2069/**
2070 *	mpt_detach - Remove a PCI intelligent MPT adapter.
2071 *	@pdev: Pointer to pci_dev structure
2072 */
2073
2074void
2075mpt_detach(struct pci_dev *pdev)
2076{
2077	MPT_ADAPTER 	*ioc = pci_get_drvdata(pdev);
2078	char pname[64];
2079	u8 cb_idx;
2080	unsigned long flags;
2081	struct workqueue_struct *wq;
2082
2083	/*
2084	 * Stop polling ioc for fault condition
2085	 */
2086	spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
2087	wq = ioc->reset_work_q;
2088	ioc->reset_work_q = NULL;
2089	spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
2090	cancel_delayed_work(&ioc->fault_reset_work);
2091	destroy_workqueue(wq);
2092
2093	spin_lock_irqsave(&ioc->fw_event_lock, flags);
2094	wq = ioc->fw_event_q;
2095	ioc->fw_event_q = NULL;
2096	spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
2097	destroy_workqueue(wq);
2098
2099	snprintf(pname, sizeof(pname), MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name);
2100	remove_proc_entry(pname, NULL);
2101	snprintf(pname, sizeof(pname), MPT_PROCFS_MPTBASEDIR "/%s/info", ioc->name);
2102	remove_proc_entry(pname, NULL);
2103	snprintf(pname, sizeof(pname), MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
2104	remove_proc_entry(pname, NULL);
2105
2106	/* call per device driver remove entry point */
2107	for(cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
2108		if(MptDeviceDriverHandlers[cb_idx] &&
2109		  MptDeviceDriverHandlers[cb_idx]->remove) {
2110			MptDeviceDriverHandlers[cb_idx]->remove(pdev);
2111		}
2112	}
2113
2114	/* Disable interrupts! */
2115	CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2116
2117	ioc->active = 0;
2118	synchronize_irq(pdev->irq);
2119
2120	/* Clear any lingering interrupt */
2121	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2122
2123	CHIPREG_READ32(&ioc->chip->IntStatus);
2124
2125	mpt_adapter_dispose(ioc);
2126
2127}
2128
2129/**************************************************************************
2130 * Power Management
2131 */
2132#ifdef CONFIG_PM
2133/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2134/**
2135 *	mpt_suspend - Fusion MPT base driver suspend routine.
2136 *	@pdev: Pointer to pci_dev structure
2137 *	@state: new state to enter
2138 */
2139int
2140mpt_suspend(struct pci_dev *pdev, pm_message_t state)
2141{
2142	u32 device_state;
2143	MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
2144
2145	device_state = pci_choose_state(pdev, state);
2146	printk(MYIOC_s_INFO_FMT "pci-suspend: pdev=0x%p, slot=%s, Entering "
2147	    "operating state [D%d]\n", ioc->name, pdev, pci_name(pdev),
2148	    device_state);
2149
2150	/* put ioc into READY_STATE */
2151	if (SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) {
2152		printk(MYIOC_s_ERR_FMT
2153		"pci-suspend:  IOC msg unit reset failed!\n", ioc->name);
2154	}
2155
2156	/* disable interrupts */
2157	CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2158	ioc->active = 0;
2159
2160	/* Clear any lingering interrupt */
2161	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2162
2163	free_irq(ioc->pci_irq, ioc);
2164	if (ioc->msi_enable)
2165		pci_disable_msi(ioc->pcidev);
2166	ioc->pci_irq = -1;
2167	pci_save_state(pdev);
2168	pci_disable_device(pdev);
2169	pci_release_selected_regions(pdev, ioc->bars);
2170	pci_set_power_state(pdev, device_state);
2171	return 0;
2172}
2173
2174/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2175/**
2176 *	mpt_resume - Fusion MPT base driver resume routine.
2177 *	@pdev: Pointer to pci_dev structure
2178 */
2179int
2180mpt_resume(struct pci_dev *pdev)
2181{
2182	MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
2183	u32 device_state = pdev->current_state;
2184	int recovery_state;
2185	int err;
2186
2187	printk(MYIOC_s_INFO_FMT "pci-resume: pdev=0x%p, slot=%s, Previous "
2188	    "operating state [D%d]\n", ioc->name, pdev, pci_name(pdev),
2189	    device_state);
2190
2191	pci_set_power_state(pdev, PCI_D0);
2192	pci_enable_wake(pdev, PCI_D0, 0);
2193	pci_restore_state(pdev);
2194	ioc->pcidev = pdev;
2195	err = mpt_mapresources(ioc);
2196	if (err)
2197		return err;
2198
2199	if (ioc->dma_mask == DMA_BIT_MASK(64)) {
2200		if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1078)
2201			ioc->add_sge = &mpt_add_sge_64bit_1078;
2202		else
2203			ioc->add_sge = &mpt_add_sge_64bit;
2204		ioc->add_chain = &mpt_add_chain_64bit;
2205		ioc->sg_addr_size = 8;
2206	} else {
2207
2208		ioc->add_sge = &mpt_add_sge;
2209		ioc->add_chain = &mpt_add_chain;
2210		ioc->sg_addr_size = 4;
2211	}
2212	ioc->SGE_size = sizeof(u32) + ioc->sg_addr_size;
2213
2214	printk(MYIOC_s_INFO_FMT "pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
2215	    ioc->name, (mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
2216	    CHIPREG_READ32(&ioc->chip->Doorbell));
2217
2218	/*
2219	 * Errata workaround for SAS pci express:
2220	 * Upon returning to the D0 state, the contents of the doorbell will be
2221	 * stale data, and this will incorrectly signal to the host driver that
2222	 * the firmware is ready to process mpt commands.   The workaround is
2223	 * to issue a diagnostic reset.
2224	 */
2225	if (ioc->bus_type == SAS && (pdev->device ==
2226	    MPI_MANUFACTPAGE_DEVID_SAS1068E || pdev->device ==
2227	    MPI_MANUFACTPAGE_DEVID_SAS1064E)) {
2228		if (KickStart(ioc, 1, CAN_SLEEP) < 0) {
2229			printk(MYIOC_s_WARN_FMT "pci-resume: Cannot recover\n",
2230			    ioc->name);
2231			goto out;
2232		}
2233	}
2234
2235	/* bring ioc to operational state */
2236	printk(MYIOC_s_INFO_FMT "Sending mpt_do_ioc_recovery\n", ioc->name);
2237	recovery_state = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
2238						 CAN_SLEEP);
2239	if (recovery_state != 0)
2240		printk(MYIOC_s_WARN_FMT "pci-resume: Cannot recover, "
2241		    "error:[%x]\n", ioc->name, recovery_state);
2242	else
2243		printk(MYIOC_s_INFO_FMT
2244		    "pci-resume: success\n", ioc->name);
2245 out:
2246	return 0;
2247
2248}
2249#endif
2250
2251static int
2252mpt_signal_reset(u8 index, MPT_ADAPTER *ioc, int reset_phase)
2253{
2254	if ((MptDriverClass[index] == MPTSPI_DRIVER &&
2255	     ioc->bus_type != SPI) ||
2256	    (MptDriverClass[index] == MPTFC_DRIVER &&
2257	     ioc->bus_type != FC) ||
2258	    (MptDriverClass[index] == MPTSAS_DRIVER &&
2259	     ioc->bus_type != SAS))
2260		/* make sure we only call the relevant reset handler
2261		 * for the bus */
2262		return 0;
2263	return (MptResetHandlers[index])(ioc, reset_phase);
2264}
2265
2266/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2267/**
2268 *	mpt_do_ioc_recovery - Initialize or recover MPT adapter.
2269 *	@ioc: Pointer to MPT adapter structure
2270 *	@reason: Event word / reason
2271 *	@sleepFlag: Use schedule if CAN_SLEEP else use udelay.
2272 *
2273 *	This routine performs all the steps necessary to bring the IOC
2274 *	to a OPERATIONAL state.
2275 *
2276 *	This routine also pre-fetches the LAN MAC address of a Fibre Channel
2277 *	MPT adapter.
2278 *
2279 *	Returns:
2280 *		 0 for success
2281 *		-1 if failed to get board READY
2282 *		-2 if READY but IOCFacts Failed
2283 *		-3 if READY but PrimeIOCFifos Failed
2284 *		-4 if READY but IOCInit Failed
2285 *		-5 if failed to enable_device and/or request_selected_regions
2286 *		-6 if failed to upload firmware
2287 */
2288static int
2289mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
2290{
2291	int	 hard_reset_done = 0;
2292	int	 alt_ioc_ready = 0;
2293	int	 hard;
2294	int	 rc=0;
2295	int	 ii;
2296	int	 ret = 0;
2297	int	 reset_alt_ioc_active = 0;
2298	int	 irq_allocated = 0;
2299	u8	*a;
2300
2301	printk(MYIOC_s_INFO_FMT "Initiating %s\n", ioc->name,
2302	    reason == MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");
2303
2304	/* Disable reply interrupts (also blocks FreeQ) */
2305	CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2306	ioc->active = 0;
2307
2308	if (ioc->alt_ioc) {
2309		if (ioc->alt_ioc->active ||
2310		    reason == MPT_HOSTEVENT_IOC_RECOVER) {
2311			reset_alt_ioc_active = 1;
2312			/* Disable alt-IOC's reply interrupts
2313			 *  (and FreeQ) for a bit
2314			 **/
2315			CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask,
2316				0xFFFFFFFF);
2317			ioc->alt_ioc->active = 0;
2318		}
2319	}
2320
2321	hard = 1;
2322	if (reason == MPT_HOSTEVENT_IOC_BRINGUP)
2323		hard = 0;
2324
2325	if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) {
2326		if (hard_reset_done == -4) {
2327			printk(MYIOC_s_WARN_FMT "Owned by PEER..skipping!\n",
2328			    ioc->name);
2329
2330			if (reset_alt_ioc_active && ioc->alt_ioc) {
2331				/* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
2332				dprintk(ioc, printk(MYIOC_s_INFO_FMT
2333				    "alt_ioc reply irq re-enabled\n", ioc->alt_ioc->name));
2334				CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
2335				ioc->alt_ioc->active = 1;
2336			}
2337
2338		} else {
2339			printk(MYIOC_s_WARN_FMT
2340			    "NOT READY WARNING!\n", ioc->name);
2341		}
2342		ret = -1;
2343		goto out;
2344	}
2345
2346	/* hard_reset_done = 0 if a soft reset was performed
2347	 * and 1 if a hard reset was performed.
2348	 */
2349	if (hard_reset_done && reset_alt_ioc_active && ioc->alt_ioc) {
2350		if ((rc = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0)
2351			alt_ioc_ready = 1;
2352		else
2353			printk(MYIOC_s_WARN_FMT
2354			    ": alt-ioc Not ready WARNING!\n",
2355			    ioc->alt_ioc->name);
2356	}
2357
2358	for (ii=0; ii<5; ii++) {
2359		/* Get IOC facts! Allow 5 retries */
2360		if ((rc = GetIocFacts(ioc, sleepFlag, reason)) == 0)
2361			break;
2362	}
2363
2364
2365	if (ii == 5) {
2366		dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2367		    "Retry IocFacts failed rc=%x\n", ioc->name, rc));
2368		ret = -2;
2369	} else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2370		MptDisplayIocCapabilities(ioc);
2371	}
2372
2373	if (alt_ioc_ready) {
2374		if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {
2375			dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2376			    "Initial Alt IocFacts failed rc=%x\n",
2377			    ioc->name, rc));
2378			/* Retry - alt IOC was initialized once
2379			 */
2380			rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason);
2381		}
2382		if (rc) {
2383			dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2384			    "Retry Alt IocFacts failed rc=%x\n", ioc->name, rc));
2385			alt_ioc_ready = 0;
2386			reset_alt_ioc_active = 0;
2387		} else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2388			MptDisplayIocCapabilities(ioc->alt_ioc);
2389		}
2390	}
2391
2392	if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP) &&
2393	    (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)) {
2394		pci_release_selected_regions(ioc->pcidev, ioc->bars);
2395		ioc->bars = pci_select_bars(ioc->pcidev, IORESOURCE_MEM |
2396		    IORESOURCE_IO);
2397		if (pci_enable_device(ioc->pcidev))
2398			return -5;
2399		if (pci_request_selected_regions(ioc->pcidev, ioc->bars,
2400			"mpt"))
2401			return -5;
2402	}
2403
2404	/*
2405	 * Device is reset now. It must have de-asserted the interrupt line
2406	 * (if it was asserted) and it should be safe to register for the
2407	 * interrupt now.
2408	 */
2409	if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
2410		ioc->pci_irq = -1;
2411		if (ioc->pcidev->irq) {
2412			if (ioc->msi_enable && !pci_enable_msi(ioc->pcidev))
2413				printk(MYIOC_s_INFO_FMT "PCI-MSI enabled\n",
2414				    ioc->name);
2415			else
2416				ioc->msi_enable = 0;
2417			rc = request_irq(ioc->pcidev->irq, mpt_interrupt,
2418			    IRQF_SHARED, ioc->name, ioc);
2419			if (rc < 0) {
2420				printk(MYIOC_s_ERR_FMT "Unable to allocate "
2421				    "interrupt %d!\n",
2422				    ioc->name, ioc->pcidev->irq);
2423				if (ioc->msi_enable)
2424					pci_disable_msi(ioc->pcidev);
2425				ret = -EBUSY;
2426				goto out;
2427			}
2428			irq_allocated = 1;
2429			ioc->pci_irq = ioc->pcidev->irq;
2430			pci_set_master(ioc->pcidev);		/* ?? */
2431			pci_set_drvdata(ioc->pcidev, ioc);
2432			dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2433			    "installed at interrupt %d\n", ioc->name,
2434			    ioc->pcidev->irq));
2435		}
2436	}
2437
2438	/* Prime reply & request queues!
2439	 * (mucho alloc's) Must be done prior to
2440	 * init as upper addresses are needed for init.
2441	 * If fails, continue with alt-ioc processing
2442	 */
2443	dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "PrimeIocFifos\n",
2444	    ioc->name));
2445	if ((ret == 0) && ((rc = PrimeIocFifos(ioc)) != 0))
2446		ret = -3;
2447
2448	/* May need to check/upload firmware & data here!
2449	 * If fails, continue with alt-ioc processing
2450	 */
2451	dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "SendIocInit\n",
2452	    ioc->name));
2453	if ((ret == 0) && ((rc = SendIocInit(ioc, sleepFlag)) != 0))
2454		ret = -4;
2455// NEW!
2456	if (alt_ioc_ready && ((rc = PrimeIocFifos(ioc->alt_ioc)) != 0)) {
2457		printk(MYIOC_s_WARN_FMT
2458		    ": alt-ioc (%d) FIFO mgmt alloc WARNING!\n",
2459		    ioc->alt_ioc->name, rc);
2460		alt_ioc_ready = 0;
2461		reset_alt_ioc_active = 0;
2462	}
2463
2464	if (alt_ioc_ready) {
2465		if ((rc = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) {
2466			alt_ioc_ready = 0;
2467			reset_alt_ioc_active = 0;
2468			printk(MYIOC_s_WARN_FMT
2469				": alt-ioc: (%d) init failure WARNING!\n",
2470					ioc->alt_ioc->name, rc);
2471		}
2472	}
2473
2474	if (reason == MPT_HOSTEVENT_IOC_BRINGUP){
2475		if (ioc->upload_fw) {
2476			ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2477			    "firmware upload required!\n", ioc->name));
2478
2479			/* Controller is not operational, cannot do upload
2480			 */
2481			if (ret == 0) {
2482				rc = mpt_do_upload(ioc, sleepFlag);
2483				if (rc == 0) {
2484					if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
2485						/*
2486						 * Maintain only one pointer to FW memory
2487						 * so there will not be two attempt to
2488						 * downloadboot onboard dual function
2489						 * chips (mpt_adapter_disable,
2490						 * mpt_diag_reset)
2491						 */
2492						ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2493						    "mpt_upload:  alt_%s has cached_fw=%p \n",
2494						    ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw));
2495						ioc->cached_fw = NULL;
2496					}
2497				} else {
2498					printk(MYIOC_s_WARN_FMT
2499					    "firmware upload failure!\n", ioc->name);
2500					ret = -6;
2501				}
2502			}
2503		}
2504	}
2505
2506	/*  Enable MPT base driver management of EventNotification
2507	 *  and EventAck handling.
2508	 */
2509	if ((ret == 0) && (!ioc->facts.EventState)) {
2510		dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2511			"SendEventNotification\n",
2512		    ioc->name));
2513		ret = SendEventNotification(ioc, 1, sleepFlag);	/* 1=Enable */
2514	}
2515
2516	if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState)
2517		rc = SendEventNotification(ioc->alt_ioc, 1, sleepFlag);
2518
2519	if (ret == 0) {
2520		/* Enable! (reply interrupt) */
2521		CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
2522		ioc->active = 1;
2523	}
2524	if (rc == 0) {	/* alt ioc */
2525		if (reset_alt_ioc_active && ioc->alt_ioc) {
2526			/* (re)Enable alt-IOC! (reply interrupt) */
2527			dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "alt-ioc"
2528				"reply irq re-enabled\n",
2529				ioc->alt_ioc->name));
2530			CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask,
2531				MPI_HIM_DIM);
2532			ioc->alt_ioc->active = 1;
2533		}
2534	}
2535
2536
2537	/*	Add additional "reason" check before call to GetLanConfigPages
2538	 *	(combined with GetIoUnitPage2 call).  This prevents a somewhat
2539	 *	recursive scenario; GetLanConfigPages times out, timer expired
2540	 *	routine calls HardResetHandler, which calls into here again,
2541	 *	and we try GetLanConfigPages again...
2542	 */
2543	if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
2544
2545		/*
2546		 * Initialize link list for inactive raid volumes.
2547		 */
2548		mutex_init(&ioc->raid_data.inactive_list_mutex);
2549		INIT_LIST_HEAD(&ioc->raid_data.inactive_list);
2550
2551		switch (ioc->bus_type) {
2552
2553		case SAS:
2554			/* clear persistency table */
2555			if(ioc->facts.IOCExceptions &
2556			    MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL) {
2557				ret = mptbase_sas_persist_operation(ioc,
2558				    MPI_SAS_OP_CLEAR_NOT_PRESENT);
2559				if(ret != 0)
2560					goto out;
2561			}
2562
2563			/* Find IM volumes
2564			 */
2565			mpt_findImVolumes(ioc);
2566
2567			/* Check, and possibly reset, the coalescing value
2568			 */
2569			mpt_read_ioc_pg_1(ioc);
2570
2571			break;
2572
2573		case FC:
2574			if ((ioc->pfacts[0].ProtocolFlags &
2575				MPI_PORTFACTS_PROTOCOL_LAN) &&
2576			    (ioc->lan_cnfg_page0.Header.PageLength == 0)) {
2577				/*
2578				 *  Pre-fetch the ports LAN MAC address!
2579				 *  (LANPage1_t stuff)
2580				 */
2581				(void) GetLanConfigPages(ioc);
2582				a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
2583				dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2584					"LanAddr = %pMR\n", ioc->name, a));
2585			}
2586			break;
2587
2588		case SPI:
2589			/* Get NVRAM and adapter maximums from SPP 0 and 2
2590			 */
2591			mpt_GetScsiPortSettings(ioc, 0);
2592
2593			/* Get version and length of SDP 1
2594			 */
2595			mpt_readScsiDevicePageHeaders(ioc, 0);
2596
2597			/* Find IM volumes
2598			 */
2599			if (ioc->facts.MsgVersion >= MPI_VERSION_01_02)
2600				mpt_findImVolumes(ioc);
2601
2602			/* Check, and possibly reset, the coalescing value
2603			 */
2604			mpt_read_ioc_pg_1(ioc);
2605
2606			mpt_read_ioc_pg_4(ioc);
2607
2608			break;
2609		}
2610
2611		GetIoUnitPage2(ioc);
2612		mpt_get_manufacturing_pg_0(ioc);
2613	}
2614
2615 out:
2616	if ((ret != 0) && irq_allocated) {
2617		free_irq(ioc->pci_irq, ioc);
2618		if (ioc->msi_enable)
2619			pci_disable_msi(ioc->pcidev);
2620	}
2621	return ret;
2622}
2623
2624/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2625/**
2626 *	mpt_detect_bound_ports - Search for matching PCI bus/dev_function
2627 *	@ioc: Pointer to MPT adapter structure
2628 *	@pdev: Pointer to (struct pci_dev) structure
2629 *
2630 *	Search for PCI bus/dev_function which matches
2631 *	PCI bus/dev_function (+/-1) for newly discovered 929,
2632 *	929X, 1030 or 1035.
2633 *
2634 *	If match on PCI dev_function +/-1 is found, bind the two MPT adapters
2635 *	using alt_ioc pointer fields in their %MPT_ADAPTER structures.
2636 */
2637static void
2638mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
2639{
2640	struct pci_dev *peer=NULL;
2641	unsigned int slot = PCI_SLOT(pdev->devfn);
2642	unsigned int func = PCI_FUNC(pdev->devfn);
2643	MPT_ADAPTER *ioc_srch;
2644
2645	dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PCI device %s devfn=%x/%x,"
2646	    " searching for devfn match on %x or %x\n",
2647	    ioc->name, pci_name(pdev), pdev->bus->number,
2648	    pdev->devfn, func-1, func+1));
2649
2650	peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func-1));
2651	if (!peer) {
2652		peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func+1));
2653		if (!peer)
2654			return;
2655	}
2656
2657	list_for_each_entry(ioc_srch, &ioc_list, list) {
2658		struct pci_dev *_pcidev = ioc_srch->pcidev;
2659		if (_pcidev == peer) {
2660			/* Paranoia checks */
2661			if (ioc->alt_ioc != NULL) {
2662				printk(MYIOC_s_WARN_FMT
2663				    "Oops, already bound (%s <==> %s)!\n",
2664				    ioc->name, ioc->name, ioc->alt_ioc->name);
2665				break;
2666			} else if (ioc_srch->alt_ioc != NULL) {
2667				printk(MYIOC_s_WARN_FMT
2668				    "Oops, already bound (%s <==> %s)!\n",
2669				    ioc_srch->name, ioc_srch->name,
2670				    ioc_srch->alt_ioc->name);
2671				break;
2672			}
2673			dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2674				"FOUND! binding %s <==> %s\n",
2675				ioc->name, ioc->name, ioc_srch->name));
2676			ioc_srch->alt_ioc = ioc;
2677			ioc->alt_ioc = ioc_srch;
2678		}
2679	}
2680	pci_dev_put(peer);
2681}
2682
2683/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2684/**
2685 *	mpt_adapter_disable - Disable misbehaving MPT adapter.
2686 *	@ioc: Pointer to MPT adapter structure
2687 */
2688static void
2689mpt_adapter_disable(MPT_ADAPTER *ioc)
2690{
2691	int sz;
2692	int ret;
2693
2694	if (ioc->cached_fw != NULL) {
2695		ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2696			"%s: Pushing FW onto adapter\n", __func__, ioc->name));
2697		if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *)
2698		    ioc->cached_fw, CAN_SLEEP)) < 0) {
2699			printk(MYIOC_s_WARN_FMT
2700			    ": firmware downloadboot failure (%d)!\n",
2701			    ioc->name, ret);
2702		}
2703	}
2704
2705	/*
2706	 * Put the controller into ready state (if its not already)
2707	 */
2708	if (mpt_GetIocState(ioc, 1) != MPI_IOC_STATE_READY) {
2709		if (!SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET,
2710		    CAN_SLEEP)) {
2711			if (mpt_GetIocState(ioc, 1) != MPI_IOC_STATE_READY)
2712				printk(MYIOC_s_ERR_FMT "%s:  IOC msg unit "
2713				    "reset failed to put ioc in ready state!\n",
2714				    ioc->name, __func__);
2715		} else
2716			printk(MYIOC_s_ERR_FMT "%s:  IOC msg unit reset "
2717			    "failed!\n", ioc->name, __func__);
2718	}
2719
2720
2721	/* Disable adapter interrupts! */
2722	synchronize_irq(ioc->pcidev->irq);
2723	CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2724	ioc->active = 0;
2725
2726	/* Clear any lingering interrupt */
2727	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2728	CHIPREG_READ32(&ioc->chip->IntStatus);
2729
2730	if (ioc->alloc != NULL) {
2731		sz = ioc->alloc_sz;
2732		dexitprintk(ioc, printk(MYIOC_s_INFO_FMT "free  @ %p, sz=%d bytes\n",
2733		    ioc->name, ioc->alloc, ioc->alloc_sz));
2734		dma_free_coherent(&ioc->pcidev->dev, sz, ioc->alloc,
2735				ioc->alloc_dma);
2736		ioc->reply_frames = NULL;
2737		ioc->req_frames = NULL;
2738		ioc->alloc = NULL;
2739		ioc->alloc_total -= sz;
2740	}
2741
2742	if (ioc->sense_buf_pool != NULL) {
2743		sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
2744		dma_free_coherent(&ioc->pcidev->dev, sz, ioc->sense_buf_pool,
2745				ioc->sense_buf_pool_dma);
2746		ioc->sense_buf_pool = NULL;
2747		ioc->alloc_total -= sz;
2748	}
2749
2750	if (ioc->events != NULL){
2751		sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
2752		kfree(ioc->events);
2753		ioc->events = NULL;
2754		ioc->alloc_total -= sz;
2755	}
2756
2757	mpt_free_fw_memory(ioc);
2758
2759	kfree(ioc->spi_data.nvram);
2760	mpt_inactive_raid_list_free(ioc);
2761	kfree(ioc->raid_data.pIocPg2);
2762	kfree(ioc->raid_data.pIocPg3);
2763	ioc->spi_data.nvram = NULL;
2764	ioc->raid_data.pIocPg3 = NULL;
2765
2766	if (ioc->spi_data.pIocPg4 != NULL) {
2767		sz = ioc->spi_data.IocPg4Sz;
2768		dma_free_coherent(&ioc->pcidev->dev, sz,
2769				  ioc->spi_data.pIocPg4,
2770				  ioc->spi_data.IocPg4_dma);
2771		ioc->spi_data.pIocPg4 = NULL;
2772		ioc->alloc_total -= sz;
2773	}
2774
2775	if (ioc->ReqToChain != NULL) {
2776		kfree(ioc->ReqToChain);
2777		kfree(ioc->RequestNB);
2778		ioc->ReqToChain = NULL;
2779	}
2780
2781	kfree(ioc->ChainToChain);
2782	ioc->ChainToChain = NULL;
2783
2784	if (ioc->HostPageBuffer != NULL) {
2785		if((ret = mpt_host_page_access_control(ioc,
2786		    MPI_DB_HPBAC_FREE_BUFFER, NO_SLEEP)) != 0) {
2787			printk(MYIOC_s_ERR_FMT
2788			   ": %s: host page buffers free failed (%d)!\n",
2789			    ioc->name, __func__, ret);
2790		}
2791		dexitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2792			"HostPageBuffer free  @ %p, sz=%d bytes\n",
2793			ioc->name, ioc->HostPageBuffer,
2794			ioc->HostPageBuffer_sz));
2795		dma_free_coherent(&ioc->pcidev->dev, ioc->HostPageBuffer_sz,
2796		    ioc->HostPageBuffer, ioc->HostPageBuffer_dma);
2797		ioc->HostPageBuffer = NULL;
2798		ioc->HostPageBuffer_sz = 0;
2799		ioc->alloc_total -= ioc->HostPageBuffer_sz;
2800	}
2801
2802	pci_set_drvdata(ioc->pcidev, NULL);
2803}
2804/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2805/**
2806 *	mpt_adapter_dispose - Free all resources associated with an MPT adapter
2807 *	@ioc: Pointer to MPT adapter structure
2808 *
2809 *	This routine unregisters h/w resources and frees all alloc'd memory
2810 *	associated with a MPT adapter structure.
2811 */
2812static void
2813mpt_adapter_dispose(MPT_ADAPTER *ioc)
2814{
2815	int sz_first, sz_last;
2816
2817	if (ioc == NULL)
2818		return;
2819
2820	sz_first = ioc->alloc_total;
2821
2822	mpt_adapter_disable(ioc);
2823
2824	if (ioc->pci_irq != -1) {
2825		free_irq(ioc->pci_irq, ioc);
2826		if (ioc->msi_enable)
2827			pci_disable_msi(ioc->pcidev);
2828		ioc->pci_irq = -1;
2829	}
2830
2831	if (ioc->memmap != NULL) {
2832		iounmap(ioc->memmap);
2833		ioc->memmap = NULL;
2834	}
2835
2836	pci_disable_device(ioc->pcidev);
2837	pci_release_selected_regions(ioc->pcidev, ioc->bars);
2838
2839	/*  Zap the adapter lookup ptr!  */
2840	list_del(&ioc->list);
2841
2842	sz_last = ioc->alloc_total;
2843	dprintk(ioc, printk(MYIOC_s_INFO_FMT "free'd %d of %d bytes\n",
2844	    ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first));
2845
2846	if (ioc->alt_ioc)
2847		ioc->alt_ioc->alt_ioc = NULL;
2848
2849	kfree(ioc);
2850}
2851
2852/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2853/**
2854 *	MptDisplayIocCapabilities - Disply IOC's capabilities.
2855 *	@ioc: Pointer to MPT adapter structure
2856 */
2857static void
2858MptDisplayIocCapabilities(MPT_ADAPTER *ioc)
2859{
2860	int i = 0;
2861
2862	printk(KERN_INFO "%s: ", ioc->name);
2863	if (ioc->prod_name)
2864		pr_cont("%s: ", ioc->prod_name);
2865	pr_cont("Capabilities={");
2866
2867	if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
2868		pr_cont("Initiator");
2869		i++;
2870	}
2871
2872	if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2873		pr_cont("%sTarget", i ? "," : "");
2874		i++;
2875	}
2876
2877	if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
2878		pr_cont("%sLAN", i ? "," : "");
2879		i++;
2880	}
2881
2882#if 0
2883	/*
2884	 *  This would probably evoke more questions than it's worth
2885	 */
2886	if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2887		pr_cont("%sLogBusAddr", i ? "," : "");
2888		i++;
2889	}
2890#endif
2891
2892	pr_cont("}\n");
2893}
2894
2895/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2896/**
2897 *	MakeIocReady - Get IOC to a READY state, using KickStart if needed.
2898 *	@ioc: Pointer to MPT_ADAPTER structure
2899 *	@force: Force hard KickStart of IOC
2900 *	@sleepFlag: Specifies whether the process can sleep
2901 *
2902 *	Returns:
2903 *		 1 - DIAG reset and READY
2904 *		 0 - READY initially OR soft reset and READY
2905 *		-1 - Any failure on KickStart
2906 *		-2 - Msg Unit Reset Failed
2907 *		-3 - IO Unit Reset Failed
2908 *		-4 - IOC owned by a PEER
2909 */
2910static int
2911MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
2912{
2913	u32	 ioc_state;
2914	int	 statefault = 0;
2915	int	 cntdn;
2916	int	 hard_reset_done = 0;
2917	int	 r;
2918	int	 ii;
2919	int	 whoinit;
2920
2921	/* Get current [raw] IOC state  */
2922	ioc_state = mpt_GetIocState(ioc, 0);
2923	dhsprintk(ioc, printk(MYIOC_s_INFO_FMT "MakeIocReady [raw] state=%08x\n", ioc->name, ioc_state));
2924
2925	/*
2926	 *	Check to see if IOC got left/stuck in doorbell handshake
2927	 *	grip of death.  If so, hard reset the IOC.
2928	 */
2929	if (ioc_state & MPI_DOORBELL_ACTIVE) {
2930		statefault = 1;
2931		printk(MYIOC_s_WARN_FMT "Unexpected doorbell active!\n",
2932				ioc->name);
2933	}
2934
2935	/* Is it already READY? */
2936	if (!statefault &&
2937	    ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY)) {
2938		dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2939		    "IOC is in READY state\n", ioc->name));
2940		return 0;
2941	}
2942
2943	/*
2944	 *	Check to see if IOC is in FAULT state.
2945	 */
2946	if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
2947		statefault = 2;
2948		printk(MYIOC_s_WARN_FMT "IOC is in FAULT state!!!\n",
2949		    ioc->name);
2950		printk(MYIOC_s_WARN_FMT "           FAULT code = %04xh\n",
2951		    ioc->name, ioc_state & MPI_DOORBELL_DATA_MASK);
2952	}
2953
2954	/*
2955	 *	Hmmm...  Did it get left operational?
2956	 */
2957	if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) {
2958		dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOC operational unexpected\n",
2959				ioc->name));
2960
2961		/* Check WhoInit.
2962		 * If PCI Peer, exit.
2963		 * Else, if no fault conditions are present, issue a MessageUnitReset
2964		 * Else, fall through to KickStart case
2965		 */
2966		whoinit = (ioc_state & MPI_DOORBELL_WHO_INIT_MASK) >> MPI_DOORBELL_WHO_INIT_SHIFT;
2967		dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2968			"whoinit 0x%x statefault %d force %d\n",
2969			ioc->name, whoinit, statefault, force));
2970		if (whoinit == MPI_WHOINIT_PCI_PEER)
2971			return -4;
2972		else {
2973			if ((statefault == 0 ) && (force == 0)) {
2974				if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0)
2975					return 0;
2976			}
2977			statefault = 3;
2978		}
2979	}
2980
2981	hard_reset_done = KickStart(ioc, statefault||force, sleepFlag);
2982	if (hard_reset_done < 0)
2983		return -1;
2984
2985	/*
2986	 *  Loop here waiting for IOC to come READY.
2987	 */
2988	ii = 0;
2989	cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 5;	/* 5 seconds */
2990
2991	while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
2992		if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
2993			/*
2994			 *  BIOS or previous driver load left IOC in OP state.
2995			 *  Reset messaging FIFOs.
2996			 */
2997			if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) != 0) {
2998				printk(MYIOC_s_ERR_FMT "IOC msg unit reset failed!\n", ioc->name);
2999				return -2;
3000			}
3001		} else if (ioc_state == MPI_IOC_STATE_RESET) {
3002			/*
3003			 *  Something is wrong.  Try to get IOC back
3004			 *  to a known state.
3005			 */
3006			if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET, sleepFlag)) != 0) {
3007				printk(MYIOC_s_ERR_FMT "IO unit reset failed!\n", ioc->name);
3008				return -3;
3009			}
3010		}
3011
3012		ii++; cntdn--;
3013		if (!cntdn) {
3014			printk(MYIOC_s_ERR_FMT
3015				"Wait IOC_READY state (0x%x) timeout(%d)!\n",
3016				ioc->name, ioc_state, (int)((ii+5)/HZ));
3017			return -ETIME;
3018		}
3019
3020		if (sleepFlag == CAN_SLEEP) {
3021			msleep(1);
3022		} else {
3023			mdelay (1);	/* 1 msec delay */
3024		}
3025
3026	}
3027
3028	if (statefault < 3) {
3029		printk(MYIOC_s_INFO_FMT "Recovered from %s\n", ioc->name,
3030			statefault == 1 ? "stuck handshake" : "IOC FAULT");
3031	}
3032
3033	return hard_reset_done;
3034}
3035
3036/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3037/**
3038 *	mpt_GetIocState - Get the current state of a MPT adapter.
3039 *	@ioc: Pointer to MPT_ADAPTER structure
3040 *	@cooked: Request raw or cooked IOC state
3041 *
3042 *	Returns all IOC Doorbell register bits if cooked==0, else just the
3043 *	Doorbell bits in MPI_IOC_STATE_MASK.
3044 */
3045u32
3046mpt_GetIocState(MPT_ADAPTER *ioc, int cooked)
3047{
3048	u32 s, sc;
3049
3050	/*  Get!  */
3051	s = CHIPREG_READ32(&ioc->chip->Doorbell);
3052	sc = s & MPI_IOC_STATE_MASK;
3053
3054	/*  Save!  */
3055	ioc->last_state = sc;
3056
3057	return cooked ? sc : s;
3058}
3059
3060/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3061/**
3062 *	GetIocFacts - Send IOCFacts request to MPT adapter.
3063 *	@ioc: Pointer to MPT_ADAPTER structure
3064 *	@sleepFlag: Specifies whether the process can sleep
3065 *	@reason: If recovery, only update facts.
3066 *
3067 *	Returns 0 for success, non-zero for failure.
3068 */
3069static int
3070GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
3071{
3072	IOCFacts_t		 get_facts;
3073	IOCFactsReply_t		*facts;
3074	int			 r;
3075	int			 req_sz;
3076	int			 reply_sz;
3077	int			 sz;
3078	u32			 vv;
3079	u8			 shiftFactor=1;
3080
3081	/* IOC *must* NOT be in RESET state! */
3082	if (ioc->last_state == MPI_IOC_STATE_RESET) {
3083		printk(KERN_ERR MYNAM
3084		    ": ERROR - Can't get IOCFacts, %s NOT READY! (%08x)\n",
3085		    ioc->name, ioc->last_state);
3086		return -44;
3087	}
3088
3089	facts = &ioc->facts;
3090
3091	/* Destination (reply area)... */
3092	reply_sz = sizeof(*facts);
3093	memset(facts, 0, reply_sz);
3094
3095	/* Request area (get_facts on the stack right now!) */
3096	req_sz = sizeof(get_facts);
3097	memset(&get_facts, 0, req_sz);
3098
3099	get_facts.Function = MPI_FUNCTION_IOC_FACTS;
3100	/* Assert: All other get_facts fields are zero! */
3101
3102	dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3103	    "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
3104	    ioc->name, req_sz, reply_sz));
3105
3106	/* No non-zero fields in the get_facts request are greater than
3107	 * 1 byte in size, so we can just fire it off as is.
3108	 */
3109	r = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_facts,
3110			reply_sz, (u16*)facts, 5 /*seconds*/, sleepFlag);
3111	if (r != 0)
3112		return r;
3113
3114	/*
3115	 * Now byte swap (GRRR) the necessary fields before any further
3116	 * inspection of reply contents.
3117	 *
3118	 * But need to do some sanity checks on MsgLength (byte) field
3119	 * to make sure we don't zero IOC's req_sz!
3120	 */
3121	/* Did we get a valid reply? */
3122	if (facts->MsgLength > offsetof(IOCFactsReply_t, RequestFrameSize)/sizeof(u32)) {
3123		if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
3124			/*
3125			 * If not been here, done that, save off first WhoInit value
3126			 */
3127			if (ioc->FirstWhoInit == WHOINIT_UNKNOWN)
3128				ioc->FirstWhoInit = facts->WhoInit;
3129		}
3130
3131		facts->MsgVersion = le16_to_cpu(facts->MsgVersion);
3132		facts->MsgContext = le32_to_cpu(facts->MsgContext);
3133		facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions);
3134		facts->IOCStatus = le16_to_cpu(facts->IOCStatus);
3135		facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo);
3136		/* CHECKME! IOCStatus, IOCLogInfo */
3137
3138		facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth);
3139		facts->RequestFrameSize = le16_to_cpu(facts->RequestFrameSize);
3140
3141		/*
3142		 * FC f/w version changed between 1.1 and 1.2
3143		 *	Old: u16{Major(4),Minor(4),SubMinor(8)}
3144		 *	New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
3145		 */
3146		if (facts->MsgVersion < MPI_VERSION_01_02) {
3147			/*
3148			 *	Handle old FC f/w style, convert to new...
3149			 */
3150			u16	 oldv = le16_to_cpu(facts->Reserved_0101_FWVersion);
3151			facts->FWVersion.Word =
3152					((oldv<<12) & 0xFF000000) |
3153					((oldv<<8)  & 0x000FFF00);
3154		} else
3155			facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word);
3156
3157		facts->ProductID = le16_to_cpu(facts->ProductID);
3158
3159		if ((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
3160		    > MPI_FW_HEADER_PID_PROD_TARGET_SCSI)
3161			ioc->ir_firmware = 1;
3162
3163		facts->CurrentHostMfaHighAddr =
3164				le32_to_cpu(facts->CurrentHostMfaHighAddr);
3165		facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits);
3166		facts->CurrentSenseBufferHighAddr =
3167				le32_to_cpu(facts->CurrentSenseBufferHighAddr);
3168		facts->CurReplyFrameSize =
3169				le16_to_cpu(facts->CurReplyFrameSize);
3170		facts->IOCCapabilities = le32_to_cpu(facts->IOCCapabilities);
3171
3172		/*
3173		 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
3174		 * Older MPI-1.00.xx struct had 13 dwords, and enlarged
3175		 * to 14 in MPI-1.01.0x.
3176		 */
3177		if (facts->MsgLength >= (offsetof(IOCFactsReply_t,FWImageSize) + 7)/4 &&
3178		    facts->MsgVersion > MPI_VERSION_01_00) {
3179			facts->FWImageSize = le32_to_cpu(facts->FWImageSize);
3180		}
3181
3182		facts->FWImageSize = ALIGN(facts->FWImageSize, 4);
3183
3184		if (!facts->RequestFrameSize) {
3185			/*  Something is wrong!  */
3186			printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n",
3187					ioc->name);
3188			return -55;
3189		}
3190
3191		r = sz = facts->BlockSize;
3192		vv = ((63 / (sz * 4)) + 1) & 0x03;
3193		ioc->NB_for_64_byte_frame = vv;
3194		while ( sz )
3195		{
3196			shiftFactor++;
3197			sz = sz >> 1;
3198		}
3199		ioc->NBShiftFactor  = shiftFactor;
3200		dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3201		    "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
3202		    ioc->name, vv, shiftFactor, r));
3203
3204		if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
3205			/*
3206			 * Set values for this IOC's request & reply frame sizes,
3207			 * and request & reply queue depths...
3208			 */
3209			ioc->req_sz = min(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4);
3210			ioc->req_depth = min_t(int, MPT_MAX_REQ_DEPTH, facts->GlobalCredits);
3211			ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
3212			ioc->reply_depth = min_t(int, MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth);
3213
3214			dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "reply_sz=%3d, reply_depth=%4d\n",
3215				ioc->name, ioc->reply_sz, ioc->reply_depth));
3216			dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "req_sz  =%3d, req_depth  =%4d\n",
3217				ioc->name, ioc->req_sz, ioc->req_depth));
3218
3219			/* Get port facts! */
3220			if ( (r = GetPortFacts(ioc, 0, sleepFlag)) != 0 )
3221				return r;
3222		}
3223	} else {
3224		printk(MYIOC_s_ERR_FMT
3225		     "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
3226		     ioc->name, facts->MsgLength, (offsetof(IOCFactsReply_t,
3227		     RequestFrameSize)/sizeof(u32)));
3228		return -66;
3229	}
3230
3231	return 0;
3232}
3233
3234/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3235/**
3236 *	GetPortFacts - Send PortFacts request to MPT adapter.
3237 *	@ioc: Pointer to MPT_ADAPTER structure
3238 *	@portnum: Port number
3239 *	@sleepFlag: Specifies whether the process can sleep
3240 *
3241 *	Returns 0 for success, non-zero for failure.
3242 */
3243static int
3244GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
3245{
3246	PortFacts_t		 get_pfacts;
3247	PortFactsReply_t	*pfacts;
3248	int			 ii;
3249	int			 req_sz;
3250	int			 reply_sz;
3251	int			 max_id;
3252
3253	/* IOC *must* NOT be in RESET state! */
3254	if (ioc->last_state == MPI_IOC_STATE_RESET) {
3255		printk(MYIOC_s_ERR_FMT "Can't get PortFacts NOT READY! (%08x)\n",
3256		    ioc->name, ioc->last_state );
3257		return -4;
3258	}
3259
3260	pfacts = &ioc->pfacts[portnum];
3261
3262	/* Destination (reply area)...  */
3263	reply_sz = sizeof(*pfacts);
3264	memset(pfacts, 0, reply_sz);
3265
3266	/* Request area (get_pfacts on the stack right now!) */
3267	req_sz = sizeof(get_pfacts);
3268	memset(&get_pfacts, 0, req_sz);
3269
3270	get_pfacts.Function = MPI_FUNCTION_PORT_FACTS;
3271	get_pfacts.PortNumber = portnum;
3272	/* Assert: All other get_pfacts fields are zero! */
3273
3274	dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending get PortFacts(%d) request\n",
3275			ioc->name, portnum));
3276
3277	/* No non-zero fields in the get_pfacts request are greater than
3278	 * 1 byte in size, so we can just fire it off as is.
3279	 */
3280	ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_pfacts,
3281				reply_sz, (u16*)pfacts, 5 /*seconds*/, sleepFlag);
3282	if (ii != 0)
3283		return ii;
3284
3285	/* Did we get a valid reply? */
3286
3287	/* Now byte swap the necessary fields in the response. */
3288	pfacts->MsgContext = le32_to_cpu(pfacts->MsgContext);
3289	pfacts->IOCStatus = le16_to_cpu(pfacts->IOCStatus);
3290	pfacts->IOCLogInfo = le32_to_cpu(pfacts->IOCLogInfo);
3291	pfacts->MaxDevices = le16_to_cpu(pfacts->MaxDevices);
3292	pfacts->PortSCSIID = le16_to_cpu(pfacts->PortSCSIID);
3293	pfacts->ProtocolFlags = le16_to_cpu(pfacts->ProtocolFlags);
3294	pfacts->MaxPostedCmdBuffers = le16_to_cpu(pfacts->MaxPostedCmdBuffers);
3295	pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs);
3296	pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets);
3297
3298	max_id = (ioc->bus_type == SAS) ? pfacts->PortSCSIID :
3299	    pfacts->MaxDevices;
3300	ioc->devices_per_bus = (max_id > 255) ? 256 : max_id;
3301	ioc->number_of_buses = (ioc->devices_per_bus < 256) ? 1 : max_id/256;
3302
3303	/*
3304	 * Place all the devices on channels
3305	 *
3306	 * (for debuging)
3307	 */
3308	if (mpt_channel_mapping) {
3309		ioc->devices_per_bus = 1;
3310		ioc->number_of_buses = (max_id > 255) ? 255 : max_id;
3311	}
3312
3313	return 0;
3314}
3315
3316/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3317/**
3318 *	SendIocInit - Send IOCInit request to MPT adapter.
3319 *	@ioc: Pointer to MPT_ADAPTER structure
3320 *	@sleepFlag: Specifies whether the process can sleep
3321 *
3322 *	Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
3323 *
3324 *	Returns 0 for success, non-zero for failure.
3325 */
3326static int
3327SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
3328{
3329	IOCInit_t		 ioc_init;
3330	MPIDefaultReply_t	 init_reply;
3331	u32			 state;
3332	int			 r;
3333	int			 count;
3334	int			 cntdn;
3335
3336	memset(&ioc_init, 0, sizeof(ioc_init));
3337	memset(&init_reply, 0, sizeof(init_reply));
3338
3339	ioc_init.WhoInit = MPI_WHOINIT_HOST_DRIVER;
3340	ioc_init.Function = MPI_FUNCTION_IOC_INIT;
3341
3342	/* If we are in a recovery mode and we uploaded the FW image,
3343	 * then this pointer is not NULL. Skip the upload a second time.
3344	 * Set this flag if cached_fw set for either IOC.
3345	 */
3346	if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
3347		ioc->upload_fw = 1;
3348	else
3349		ioc->upload_fw = 0;
3350	ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "upload_fw %d facts.Flags=%x\n",
3351		   ioc->name, ioc->upload_fw, ioc->facts.Flags));
3352
3353	ioc_init.MaxDevices = (U8)ioc->devices_per_bus;
3354	ioc_init.MaxBuses = (U8)ioc->number_of_buses;
3355
3356	dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "facts.MsgVersion=%x\n",
3357		   ioc->name, ioc->facts.MsgVersion));
3358	if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) {
3359		// set MsgVersion and HeaderVersion host driver was built with
3360		ioc_init.MsgVersion = cpu_to_le16(MPI_VERSION);
3361	        ioc_init.HeaderVersion = cpu_to_le16(MPI_HEADER_VERSION);
3362
3363		if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT) {
3364			ioc_init.HostPageBufferSGE = ioc->facts.HostPageBufferSGE;
3365		} else if(mpt_host_page_alloc(ioc, &ioc_init))
3366			return -99;
3367	}
3368	ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz);	/* in BYTES */
3369
3370	if (ioc->sg_addr_size == sizeof(u64)) {
3371		/* Save the upper 32-bits of the request
3372		 * (reply) and sense buffers.
3373		 */
3374		ioc_init.HostMfaHighAddr = cpu_to_le32((u32)((u64)ioc->alloc_dma >> 32));
3375		ioc_init.SenseBufferHighAddr = cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
3376	} else {
3377		/* Force 32-bit addressing */
3378		ioc_init.HostMfaHighAddr = cpu_to_le32(0);
3379		ioc_init.SenseBufferHighAddr = cpu_to_le32(0);
3380	}
3381
3382	ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr;
3383	ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr;
3384	ioc->facts.MaxDevices = ioc_init.MaxDevices;
3385	ioc->facts.MaxBuses = ioc_init.MaxBuses;
3386
3387	dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOCInit (req @ %p)\n",
3388			ioc->name, &ioc_init));
3389
3390	r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
3391				sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag);
3392	if (r != 0) {
3393		printk(MYIOC_s_ERR_FMT "Sending IOCInit failed(%d)!\n",ioc->name, r);
3394		return r;
3395	}
3396
3397	/* No need to byte swap the multibyte fields in the reply
3398	 * since we don't even look at its contents.
3399	 */
3400
3401	dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending PortEnable (req @ %p)\n",
3402			ioc->name, &ioc_init));
3403
3404	if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0) {
3405		printk(MYIOC_s_ERR_FMT "Sending PortEnable failed(%d)!\n",ioc->name, r);
3406		return r;
3407	}
3408
3409	/* YIKES!  SUPER IMPORTANT!!!
3410	 *  Poll IocState until _OPERATIONAL while IOC is doing
3411	 *  LoopInit and TargetDiscovery!
3412	 */
3413	count = 0;
3414	cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 60;	/* 60 seconds */
3415	state = mpt_GetIocState(ioc, 1);
3416	while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) {
3417		if (sleepFlag == CAN_SLEEP) {
3418			msleep(1);
3419		} else {
3420			mdelay(1);
3421		}
3422
3423		if (!cntdn) {
3424			printk(MYIOC_s_ERR_FMT "Wait IOC_OP state timeout(%d)!\n",
3425					ioc->name, (int)((count+5)/HZ));
3426			return -9;
3427		}
3428
3429		state = mpt_GetIocState(ioc, 1);
3430		count++;
3431	}
3432	dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wait IOC_OPERATIONAL state (cnt=%d)\n",
3433			ioc->name, count));
3434
3435	ioc->aen_event_read_flag=0;
3436	return r;
3437}
3438
3439/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3440/**
3441 *	SendPortEnable - Send PortEnable request to MPT adapter port.
3442 *	@ioc: Pointer to MPT_ADAPTER structure
3443 *	@portnum: Port number to enable
3444 *	@sleepFlag: Specifies whether the process can sleep
3445 *
3446 *	Send PortEnable to bring IOC to OPERATIONAL state.
3447 *
3448 *	Returns 0 for success, non-zero for failure.
3449 */
3450static int
3451SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
3452{
3453	PortEnable_t		 port_enable;
3454	MPIDefaultReply_t	 reply_buf;
3455	int	 rc;
3456	int	 req_sz;
3457	int	 reply_sz;
3458
3459	/*  Destination...  */
3460	reply_sz = sizeof(MPIDefaultReply_t);
3461	memset(&reply_buf, 0, reply_sz);
3462
3463	req_sz = sizeof(PortEnable_t);
3464	memset(&port_enable, 0, req_sz);
3465
3466	port_enable.Function = MPI_FUNCTION_PORT_ENABLE;
3467	port_enable.PortNumber = portnum;
3468/*	port_enable.ChainOffset = 0;		*/
3469/*	port_enable.MsgFlags = 0;		*/
3470/*	port_enable.MsgContext = 0;		*/
3471
3472	dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Port(%d)Enable (req @ %p)\n",
3473			ioc->name, portnum, &port_enable));
3474
3475	/* RAID FW may take a long time to enable
3476	 */
3477	if (ioc->ir_firmware || ioc->bus_type == SAS) {
3478		rc = mpt_handshake_req_reply_wait(ioc, req_sz,
3479		(u32*)&port_enable, reply_sz, (u16*)&reply_buf,
3480		300 /*seconds*/, sleepFlag);
3481	} else {
3482		rc = mpt_handshake_req_reply_wait(ioc, req_sz,
3483		(u32*)&port_enable, reply_sz, (u16*)&reply_buf,
3484		30 /*seconds*/, sleepFlag);
3485	}
3486	return rc;
3487}
3488
3489/**
3490 *	mpt_alloc_fw_memory - allocate firmware memory
3491 *	@ioc: Pointer to MPT_ADAPTER structure
3492 *      @size: total FW bytes
3493 *
3494 *	If memory has already been allocated, the same (cached) value
3495 *	is returned.
3496 *
3497 *	Return 0 if successful, or non-zero for failure
3498 **/
3499int
3500mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
3501{
3502	int rc;
3503
3504	if (ioc->cached_fw) {
3505		rc = 0;  /* use already allocated memory */
3506		goto out;
3507	}
3508	else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
3509		ioc->cached_fw = ioc->alt_ioc->cached_fw;  /* use alt_ioc's memory */
3510		ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma;
3511		rc = 0;
3512		goto out;
3513	}
3514	ioc->cached_fw = dma_alloc_coherent(&ioc->pcidev->dev, size,
3515					    &ioc->cached_fw_dma, GFP_ATOMIC);
3516	if (!ioc->cached_fw) {
3517		printk(MYIOC_s_ERR_FMT "Unable to allocate memory for the cached firmware image!\n",
3518		    ioc->name);
3519		rc = -1;
3520	} else {
3521		dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "FW Image  @ %p[%p], sz=%d[%x] bytes\n",
3522		    ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, size, size));
3523		ioc->alloc_total += size;
3524		rc = 0;
3525	}
3526 out:
3527	return rc;
3528}
3529
3530/**
3531 *	mpt_free_fw_memory - free firmware memory
3532 *	@ioc: Pointer to MPT_ADAPTER structure
3533 *
3534 *	If alt_img is NULL, delete from ioc structure.
3535 *	Else, delete a secondary image in same format.
3536 **/
3537void
3538mpt_free_fw_memory(MPT_ADAPTER *ioc)
3539{
3540	int sz;
3541
3542	if (!ioc->cached_fw)
3543		return;
3544
3545	sz = ioc->facts.FWImageSize;
3546	dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "free_fw_memory: FW Image  @ %p[%p], sz=%d[%x] bytes\n",
3547		 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3548	dma_free_coherent(&ioc->pcidev->dev, sz, ioc->cached_fw,
3549			  ioc->cached_fw_dma);
3550	ioc->alloc_total -= sz;
3551	ioc->cached_fw = NULL;
3552}
3553
3554/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3555/**
3556 *	mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
3557 *	@ioc: Pointer to MPT_ADAPTER structure
3558 *	@sleepFlag: Specifies whether the process can sleep
3559 *
3560 *	Returns 0 for success, >0 for handshake failure
3561 *		<0 for fw upload failure.
3562 *
3563 *	Remark: If bound IOC and a successful FWUpload was performed
3564 *	on the bound IOC, the second image is discarded
3565 *	and memory is free'd. Both channels must upload to prevent
3566 *	IOC from running in degraded mode.
3567 */
3568static int
3569mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
3570{
3571	u8			 reply[sizeof(FWUploadReply_t)];
3572	FWUpload_t		*prequest;
3573	FWUploadReply_t		*preply;
3574	FWUploadTCSGE_t		*ptcsge;
3575	u32			 flagsLength;
3576	int			 ii, sz, reply_sz;
3577	int			 cmdStatus;
3578	int			request_size;
3579	/* If the image size is 0, we are done.
3580	 */
3581	if ((sz = ioc->facts.FWImageSize) == 0)
3582		return 0;
3583
3584	if (mpt_alloc_fw_memory(ioc, ioc->facts.FWImageSize) != 0)
3585		return -ENOMEM;
3586
3587	dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": FW Image  @ %p[%p], sz=%d[%x] bytes\n",
3588	    ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3589
3590	prequest = (sleepFlag == NO_SLEEP) ? kzalloc(ioc->req_sz, GFP_ATOMIC) :
3591	    kzalloc(ioc->req_sz, GFP_KERNEL);
3592	if (!prequest) {
3593		dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "fw upload failed "
3594		    "while allocating memory \n", ioc->name));
3595		mpt_free_fw_memory(ioc);
3596		return -ENOMEM;
3597	}
3598
3599	preply = (FWUploadReply_t *)&reply;
3600
3601	reply_sz = sizeof(reply);
3602	memset(preply, 0, reply_sz);
3603
3604	prequest->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM;
3605	prequest->Function = MPI_FUNCTION_FW_UPLOAD;
3606
3607	ptcsge = (FWUploadTCSGE_t *) &prequest->SGL;
3608	ptcsge->DetailsLength = 12;
3609	ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
3610	ptcsge->ImageSize = cpu_to_le32(sz);
3611	ptcsge++;
3612
3613	flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz;
3614	ioc->add_sge((char *)ptcsge, flagsLength, ioc->cached_fw_dma);
3615	request_size = offsetof(FWUpload_t, SGL) + sizeof(FWUploadTCSGE_t) +
3616	    ioc->SGE_size;
3617	dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending FW Upload "
3618	    " (req @ %p) fw_size=%d mf_request_size=%d\n", ioc->name, prequest,
3619	    ioc->facts.FWImageSize, request_size));
3620	DBG_DUMP_FW_REQUEST_FRAME(ioc, (u32 *)prequest);
3621
3622	ii = mpt_handshake_req_reply_wait(ioc, request_size, (u32 *)prequest,
3623	    reply_sz, (u16 *)preply, 65 /*seconds*/, sleepFlag);
3624
3625	dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "FW Upload completed "
3626	    "rc=%x \n", ioc->name, ii));
3627
3628	cmdStatus = -EFAULT;
3629	if (ii == 0) {
3630		/* Handshake transfer was complete and successful.
3631		 * Check the Reply Frame.
3632		 */
3633		int status;
3634		status = le16_to_cpu(preply->IOCStatus) &
3635				MPI_IOCSTATUS_MASK;
3636		if (status == MPI_IOCSTATUS_SUCCESS &&
3637		    ioc->facts.FWImageSize ==
3638		    le32_to_cpu(preply->ActualImageSize))
3639				cmdStatus = 0;
3640	}
3641	dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": do_upload cmdStatus=%d \n",
3642			ioc->name, cmdStatus));
3643
3644
3645	if (cmdStatus) {
3646		ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "fw upload failed, "
3647		    "freeing image \n", ioc->name));
3648		mpt_free_fw_memory(ioc);
3649	}
3650	kfree(prequest);
3651
3652	return cmdStatus;
3653}
3654
3655/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3656/**
3657 *	mpt_downloadboot - DownloadBoot code
3658 *	@ioc: Pointer to MPT_ADAPTER structure
3659 *	@pFwHeader: Pointer to firmware header info
3660 *	@sleepFlag: Specifies whether the process can sleep
3661 *
3662 *	FwDownloadBoot requires Programmed IO access.
3663 *
3664 *	Returns 0 for success
3665 *		-1 FW Image size is 0
3666 *		-2 No valid cached_fw Pointer
3667 *		<0 for fw upload failure.
3668 */
3669static int
3670mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
3671{
3672	MpiExtImageHeader_t	*pExtImage;
3673	u32			 fwSize;
3674	u32			 diag0val;
3675	int			 count;
3676	u32			*ptrFw;
3677	u32			 diagRwData;
3678	u32			 nextImage;
3679	u32			 load_addr;
3680	u32 			 ioc_state=0;
3681
3682	ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
3683				ioc->name, pFwHeader->ImageSize, pFwHeader->ImageSize, pFwHeader));
3684
3685	CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3686	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3687	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3688	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3689	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3690	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3691
3692	CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM));
3693
3694	/* wait 1 msec */
3695	if (sleepFlag == CAN_SLEEP) {
3696		msleep(1);
3697	} else {
3698		mdelay (1);
3699	}
3700
3701	diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3702	CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3703
3704	for (count = 0; count < 30; count ++) {
3705		diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3706		if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3707			ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RESET_ADAPTER cleared, count=%d\n",
3708				ioc->name, count));
3709			break;
3710		}
3711		/* wait .1 sec */
3712		if (sleepFlag == CAN_SLEEP) {
3713			msleep (100);
3714		} else {
3715			mdelay (100);
3716		}
3717	}
3718
3719	if ( count == 30 ) {
3720		ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot failed! "
3721		"Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n",
3722		ioc->name, diag0val));
3723		return -3;
3724	}
3725
3726	CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3727	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3728	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3729	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3730	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3731	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3732
3733	/* Set the DiagRwEn and Disable ARM bits */
3734	CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
3735
3736	fwSize = (pFwHeader->ImageSize + 3)/4;
3737	ptrFw = (u32 *) pFwHeader;
3738
3739	/* Write the LoadStartAddress to the DiagRw Address Register
3740	 * using Programmed IO
3741	 */
3742	if (ioc->errata_flag_1064)
3743		pci_enable_io_access(ioc->pcidev);
3744
3745	CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->LoadStartAddress);
3746	ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "LoadStart addr written 0x%x \n",
3747		ioc->name, pFwHeader->LoadStartAddress));
3748
3749	ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write FW Image: 0x%x bytes @ %p\n",
3750				ioc->name, fwSize*4, ptrFw));
3751	while (fwSize--) {
3752		CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3753	}
3754
3755	nextImage = pFwHeader->NextImageHeaderOffset;
3756	while (nextImage) {
3757		pExtImage = (MpiExtImageHeader_t *) ((char *)pFwHeader + nextImage);
3758
3759		load_addr = pExtImage->LoadStartAddress;
3760
3761		fwSize = (pExtImage->ImageSize + 3) >> 2;
3762		ptrFw = (u32 *)pExtImage;
3763
3764		ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n",
3765						ioc->name, fwSize*4, fwSize*4, ptrFw, load_addr));
3766		CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr);
3767
3768		while (fwSize--) {
3769			CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3770		}
3771		nextImage = pExtImage->NextImageHeaderOffset;
3772	}
3773
3774	/* Write the IopResetVectorRegAddr */
3775	ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Addr=%x! \n", ioc->name, 	pFwHeader->IopResetRegAddr));
3776	CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->IopResetRegAddr);
3777
3778	/* Write the IopResetVectorValue */
3779	ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Value=%x! \n", ioc->name, pFwHeader->IopResetVectorValue));
3780	CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, pFwHeader->IopResetVectorValue);
3781
3782	/* Clear the internal flash bad bit - autoincrementing register,
3783	 * so must do two writes.
3784	 */
3785	if (ioc->bus_type == SPI) {
3786		/*
3787		 * 1030 and 1035 H/W errata, workaround to access
3788		 * the ClearFlashBadSignatureBit
3789		 */
3790		CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3791		diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
3792		diagRwData |= 0x40000000;
3793		CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3794		CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
3795
3796	} else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ {
3797		diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3798		CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val |
3799		    MPI_DIAG_CLEAR_FLASH_BAD_SIG);
3800
3801		/* wait 1 msec */
3802		if (sleepFlag == CAN_SLEEP) {
3803			msleep (1);
3804		} else {
3805			mdelay (1);
3806		}
3807	}
3808
3809	if (ioc->errata_flag_1064)
3810		pci_disable_io_access(ioc->pcidev);
3811
3812	diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3813	ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot diag0val=%x, "
3814		"turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
3815		ioc->name, diag0val));
3816	diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE);
3817	ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot now diag0val=%x\n",
3818		ioc->name, diag0val));
3819	CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3820
3821	/* Write 0xFF to reset the sequencer */
3822	CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3823
3824	if (ioc->bus_type == SAS) {
3825		ioc_state = mpt_GetIocState(ioc, 0);
3826		if ( (GetIocFacts(ioc, sleepFlag,
3827				MPT_HOSTEVENT_IOC_BRINGUP)) != 0 ) {
3828			ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "GetIocFacts failed: IocState=%x\n",
3829					ioc->name, ioc_state));
3830			return -EFAULT;
3831		}
3832	}
3833
3834	for (count=0; count<HZ*20; count++) {
3835		if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) {
3836			ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3837				"downloadboot successful! (count=%d) IocState=%x\n",
3838				ioc->name, count, ioc_state));
3839			if (ioc->bus_type == SAS) {
3840				return 0;
3841			}
3842			if ((SendIocInit(ioc, sleepFlag)) != 0) {
3843				ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3844					"downloadboot: SendIocInit failed\n",
3845					ioc->name));
3846				return -EFAULT;
3847			}
3848			ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3849					"downloadboot: SendIocInit successful\n",
3850					ioc->name));
3851			return 0;
3852		}
3853		if (sleepFlag == CAN_SLEEP) {
3854			msleep (10);
3855		} else {
3856			mdelay (10);
3857		}
3858	}
3859	ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3860		"downloadboot failed! IocState=%x\n",ioc->name, ioc_state));
3861	return -EFAULT;
3862}
3863
3864/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3865/**
3866 *	KickStart - Perform hard reset of MPT adapter.
3867 *	@ioc: Pointer to MPT_ADAPTER structure
3868 *	@force: Force hard reset
3869 *	@sleepFlag: Specifies whether the process can sleep
3870 *
3871 *	This routine places MPT adapter in diagnostic mode via the
3872 *	WriteSequence register, and then performs a hard reset of adapter
3873 *	via the Diagnostic register.
3874 *
3875 *	Inputs:   sleepflag - CAN_SLEEP (non-interrupt thread)
3876 *			or NO_SLEEP (interrupt thread, use mdelay)
3877 *		  force - 1 if doorbell active, board fault state
3878 *				board operational, IOC_RECOVERY or
3879 *				IOC_BRINGUP and there is an alt_ioc.
3880 *			  0 else
3881 *
3882 *	Returns:
3883 *		 1 - hard reset, READY
3884 *		 0 - no reset due to History bit, READY
3885 *		-1 - no reset due to History bit but not READY
3886 *		     OR reset but failed to come READY
3887 *		-2 - no reset, could not enter DIAG mode
3888 *		-3 - reset but bad FW bit
3889 */
3890static int
3891KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
3892{
3893	int hard_reset_done = 0;
3894	u32 ioc_state=0;
3895	int cnt,cntdn;
3896
3897	dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStarting!\n", ioc->name));
3898	if (ioc->bus_type == SPI) {
3899		/* Always issue a Msg Unit Reset first. This will clear some
3900		 * SCSI bus hang conditions.
3901		 */
3902		SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
3903
3904		if (sleepFlag == CAN_SLEEP) {
3905			msleep (1000);
3906		} else {
3907			mdelay (1000);
3908		}
3909	}
3910
3911	hard_reset_done = mpt_diag_reset(ioc, force, sleepFlag);
3912	if (hard_reset_done < 0)
3913		return hard_reset_done;
3914
3915	dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset successful!\n",
3916		ioc->name));
3917
3918	cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 2;	/* 2 seconds */
3919	for (cnt=0; cnt<cntdn; cnt++) {
3920		ioc_state = mpt_GetIocState(ioc, 1);
3921		if ((ioc_state == MPI_IOC_STATE_READY) || (ioc_state == MPI_IOC_STATE_OPERATIONAL)) {
3922			dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStart successful! (cnt=%d)\n",
3923 					ioc->name, cnt));
3924			return hard_reset_done;
3925		}
3926		if (sleepFlag == CAN_SLEEP) {
3927			msleep (10);
3928		} else {
3929			mdelay (10);
3930		}
3931	}
3932
3933	dinitprintk(ioc, printk(MYIOC_s_ERR_FMT "Failed to come READY after reset! IocState=%x\n",
3934		ioc->name, mpt_GetIocState(ioc, 0)));
3935	return -1;
3936}
3937
3938/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3939/**
3940 *	mpt_diag_reset - Perform hard reset of the adapter.
3941 *	@ioc: Pointer to MPT_ADAPTER structure
3942 *	@ignore: Set if to honor and clear to ignore
3943 *		the reset history bit
3944 *	@sleepFlag: CAN_SLEEP if called in a non-interrupt thread,
3945 *		else set to NO_SLEEP (use mdelay instead)
3946 *
3947 *	This routine places the adapter in diagnostic mode via the
3948 *	WriteSequence register and then performs a hard reset of adapter
3949 *	via the Diagnostic register. Adapter should be in ready state
3950 *	upon successful completion.
3951 *
3952 *	Returns:  1  hard reset successful
3953 *		  0  no reset performed because reset history bit set
3954 *		 -2  enabling diagnostic mode failed
3955 *		 -3  diagnostic reset failed
3956 */
3957static int
3958mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3959{
3960	u32 diag0val;
3961	u32 doorbell;
3962	int hard_reset_done = 0;
3963	int count = 0;
3964	u32 diag1val = 0;
3965	MpiFwHeader_t *cached_fw;	/* Pointer to FW */
3966	u8	 cb_idx;
3967
3968	/* Clear any existing interrupts */
3969	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3970
3971	if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) {
3972
3973		if (!ignore)
3974			return 0;
3975
3976		drsprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset "
3977			"address=%p\n",  ioc->name, __func__,
3978			&ioc->chip->Doorbell, &ioc->chip->Reset_1078));
3979		CHIPREG_WRITE32(&ioc->chip->Reset_1078, 0x07);
3980		if (sleepFlag == CAN_SLEEP)
3981			msleep(1);
3982		else
3983			mdelay(1);
3984
3985		/*
3986		 * Call each currently registered protocol IOC reset handler
3987		 * with pre-reset indication.
3988		 * NOTE: If we're doing _IOC_BRINGUP, there can be no
3989		 * MptResetHandlers[] registered yet.
3990		 */
3991		for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
3992			if (MptResetHandlers[cb_idx])
3993				(*(MptResetHandlers[cb_idx]))(ioc,
3994						MPT_IOC_PRE_RESET);
3995		}
3996
3997		for (count = 0; count < 60; count ++) {
3998			doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3999			doorbell &= MPI_IOC_STATE_MASK;
4000
4001			drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4002				"looking for READY STATE: doorbell=%x"
4003			        " count=%d\n",
4004				ioc->name, doorbell, count));
4005
4006			if (doorbell == MPI_IOC_STATE_READY) {
4007				return 1;
4008			}
4009
4010			/* wait 1 sec */
4011			if (sleepFlag == CAN_SLEEP)
4012				msleep(1000);
4013			else
4014				mdelay(1000);
4015		}
4016		return -1;
4017	}
4018
4019	/* Use "Diagnostic reset" method! (only thing available!) */
4020	diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4021
4022	if (ioc->debug_level & MPT_DEBUG) {
4023		if (ioc->alt_ioc)
4024			diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
4025		dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG1: diag0=%08x, diag1=%08x\n",
4026			ioc->name, diag0val, diag1val));
4027	}
4028
4029	/* Do the reset if we are told to ignore the reset history
4030	 * or if the reset history is 0
4031	 */
4032	if (ignore || !(diag0val & MPI_DIAG_RESET_HISTORY)) {
4033		while ((diag0val & MPI_DIAG_DRWE) == 0) {
4034			/* Write magic sequence to WriteSequence register
4035			 * Loop until in diagnostic mode
4036			 */
4037			CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
4038			CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
4039			CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
4040			CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
4041			CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
4042			CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
4043
4044			/* wait 100 msec */
4045			if (sleepFlag == CAN_SLEEP) {
4046				msleep (100);
4047			} else {
4048				mdelay (100);
4049			}
4050
4051			count++;
4052			if (count > 20) {
4053				printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
4054						ioc->name, diag0val);
4055				return -2;
4056
4057			}
4058
4059			diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4060
4061			dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
4062					ioc->name, diag0val));
4063		}
4064
4065		if (ioc->debug_level & MPT_DEBUG) {
4066			if (ioc->alt_ioc)
4067				diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
4068			dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG2: diag0=%08x, diag1=%08x\n",
4069				ioc->name, diag0val, diag1val));
4070		}
4071		/*
4072		 * Disable the ARM (Bug fix)
4073		 *
4074		 */
4075		CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM);
4076		mdelay(1);
4077
4078		/*
4079		 * Now hit the reset bit in the Diagnostic register
4080		 * (THE BIG HAMMER!) (Clears DRWE bit).
4081		 */
4082		CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
4083		hard_reset_done = 1;
4084		dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset performed\n",
4085				ioc->name));
4086
4087		/*
4088		 * Call each currently registered protocol IOC reset handler
4089		 * with pre-reset indication.
4090		 * NOTE: If we're doing _IOC_BRINGUP, there can be no
4091		 * MptResetHandlers[] registered yet.
4092		 */
4093		for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
4094			if (MptResetHandlers[cb_idx]) {
4095				mpt_signal_reset(cb_idx,
4096					ioc, MPT_IOC_PRE_RESET);
4097				if (ioc->alt_ioc) {
4098					mpt_signal_reset(cb_idx,
4099					ioc->alt_ioc, MPT_IOC_PRE_RESET);
4100				}
4101			}
4102		}
4103
4104		if (ioc->cached_fw)
4105			cached_fw = (MpiFwHeader_t *)ioc->cached_fw;
4106		else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
4107			cached_fw = (MpiFwHeader_t *)ioc->alt_ioc->cached_fw;
4108		else
4109			cached_fw = NULL;
4110		if (cached_fw) {
4111			/* If the DownloadBoot operation fails, the
4112			 * IOC will be left unusable. This is a fatal error
4113			 * case.  _diag_reset will return < 0
4114			 */
4115			for (count = 0; count < 30; count ++) {
4116				diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4117				if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
4118					break;
4119				}
4120
4121				dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "cached_fw: diag0val=%x count=%d\n",
4122					ioc->name, diag0val, count));
4123				/* wait 1 sec */
4124				if (sleepFlag == CAN_SLEEP) {
4125					msleep (1000);
4126				} else {
4127					mdelay (1000);
4128				}
4129			}
4130			if ((count = mpt_downloadboot(ioc, cached_fw, sleepFlag)) < 0) {
4131				printk(MYIOC_s_WARN_FMT
4132					"firmware downloadboot failure (%d)!\n", ioc->name, count);
4133			}
4134
4135		} else {
4136			/* Wait for FW to reload and for board
4137			 * to go to the READY state.
4138			 * Maximum wait is 60 seconds.
4139			 * If fail, no error will check again
4140			 * with calling program.
4141			 */
4142			for (count = 0; count < 60; count ++) {
4143				doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
4144				doorbell &= MPI_IOC_STATE_MASK;
4145
4146				drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4147				    "looking for READY STATE: doorbell=%x"
4148				    " count=%d\n", ioc->name, doorbell, count));
4149
4150				if (doorbell == MPI_IOC_STATE_READY) {
4151					break;
4152				}
4153
4154				/* wait 1 sec */
4155				if (sleepFlag == CAN_SLEEP) {
4156					msleep (1000);
4157				} else {
4158					mdelay (1000);
4159				}
4160			}
4161
4162			if (doorbell != MPI_IOC_STATE_READY)
4163				printk(MYIOC_s_ERR_FMT "Failed to come READY "
4164				    "after reset! IocState=%x", ioc->name,
4165				    doorbell);
4166		}
4167	}
4168
4169	diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4170	if (ioc->debug_level & MPT_DEBUG) {
4171		if (ioc->alt_ioc)
4172			diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
4173		dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG3: diag0=%08x, diag1=%08x\n",
4174			ioc->name, diag0val, diag1val));
4175	}
4176
4177	/* Clear RESET_HISTORY bit!  Place board in the
4178	 * diagnostic mode to update the diag register.
4179	 */
4180	diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4181	count = 0;
4182	while ((diag0val & MPI_DIAG_DRWE) == 0) {
4183		/* Write magic sequence to WriteSequence register
4184		 * Loop until in diagnostic mode
4185		 */
4186		CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
4187		CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
4188		CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
4189		CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
4190		CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
4191		CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
4192
4193		/* wait 100 msec */
4194		if (sleepFlag == CAN_SLEEP) {
4195			msleep (100);
4196		} else {
4197			mdelay (100);
4198		}
4199
4200		count++;
4201		if (count > 20) {
4202			printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
4203					ioc->name, diag0val);
4204			break;
4205		}
4206		diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4207	}
4208	diag0val &= ~MPI_DIAG_RESET_HISTORY;
4209	CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
4210	diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4211	if (diag0val & MPI_DIAG_RESET_HISTORY) {
4212		printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n",
4213				ioc->name);
4214	}
4215
4216	/* Disable Diagnostic Mode
4217	 */
4218	CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFFFFFFFF);
4219
4220	/* Check FW reload status flags.
4221	 */
4222	diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4223	if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
4224		printk(MYIOC_s_ERR_FMT "Diagnostic reset FAILED! (%02xh)\n",
4225				ioc->name, diag0val);
4226		return -3;
4227	}
4228
4229	if (ioc->debug_level & MPT_DEBUG) {
4230		if (ioc->alt_ioc)
4231			diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
4232		dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG4: diag0=%08x, diag1=%08x\n",
4233			ioc->name, diag0val, diag1val));
4234	}
4235
4236	/*
4237	 * Reset flag that says we've enabled event notification
4238	 */
4239	ioc->facts.EventState = 0;
4240
4241	if (ioc->alt_ioc)
4242		ioc->alt_ioc->facts.EventState = 0;
4243
4244	return hard_reset_done;
4245}
4246
4247/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4248/**
4249 *	SendIocReset - Send IOCReset request to MPT adapter.
4250 *	@ioc: Pointer to MPT_ADAPTER structure
4251 *	@reset_type: reset type, expected values are
4252 *	%MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
4253 *	@sleepFlag: Specifies whether the process can sleep
4254 *
4255 *	Send IOCReset request to the MPT adapter.
4256 *
4257 *	Returns 0 for success, non-zero for failure.
4258 */
4259static int
4260SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
4261{
4262	int r;
4263	u32 state;
4264	int cntdn, count;
4265
4266	drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOC reset(0x%02x)!\n",
4267			ioc->name, reset_type));
4268	CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
4269	if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4270		return r;
4271
4272	/* FW ACK'd request, wait for READY state
4273	 */
4274	count = 0;
4275	cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15;	/* 15 seconds */
4276
4277	while ((state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
4278		cntdn--;
4279		count++;
4280		if (!cntdn) {
4281			if (sleepFlag != CAN_SLEEP)
4282				count *= 10;
4283
4284			printk(MYIOC_s_ERR_FMT
4285			    "Wait IOC_READY state (0x%x) timeout(%d)!\n",
4286			    ioc->name, state, (int)((count+5)/HZ));
4287			return -ETIME;
4288		}
4289
4290		if (sleepFlag == CAN_SLEEP) {
4291			msleep(1);
4292		} else {
4293			mdelay (1);	/* 1 msec delay */
4294		}
4295	}
4296
4297	/* TODO!
4298	 *  Cleanup all event stuff for this IOC; re-issue EventNotification
4299	 *  request if needed.
4300	 */
4301	if (ioc->facts.Function)
4302		ioc->facts.EventState = 0;
4303
4304	return 0;
4305}
4306
4307/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4308/**
4309 *	initChainBuffers - Allocate memory for and initialize chain buffers
4310 *	@ioc: Pointer to MPT_ADAPTER structure
4311 *
4312 *	Allocates memory for and initializes chain buffers,
4313 *	chain buffer control arrays and spinlock.
4314 */
4315static int
4316initChainBuffers(MPT_ADAPTER *ioc)
4317{
4318	u8		*mem;
4319	int		sz, ii, num_chain;
4320	int 		scale, num_sge, numSGE;
4321
4322	/* ReqToChain size must equal the req_depth
4323	 * index = req_idx
4324	 */
4325	if (ioc->ReqToChain == NULL) {
4326		sz = ioc->req_depth * sizeof(int);
4327		mem = kmalloc(sz, GFP_ATOMIC);
4328		if (mem == NULL)
4329			return -1;
4330
4331		ioc->ReqToChain = (int *) mem;
4332		dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReqToChain alloc  @ %p, sz=%d bytes\n",
4333			 	ioc->name, mem, sz));
4334		mem = kmalloc(sz, GFP_ATOMIC);
4335		if (mem == NULL)
4336			return -1;
4337
4338		ioc->RequestNB = (int *) mem;
4339		dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestNB alloc  @ %p, sz=%d bytes\n",
4340			 	ioc->name, mem, sz));
4341	}
4342	for (ii = 0; ii < ioc->req_depth; ii++) {
4343		ioc->ReqToChain[ii] = MPT_HOST_NO_CHAIN;
4344	}
4345
4346	/* ChainToChain size must equal the total number
4347	 * of chain buffers to be allocated.
4348	 * index = chain_idx
4349	 *
4350	 * Calculate the number of chain buffers needed(plus 1) per I/O
4351	 * then multiply the maximum number of simultaneous cmds
4352	 *
4353	 * num_sge = num sge in request frame + last chain buffer
4354	 * scale = num sge per chain buffer if no chain element
4355	 */
4356	scale = ioc->req_sz / ioc->SGE_size;
4357	if (ioc->sg_addr_size == sizeof(u64))
4358		num_sge =  scale + (ioc->req_sz - 60) / ioc->SGE_size;
4359	else
4360		num_sge =  1 + scale + (ioc->req_sz - 64) / ioc->SGE_size;
4361
4362	if (ioc->sg_addr_size == sizeof(u64)) {
4363		numSGE = (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
4364			(ioc->req_sz - 60) / ioc->SGE_size;
4365	} else {
4366		numSGE = 1 + (scale - 1) * (ioc->facts.MaxChainDepth-1) +
4367		    scale + (ioc->req_sz - 64) / ioc->SGE_size;
4368	}
4369	dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "num_sge=%d numSGE=%d\n",
4370		ioc->name, num_sge, numSGE));
4371
4372	if (ioc->bus_type == FC) {
4373		if (numSGE > MPT_SCSI_FC_SG_DEPTH)
4374			numSGE = MPT_SCSI_FC_SG_DEPTH;
4375	} else {
4376		if (numSGE > MPT_SCSI_SG_DEPTH)
4377			numSGE = MPT_SCSI_SG_DEPTH;
4378	}
4379
4380	num_chain = 1;
4381	while (numSGE - num_sge > 0) {
4382		num_chain++;
4383		num_sge += (scale - 1);
4384	}
4385	num_chain++;
4386
4387	dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Now numSGE=%d num_sge=%d num_chain=%d\n",
4388		ioc->name, numSGE, num_sge, num_chain));
4389
4390	if (ioc->bus_type == SPI)
4391		num_chain *= MPT_SCSI_CAN_QUEUE;
4392	else if (ioc->bus_type == SAS)
4393		num_chain *= MPT_SAS_CAN_QUEUE;
4394	else
4395		num_chain *= MPT_FC_CAN_QUEUE;
4396
4397	ioc->num_chain = num_chain;
4398
4399	sz = num_chain * sizeof(int);
4400	if (ioc->ChainToChain == NULL) {
4401		mem = kmalloc(sz, GFP_ATOMIC);
4402		if (mem == NULL)
4403			return -1;
4404
4405		ioc->ChainToChain = (int *) mem;
4406		dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainToChain alloc @ %p, sz=%d bytes\n",
4407			 	ioc->name, mem, sz));
4408	} else {
4409		mem = (u8 *) ioc->ChainToChain;
4410	}
4411	memset(mem, 0xFF, sz);
4412	return num_chain;
4413}
4414
4415/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4416/**
4417 *	PrimeIocFifos - Initialize IOC request and reply FIFOs.
4418 *	@ioc: Pointer to MPT_ADAPTER structure
4419 *
4420 *	This routine allocates memory for the MPT reply and request frame
4421 *	pools (if necessary), and primes the IOC reply FIFO with
4422 *	reply frames.
4423 *
4424 *	Returns 0 for success, non-zero for failure.
4425 */
4426static int
4427PrimeIocFifos(MPT_ADAPTER *ioc)
4428{
4429	MPT_FRAME_HDR *mf;
4430	unsigned long flags;
4431	dma_addr_t alloc_dma;
4432	u8 *mem;
4433	int i, reply_sz, sz, total_size, num_chain;
4434	u64	dma_mask;
4435
4436	dma_mask = 0;
4437
4438	/*  Prime reply FIFO...  */
4439
4440	if (ioc->reply_frames == NULL) {
4441		if ( (num_chain = initChainBuffers(ioc)) < 0)
4442			return -1;
4443		/*
4444		 * 1078 errata workaround for the 36GB limitation
4445		 */
4446		if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078 &&
4447		    ioc->dma_mask > DMA_BIT_MASK(35)) {
4448			if (!dma_set_mask(&ioc->pcidev->dev, DMA_BIT_MASK(32))
4449			    && !dma_set_coherent_mask(&ioc->pcidev->dev, DMA_BIT_MASK(32))) {
4450				dma_mask = DMA_BIT_MASK(35);
4451				d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4452				    "setting 35 bit addressing for "
4453				    "Request/Reply/Chain and Sense Buffers\n",
4454				    ioc->name));
4455			} else {
4456				/*Reseting DMA mask to 64 bit*/
4457				dma_set_mask(&ioc->pcidev->dev,
4458					     DMA_BIT_MASK(64));
4459				dma_set_coherent_mask(&ioc->pcidev->dev,
4460						      DMA_BIT_MASK(64));
4461
4462				printk(MYIOC_s_ERR_FMT
4463				    "failed setting 35 bit addressing for "
4464				    "Request/Reply/Chain and Sense Buffers\n",
4465				    ioc->name);
4466				return -1;
4467			}
4468		}
4469
4470		total_size = reply_sz = (ioc->reply_sz * ioc->reply_depth);
4471		dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
4472			 	ioc->name, ioc->reply_sz, ioc->reply_depth));
4473		dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d[%x] bytes\n",
4474			 	ioc->name, reply_sz, reply_sz));
4475
4476		sz = (ioc->req_sz * ioc->req_depth);
4477		dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d bytes, RequestDepth=%d\n",
4478			 	ioc->name, ioc->req_sz, ioc->req_depth));
4479		dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d[%x] bytes\n",
4480			 	ioc->name, sz, sz));
4481		total_size += sz;
4482
4483		sz = num_chain * ioc->req_sz; /* chain buffer pool size */
4484		dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d bytes, ChainDepth=%d\n",
4485			 	ioc->name, ioc->req_sz, num_chain));
4486		dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
4487			 	ioc->name, sz, sz, num_chain));
4488
4489		total_size += sz;
4490		mem = dma_alloc_coherent(&ioc->pcidev->dev, total_size,
4491				&alloc_dma, GFP_KERNEL);
4492		if (mem == NULL) {
4493			printk(MYIOC_s_ERR_FMT "Unable to allocate Reply, Request, Chain Buffers!\n",
4494				ioc->name);
4495			goto out_fail;
4496		}
4497
4498		dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Total alloc @ %p[%p], sz=%d[%x] bytes\n",
4499			 	ioc->name, mem, (void *)(ulong)alloc_dma, total_size, total_size));
4500
4501		memset(mem, 0, total_size);
4502		ioc->alloc_total += total_size;
4503		ioc->alloc = mem;
4504		ioc->alloc_dma = alloc_dma;
4505		ioc->alloc_sz = total_size;
4506		ioc->reply_frames = (MPT_FRAME_HDR *) mem;
4507		ioc->reply_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
4508
4509		dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n",
4510	 		ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
4511
4512		alloc_dma += reply_sz;
4513		mem += reply_sz;
4514
4515		/*  Request FIFO - WE manage this!  */
4516
4517		ioc->req_frames = (MPT_FRAME_HDR *) mem;
4518		ioc->req_frames_dma = alloc_dma;
4519
4520		dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffers @ %p[%p]\n",
4521			 	ioc->name, mem, (void *)(ulong)alloc_dma));
4522
4523		ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
4524
4525		for (i = 0; i < ioc->req_depth; i++) {
4526			alloc_dma += ioc->req_sz;
4527			mem += ioc->req_sz;
4528		}
4529
4530		ioc->ChainBuffer = mem;
4531		ioc->ChainBufferDMA = alloc_dma;
4532
4533		dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffers @ %p(%p)\n",
4534			ioc->name, ioc->ChainBuffer, (void *)(ulong)ioc->ChainBufferDMA));
4535
4536		/* Initialize the free chain Q.
4537	 	*/
4538
4539		INIT_LIST_HEAD(&ioc->FreeChainQ);
4540
4541		/* Post the chain buffers to the FreeChainQ.
4542	 	*/
4543		mem = (u8 *)ioc->ChainBuffer;
4544		for (i=0; i < num_chain; i++) {
4545			mf = (MPT_FRAME_HDR *) mem;
4546			list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeChainQ);
4547			mem += ioc->req_sz;
4548		}
4549
4550		/* Initialize Request frames linked list
4551		 */
4552		alloc_dma = ioc->req_frames_dma;
4553		mem = (u8 *) ioc->req_frames;
4554
4555		spin_lock_irqsave(&ioc->FreeQlock, flags);
4556		INIT_LIST_HEAD(&ioc->FreeQ);
4557		for (i = 0; i < ioc->req_depth; i++) {
4558			mf = (MPT_FRAME_HDR *) mem;
4559
4560			/*  Queue REQUESTs *internally*!  */
4561			list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
4562
4563			mem += ioc->req_sz;
4564		}
4565		spin_unlock_irqrestore(&ioc->FreeQlock, flags);
4566
4567		sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
4568		ioc->sense_buf_pool = dma_alloc_coherent(&ioc->pcidev->dev, sz,
4569				&ioc->sense_buf_pool_dma, GFP_KERNEL);
4570		if (ioc->sense_buf_pool == NULL) {
4571			printk(MYIOC_s_ERR_FMT "Unable to allocate Sense Buffers!\n",
4572				ioc->name);
4573			goto out_fail;
4574		}
4575
4576		ioc->sense_buf_low_dma = (u32) (ioc->sense_buf_pool_dma & 0xFFFFFFFF);
4577		ioc->alloc_total += sz;
4578		dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SenseBuffers @ %p[%p]\n",
4579 			ioc->name, ioc->sense_buf_pool, (void *)(ulong)ioc->sense_buf_pool_dma));
4580
4581	}
4582
4583	/* Post Reply frames to FIFO
4584	 */
4585	alloc_dma = ioc->alloc_dma;
4586	dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n",
4587	 	ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
4588
4589	for (i = 0; i < ioc->reply_depth; i++) {
4590		/*  Write each address to the IOC!  */
4591		CHIPREG_WRITE32(&ioc->chip->ReplyFifo, alloc_dma);
4592		alloc_dma += ioc->reply_sz;
4593	}
4594
4595	if (dma_mask == DMA_BIT_MASK(35) && !dma_set_mask(&ioc->pcidev->dev,
4596	    ioc->dma_mask) && !dma_set_coherent_mask(&ioc->pcidev->dev,
4597	    ioc->dma_mask))
4598		d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4599		    "restoring 64 bit addressing\n", ioc->name));
4600
4601	return 0;
4602
4603out_fail:
4604
4605	if (ioc->alloc != NULL) {
4606		sz = ioc->alloc_sz;
4607		dma_free_coherent(&ioc->pcidev->dev, sz, ioc->alloc,
4608				ioc->alloc_dma);
4609		ioc->reply_frames = NULL;
4610		ioc->req_frames = NULL;
4611		ioc->alloc_total -= sz;
4612	}
4613	if (ioc->sense_buf_pool != NULL) {
4614		sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
4615		dma_free_coherent(&ioc->pcidev->dev, sz, ioc->sense_buf_pool,
4616				ioc->sense_buf_pool_dma);
4617		ioc->sense_buf_pool = NULL;
4618	}
4619
4620	if (dma_mask == DMA_BIT_MASK(35) && !dma_set_mask(&ioc->pcidev->dev,
4621	    DMA_BIT_MASK(64)) && !dma_set_coherent_mask(&ioc->pcidev->dev,
4622	    DMA_BIT_MASK(64)))
4623		d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4624		    "restoring 64 bit addressing\n", ioc->name));
4625
4626	return -1;
4627}
4628
4629/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4630/**
4631 *	mpt_handshake_req_reply_wait - Send MPT request to and receive reply
4632 *	from IOC via doorbell handshake method.
4633 *	@ioc: Pointer to MPT_ADAPTER structure
4634 *	@reqBytes: Size of the request in bytes
4635 *	@req: Pointer to MPT request frame
4636 *	@replyBytes: Expected size of the reply in bytes
4637 *	@u16reply: Pointer to area where reply should be written
4638 *	@maxwait: Max wait time for a reply (in seconds)
4639 *	@sleepFlag: Specifies whether the process can sleep
4640 *
4641 *	NOTES: It is the callers responsibility to byte-swap fields in the
4642 *	request which are greater than 1 byte in size.  It is also the
4643 *	callers responsibility to byte-swap response fields which are
4644 *	greater than 1 byte in size.
4645 *
4646 *	Returns 0 for success, non-zero for failure.
4647 */
4648static int
4649mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
4650		int replyBytes, u16 *u16reply, int maxwait, int sleepFlag)
4651{
4652	MPIDefaultReply_t *mptReply;
4653	int failcnt = 0;
4654	int t;
4655
4656	/*
4657	 * Get ready to cache a handshake reply
4658	 */
4659	ioc->hs_reply_idx = 0;
4660	mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4661	mptReply->MsgLength = 0;
4662
4663	/*
4664	 * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
4665	 * then tell IOC that we want to handshake a request of N words.
4666	 * (WRITE u32val to Doorbell reg).
4667	 */
4668	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4669	CHIPREG_WRITE32(&ioc->chip->Doorbell,
4670			((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
4671			 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
4672
4673	/*
4674	 * Wait for IOC's doorbell handshake int
4675	 */
4676	if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4677		failcnt++;
4678
4679	dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
4680			ioc->name, reqBytes, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4681
4682	/* Read doorbell and check for active bit */
4683	if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
4684			return -1;
4685
4686	/*
4687	 * Clear doorbell int (WRITE 0 to IntStatus reg),
4688	 * then wait for IOC to ACKnowledge that it's ready for
4689	 * our handshake request.
4690	 */
4691	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4692	if (!failcnt && (t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4693		failcnt++;
4694
4695	if (!failcnt) {
4696		int	 ii;
4697		u8	*req_as_bytes = (u8 *) req;
4698
4699		/*
4700		 * Stuff request words via doorbell handshake,
4701		 * with ACK from IOC for each.
4702		 */
4703		for (ii = 0; !failcnt && ii < reqBytes/4; ii++) {
4704			u32 word = ((req_as_bytes[(ii*4) + 0] <<  0) |
4705				    (req_as_bytes[(ii*4) + 1] <<  8) |
4706				    (req_as_bytes[(ii*4) + 2] << 16) |
4707				    (req_as_bytes[(ii*4) + 3] << 24));
4708
4709			CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
4710			if ((t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4711				failcnt++;
4712		}
4713
4714		dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handshake request frame (@%p) header\n", ioc->name, req));
4715		DBG_DUMP_REQUEST_FRAME_HDR(ioc, (u32 *)req);
4716
4717		dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request post done, WaitCnt=%d%s\n",
4718				ioc->name, t, failcnt ? " - MISSING DOORBELL ACK!" : ""));
4719
4720		/*
4721		 * Wait for completion of doorbell handshake reply from the IOC
4722		 */
4723		if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0)
4724			failcnt++;
4725
4726		dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake reply count=%d%s\n",
4727				ioc->name, t, failcnt ? " - MISSING DOORBELL REPLY!" : ""));
4728
4729		/*
4730		 * Copy out the cached reply...
4731		 */
4732		for (ii=0; ii < min(replyBytes/2,mptReply->MsgLength*2); ii++)
4733			u16reply[ii] = ioc->hs_reply[ii];
4734	} else {
4735		return -99;
4736	}
4737
4738	return -failcnt;
4739}
4740
4741/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4742/**
4743 *	WaitForDoorbellAck - Wait for IOC doorbell handshake acknowledge
4744 *	@ioc: Pointer to MPT_ADAPTER structure
4745 *	@howlong: How long to wait (in seconds)
4746 *	@sleepFlag: Specifies whether the process can sleep
4747 *
4748 *	This routine waits (up to ~2 seconds max) for IOC doorbell
4749 *	handshake ACKnowledge, indicated by the IOP_DOORBELL_STATUS
4750 *	bit in its IntStatus register being clear.
4751 *
4752 *	Returns a negative value on failure, else wait loop count.
4753 */
4754static int
4755WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4756{
4757	int cntdn;
4758	int count = 0;
4759	u32 intstat=0;
4760
4761	cntdn = 1000 * howlong;
4762
4763	if (sleepFlag == CAN_SLEEP) {
4764		while (--cntdn) {
4765			msleep (1);
4766			intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4767			if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4768				break;
4769			count++;
4770		}
4771	} else {
4772		while (--cntdn) {
4773			udelay (1000);
4774			intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4775			if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4776				break;
4777			count++;
4778		}
4779	}
4780
4781	if (cntdn) {
4782		dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell ACK (count=%d)\n",
4783				ioc->name, count));
4784		return count;
4785	}
4786
4787	printk(MYIOC_s_ERR_FMT "Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
4788			ioc->name, count, intstat);
4789	return -1;
4790}
4791
4792/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4793/**
4794 *	WaitForDoorbellInt - Wait for IOC to set its doorbell interrupt bit
4795 *	@ioc: Pointer to MPT_ADAPTER structure
4796 *	@howlong: How long to wait (in seconds)
4797 *	@sleepFlag: Specifies whether the process can sleep
4798 *
4799 *	This routine waits (up to ~2 seconds max) for IOC doorbell interrupt
4800 *	(MPI_HIS_DOORBELL_INTERRUPT) to be set in the IntStatus register.
4801 *
4802 *	Returns a negative value on failure, else wait loop count.
4803 */
4804static int
4805WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4806{
4807	int cntdn;
4808	int count = 0;
4809	u32 intstat=0;
4810
4811	cntdn = 1000 * howlong;
4812	if (sleepFlag == CAN_SLEEP) {
4813		while (--cntdn) {
4814			intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4815			if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4816				break;
4817			msleep(1);
4818			count++;
4819		}
4820	} else {
4821		while (--cntdn) {
4822			intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4823			if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4824				break;
4825			udelay (1000);
4826			count++;
4827		}
4828	}
4829
4830	if (cntdn) {
4831		dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell INT (cnt=%d) howlong=%d\n",
4832				ioc->name, count, howlong));
4833		return count;
4834	}
4835
4836	printk(MYIOC_s_ERR_FMT "Doorbell INT timeout (count=%d), IntStatus=%x!\n",
4837			ioc->name, count, intstat);
4838	return -1;
4839}
4840
4841/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4842/**
4843 *	WaitForDoorbellReply - Wait for and capture an IOC handshake reply.
4844 *	@ioc: Pointer to MPT_ADAPTER structure
4845 *	@howlong: How long to wait (in seconds)
4846 *	@sleepFlag: Specifies whether the process can sleep
4847 *
4848 *	This routine polls the IOC for a handshake reply, 16 bits at a time.
4849 *	Reply is cached to IOC private area large enough to hold a maximum
4850 *	of 128 bytes of reply data.
4851 *
4852 *	Returns a negative value on failure, else size of reply in WORDS.
4853 */
4854static int
4855WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4856{
4857	int u16cnt = 0;
4858	int failcnt = 0;
4859	int t;
4860	u16 *hs_reply = ioc->hs_reply;
4861	volatile MPIDefaultReply_t *mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4862	u16 hword;
4863
4864	hs_reply[0] = hs_reply[1] = hs_reply[7] = 0;
4865
4866	/*
4867	 * Get first two u16's so we can look at IOC's intended reply MsgLength
4868	 */
4869	u16cnt=0;
4870	if ((t = WaitForDoorbellInt(ioc, howlong, sleepFlag)) < 0) {
4871		failcnt++;
4872	} else {
4873		hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4874		CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4875		if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4876			failcnt++;
4877		else {
4878			hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4879			CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4880		}
4881	}
4882
4883	dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitCnt=%d First handshake reply word=%08x%s\n",
4884			ioc->name, t, le32_to_cpu(*(u32 *)hs_reply),
4885			failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4886
4887	/*
4888	 * If no error (and IOC said MsgLength is > 0), piece together
4889	 * reply 16 bits at a time.
4890	 */
4891	for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
4892		if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4893			failcnt++;
4894		hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4895		/* don't overflow our IOC hs_reply[] buffer! */
4896		if (u16cnt < ARRAY_SIZE(ioc->hs_reply))
4897			hs_reply[u16cnt] = hword;
4898		CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4899	}
4900
4901	if (!failcnt && (t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4902		failcnt++;
4903	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4904
4905	if (failcnt) {
4906		printk(MYIOC_s_ERR_FMT "Handshake reply failure!\n",
4907				ioc->name);
4908		return -failcnt;
4909	}
4910#if 0
4911	else if (u16cnt != (2 * mptReply->MsgLength)) {
4912		return -101;
4913	}
4914	else if ((mptReply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
4915		return -102;
4916	}
4917#endif
4918
4919	dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got Handshake reply:\n", ioc->name));
4920	DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mptReply);
4921
4922	dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
4923			ioc->name, t, u16cnt/2));
4924	return u16cnt/2;
4925}
4926
4927/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4928/**
4929 *	GetLanConfigPages - Fetch LANConfig pages.
4930 *	@ioc: Pointer to MPT_ADAPTER structure
4931 *
4932 *	Return: 0 for success
4933 *	-ENOMEM if no memory available
4934 *		-EPERM if not allowed due to ISR context
4935 *		-EAGAIN if no msg frames currently available
4936 *		-EFAULT for non-successful reply or no reply (timeout)
4937 */
4938static int
4939GetLanConfigPages(MPT_ADAPTER *ioc)
4940{
4941	ConfigPageHeader_t	 hdr;
4942	CONFIGPARMS		 cfg;
4943	LANPage0_t		*ppage0_alloc;
4944	dma_addr_t		 page0_dma;
4945	LANPage1_t		*ppage1_alloc;
4946	dma_addr_t		 page1_dma;
4947	int			 rc = 0;
4948	int			 data_sz;
4949	int			 copy_sz;
4950
4951	/* Get LAN Page 0 header */
4952	hdr.PageVersion = 0;
4953	hdr.PageLength = 0;
4954	hdr.PageNumber = 0;
4955	hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4956	cfg.cfghdr.hdr = &hdr;
4957	cfg.physAddr = -1;
4958	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4959	cfg.dir = 0;
4960	cfg.pageAddr = 0;
4961	cfg.timeout = 0;
4962
4963	if ((rc = mpt_config(ioc, &cfg)) != 0)
4964		return rc;
4965
4966	if (hdr.PageLength > 0) {
4967		data_sz = hdr.PageLength * 4;
4968		ppage0_alloc = dma_alloc_coherent(&ioc->pcidev->dev, data_sz,
4969						  &page0_dma, GFP_KERNEL);
4970		rc = -ENOMEM;
4971		if (ppage0_alloc) {
4972			memset((u8 *)ppage0_alloc, 0, data_sz);
4973			cfg.physAddr = page0_dma;
4974			cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4975
4976			if ((rc = mpt_config(ioc, &cfg)) == 0) {
4977				/* save the data */
4978				copy_sz = min_t(int, sizeof(LANPage0_t), data_sz);
4979				memcpy(&ioc->lan_cnfg_page0, ppage0_alloc, copy_sz);
4980
4981			}
4982
4983			dma_free_coherent(&ioc->pcidev->dev, data_sz,
4984					  (u8 *)ppage0_alloc, page0_dma);
4985
4986			/* FIXME!
4987			 *	Normalize endianness of structure data,
4988			 *	by byte-swapping all > 1 byte fields!
4989			 */
4990
4991		}
4992
4993		if (rc)
4994			return rc;
4995	}
4996
4997	/* Get LAN Page 1 header */
4998	hdr.PageVersion = 0;
4999	hdr.PageLength = 0;
5000	hdr.PageNumber = 1;
5001	hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
5002	cfg.cfghdr.hdr = &hdr;
5003	cfg.physAddr = -1;
5004	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5005	cfg.dir = 0;
5006	cfg.pageAddr = 0;
5007
5008	if ((rc = mpt_config(ioc, &cfg)) != 0)
5009		return rc;
5010
5011	if (hdr.PageLength == 0)
5012		return 0;
5013
5014	data_sz = hdr.PageLength * 4;
5015	rc = -ENOMEM;
5016	ppage1_alloc = dma_alloc_coherent(&ioc->pcidev->dev, data_sz,
5017					  &page1_dma, GFP_KERNEL);
5018	if (ppage1_alloc) {
5019		memset((u8 *)ppage1_alloc, 0, data_sz);
5020		cfg.physAddr = page1_dma;
5021		cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5022
5023		if ((rc = mpt_config(ioc, &cfg)) == 0) {
5024			/* save the data */
5025			copy_sz = min_t(int, sizeof(LANPage1_t), data_sz);
5026			memcpy(&ioc->lan_cnfg_page1, ppage1_alloc, copy_sz);
5027		}
5028
5029		dma_free_coherent(&ioc->pcidev->dev, data_sz,
5030				  (u8 *)ppage1_alloc, page1_dma);
5031
5032		/* FIXME!
5033		 *	Normalize endianness of structure data,
5034		 *	by byte-swapping all > 1 byte fields!
5035		 */
5036
5037	}
5038
5039	return rc;
5040}
5041
5042/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5043/**
5044 *	mptbase_sas_persist_operation - Perform operation on SAS Persistent Table
5045 *	@ioc: Pointer to MPT_ADAPTER structure
5046 *	@persist_opcode: see below
5047 *
5048 *	===============================  ======================================
5049 *	MPI_SAS_OP_CLEAR_NOT_PRESENT     Free all persist TargetID mappings for
5050 *					 devices not currently present.
5051 *	MPI_SAS_OP_CLEAR_ALL_PERSISTENT  Clear al persist TargetID mappings
5052 *	===============================  ======================================
5053 *
5054 *	NOTE: Don't use not this function during interrupt time.
5055 *
5056 *	Returns 0 for success, non-zero error
5057 */
5058
5059/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5060int
5061mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode)
5062{
5063	SasIoUnitControlRequest_t	*sasIoUnitCntrReq;
5064	SasIoUnitControlReply_t		*sasIoUnitCntrReply;
5065	MPT_FRAME_HDR			*mf = NULL;
5066	MPIHeader_t			*mpi_hdr;
5067	int				ret = 0;
5068	unsigned long 	 		timeleft;
5069
5070	mutex_lock(&ioc->mptbase_cmds.mutex);
5071
5072	/* init the internal cmd struct */
5073	memset(ioc->mptbase_cmds.reply, 0 , MPT_DEFAULT_FRAME_SIZE);
5074	INITIALIZE_MGMT_STATUS(ioc->mptbase_cmds.status)
5075
5076	/* insure garbage is not sent to fw */
5077	switch(persist_opcode) {
5078
5079	case MPI_SAS_OP_CLEAR_NOT_PRESENT:
5080	case MPI_SAS_OP_CLEAR_ALL_PERSISTENT:
5081		break;
5082
5083	default:
5084		ret = -1;
5085		goto out;
5086	}
5087
5088	printk(KERN_DEBUG  "%s: persist_opcode=%x\n",
5089		__func__, persist_opcode);
5090
5091	/* Get a MF for this command.
5092	 */
5093	if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5094		printk(KERN_DEBUG "%s: no msg frames!\n", __func__);
5095		ret = -1;
5096		goto out;
5097        }
5098
5099	mpi_hdr = (MPIHeader_t *) mf;
5100	sasIoUnitCntrReq = (SasIoUnitControlRequest_t *)mf;
5101	memset(sasIoUnitCntrReq,0,sizeof(SasIoUnitControlRequest_t));
5102	sasIoUnitCntrReq->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
5103	sasIoUnitCntrReq->MsgContext = mpi_hdr->MsgContext;
5104	sasIoUnitCntrReq->Operation = persist_opcode;
5105
5106	mpt_put_msg_frame(mpt_base_index, ioc, mf);
5107	timeleft = wait_for_completion_timeout(&ioc->mptbase_cmds.done, 10*HZ);
5108	if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
5109		ret = -ETIME;
5110		printk(KERN_DEBUG "%s: failed\n", __func__);
5111		if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
5112			goto out;
5113		if (!timeleft) {
5114			printk(MYIOC_s_WARN_FMT
5115			       "Issuing Reset from %s!!, doorbell=0x%08x\n",
5116			       ioc->name, __func__, mpt_GetIocState(ioc, 0));
5117			mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
5118			mpt_free_msg_frame(ioc, mf);
5119		}
5120		goto out;
5121	}
5122
5123	if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
5124		ret = -1;
5125		goto out;
5126	}
5127
5128	sasIoUnitCntrReply =
5129	    (SasIoUnitControlReply_t *)ioc->mptbase_cmds.reply;
5130	if (le16_to_cpu(sasIoUnitCntrReply->IOCStatus) != MPI_IOCSTATUS_SUCCESS) {
5131		printk(KERN_DEBUG "%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
5132		    __func__, sasIoUnitCntrReply->IOCStatus,
5133		    sasIoUnitCntrReply->IOCLogInfo);
5134		printk(KERN_DEBUG "%s: failed\n", __func__);
5135		ret = -1;
5136	} else
5137		printk(KERN_DEBUG "%s: success\n", __func__);
5138 out:
5139
5140	CLEAR_MGMT_STATUS(ioc->mptbase_cmds.status)
5141	mutex_unlock(&ioc->mptbase_cmds.mutex);
5142	return ret;
5143}
5144
5145/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5146
5147static void
5148mptbase_raid_process_event_data(MPT_ADAPTER *ioc,
5149    MpiEventDataRaid_t * pRaidEventData)
5150{
5151	int 	volume;
5152	int 	reason;
5153	int 	disk;
5154	int 	status;
5155	int 	flags;
5156	int 	state;
5157
5158	volume	= pRaidEventData->VolumeID;
5159	reason	= pRaidEventData->ReasonCode;
5160	disk	= pRaidEventData->PhysDiskNum;
5161	status	= le32_to_cpu(pRaidEventData->SettingsStatus);
5162	flags	= (status >> 0) & 0xff;
5163	state	= (status >> 8) & 0xff;
5164
5165	if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
5166		return;
5167	}
5168
5169	if ((reason >= MPI_EVENT_RAID_RC_PHYSDISK_CREATED &&
5170	     reason <= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED) ||
5171	    (reason == MPI_EVENT_RAID_RC_SMART_DATA)) {
5172		printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for PhysDisk %d id=%d\n",
5173			ioc->name, disk, volume);
5174	} else {
5175		printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for VolumeID %d\n",
5176			ioc->name, volume);
5177	}
5178
5179	switch(reason) {
5180	case MPI_EVENT_RAID_RC_VOLUME_CREATED:
5181		printk(MYIOC_s_INFO_FMT "  volume has been created\n",
5182			ioc->name);
5183		break;
5184
5185	case MPI_EVENT_RAID_RC_VOLUME_DELETED:
5186
5187		printk(MYIOC_s_INFO_FMT "  volume has been deleted\n",
5188			ioc->name);
5189		break;
5190
5191	case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED:
5192		printk(MYIOC_s_INFO_FMT "  volume settings have been changed\n",
5193			ioc->name);
5194		break;
5195
5196	case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
5197		printk(MYIOC_s_INFO_FMT "  volume is now %s%s%s%s\n",
5198			ioc->name,
5199			state == MPI_RAIDVOL0_STATUS_STATE_OPTIMAL
5200			 ? "optimal"
5201			 : state == MPI_RAIDVOL0_STATUS_STATE_DEGRADED
5202			  ? "degraded"
5203			  : state == MPI_RAIDVOL0_STATUS_STATE_FAILED
5204			   ? "failed"
5205			   : "state unknown",
5206			flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED
5207			 ? ", enabled" : "",
5208			flags & MPI_RAIDVOL0_STATUS_FLAG_QUIESCED
5209			 ? ", quiesced" : "",
5210			flags & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
5211			 ? ", resync in progress" : "" );
5212		break;
5213
5214	case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED:
5215		printk(MYIOC_s_INFO_FMT "  volume membership of PhysDisk %d has changed\n",
5216			ioc->name, disk);
5217		break;
5218
5219	case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
5220		printk(MYIOC_s_INFO_FMT "  PhysDisk has been created\n",
5221			ioc->name);
5222		break;
5223
5224	case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
5225		printk(MYIOC_s_INFO_FMT "  PhysDisk has been deleted\n",
5226			ioc->name);
5227		break;
5228
5229	case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED:
5230		printk(MYIOC_s_INFO_FMT "  PhysDisk settings have been changed\n",
5231			ioc->name);
5232		break;
5233
5234	case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
5235		printk(MYIOC_s_INFO_FMT "  PhysDisk is now %s%s%s\n",
5236			ioc->name,
5237			state == MPI_PHYSDISK0_STATUS_ONLINE
5238			 ? "online"
5239			 : state == MPI_PHYSDISK0_STATUS_MISSING
5240			  ? "missing"
5241			  : state == MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE
5242			   ? "not compatible"
5243			   : state == MPI_PHYSDISK0_STATUS_FAILED
5244			    ? "failed"
5245			    : state == MPI_PHYSDISK0_STATUS_INITIALIZING
5246			     ? "initializing"
5247			     : state == MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED
5248			      ? "offline requested"
5249			      : state == MPI_PHYSDISK0_STATUS_FAILED_REQUESTED
5250			       ? "failed requested"
5251			       : state == MPI_PHYSDISK0_STATUS_OTHER_OFFLINE
5252			        ? "offline"
5253			        : "state unknown",
5254			flags & MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC
5255			 ? ", out of sync" : "",
5256			flags & MPI_PHYSDISK0_STATUS_FLAG_QUIESCED
5257			 ? ", quiesced" : "" );
5258		break;
5259
5260	case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED:
5261		printk(MYIOC_s_INFO_FMT "  Domain Validation needed for PhysDisk %d\n",
5262			ioc->name, disk);
5263		break;
5264
5265	case MPI_EVENT_RAID_RC_SMART_DATA:
5266		printk(MYIOC_s_INFO_FMT "  SMART data received, ASC/ASCQ = %02xh/%02xh\n",
5267			ioc->name, pRaidEventData->ASC, pRaidEventData->ASCQ);
5268		break;
5269
5270	case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED:
5271		printk(MYIOC_s_INFO_FMT "  replacement of PhysDisk %d has started\n",
5272			ioc->name, disk);
5273		break;
5274	}
5275}
5276
5277/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5278/**
5279 *	GetIoUnitPage2 - Retrieve BIOS version and boot order information.
5280 *	@ioc: Pointer to MPT_ADAPTER structure
5281 *
5282 *	Returns: 0 for success
5283 *	-ENOMEM if no memory available
5284 *		-EPERM if not allowed due to ISR context
5285 *		-EAGAIN if no msg frames currently available
5286 *		-EFAULT for non-successful reply or no reply (timeout)
5287 */
5288static int
5289GetIoUnitPage2(MPT_ADAPTER *ioc)
5290{
5291	ConfigPageHeader_t	 hdr;
5292	CONFIGPARMS		 cfg;
5293	IOUnitPage2_t		*ppage_alloc;
5294	dma_addr_t		 page_dma;
5295	int			 data_sz;
5296	int			 rc;
5297
5298	/* Get the page header */
5299	hdr.PageVersion = 0;
5300	hdr.PageLength = 0;
5301	hdr.PageNumber = 2;
5302	hdr.PageType = MPI_CONFIG_PAGETYPE_IO_UNIT;
5303	cfg.cfghdr.hdr = &hdr;
5304	cfg.physAddr = -1;
5305	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5306	cfg.dir = 0;
5307	cfg.pageAddr = 0;
5308	cfg.timeout = 0;
5309
5310	if ((rc = mpt_config(ioc, &cfg)) != 0)
5311		return rc;
5312
5313	if (hdr.PageLength == 0)
5314		return 0;
5315
5316	/* Read the config page */
5317	data_sz = hdr.PageLength * 4;
5318	rc = -ENOMEM;
5319	ppage_alloc = dma_alloc_coherent(&ioc->pcidev->dev, data_sz,
5320					 &page_dma, GFP_KERNEL);
5321	if (ppage_alloc) {
5322		memset((u8 *)ppage_alloc, 0, data_sz);
5323		cfg.physAddr = page_dma;
5324		cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5325
5326		/* If Good, save data */
5327		if ((rc = mpt_config(ioc, &cfg)) == 0)
5328			ioc->biosVersion = le32_to_cpu(ppage_alloc->BiosVersion);
5329
5330		dma_free_coherent(&ioc->pcidev->dev, data_sz,
5331				  (u8 *)ppage_alloc, page_dma);
5332	}
5333
5334	return rc;
5335}
5336
5337/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5338/**
5339 *	mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
5340 *	@ioc: Pointer to a Adapter Strucutre
5341 *	@portnum: IOC port number
5342 *
5343 *	Return: -EFAULT if read of config page header fails
5344 *			or if no nvram
5345 *	If read of SCSI Port Page 0 fails,
5346 *		NVRAM = MPT_HOST_NVRAM_INVALID  (0xFFFFFFFF)
5347 *		Adapter settings: async, narrow
5348 *		Return 1
5349 *	If read of SCSI Port Page 2 fails,
5350 *		Adapter settings valid
5351 *		NVRAM = MPT_HOST_NVRAM_INVALID  (0xFFFFFFFF)
5352 *		Return 1
5353 *	Else
5354 *		Both valid
5355 *		Return 0
5356 *	CHECK - what type of locking mechanisms should be used????
5357 */
5358static int
5359mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
5360{
5361	u8			*pbuf;
5362	dma_addr_t		 buf_dma;
5363	CONFIGPARMS		 cfg;
5364	ConfigPageHeader_t	 header;
5365	int			 ii;
5366	int			 data, rc = 0;
5367
5368	/* Allocate memory
5369	 */
5370	if (!ioc->spi_data.nvram) {
5371		int	 sz;
5372		u8	*mem;
5373		sz = MPT_MAX_SCSI_DEVICES * sizeof(int);
5374		mem = kmalloc(sz, GFP_ATOMIC);
5375		if (mem == NULL)
5376			return -EFAULT;
5377
5378		ioc->spi_data.nvram = (int *) mem;
5379
5380		dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SCSI device NVRAM settings @ %p, sz=%d\n",
5381			ioc->name, ioc->spi_data.nvram, sz));
5382	}
5383
5384	/* Invalidate NVRAM information
5385	 */
5386	for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5387		ioc->spi_data.nvram[ii] = MPT_HOST_NVRAM_INVALID;
5388	}
5389
5390	/* Read SPP0 header, allocate memory, then read page.
5391	 */
5392	header.PageVersion = 0;
5393	header.PageLength = 0;
5394	header.PageNumber = 0;
5395	header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
5396	cfg.cfghdr.hdr = &header;
5397	cfg.physAddr = -1;
5398	cfg.pageAddr = portnum;
5399	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5400	cfg.dir = 0;
5401	cfg.timeout = 0;	/* use default */
5402	if (mpt_config(ioc, &cfg) != 0)
5403		 return -EFAULT;
5404
5405	if (header.PageLength > 0) {
5406		pbuf = dma_alloc_coherent(&ioc->pcidev->dev,
5407					  header.PageLength * 4, &buf_dma,
5408					  GFP_KERNEL);
5409		if (pbuf) {
5410			cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5411			cfg.physAddr = buf_dma;
5412			if (mpt_config(ioc, &cfg) != 0) {
5413				ioc->spi_data.maxBusWidth = MPT_NARROW;
5414				ioc->spi_data.maxSyncOffset = 0;
5415				ioc->spi_data.minSyncFactor = MPT_ASYNC;
5416				ioc->spi_data.busType = MPT_HOST_BUS_UNKNOWN;
5417				rc = 1;
5418				ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5419					"Unable to read PortPage0 minSyncFactor=%x\n",
5420					ioc->name, ioc->spi_data.minSyncFactor));
5421			} else {
5422				/* Save the Port Page 0 data
5423				 */
5424				SCSIPortPage0_t  *pPP0 = (SCSIPortPage0_t  *) pbuf;
5425				pPP0->Capabilities = le32_to_cpu(pPP0->Capabilities);
5426				pPP0->PhysicalInterface = le32_to_cpu(pPP0->PhysicalInterface);
5427
5428				if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 ) {
5429					ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS;
5430					ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5431						"noQas due to Capabilities=%x\n",
5432						ioc->name, pPP0->Capabilities));
5433				}
5434				ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0;
5435				data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK;
5436				if (data) {
5437					ioc->spi_data.maxSyncOffset = (u8) (data >> 16);
5438					data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK;
5439					ioc->spi_data.minSyncFactor = (u8) (data >> 8);
5440					ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5441						"PortPage0 minSyncFactor=%x\n",
5442						ioc->name, ioc->spi_data.minSyncFactor));
5443				} else {
5444					ioc->spi_data.maxSyncOffset = 0;
5445					ioc->spi_data.minSyncFactor = MPT_ASYNC;
5446				}
5447
5448				ioc->spi_data.busType = pPP0->PhysicalInterface & MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK;
5449
5450				/* Update the minSyncFactor based on bus type.
5451				 */
5452				if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) ||
5453					(ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE))  {
5454
5455					if (ioc->spi_data.minSyncFactor < MPT_ULTRA) {
5456						ioc->spi_data.minSyncFactor = MPT_ULTRA;
5457						ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5458							"HVD or SE detected, minSyncFactor=%x\n",
5459							ioc->name, ioc->spi_data.minSyncFactor));
5460					}
5461				}
5462			}
5463			if (pbuf) {
5464				dma_free_coherent(&ioc->pcidev->dev,
5465						  header.PageLength * 4, pbuf,
5466						  buf_dma);
5467			}
5468		}
5469	}
5470
5471	/* SCSI Port Page 2 - Read the header then the page.
5472	 */
5473	header.PageVersion = 0;
5474	header.PageLength = 0;
5475	header.PageNumber = 2;
5476	header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
5477	cfg.cfghdr.hdr = &header;
5478	cfg.physAddr = -1;
5479	cfg.pageAddr = portnum;
5480	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5481	cfg.dir = 0;
5482	if (mpt_config(ioc, &cfg) != 0)
5483		return -EFAULT;
5484
5485	if (header.PageLength > 0) {
5486		/* Allocate memory and read SCSI Port Page 2
5487		 */
5488		pbuf = dma_alloc_coherent(&ioc->pcidev->dev,
5489					  header.PageLength * 4, &buf_dma,
5490					  GFP_KERNEL);
5491		if (pbuf) {
5492			cfg.action = MPI_CONFIG_ACTION_PAGE_READ_NVRAM;
5493			cfg.physAddr = buf_dma;
5494			if (mpt_config(ioc, &cfg) != 0) {
5495				/* Nvram data is left with INVALID mark
5496				 */
5497				rc = 1;
5498			} else if (ioc->pcidev->vendor == PCI_VENDOR_ID_ATTO) {
5499
5500				/* This is an ATTO adapter, read Page2 accordingly
5501				*/
5502				ATTO_SCSIPortPage2_t *pPP2 = (ATTO_SCSIPortPage2_t  *) pbuf;
5503				ATTODeviceInfo_t *pdevice = NULL;
5504				u16 ATTOFlags;
5505
5506				/* Save the Port Page 2 data
5507				 * (reformat into a 32bit quantity)
5508				 */
5509				for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5510				  pdevice = &pPP2->DeviceSettings[ii];
5511				  ATTOFlags = le16_to_cpu(pdevice->ATTOFlags);
5512				  data = 0;
5513
5514				  /* Translate ATTO device flags to LSI format
5515				   */
5516				  if (ATTOFlags & ATTOFLAG_DISC)
5517				    data |= (MPI_SCSIPORTPAGE2_DEVICE_DISCONNECT_ENABLE);
5518				  if (ATTOFlags & ATTOFLAG_ID_ENB)
5519				    data |= (MPI_SCSIPORTPAGE2_DEVICE_ID_SCAN_ENABLE);
5520				  if (ATTOFlags & ATTOFLAG_LUN_ENB)
5521				    data |= (MPI_SCSIPORTPAGE2_DEVICE_LUN_SCAN_ENABLE);
5522				  if (ATTOFlags & ATTOFLAG_TAGGED)
5523				    data |= (MPI_SCSIPORTPAGE2_DEVICE_TAG_QUEUE_ENABLE);
5524				  if (!(ATTOFlags & ATTOFLAG_WIDE_ENB))
5525				    data |= (MPI_SCSIPORTPAGE2_DEVICE_WIDE_DISABLE);
5526
5527				  data = (data << 16) | (pdevice->Period << 8) | 10;
5528				  ioc->spi_data.nvram[ii] = data;
5529				}
5530			} else {
5531				SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t  *) pbuf;
5532				MpiDeviceInfo_t	*pdevice = NULL;
5533
5534				/*
5535				 * Save "Set to Avoid SCSI Bus Resets" flag
5536				 */
5537				ioc->spi_data.bus_reset =
5538				    (le32_to_cpu(pPP2->PortFlags) &
5539			        MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET) ?
5540				    0 : 1 ;
5541
5542				/* Save the Port Page 2 data
5543				 * (reformat into a 32bit quantity)
5544				 */
5545				data = le32_to_cpu(pPP2->PortFlags) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK;
5546				ioc->spi_data.PortFlags = data;
5547				for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5548					pdevice = &pPP2->DeviceSettings[ii];
5549					data = (le16_to_cpu(pdevice->DeviceFlags) << 16) |
5550						(pdevice->SyncFactor << 8) | pdevice->Timeout;
5551					ioc->spi_data.nvram[ii] = data;
5552				}
5553			}
5554
5555			dma_free_coherent(&ioc->pcidev->dev,
5556					  header.PageLength * 4, pbuf,
5557					  buf_dma);
5558		}
5559	}
5560
5561	/* Update Adapter limits with those from NVRAM
5562	 * Comment: Don't need to do this. Target performance
5563	 * parameters will never exceed the adapters limits.
5564	 */
5565
5566	return rc;
5567}
5568
5569/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5570/**
5571 *	mpt_readScsiDevicePageHeaders - save version and length of SDP1
5572 *	@ioc: Pointer to a Adapter Strucutre
5573 *	@portnum: IOC port number
5574 *
5575 *	Return: -EFAULT if read of config page header fails
5576 *		or 0 if success.
5577 */
5578static int
5579mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
5580{
5581	CONFIGPARMS		 cfg;
5582	ConfigPageHeader_t	 header;
5583
5584	/* Read the SCSI Device Page 1 header
5585	 */
5586	header.PageVersion = 0;
5587	header.PageLength = 0;
5588	header.PageNumber = 1;
5589	header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
5590	cfg.cfghdr.hdr = &header;
5591	cfg.physAddr = -1;
5592	cfg.pageAddr = portnum;
5593	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5594	cfg.dir = 0;
5595	cfg.timeout = 0;
5596	if (mpt_config(ioc, &cfg) != 0)
5597		 return -EFAULT;
5598
5599	ioc->spi_data.sdp1version = cfg.cfghdr.hdr->PageVersion;
5600	ioc->spi_data.sdp1length = cfg.cfghdr.hdr->PageLength;
5601
5602	header.PageVersion = 0;
5603	header.PageLength = 0;
5604	header.PageNumber = 0;
5605	header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
5606	if (mpt_config(ioc, &cfg) != 0)
5607		 return -EFAULT;
5608
5609	ioc->spi_data.sdp0version = cfg.cfghdr.hdr->PageVersion;
5610	ioc->spi_data.sdp0length = cfg.cfghdr.hdr->PageLength;
5611
5612	dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 0: version %d length %d\n",
5613			ioc->name, ioc->spi_data.sdp0version, ioc->spi_data.sdp0length));
5614
5615	dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 1: version %d length %d\n",
5616			ioc->name, ioc->spi_data.sdp1version, ioc->spi_data.sdp1length));
5617	return 0;
5618}
5619
5620/**
5621 * mpt_inactive_raid_list_free - This clears this link list.
5622 * @ioc : pointer to per adapter structure
5623 **/
5624static void
5625mpt_inactive_raid_list_free(MPT_ADAPTER *ioc)
5626{
5627	struct inactive_raid_component_info *component_info, *pNext;
5628
5629	if (list_empty(&ioc->raid_data.inactive_list))
5630		return;
5631
5632	mutex_lock(&ioc->raid_data.inactive_list_mutex);
5633	list_for_each_entry_safe(component_info, pNext,
5634	    &ioc->raid_data.inactive_list, list) {
5635		list_del(&component_info->list);
5636		kfree(component_info);
5637	}
5638	mutex_unlock(&ioc->raid_data.inactive_list_mutex);
5639}
5640
5641/**
5642 * mpt_inactive_raid_volumes - sets up link list of phy_disk_nums for devices belonging in an inactive volume
5643 *
5644 * @ioc : pointer to per adapter structure
5645 * @channel : volume channel
5646 * @id : volume target id
5647 **/
5648static void
5649mpt_inactive_raid_volumes(MPT_ADAPTER *ioc, u8 channel, u8 id)
5650{
5651	CONFIGPARMS			cfg;
5652	ConfigPageHeader_t		hdr;
5653	dma_addr_t			dma_handle;
5654	pRaidVolumePage0_t		buffer = NULL;
5655	int				i;
5656	RaidPhysDiskPage0_t 		phys_disk;
5657	struct inactive_raid_component_info *component_info;
5658	int				handle_inactive_volumes;
5659
5660	memset(&cfg, 0 , sizeof(CONFIGPARMS));
5661	memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5662	hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
5663	cfg.pageAddr = (channel << 8) + id;
5664	cfg.cfghdr.hdr = &hdr;
5665	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5666
5667	if (mpt_config(ioc, &cfg) != 0)
5668		goto out;
5669
5670	if (!hdr.PageLength)
5671		goto out;
5672
5673	buffer = dma_alloc_coherent(&ioc->pcidev->dev, hdr.PageLength * 4,
5674				    &dma_handle, GFP_KERNEL);
5675
5676	if (!buffer)
5677		goto out;
5678
5679	cfg.physAddr = dma_handle;
5680	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5681
5682	if (mpt_config(ioc, &cfg) != 0)
5683		goto out;
5684
5685	if (!buffer->NumPhysDisks)
5686		goto out;
5687
5688	handle_inactive_volumes =
5689	   (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE ||
5690	   (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED) == 0 ||
5691	    buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_FAILED ||
5692	    buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_MISSING) ? 1 : 0;
5693
5694	if (!handle_inactive_volumes)
5695		goto out;
5696
5697	mutex_lock(&ioc->raid_data.inactive_list_mutex);
5698	for (i = 0; i < buffer->NumPhysDisks; i++) {
5699		if(mpt_raid_phys_disk_pg0(ioc,
5700		    buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
5701			continue;
5702
5703		if ((component_info = kmalloc(sizeof (*component_info),
5704		 GFP_KERNEL)) == NULL)
5705			continue;
5706
5707		component_info->volumeID = id;
5708		component_info->volumeBus = channel;
5709		component_info->d.PhysDiskNum = phys_disk.PhysDiskNum;
5710		component_info->d.PhysDiskBus = phys_disk.PhysDiskBus;
5711		component_info->d.PhysDiskID = phys_disk.PhysDiskID;
5712		component_info->d.PhysDiskIOC = phys_disk.PhysDiskIOC;
5713
5714		list_add_tail(&component_info->list,
5715		    &ioc->raid_data.inactive_list);
5716	}
5717	mutex_unlock(&ioc->raid_data.inactive_list_mutex);
5718
5719 out:
5720	if (buffer)
5721		dma_free_coherent(&ioc->pcidev->dev, hdr.PageLength * 4,
5722				  buffer, dma_handle);
5723}
5724
5725/**
5726 *	mpt_raid_phys_disk_pg0 - returns phys disk page zero
5727 *	@ioc: Pointer to a Adapter Structure
5728 *	@phys_disk_num: io unit unique phys disk num generated by the ioc
5729 *	@phys_disk: requested payload data returned
5730 *
5731 *	Return:
5732 *	0 on success
5733 *	-EFAULT if read of config page header fails or data pointer not NULL
5734 *	-ENOMEM if pci_alloc failed
5735 **/
5736int
5737mpt_raid_phys_disk_pg0(MPT_ADAPTER *ioc, u8 phys_disk_num,
5738			RaidPhysDiskPage0_t *phys_disk)
5739{
5740	CONFIGPARMS			cfg;
5741	ConfigPageHeader_t		hdr;
5742	dma_addr_t			dma_handle;
5743	pRaidPhysDiskPage0_t		buffer = NULL;
5744	int				rc;
5745
5746	memset(&cfg, 0 , sizeof(CONFIGPARMS));
5747	memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5748	memset(phys_disk, 0, sizeof(RaidPhysDiskPage0_t));
5749
5750	hdr.PageVersion = MPI_RAIDPHYSDISKPAGE0_PAGEVERSION;
5751	hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
5752	cfg.cfghdr.hdr = &hdr;
5753	cfg.physAddr = -1;
5754	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5755
5756	if (mpt_config(ioc, &cfg) != 0) {
5757		rc = -EFAULT;
5758		goto out;
5759	}
5760
5761	if (!hdr.PageLength) {
5762		rc = -EFAULT;
5763		goto out;
5764	}
5765
5766	buffer = dma_alloc_coherent(&ioc->pcidev->dev, hdr.PageLength * 4,
5767				    &dma_handle, GFP_KERNEL);
5768
5769	if (!buffer) {
5770		rc = -ENOMEM;
5771		goto out;
5772	}
5773
5774	cfg.physAddr = dma_handle;
5775	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5776	cfg.pageAddr = phys_disk_num;
5777
5778	if (mpt_config(ioc, &cfg) != 0) {
5779		rc = -EFAULT;
5780		goto out;
5781	}
5782
5783	rc = 0;
5784	memcpy(phys_disk, buffer, sizeof(*buffer));
5785	phys_disk->MaxLBA = le32_to_cpu(buffer->MaxLBA);
5786
5787 out:
5788
5789	if (buffer)
5790		dma_free_coherent(&ioc->pcidev->dev, hdr.PageLength * 4,
5791				  buffer, dma_handle);
5792
5793	return rc;
5794}
5795
5796/**
5797 *	mpt_raid_phys_disk_get_num_paths - returns number paths associated to this phys_num
5798 *	@ioc: Pointer to a Adapter Structure
5799 *	@phys_disk_num: io unit unique phys disk num generated by the ioc
5800 *
5801 *	Return:
5802 *	returns number paths
5803 **/
5804int
5805mpt_raid_phys_disk_get_num_paths(MPT_ADAPTER *ioc, u8 phys_disk_num)
5806{
5807	CONFIGPARMS		 	cfg;
5808	ConfigPageHeader_t	 	hdr;
5809	dma_addr_t			dma_handle;
5810	pRaidPhysDiskPage1_t		buffer = NULL;
5811	int				rc;
5812
5813	memset(&cfg, 0 , sizeof(CONFIGPARMS));
5814	memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5815
5816	hdr.PageVersion = MPI_RAIDPHYSDISKPAGE1_PAGEVERSION;
5817	hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
5818	hdr.PageNumber = 1;
5819	cfg.cfghdr.hdr = &hdr;
5820	cfg.physAddr = -1;
5821	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5822
5823	if (mpt_config(ioc, &cfg) != 0) {
5824		rc = 0;
5825		goto out;
5826	}
5827
5828	if (!hdr.PageLength) {
5829		rc = 0;
5830		goto out;
5831	}
5832
5833	buffer = dma_alloc_coherent(&ioc->pcidev->dev, hdr.PageLength * 4,
5834				    &dma_handle, GFP_KERNEL);
5835
5836	if (!buffer) {
5837		rc = 0;
5838		goto out;
5839	}
5840
5841	cfg.physAddr = dma_handle;
5842	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5843	cfg.pageAddr = phys_disk_num;
5844
5845	if (mpt_config(ioc, &cfg) != 0) {
5846		rc = 0;
5847		goto out;
5848	}
5849
5850	rc = buffer->NumPhysDiskPaths;
5851 out:
5852
5853	if (buffer)
5854		dma_free_coherent(&ioc->pcidev->dev, hdr.PageLength * 4,
5855				  buffer, dma_handle);
5856
5857	return rc;
5858}
5859EXPORT_SYMBOL(mpt_raid_phys_disk_get_num_paths);
5860
5861/**
5862 *	mpt_raid_phys_disk_pg1 - returns phys disk page 1
5863 *	@ioc: Pointer to a Adapter Structure
5864 *	@phys_disk_num: io unit unique phys disk num generated by the ioc
5865 *	@phys_disk: requested payload data returned
5866 *
5867 *	Return:
5868 *	0 on success
5869 *	-EFAULT if read of config page header fails or data pointer not NULL
5870 *	-ENOMEM if pci_alloc failed
5871 **/
5872int
5873mpt_raid_phys_disk_pg1(MPT_ADAPTER *ioc, u8 phys_disk_num,
5874		RaidPhysDiskPage1_t *phys_disk)
5875{
5876	CONFIGPARMS		 	cfg;
5877	ConfigPageHeader_t	 	hdr;
5878	dma_addr_t			dma_handle;
5879	pRaidPhysDiskPage1_t		buffer = NULL;
5880	int				rc;
5881	int				i;
5882	__le64				sas_address;
5883
5884	memset(&cfg, 0 , sizeof(CONFIGPARMS));
5885	memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5886	rc = 0;
5887
5888	hdr.PageVersion = MPI_RAIDPHYSDISKPAGE1_PAGEVERSION;
5889	hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
5890	hdr.PageNumber = 1;
5891	cfg.cfghdr.hdr = &hdr;
5892	cfg.physAddr = -1;
5893	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5894
5895	if (mpt_config(ioc, &cfg) != 0) {
5896		rc = -EFAULT;
5897		goto out;
5898	}
5899
5900	if (!hdr.PageLength) {
5901		rc = -EFAULT;
5902		goto out;
5903	}
5904
5905	buffer = dma_alloc_coherent(&ioc->pcidev->dev, hdr.PageLength * 4,
5906				    &dma_handle, GFP_KERNEL);
5907
5908	if (!buffer) {
5909		rc = -ENOMEM;
5910		goto out;
5911	}
5912
5913	cfg.physAddr = dma_handle;
5914	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5915	cfg.pageAddr = phys_disk_num;
5916
5917	if (mpt_config(ioc, &cfg) != 0) {
5918		rc = -EFAULT;
5919		goto out;
5920	}
5921
5922	phys_disk->NumPhysDiskPaths = buffer->NumPhysDiskPaths;
5923	phys_disk->PhysDiskNum = phys_disk_num;
5924	for (i = 0; i < phys_disk->NumPhysDiskPaths; i++) {
5925		phys_disk->Path[i].PhysDiskID = buffer->Path[i].PhysDiskID;
5926		phys_disk->Path[i].PhysDiskBus = buffer->Path[i].PhysDiskBus;
5927		phys_disk->Path[i].OwnerIdentifier =
5928				buffer->Path[i].OwnerIdentifier;
5929		phys_disk->Path[i].Flags = le16_to_cpu(buffer->Path[i].Flags);
5930		memcpy(&sas_address, &buffer->Path[i].WWID, sizeof(__le64));
5931		sas_address = le64_to_cpu(sas_address);
5932		memcpy(&phys_disk->Path[i].WWID, &sas_address, sizeof(__le64));
5933		memcpy(&sas_address,
5934				&buffer->Path[i].OwnerWWID, sizeof(__le64));
5935		sas_address = le64_to_cpu(sas_address);
5936		memcpy(&phys_disk->Path[i].OwnerWWID,
5937				&sas_address, sizeof(__le64));
5938	}
5939
5940 out:
5941
5942	if (buffer)
5943		dma_free_coherent(&ioc->pcidev->dev, hdr.PageLength * 4,
5944				  buffer, dma_handle);
5945
5946	return rc;
5947}
5948EXPORT_SYMBOL(mpt_raid_phys_disk_pg1);
5949
5950
5951/**
5952 *	mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
5953 *	@ioc: Pointer to a Adapter Strucutre
5954 *
5955 *	Return:
5956 *	0 on success
5957 *	-EFAULT if read of config page header fails or data pointer not NULL
5958 *	-ENOMEM if pci_alloc failed
5959 **/
5960int
5961mpt_findImVolumes(MPT_ADAPTER *ioc)
5962{
5963	IOCPage2_t		*pIoc2;
5964	u8			*mem;
5965	dma_addr_t		 ioc2_dma;
5966	CONFIGPARMS		 cfg;
5967	ConfigPageHeader_t	 header;
5968	int			 rc = 0;
5969	int			 iocpage2sz;
5970	int			 i;
5971
5972	if (!ioc->ir_firmware)
5973		return 0;
5974
5975	/* Free the old page
5976	 */
5977	kfree(ioc->raid_data.pIocPg2);
5978	ioc->raid_data.pIocPg2 = NULL;
5979	mpt_inactive_raid_list_free(ioc);
5980
5981	/* Read IOCP2 header then the page.
5982	 */
5983	header.PageVersion = 0;
5984	header.PageLength = 0;
5985	header.PageNumber = 2;
5986	header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5987	cfg.cfghdr.hdr = &header;
5988	cfg.physAddr = -1;
5989	cfg.pageAddr = 0;
5990	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5991	cfg.dir = 0;
5992	cfg.timeout = 0;
5993	if (mpt_config(ioc, &cfg) != 0)
5994		 return -EFAULT;
5995
5996	if (header.PageLength == 0)
5997		return -EFAULT;
5998
5999	iocpage2sz = header.PageLength * 4;
6000	pIoc2 = dma_alloc_coherent(&ioc->pcidev->dev, iocpage2sz, &ioc2_dma,
6001				   GFP_KERNEL);
6002	if (!pIoc2)
6003		return -ENOMEM;
6004
6005	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
6006	cfg.physAddr = ioc2_dma;
6007	if (mpt_config(ioc, &cfg) != 0)
6008		goto out;
6009
6010	mem = kmemdup(pIoc2, iocpage2sz, GFP_KERNEL);
6011	if (!mem) {
6012		rc = -ENOMEM;
6013		goto out;
6014	}
6015
6016	ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem;
6017
6018	mpt_read_ioc_pg_3(ioc);
6019
6020	for (i = 0; i < pIoc2->NumActiveVolumes ; i++)
6021		mpt_inactive_raid_volumes(ioc,
6022		    pIoc2->RaidVolume[i].VolumeBus,
6023		    pIoc2->RaidVolume[i].VolumeID);
6024
6025 out:
6026	dma_free_coherent(&ioc->pcidev->dev, iocpage2sz, pIoc2, ioc2_dma);
6027
6028	return rc;
6029}
6030
6031static int
6032mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
6033{
6034	IOCPage3_t		*pIoc3;
6035	u8			*mem;
6036	CONFIGPARMS		 cfg;
6037	ConfigPageHeader_t	 header;
6038	dma_addr_t		 ioc3_dma;
6039	int			 iocpage3sz = 0;
6040
6041	/* Free the old page
6042	 */
6043	kfree(ioc->raid_data.pIocPg3);
6044	ioc->raid_data.pIocPg3 = NULL;
6045
6046	/* There is at least one physical disk.
6047	 * Read and save IOC Page 3
6048	 */
6049	header.PageVersion = 0;
6050	header.PageLength = 0;
6051	header.PageNumber = 3;
6052	header.PageType = MPI_CONFIG_PAGETYPE_IOC;
6053	cfg.cfghdr.hdr = &header;
6054	cfg.physAddr = -1;
6055	cfg.pageAddr = 0;
6056	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
6057	cfg.dir = 0;
6058	cfg.timeout = 0;
6059	if (mpt_config(ioc, &cfg) != 0)
6060		return 0;
6061
6062	if (header.PageLength == 0)
6063		return 0;
6064
6065	/* Read Header good, alloc memory
6066	 */
6067	iocpage3sz = header.PageLength * 4;
6068	pIoc3 = dma_alloc_coherent(&ioc->pcidev->dev, iocpage3sz, &ioc3_dma,
6069				   GFP_KERNEL);
6070	if (!pIoc3)
6071		return 0;
6072
6073	/* Read the Page and save the data
6074	 * into malloc'd memory.
6075	 */
6076	cfg.physAddr = ioc3_dma;
6077	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
6078	if (mpt_config(ioc, &cfg) == 0) {
6079		mem = kmalloc(iocpage3sz, GFP_KERNEL);
6080		if (mem) {
6081			memcpy(mem, (u8 *)pIoc3, iocpage3sz);
6082			ioc->raid_data.pIocPg3 = (IOCPage3_t *) mem;
6083		}
6084	}
6085
6086	dma_free_coherent(&ioc->pcidev->dev, iocpage3sz, pIoc3, ioc3_dma);
6087
6088	return 0;
6089}
6090
6091static void
6092mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
6093{
6094	IOCPage4_t		*pIoc4;
6095	CONFIGPARMS		 cfg;
6096	ConfigPageHeader_t	 header;
6097	dma_addr_t		 ioc4_dma;
6098	int			 iocpage4sz;
6099
6100	/* Read and save IOC Page 4
6101	 */
6102	header.PageVersion = 0;
6103	header.PageLength = 0;
6104	header.PageNumber = 4;
6105	header.PageType = MPI_CONFIG_PAGETYPE_IOC;
6106	cfg.cfghdr.hdr = &header;
6107	cfg.physAddr = -1;
6108	cfg.pageAddr = 0;
6109	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
6110	cfg.dir = 0;
6111	cfg.timeout = 0;
6112	if (mpt_config(ioc, &cfg) != 0)
6113		return;
6114
6115	if (header.PageLength == 0)
6116		return;
6117
6118	if ( (pIoc4 = ioc->spi_data.pIocPg4) == NULL ) {
6119		iocpage4sz = (header.PageLength + 4) * 4; /* Allow 4 additional SEP's */
6120		pIoc4 = dma_alloc_coherent(&ioc->pcidev->dev, iocpage4sz,
6121					   &ioc4_dma, GFP_KERNEL);
6122		if (!pIoc4)
6123			return;
6124		ioc->alloc_total += iocpage4sz;
6125	} else {
6126		ioc4_dma = ioc->spi_data.IocPg4_dma;
6127		iocpage4sz = ioc->spi_data.IocPg4Sz;
6128	}
6129
6130	/* Read the Page into dma memory.
6131	 */
6132	cfg.physAddr = ioc4_dma;
6133	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
6134	if (mpt_config(ioc, &cfg) == 0) {
6135		ioc->spi_data.pIocPg4 = (IOCPage4_t *) pIoc4;
6136		ioc->spi_data.IocPg4_dma = ioc4_dma;
6137		ioc->spi_data.IocPg4Sz = iocpage4sz;
6138	} else {
6139		dma_free_coherent(&ioc->pcidev->dev, iocpage4sz, pIoc4,
6140				  ioc4_dma);
6141		ioc->spi_data.pIocPg4 = NULL;
6142		ioc->alloc_total -= iocpage4sz;
6143	}
6144}
6145
6146static void
6147mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
6148{
6149	IOCPage1_t		*pIoc1;
6150	CONFIGPARMS		 cfg;
6151	ConfigPageHeader_t	 header;
6152	dma_addr_t		 ioc1_dma;
6153	int			 iocpage1sz = 0;
6154	u32			 tmp;
6155
6156	/* Check the Coalescing Timeout in IOC Page 1
6157	 */
6158	header.PageVersion = 0;
6159	header.PageLength = 0;
6160	header.PageNumber = 1;
6161	header.PageType = MPI_CONFIG_PAGETYPE_IOC;
6162	cfg.cfghdr.hdr = &header;
6163	cfg.physAddr = -1;
6164	cfg.pageAddr = 0;
6165	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
6166	cfg.dir = 0;
6167	cfg.timeout = 0;
6168	if (mpt_config(ioc, &cfg) != 0)
6169		return;
6170
6171	if (header.PageLength == 0)
6172		return;
6173
6174	/* Read Header good, alloc memory
6175	 */
6176	iocpage1sz = header.PageLength * 4;
6177	pIoc1 = dma_alloc_coherent(&ioc->pcidev->dev, iocpage1sz, &ioc1_dma,
6178				   GFP_KERNEL);
6179	if (!pIoc1)
6180		return;
6181
6182	/* Read the Page and check coalescing timeout
6183	 */
6184	cfg.physAddr = ioc1_dma;
6185	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
6186	if (mpt_config(ioc, &cfg) == 0) {
6187
6188		tmp = le32_to_cpu(pIoc1->Flags) & MPI_IOCPAGE1_REPLY_COALESCING;
6189		if (tmp == MPI_IOCPAGE1_REPLY_COALESCING) {
6190			tmp = le32_to_cpu(pIoc1->CoalescingTimeout);
6191
6192			dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Coalescing Enabled Timeout = %d\n",
6193					ioc->name, tmp));
6194
6195			if (tmp > MPT_COALESCING_TIMEOUT) {
6196				pIoc1->CoalescingTimeout = cpu_to_le32(MPT_COALESCING_TIMEOUT);
6197
6198				/* Write NVRAM and current
6199				 */
6200				cfg.dir = 1;
6201				cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
6202				if (mpt_config(ioc, &cfg) == 0) {
6203					dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Reset Current Coalescing Timeout to = %d\n",
6204							ioc->name, MPT_COALESCING_TIMEOUT));
6205
6206					cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM;
6207					if (mpt_config(ioc, &cfg) == 0) {
6208						dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6209								"Reset NVRAM Coalescing Timeout to = %d\n",
6210								ioc->name, MPT_COALESCING_TIMEOUT));
6211					} else {
6212						dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6213								"Reset NVRAM Coalescing Timeout Failed\n",
6214								ioc->name));
6215					}
6216
6217				} else {
6218					dprintk(ioc, printk(MYIOC_s_WARN_FMT
6219						"Reset of Current Coalescing Timeout Failed!\n",
6220						ioc->name));
6221				}
6222			}
6223
6224		} else {
6225			dprintk(ioc, printk(MYIOC_s_WARN_FMT "Coalescing Disabled\n", ioc->name));
6226		}
6227	}
6228
6229	dma_free_coherent(&ioc->pcidev->dev, iocpage1sz, pIoc1, ioc1_dma);
6230
6231	return;
6232}
6233
6234static void
6235mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc)
6236{
6237	CONFIGPARMS		cfg;
6238	ConfigPageHeader_t	hdr;
6239	dma_addr_t		buf_dma;
6240	ManufacturingPage0_t	*pbuf = NULL;
6241
6242	memset(&cfg, 0 , sizeof(CONFIGPARMS));
6243	memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
6244
6245	hdr.PageType = MPI_CONFIG_PAGETYPE_MANUFACTURING;
6246	cfg.cfghdr.hdr = &hdr;
6247	cfg.physAddr = -1;
6248	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
6249	cfg.timeout = 10;
6250
6251	if (mpt_config(ioc, &cfg) != 0)
6252		goto out;
6253
6254	if (!cfg.cfghdr.hdr->PageLength)
6255		goto out;
6256
6257	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
6258	pbuf = dma_alloc_coherent(&ioc->pcidev->dev, hdr.PageLength * 4,
6259				  &buf_dma, GFP_KERNEL);
6260	if (!pbuf)
6261		goto out;
6262
6263	cfg.physAddr = buf_dma;
6264
6265	if (mpt_config(ioc, &cfg) != 0)
6266		goto out;
6267
6268	memcpy(ioc->board_name, pbuf->BoardName, sizeof(ioc->board_name));
6269	memcpy(ioc->board_assembly, pbuf->BoardAssembly, sizeof(ioc->board_assembly));
6270	memcpy(ioc->board_tracer, pbuf->BoardTracerNumber, sizeof(ioc->board_tracer));
6271
6272out:
6273
6274	if (pbuf)
6275		dma_free_coherent(&ioc->pcidev->dev, hdr.PageLength * 4, pbuf,
6276				  buf_dma);
6277}
6278
6279/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6280/**
6281 *	SendEventNotification - Send EventNotification (on or off) request to adapter
6282 *	@ioc: Pointer to MPT_ADAPTER structure
6283 *	@EvSwitch: Event switch flags
6284 *	@sleepFlag: Specifies whether the process can sleep
6285 */
6286static int
6287SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch, int sleepFlag)
6288{
6289	EventNotification_t	evn;
6290	MPIDefaultReply_t	reply_buf;
6291
6292	memset(&evn, 0, sizeof(EventNotification_t));
6293	memset(&reply_buf, 0, sizeof(MPIDefaultReply_t));
6294
6295	evn.Function = MPI_FUNCTION_EVENT_NOTIFICATION;
6296	evn.Switch = EvSwitch;
6297	evn.MsgContext = cpu_to_le32(mpt_base_index << 16);
6298
6299	devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6300	    "Sending EventNotification (%d) request %p\n",
6301	    ioc->name, EvSwitch, &evn));
6302
6303	return mpt_handshake_req_reply_wait(ioc, sizeof(EventNotification_t),
6304	    (u32 *)&evn, sizeof(MPIDefaultReply_t), (u16 *)&reply_buf, 30,
6305	    sleepFlag);
6306}
6307
6308/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6309/**
6310 *	SendEventAck - Send EventAck request to MPT adapter.
6311 *	@ioc: Pointer to MPT_ADAPTER structure
6312 *	@evnp: Pointer to original EventNotification request
6313 */
6314static int
6315SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
6316{
6317	EventAck_t	*pAck;
6318
6319	if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
6320		dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, no msg frames!!\n",
6321		    ioc->name, __func__));
6322		return -1;
6323	}
6324
6325	devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending EventAck\n", ioc->name));
6326
6327	pAck->Function     = MPI_FUNCTION_EVENT_ACK;
6328	pAck->ChainOffset  = 0;
6329	pAck->Reserved[0]  = pAck->Reserved[1] = 0;
6330	pAck->MsgFlags     = 0;
6331	pAck->Reserved1[0] = pAck->Reserved1[1] = pAck->Reserved1[2] = 0;
6332	pAck->Event        = evnp->Event;
6333	pAck->EventContext = evnp->EventContext;
6334
6335	mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)pAck);
6336
6337	return 0;
6338}
6339
6340/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6341/**
6342 *	mpt_config - Generic function to issue config message
6343 *	@ioc:   Pointer to an adapter structure
6344 *	@pCfg:  Pointer to a configuration structure. Struct contains
6345 *		action, page address, direction, physical address
6346 *		and pointer to a configuration page header
6347 *		Page header is updated.
6348 *
6349 *	Returns 0 for success
6350 *	-EAGAIN if no msg frames currently available
6351 *	-EFAULT for non-successful reply or no reply (timeout)
6352 */
6353int
6354mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
6355{
6356	Config_t	*pReq;
6357	ConfigReply_t	*pReply;
6358	ConfigExtendedPageHeader_t  *pExtHdr = NULL;
6359	MPT_FRAME_HDR	*mf;
6360	int		 ii;
6361	int		 flagsLength;
6362	long		 timeout;
6363	int		 ret;
6364	u8		 page_type = 0, extend_page;
6365	unsigned long 	 timeleft;
6366	unsigned long	 flags;
6367	u8		 issue_hard_reset = 0;
6368	u8		 retry_count = 0;
6369
6370	might_sleep();
6371
6372	/* don't send a config page during diag reset */
6373	spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6374	if (ioc->ioc_reset_in_progress) {
6375		dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6376		    "%s: busy with host reset\n", ioc->name, __func__));
6377		spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6378		return -EBUSY;
6379	}
6380	spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6381
6382	/* don't send if no chance of success */
6383	if (!ioc->active ||
6384	    mpt_GetIocState(ioc, 1) != MPI_IOC_STATE_OPERATIONAL) {
6385		dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6386		    "%s: ioc not operational, %d, %xh\n",
6387		    ioc->name, __func__, ioc->active,
6388		    mpt_GetIocState(ioc, 0)));
6389		return -EFAULT;
6390	}
6391
6392 retry_config:
6393	mutex_lock(&ioc->mptbase_cmds.mutex);
6394	/* init the internal cmd struct */
6395	memset(ioc->mptbase_cmds.reply, 0 , MPT_DEFAULT_FRAME_SIZE);
6396	INITIALIZE_MGMT_STATUS(ioc->mptbase_cmds.status)
6397
6398	/* Get and Populate a free Frame
6399	 */
6400	if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
6401		dcprintk(ioc, printk(MYIOC_s_WARN_FMT
6402		"mpt_config: no msg frames!\n", ioc->name));
6403		ret = -EAGAIN;
6404		goto out;
6405	}
6406
6407	pReq = (Config_t *)mf;
6408	pReq->Action = pCfg->action;
6409	pReq->Reserved = 0;
6410	pReq->ChainOffset = 0;
6411	pReq->Function = MPI_FUNCTION_CONFIG;
6412
6413	/* Assume page type is not extended and clear "reserved" fields. */
6414	pReq->ExtPageLength = 0;
6415	pReq->ExtPageType = 0;
6416	pReq->MsgFlags = 0;
6417
6418	for (ii=0; ii < 8; ii++)
6419		pReq->Reserved2[ii] = 0;
6420
6421	pReq->Header.PageVersion = pCfg->cfghdr.hdr->PageVersion;
6422	pReq->Header.PageLength = pCfg->cfghdr.hdr->PageLength;
6423	pReq->Header.PageNumber = pCfg->cfghdr.hdr->PageNumber;
6424	pReq->Header.PageType = (pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
6425
6426	if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
6427		pExtHdr = (ConfigExtendedPageHeader_t *)pCfg->cfghdr.ehdr;
6428		pReq->ExtPageLength = cpu_to_le16(pExtHdr->ExtPageLength);
6429		pReq->ExtPageType = pExtHdr->ExtPageType;
6430		pReq->Header.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
6431
6432		/* Page Length must be treated as a reserved field for the
6433		 * extended header.
6434		 */
6435		pReq->Header.PageLength = 0;
6436	}
6437
6438	pReq->PageAddress = cpu_to_le32(pCfg->pageAddr);
6439
6440	/* Add a SGE to the config request.
6441	 */
6442	if (pCfg->dir)
6443		flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
6444	else
6445		flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
6446
6447	if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) ==
6448	    MPI_CONFIG_PAGETYPE_EXTENDED) {
6449		flagsLength |= pExtHdr->ExtPageLength * 4;
6450		page_type = pReq->ExtPageType;
6451		extend_page = 1;
6452	} else {
6453		flagsLength |= pCfg->cfghdr.hdr->PageLength * 4;
6454		page_type = pReq->Header.PageType;
6455		extend_page = 0;
6456	}
6457
6458	dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6459	    "Sending Config request type 0x%x, page 0x%x and action %d\n",
6460	    ioc->name, page_type, pReq->Header.PageNumber, pReq->Action));
6461
6462	ioc->add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);
6463	timeout = (pCfg->timeout < 15) ? HZ*15 : HZ*pCfg->timeout;
6464	mpt_put_msg_frame(mpt_base_index, ioc, mf);
6465	timeleft = wait_for_completion_timeout(&ioc->mptbase_cmds.done,
6466		timeout);
6467	if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
6468		ret = -ETIME;
6469		dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6470		    "Failed Sending Config request type 0x%x, page 0x%x,"
6471		    " action %d, status %xh, time left %ld\n\n",
6472			ioc->name, page_type, pReq->Header.PageNumber,
6473			pReq->Action, ioc->mptbase_cmds.status, timeleft));
6474		if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
6475			goto out;
6476		if (!timeleft) {
6477			spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6478			if (ioc->ioc_reset_in_progress) {
6479				spin_unlock_irqrestore(&ioc->taskmgmt_lock,
6480					flags);
6481				printk(MYIOC_s_INFO_FMT "%s: host reset in"
6482					" progress mpt_config timed out.!!\n",
6483					__func__, ioc->name);
6484				mutex_unlock(&ioc->mptbase_cmds.mutex);
6485				return -EFAULT;
6486			}
6487			spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6488			issue_hard_reset = 1;
6489		}
6490		goto out;
6491	}
6492
6493	if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
6494		ret = -1;
6495		goto out;
6496	}
6497	pReply = (ConfigReply_t	*)ioc->mptbase_cmds.reply;
6498	ret = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
6499	if (ret == MPI_IOCSTATUS_SUCCESS) {
6500		if (extend_page) {
6501			pCfg->cfghdr.ehdr->ExtPageLength =
6502			    le16_to_cpu(pReply->ExtPageLength);
6503			pCfg->cfghdr.ehdr->ExtPageType =
6504			    pReply->ExtPageType;
6505		}
6506		pCfg->cfghdr.hdr->PageVersion = pReply->Header.PageVersion;
6507		pCfg->cfghdr.hdr->PageLength = pReply->Header.PageLength;
6508		pCfg->cfghdr.hdr->PageNumber = pReply->Header.PageNumber;
6509		pCfg->cfghdr.hdr->PageType = pReply->Header.PageType;
6510
6511	}
6512
6513	if (retry_count)
6514		printk(MYIOC_s_INFO_FMT "Retry completed "
6515		    "ret=0x%x timeleft=%ld\n",
6516		    ioc->name, ret, timeleft);
6517
6518	dcprintk(ioc, printk(KERN_DEBUG "IOCStatus=%04xh, IOCLogInfo=%08xh\n",
6519	     ret, le32_to_cpu(pReply->IOCLogInfo)));
6520
6521out:
6522
6523	CLEAR_MGMT_STATUS(ioc->mptbase_cmds.status)
6524	mutex_unlock(&ioc->mptbase_cmds.mutex);
6525	if (issue_hard_reset) {
6526		issue_hard_reset = 0;
6527		printk(MYIOC_s_WARN_FMT
6528		       "Issuing Reset from %s!!, doorbell=0x%08x\n",
6529		       ioc->name, __func__, mpt_GetIocState(ioc, 0));
6530		if (retry_count == 0) {
6531			if (mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP) != 0)
6532				retry_count++;
6533		} else
6534			mpt_HardResetHandler(ioc, CAN_SLEEP);
6535
6536		mpt_free_msg_frame(ioc, mf);
6537		/* attempt one retry for a timed out command */
6538		if (retry_count < 2) {
6539			printk(MYIOC_s_INFO_FMT
6540			    "Attempting Retry Config request"
6541			    " type 0x%x, page 0x%x,"
6542			    " action %d\n", ioc->name, page_type,
6543			    pCfg->cfghdr.hdr->PageNumber, pCfg->action);
6544			retry_count++;
6545			goto retry_config;
6546		}
6547	}
6548	return ret;
6549
6550}
6551
6552/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6553/**
6554 *	mpt_ioc_reset - Base cleanup for hard reset
6555 *	@ioc: Pointer to the adapter structure
6556 *	@reset_phase: Indicates pre- or post-reset functionality
6557 *
6558 *	Remark: Frees resources with internally generated commands.
6559 */
6560static int
6561mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
6562{
6563	switch (reset_phase) {
6564	case MPT_IOC_SETUP_RESET:
6565		ioc->taskmgmt_quiesce_io = 1;
6566		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6567		    "%s: MPT_IOC_SETUP_RESET\n", ioc->name, __func__));
6568		break;
6569	case MPT_IOC_PRE_RESET:
6570		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6571		    "%s: MPT_IOC_PRE_RESET\n", ioc->name, __func__));
6572		break;
6573	case MPT_IOC_POST_RESET:
6574		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6575		    "%s: MPT_IOC_POST_RESET\n",  ioc->name, __func__));
6576/* wake up mptbase_cmds */
6577		if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_PENDING) {
6578			ioc->mptbase_cmds.status |=
6579			    MPT_MGMT_STATUS_DID_IOCRESET;
6580			complete(&ioc->mptbase_cmds.done);
6581		}
6582/* wake up taskmgmt_cmds */
6583		if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_PENDING) {
6584			ioc->taskmgmt_cmds.status |=
6585				MPT_MGMT_STATUS_DID_IOCRESET;
6586			complete(&ioc->taskmgmt_cmds.done);
6587		}
6588		break;
6589	default:
6590		break;
6591	}
6592
6593	return 1;		/* currently means nothing really */
6594}
6595
6596
6597#ifdef CONFIG_PROC_FS		/* { */
6598/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6599/*
6600 *	procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
6601 */
6602/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6603/**
6604 *	procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
6605 *
6606 *	Returns 0 for success, non-zero for failure.
6607 */
6608static int
6609procmpt_create(void)
6610{
6611	mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL);
6612	if (mpt_proc_root_dir == NULL)
6613		return -ENOTDIR;
6614
6615	proc_create_single("summary", S_IRUGO, mpt_proc_root_dir,
6616			mpt_summary_proc_show);
6617	proc_create_single("version", S_IRUGO, mpt_proc_root_dir,
6618			mpt_version_proc_show);
6619	return 0;
6620}
6621
6622/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6623/**
6624 *	procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
6625 *
6626 *	Returns 0 for success, non-zero for failure.
6627 */
6628static void
6629procmpt_destroy(void)
6630{
6631	remove_proc_entry("version", mpt_proc_root_dir);
6632	remove_proc_entry("summary", mpt_proc_root_dir);
6633	remove_proc_entry(MPT_PROCFS_MPTBASEDIR, NULL);
6634}
6635
6636/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6637/*
6638 *	Handles read request from /proc/mpt/summary or /proc/mpt/iocN/summary.
6639 */
6640static void seq_mpt_print_ioc_summary(MPT_ADAPTER *ioc, struct seq_file *m, int showlan);
6641
6642static int mpt_summary_proc_show(struct seq_file *m, void *v)
6643{
6644	MPT_ADAPTER *ioc = m->private;
6645
6646	if (ioc) {
6647		seq_mpt_print_ioc_summary(ioc, m, 1);
6648	} else {
6649		list_for_each_entry(ioc, &ioc_list, list) {
6650			seq_mpt_print_ioc_summary(ioc, m, 1);
6651		}
6652	}
6653
6654	return 0;
6655}
6656
6657static int mpt_version_proc_show(struct seq_file *m, void *v)
6658{
6659	u8	 cb_idx;
6660	int	 scsi, fc, sas, lan, ctl, targ;
6661	char	*drvname;
6662
6663	seq_printf(m, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON);
6664	seq_printf(m, "  Fusion MPT base driver\n");
6665
6666	scsi = fc = sas = lan = ctl = targ = 0;
6667	for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6668		drvname = NULL;
6669		if (MptCallbacks[cb_idx]) {
6670			switch (MptDriverClass[cb_idx]) {
6671			case MPTSPI_DRIVER:
6672				if (!scsi++) drvname = "SPI host";
6673				break;
6674			case MPTFC_DRIVER:
6675				if (!fc++) drvname = "FC host";
6676				break;
6677			case MPTSAS_DRIVER:
6678				if (!sas++) drvname = "SAS host";
6679				break;
6680			case MPTLAN_DRIVER:
6681				if (!lan++) drvname = "LAN";
6682				break;
6683			case MPTSTM_DRIVER:
6684				if (!targ++) drvname = "SCSI target";
6685				break;
6686			case MPTCTL_DRIVER:
6687				if (!ctl++) drvname = "ioctl";
6688				break;
6689			}
6690
6691			if (drvname)
6692				seq_printf(m, "  Fusion MPT %s driver\n", drvname);
6693		}
6694	}
6695
6696	return 0;
6697}
6698
6699static int mpt_iocinfo_proc_show(struct seq_file *m, void *v)
6700{
6701	MPT_ADAPTER	*ioc = m->private;
6702	char		 expVer[32];
6703	int		 sz;
6704	int		 p;
6705
6706	mpt_get_fw_exp_ver(expVer, ioc);
6707
6708	seq_printf(m, "%s:", ioc->name);
6709	if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
6710		seq_printf(m, "  (f/w download boot flag set)");
6711//	if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
6712//		seq_printf(m, "  CONFIG_CHECKSUM_FAIL!");
6713
6714	seq_printf(m, "\n  ProductID = 0x%04x (%s)\n",
6715			ioc->facts.ProductID,
6716			ioc->prod_name);
6717	seq_printf(m, "  FWVersion = 0x%08x%s", ioc->facts.FWVersion.Word, expVer);
6718	if (ioc->facts.FWImageSize)
6719		seq_printf(m, " (fw_size=%d)", ioc->facts.FWImageSize);
6720	seq_printf(m, "\n  MsgVersion = 0x%04x\n", ioc->facts.MsgVersion);
6721	seq_printf(m, "  FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit);
6722	seq_printf(m, "  EventState = 0x%02x\n", ioc->facts.EventState);
6723
6724	seq_printf(m, "  CurrentHostMfaHighAddr = 0x%08x\n",
6725			ioc->facts.CurrentHostMfaHighAddr);
6726	seq_printf(m, "  CurrentSenseBufferHighAddr = 0x%08x\n",
6727			ioc->facts.CurrentSenseBufferHighAddr);
6728
6729	seq_printf(m, "  MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
6730	seq_printf(m, "  MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
6731
6732	seq_printf(m, "  RequestFrames @ 0x%p (Dma @ 0x%p)\n",
6733					(void *)ioc->req_frames, (void *)(ulong)ioc->req_frames_dma);
6734	/*
6735	 *  Rounding UP to nearest 4-kB boundary here...
6736	 */
6737	sz = (ioc->req_sz * ioc->req_depth) + 128;
6738	sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
6739	seq_printf(m, "    {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
6740					ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz);
6741	seq_printf(m, "    {MaxReqSz=%d}   {MaxReqDepth=%d}\n",
6742					4*ioc->facts.RequestFrameSize,
6743					ioc->facts.GlobalCredits);
6744
6745	seq_printf(m, "  Frames   @ 0x%p (Dma @ 0x%p)\n",
6746					(void *)ioc->alloc, (void *)(ulong)ioc->alloc_dma);
6747	sz = (ioc->reply_sz * ioc->reply_depth) + 128;
6748	seq_printf(m, "    {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
6749					ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz);
6750	seq_printf(m, "    {MaxRepSz=%d}   {MaxRepDepth=%d}\n",
6751					ioc->facts.CurReplyFrameSize,
6752					ioc->facts.ReplyQueueDepth);
6753
6754	seq_printf(m, "  MaxDevices = %d\n",
6755			(ioc->facts.MaxDevices==0) ? 255 : ioc->facts.MaxDevices);
6756	seq_printf(m, "  MaxBuses = %d\n", ioc->facts.MaxBuses);
6757
6758	/* per-port info */
6759	for (p=0; p < ioc->facts.NumberOfPorts; p++) {
6760		seq_printf(m, "  PortNumber = %d (of %d)\n",
6761				p+1,
6762				ioc->facts.NumberOfPorts);
6763		if (ioc->bus_type == FC) {
6764			if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
6765				u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6766				seq_printf(m, "    LanAddr = %pMR\n", a);
6767			}
6768			seq_printf(m, "    WWN = %08X%08X:%08X%08X\n",
6769					ioc->fc_port_page0[p].WWNN.High,
6770					ioc->fc_port_page0[p].WWNN.Low,
6771					ioc->fc_port_page0[p].WWPN.High,
6772					ioc->fc_port_page0[p].WWPN.Low);
6773		}
6774	}
6775
6776	return 0;
6777}
6778#endif		/* CONFIG_PROC_FS } */
6779
6780/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6781static void
6782mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc)
6783{
6784	buf[0] ='\0';
6785	if ((ioc->facts.FWVersion.Word >> 24) == 0x0E) {
6786		sprintf(buf, " (Exp %02d%02d)",
6787			(ioc->facts.FWVersion.Word >> 16) & 0x00FF,	/* Month */
6788			(ioc->facts.FWVersion.Word >> 8) & 0x1F);	/* Day */
6789
6790		/* insider hack! */
6791		if ((ioc->facts.FWVersion.Word >> 8) & 0x80)
6792			strcat(buf, " [MDBG]");
6793	}
6794}
6795
6796/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6797/**
6798 *	mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
6799 *	@ioc: Pointer to MPT_ADAPTER structure
6800 *	@buffer: Pointer to buffer where IOC summary info should be written
6801 *	@size: Pointer to number of bytes we wrote (set by this routine)
6802 *	@len: Offset at which to start writing in buffer
6803 *	@showlan: Display LAN stuff?
6804 *
6805 *	This routine writes (english readable) ASCII text, which represents
6806 *	a summary of IOC information, to a buffer.
6807 */
6808void
6809mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int showlan)
6810{
6811	char expVer[32];
6812	int y;
6813
6814	mpt_get_fw_exp_ver(expVer, ioc);
6815
6816	/*
6817	 *  Shorter summary of attached ioc's...
6818	 */
6819	y = sprintf(buffer+len, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
6820			ioc->name,
6821			ioc->prod_name,
6822			MPT_FW_REV_MAGIC_ID_STRING,	/* "FwRev=" or somesuch */
6823			ioc->facts.FWVersion.Word,
6824			expVer,
6825			ioc->facts.NumberOfPorts,
6826			ioc->req_depth);
6827
6828	if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
6829		u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6830		y += sprintf(buffer+len+y, ", LanAddr=%pMR", a);
6831	}
6832
6833	y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq);
6834
6835	if (!ioc->active)
6836		y += sprintf(buffer+len+y, " (disabled)");
6837
6838	y += sprintf(buffer+len+y, "\n");
6839
6840	*size = y;
6841}
6842
6843#ifdef CONFIG_PROC_FS
6844static void seq_mpt_print_ioc_summary(MPT_ADAPTER *ioc, struct seq_file *m, int showlan)
6845{
6846	char expVer[32];
6847
6848	mpt_get_fw_exp_ver(expVer, ioc);
6849
6850	/*
6851	 *  Shorter summary of attached ioc's...
6852	 */
6853	seq_printf(m, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
6854			ioc->name,
6855			ioc->prod_name,
6856			MPT_FW_REV_MAGIC_ID_STRING,	/* "FwRev=" or somesuch */
6857			ioc->facts.FWVersion.Word,
6858			expVer,
6859			ioc->facts.NumberOfPorts,
6860			ioc->req_depth);
6861
6862	if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
6863		u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6864		seq_printf(m, ", LanAddr=%pMR", a);
6865	}
6866
6867	seq_printf(m, ", IRQ=%d", ioc->pci_irq);
6868
6869	if (!ioc->active)
6870		seq_printf(m, " (disabled)");
6871
6872	seq_putc(m, '\n');
6873}
6874#endif
6875
6876/**
6877 *	mpt_set_taskmgmt_in_progress_flag - set flags associated with task management
6878 *	@ioc: Pointer to MPT_ADAPTER structure
6879 *
6880 *	Returns 0 for SUCCESS or -1 if FAILED.
6881 *
6882 *	If -1 is return, then it was not possible to set the flags
6883 **/
6884int
6885mpt_set_taskmgmt_in_progress_flag(MPT_ADAPTER *ioc)
6886{
6887	unsigned long	 flags;
6888	int		 retval;
6889
6890	spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6891	if (ioc->ioc_reset_in_progress || ioc->taskmgmt_in_progress ||
6892	    (ioc->alt_ioc && ioc->alt_ioc->taskmgmt_in_progress)) {
6893		retval = -1;
6894		goto out;
6895	}
6896	retval = 0;
6897	ioc->taskmgmt_in_progress = 1;
6898	ioc->taskmgmt_quiesce_io = 1;
6899	if (ioc->alt_ioc) {
6900		ioc->alt_ioc->taskmgmt_in_progress = 1;
6901		ioc->alt_ioc->taskmgmt_quiesce_io = 1;
6902	}
6903 out:
6904	spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6905	return retval;
6906}
6907EXPORT_SYMBOL(mpt_set_taskmgmt_in_progress_flag);
6908
6909/**
6910 *	mpt_clear_taskmgmt_in_progress_flag - clear flags associated with task management
6911 *	@ioc: Pointer to MPT_ADAPTER structure
6912 *
6913 **/
6914void
6915mpt_clear_taskmgmt_in_progress_flag(MPT_ADAPTER *ioc)
6916{
6917	unsigned long	 flags;
6918
6919	spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6920	ioc->taskmgmt_in_progress = 0;
6921	ioc->taskmgmt_quiesce_io = 0;
6922	if (ioc->alt_ioc) {
6923		ioc->alt_ioc->taskmgmt_in_progress = 0;
6924		ioc->alt_ioc->taskmgmt_quiesce_io = 0;
6925	}
6926	spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6927}
6928EXPORT_SYMBOL(mpt_clear_taskmgmt_in_progress_flag);
6929
6930
6931/**
6932 *	mpt_halt_firmware - Halts the firmware if it is operational and panic
6933 *	the kernel
6934 *	@ioc: Pointer to MPT_ADAPTER structure
6935 *
6936 **/
6937void __noreturn
6938mpt_halt_firmware(MPT_ADAPTER *ioc)
6939{
6940	u32	 ioc_raw_state;
6941
6942	ioc_raw_state = mpt_GetIocState(ioc, 0);
6943
6944	if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
6945		printk(MYIOC_s_ERR_FMT "IOC is in FAULT state (%04xh)!!!\n",
6946			ioc->name, ioc_raw_state & MPI_DOORBELL_DATA_MASK);
6947		panic("%s: IOC Fault (%04xh)!!!\n", ioc->name,
6948			ioc_raw_state & MPI_DOORBELL_DATA_MASK);
6949	} else {
6950		CHIPREG_WRITE32(&ioc->chip->Doorbell, 0xC0FFEE00);
6951		panic("%s: Firmware is halted due to command timeout\n",
6952			ioc->name);
6953	}
6954}
6955EXPORT_SYMBOL(mpt_halt_firmware);
6956
6957/**
6958 *	mpt_SoftResetHandler - Issues a less expensive reset
6959 *	@ioc: Pointer to MPT_ADAPTER structure
6960 *	@sleepFlag: Indicates if sleep or schedule must be called.
6961 *
6962 *	Returns 0 for SUCCESS or -1 if FAILED.
6963 *
6964 *	Message Unit Reset - instructs the IOC to reset the Reply Post and
6965 *	Free FIFO's. All the Message Frames on Reply Free FIFO are discarded.
6966 *	All posted buffers are freed, and event notification is turned off.
6967 *	IOC doesn't reply to any outstanding request. This will transfer IOC
6968 *	to READY state.
6969 **/
6970static int
6971mpt_SoftResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
6972{
6973	int		 rc;
6974	int		 ii;
6975	u8		 cb_idx;
6976	unsigned long	 flags;
6977	u32		 ioc_state;
6978	unsigned long	 time_count;
6979
6980	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SoftResetHandler Entered!\n",
6981		ioc->name));
6982
6983	ioc_state = mpt_GetIocState(ioc, 0) & MPI_IOC_STATE_MASK;
6984
6985	if (mpt_fwfault_debug)
6986		mpt_halt_firmware(ioc);
6987
6988	if (ioc_state == MPI_IOC_STATE_FAULT ||
6989	    ioc_state == MPI_IOC_STATE_RESET) {
6990		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6991		    "skipping, either in FAULT or RESET state!\n", ioc->name));
6992		return -1;
6993	}
6994
6995	if (ioc->bus_type == FC) {
6996		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6997		    "skipping, because the bus type is FC!\n", ioc->name));
6998		return -1;
6999	}
7000
7001	spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
7002	if (ioc->ioc_reset_in_progress) {
7003		spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7004		return -1;
7005	}
7006	ioc->ioc_reset_in_progress = 1;
7007	spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7008
7009	for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
7010		if (MptResetHandlers[cb_idx])
7011			mpt_signal_reset(cb_idx, ioc, MPT_IOC_SETUP_RESET);
7012	}
7013
7014	spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
7015	if (ioc->taskmgmt_in_progress) {
7016		ioc->ioc_reset_in_progress = 0;
7017		spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7018		return -1;
7019	}
7020	spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7021	/* Disable reply interrupts (also blocks FreeQ) */
7022	CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
7023	ioc->active = 0;
7024	time_count = jiffies;
7025
7026	rc = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
7027
7028	for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
7029		if (MptResetHandlers[cb_idx])
7030			mpt_signal_reset(cb_idx, ioc, MPT_IOC_PRE_RESET);
7031	}
7032
7033	if (rc)
7034		goto out;
7035
7036	ioc_state = mpt_GetIocState(ioc, 0) & MPI_IOC_STATE_MASK;
7037	if (ioc_state != MPI_IOC_STATE_READY)
7038		goto out;
7039
7040	for (ii = 0; ii < 5; ii++) {
7041		/* Get IOC facts! Allow 5 retries */
7042		rc = GetIocFacts(ioc, sleepFlag,
7043			MPT_HOSTEVENT_IOC_RECOVER);
7044		if (rc == 0)
7045			break;
7046		if (sleepFlag == CAN_SLEEP)
7047			msleep(100);
7048		else
7049			mdelay(100);
7050	}
7051	if (ii == 5)
7052		goto out;
7053
7054	rc = PrimeIocFifos(ioc);
7055	if (rc != 0)
7056		goto out;
7057
7058	rc = SendIocInit(ioc, sleepFlag);
7059	if (rc != 0)
7060		goto out;
7061
7062	rc = SendEventNotification(ioc, 1, sleepFlag);
7063	if (rc != 0)
7064		goto out;
7065
7066	if (ioc->hard_resets < -1)
7067		ioc->hard_resets++;
7068
7069	/*
7070	 * At this point, we know soft reset succeeded.
7071	 */
7072
7073	ioc->active = 1;
7074	CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
7075
7076 out:
7077	spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
7078	ioc->ioc_reset_in_progress = 0;
7079	ioc->taskmgmt_quiesce_io = 0;
7080	ioc->taskmgmt_in_progress = 0;
7081	spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7082
7083	if (ioc->active) {	/* otherwise, hard reset coming */
7084		for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
7085			if (MptResetHandlers[cb_idx])
7086				mpt_signal_reset(cb_idx, ioc,
7087					MPT_IOC_POST_RESET);
7088		}
7089	}
7090
7091	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7092		"SoftResetHandler: completed (%d seconds): %s\n",
7093		ioc->name, jiffies_to_msecs(jiffies - time_count)/1000,
7094		((rc == 0) ? "SUCCESS" : "FAILED")));
7095
7096	return rc;
7097}
7098
7099/**
7100 *	mpt_Soft_Hard_ResetHandler - Try less expensive reset
7101 *	@ioc: Pointer to MPT_ADAPTER structure
7102 *	@sleepFlag: Indicates if sleep or schedule must be called.
7103 *
7104 *	Returns 0 for SUCCESS or -1 if FAILED.
7105 *	Try for softreset first, only if it fails go for expensive
7106 *	HardReset.
7107 **/
7108int
7109mpt_Soft_Hard_ResetHandler(MPT_ADAPTER *ioc, int sleepFlag) {
7110	int ret = -1;
7111
7112	ret = mpt_SoftResetHandler(ioc, sleepFlag);
7113	if (ret == 0)
7114		return ret;
7115	ret = mpt_HardResetHandler(ioc, sleepFlag);
7116	return ret;
7117}
7118EXPORT_SYMBOL(mpt_Soft_Hard_ResetHandler);
7119
7120/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7121/*
7122 *	Reset Handling
7123 */
7124/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7125/**
7126 *	mpt_HardResetHandler - Generic reset handler
7127 *	@ioc: Pointer to MPT_ADAPTER structure
7128 *	@sleepFlag: Indicates if sleep or schedule must be called.
7129 *
7130 *	Issues SCSI Task Management call based on input arg values.
7131 *	If TaskMgmt fails, returns associated SCSI request.
7132 *
7133 *	Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
7134 *	or a non-interrupt thread.  In the former, must not call schedule().
7135 *
7136 *	Note: A return of -1 is a FATAL error case, as it means a
7137 *	FW reload/initialization failed.
7138 *
7139 *	Returns 0 for SUCCESS or -1 if FAILED.
7140 */
7141int
7142mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
7143{
7144	int	 rc;
7145	u8	 cb_idx;
7146	unsigned long	 flags;
7147	unsigned long	 time_count;
7148
7149	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler Entered!\n", ioc->name));
7150#ifdef MFCNT
7151	printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name);
7152	printk("MF count 0x%x !\n", ioc->mfcnt);
7153#endif
7154	if (mpt_fwfault_debug)
7155		mpt_halt_firmware(ioc);
7156
7157	/* Reset the adapter. Prevent more than 1 call to
7158	 * mpt_do_ioc_recovery at any instant in time.
7159	 */
7160	spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
7161	if (ioc->ioc_reset_in_progress) {
7162		spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7163		ioc->wait_on_reset_completion = 1;
7164		do {
7165			ssleep(1);
7166		} while (ioc->ioc_reset_in_progress == 1);
7167		ioc->wait_on_reset_completion = 0;
7168		return ioc->reset_status;
7169	}
7170	if (ioc->wait_on_reset_completion) {
7171		spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7172		rc = 0;
7173		time_count = jiffies;
7174		goto exit;
7175	}
7176	ioc->ioc_reset_in_progress = 1;
7177	if (ioc->alt_ioc)
7178		ioc->alt_ioc->ioc_reset_in_progress = 1;
7179	spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7180
7181
7182	/* The SCSI driver needs to adjust timeouts on all current
7183	 * commands prior to the diagnostic reset being issued.
7184	 * Prevents timeouts occurring during a diagnostic reset...very bad.
7185	 * For all other protocol drivers, this is a no-op.
7186	 */
7187	for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
7188		if (MptResetHandlers[cb_idx]) {
7189			mpt_signal_reset(cb_idx, ioc, MPT_IOC_SETUP_RESET);
7190			if (ioc->alt_ioc)
7191				mpt_signal_reset(cb_idx, ioc->alt_ioc,
7192					MPT_IOC_SETUP_RESET);
7193		}
7194	}
7195
7196	time_count = jiffies;
7197	rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag);
7198	if (rc != 0) {
7199		printk(KERN_WARNING MYNAM
7200		       ": WARNING - (%d) Cannot recover %s, doorbell=0x%08x\n",
7201		       rc, ioc->name, mpt_GetIocState(ioc, 0));
7202	} else {
7203		if (ioc->hard_resets < -1)
7204			ioc->hard_resets++;
7205	}
7206
7207	spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
7208	ioc->ioc_reset_in_progress = 0;
7209	ioc->taskmgmt_quiesce_io = 0;
7210	ioc->taskmgmt_in_progress = 0;
7211	ioc->reset_status = rc;
7212	if (ioc->alt_ioc) {
7213		ioc->alt_ioc->ioc_reset_in_progress = 0;
7214		ioc->alt_ioc->taskmgmt_quiesce_io = 0;
7215		ioc->alt_ioc->taskmgmt_in_progress = 0;
7216	}
7217	spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7218
7219	for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
7220		if (MptResetHandlers[cb_idx]) {
7221			mpt_signal_reset(cb_idx, ioc, MPT_IOC_POST_RESET);
7222			if (ioc->alt_ioc)
7223				mpt_signal_reset(cb_idx,
7224					ioc->alt_ioc, MPT_IOC_POST_RESET);
7225		}
7226	}
7227exit:
7228	dtmprintk(ioc,
7229	    printk(MYIOC_s_DEBUG_FMT
7230		"HardResetHandler: completed (%d seconds): %s\n", ioc->name,
7231		jiffies_to_msecs(jiffies - time_count)/1000, ((rc == 0) ?
7232		"SUCCESS" : "FAILED")));
7233
7234	return rc;
7235}
7236
7237#ifdef CONFIG_FUSION_LOGGING
7238static void
7239mpt_display_event_info(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply)
7240{
7241	char *ds = NULL;
7242	u32 evData0;
7243	int ii;
7244	u8 event;
7245	char *evStr = ioc->evStr;
7246
7247	event = le32_to_cpu(pEventReply->Event) & 0xFF;
7248	evData0 = le32_to_cpu(pEventReply->Data[0]);
7249
7250	switch(event) {
7251	case MPI_EVENT_NONE:
7252		ds = "None";
7253		break;
7254	case MPI_EVENT_LOG_DATA:
7255		ds = "Log Data";
7256		break;
7257	case MPI_EVENT_STATE_CHANGE:
7258		ds = "State Change";
7259		break;
7260	case MPI_EVENT_UNIT_ATTENTION:
7261		ds = "Unit Attention";
7262		break;
7263	case MPI_EVENT_IOC_BUS_RESET:
7264		ds = "IOC Bus Reset";
7265		break;
7266	case MPI_EVENT_EXT_BUS_RESET:
7267		ds = "External Bus Reset";
7268		break;
7269	case MPI_EVENT_RESCAN:
7270		ds = "Bus Rescan Event";
7271		break;
7272	case MPI_EVENT_LINK_STATUS_CHANGE:
7273		if (evData0 == MPI_EVENT_LINK_STATUS_FAILURE)
7274			ds = "Link Status(FAILURE) Change";
7275		else
7276			ds = "Link Status(ACTIVE) Change";
7277		break;
7278	case MPI_EVENT_LOOP_STATE_CHANGE:
7279		if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP)
7280			ds = "Loop State(LIP) Change";
7281		else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE)
7282			ds = "Loop State(LPE) Change";
7283		else
7284			ds = "Loop State(LPB) Change";
7285		break;
7286	case MPI_EVENT_LOGOUT:
7287		ds = "Logout";
7288		break;
7289	case MPI_EVENT_EVENT_CHANGE:
7290		if (evData0)
7291			ds = "Events ON";
7292		else
7293			ds = "Events OFF";
7294		break;
7295	case MPI_EVENT_INTEGRATED_RAID:
7296	{
7297		u8 ReasonCode = (u8)(evData0 >> 16);
7298		switch (ReasonCode) {
7299		case MPI_EVENT_RAID_RC_VOLUME_CREATED :
7300			ds = "Integrated Raid: Volume Created";
7301			break;
7302		case MPI_EVENT_RAID_RC_VOLUME_DELETED :
7303			ds = "Integrated Raid: Volume Deleted";
7304			break;
7305		case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED :
7306			ds = "Integrated Raid: Volume Settings Changed";
7307			break;
7308		case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED :
7309			ds = "Integrated Raid: Volume Status Changed";
7310			break;
7311		case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED :
7312			ds = "Integrated Raid: Volume Physdisk Changed";
7313			break;
7314		case MPI_EVENT_RAID_RC_PHYSDISK_CREATED :
7315			ds = "Integrated Raid: Physdisk Created";
7316			break;
7317		case MPI_EVENT_RAID_RC_PHYSDISK_DELETED :
7318			ds = "Integrated Raid: Physdisk Deleted";
7319			break;
7320		case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED :
7321			ds = "Integrated Raid: Physdisk Settings Changed";
7322			break;
7323		case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED :
7324			ds = "Integrated Raid: Physdisk Status Changed";
7325			break;
7326		case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED :
7327			ds = "Integrated Raid: Domain Validation Needed";
7328			break;
7329		case MPI_EVENT_RAID_RC_SMART_DATA :
7330			ds = "Integrated Raid; Smart Data";
7331			break;
7332		case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED :
7333			ds = "Integrated Raid: Replace Action Started";
7334			break;
7335		default:
7336			ds = "Integrated Raid";
7337		break;
7338		}
7339		break;
7340	}
7341	case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE:
7342		ds = "SCSI Device Status Change";
7343		break;
7344	case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
7345	{
7346		u8 id = (u8)(evData0);
7347		u8 channel = (u8)(evData0 >> 8);
7348		u8 ReasonCode = (u8)(evData0 >> 16);
7349		switch (ReasonCode) {
7350		case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
7351			snprintf(evStr, EVENT_DESCR_STR_SZ,
7352			    "SAS Device Status Change: Added: "
7353			    "id=%d channel=%d", id, channel);
7354			break;
7355		case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
7356			snprintf(evStr, EVENT_DESCR_STR_SZ,
7357			    "SAS Device Status Change: Deleted: "
7358			    "id=%d channel=%d", id, channel);
7359			break;
7360		case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
7361			snprintf(evStr, EVENT_DESCR_STR_SZ,
7362			    "SAS Device Status Change: SMART Data: "
7363			    "id=%d channel=%d", id, channel);
7364			break;
7365		case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
7366			snprintf(evStr, EVENT_DESCR_STR_SZ,
7367			    "SAS Device Status Change: No Persistency: "
7368			    "id=%d channel=%d", id, channel);
7369			break;
7370		case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED:
7371			snprintf(evStr, EVENT_DESCR_STR_SZ,
7372			    "SAS Device Status Change: Unsupported Device "
7373			    "Discovered : id=%d channel=%d", id, channel);
7374			break;
7375		case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
7376			snprintf(evStr, EVENT_DESCR_STR_SZ,
7377			    "SAS Device Status Change: Internal Device "
7378			    "Reset : id=%d channel=%d", id, channel);
7379			break;
7380		case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
7381			snprintf(evStr, EVENT_DESCR_STR_SZ,
7382			    "SAS Device Status Change: Internal Task "
7383			    "Abort : id=%d channel=%d", id, channel);
7384			break;
7385		case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
7386			snprintf(evStr, EVENT_DESCR_STR_SZ,
7387			    "SAS Device Status Change: Internal Abort "
7388			    "Task Set : id=%d channel=%d", id, channel);
7389			break;
7390		case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
7391			snprintf(evStr, EVENT_DESCR_STR_SZ,
7392			    "SAS Device Status Change: Internal Clear "
7393			    "Task Set : id=%d channel=%d", id, channel);
7394			break;
7395		case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
7396			snprintf(evStr, EVENT_DESCR_STR_SZ,
7397			    "SAS Device Status Change: Internal Query "
7398			    "Task : id=%d channel=%d", id, channel);
7399			break;
7400		default:
7401			snprintf(evStr, EVENT_DESCR_STR_SZ,
7402			    "SAS Device Status Change: Unknown: "
7403			    "id=%d channel=%d", id, channel);
7404			break;
7405		}
7406		break;
7407	}
7408	case MPI_EVENT_ON_BUS_TIMER_EXPIRED:
7409		ds = "Bus Timer Expired";
7410		break;
7411	case MPI_EVENT_QUEUE_FULL:
7412	{
7413		u16 curr_depth = (u16)(evData0 >> 16);
7414		u8 channel = (u8)(evData0 >> 8);
7415		u8 id = (u8)(evData0);
7416
7417		snprintf(evStr, EVENT_DESCR_STR_SZ,
7418		   "Queue Full: channel=%d id=%d depth=%d",
7419		   channel, id, curr_depth);
7420		break;
7421	}
7422	case MPI_EVENT_SAS_SES:
7423		ds = "SAS SES Event";
7424		break;
7425	case MPI_EVENT_PERSISTENT_TABLE_FULL:
7426		ds = "Persistent Table Full";
7427		break;
7428	case MPI_EVENT_SAS_PHY_LINK_STATUS:
7429	{
7430		u8 LinkRates = (u8)(evData0 >> 8);
7431		u8 PhyNumber = (u8)(evData0);
7432		LinkRates = (LinkRates & MPI_EVENT_SAS_PLS_LR_CURRENT_MASK) >>
7433			MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT;
7434		switch (LinkRates) {
7435		case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN:
7436			snprintf(evStr, EVENT_DESCR_STR_SZ,
7437			   "SAS PHY Link Status: Phy=%d:"
7438			   " Rate Unknown",PhyNumber);
7439			break;
7440		case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED:
7441			snprintf(evStr, EVENT_DESCR_STR_SZ,
7442			   "SAS PHY Link Status: Phy=%d:"
7443			   " Phy Disabled",PhyNumber);
7444			break;
7445		case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION:
7446			snprintf(evStr, EVENT_DESCR_STR_SZ,
7447			   "SAS PHY Link Status: Phy=%d:"
7448			   " Failed Speed Nego",PhyNumber);
7449			break;
7450		case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE:
7451			snprintf(evStr, EVENT_DESCR_STR_SZ,
7452			   "SAS PHY Link Status: Phy=%d:"
7453			   " Sata OOB Completed",PhyNumber);
7454			break;
7455		case MPI_EVENT_SAS_PLS_LR_RATE_1_5:
7456			snprintf(evStr, EVENT_DESCR_STR_SZ,
7457			   "SAS PHY Link Status: Phy=%d:"
7458			   " Rate 1.5 Gbps",PhyNumber);
7459			break;
7460		case MPI_EVENT_SAS_PLS_LR_RATE_3_0:
7461			snprintf(evStr, EVENT_DESCR_STR_SZ,
7462			   "SAS PHY Link Status: Phy=%d:"
7463			   " Rate 3.0 Gbps", PhyNumber);
7464			break;
7465		case MPI_EVENT_SAS_PLS_LR_RATE_6_0:
7466			snprintf(evStr, EVENT_DESCR_STR_SZ,
7467			   "SAS PHY Link Status: Phy=%d:"
7468			   " Rate 6.0 Gbps", PhyNumber);
7469			break;
7470		default:
7471			snprintf(evStr, EVENT_DESCR_STR_SZ,
7472			   "SAS PHY Link Status: Phy=%d", PhyNumber);
7473			break;
7474		}
7475		break;
7476	}
7477	case MPI_EVENT_SAS_DISCOVERY_ERROR:
7478		ds = "SAS Discovery Error";
7479		break;
7480	case MPI_EVENT_IR_RESYNC_UPDATE:
7481	{
7482		u8 resync_complete = (u8)(evData0 >> 16);
7483		snprintf(evStr, EVENT_DESCR_STR_SZ,
7484		    "IR Resync Update: Complete = %d:",resync_complete);
7485		break;
7486	}
7487	case MPI_EVENT_IR2:
7488	{
7489		u8 id = (u8)(evData0);
7490		u8 channel = (u8)(evData0 >> 8);
7491		u8 phys_num = (u8)(evData0 >> 24);
7492		u8 ReasonCode = (u8)(evData0 >> 16);
7493
7494		switch (ReasonCode) {
7495		case MPI_EVENT_IR2_RC_LD_STATE_CHANGED:
7496			snprintf(evStr, EVENT_DESCR_STR_SZ,
7497			    "IR2: LD State Changed: "
7498			    "id=%d channel=%d phys_num=%d",
7499			    id, channel, phys_num);
7500			break;
7501		case MPI_EVENT_IR2_RC_PD_STATE_CHANGED:
7502			snprintf(evStr, EVENT_DESCR_STR_SZ,
7503			    "IR2: PD State Changed "
7504			    "id=%d channel=%d phys_num=%d",
7505			    id, channel, phys_num);
7506			break;
7507		case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL:
7508			snprintf(evStr, EVENT_DESCR_STR_SZ,
7509			    "IR2: Bad Block Table Full: "
7510			    "id=%d channel=%d phys_num=%d",
7511			    id, channel, phys_num);
7512			break;
7513		case MPI_EVENT_IR2_RC_PD_INSERTED:
7514			snprintf(evStr, EVENT_DESCR_STR_SZ,
7515			    "IR2: PD Inserted: "
7516			    "id=%d channel=%d phys_num=%d",
7517			    id, channel, phys_num);
7518			break;
7519		case MPI_EVENT_IR2_RC_PD_REMOVED:
7520			snprintf(evStr, EVENT_DESCR_STR_SZ,
7521			    "IR2: PD Removed: "
7522			    "id=%d channel=%d phys_num=%d",
7523			    id, channel, phys_num);
7524			break;
7525		case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED:
7526			snprintf(evStr, EVENT_DESCR_STR_SZ,
7527			    "IR2: Foreign CFG Detected: "
7528			    "id=%d channel=%d phys_num=%d",
7529			    id, channel, phys_num);
7530			break;
7531		case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR:
7532			snprintf(evStr, EVENT_DESCR_STR_SZ,
7533			    "IR2: Rebuild Medium Error: "
7534			    "id=%d channel=%d phys_num=%d",
7535			    id, channel, phys_num);
7536			break;
7537		case MPI_EVENT_IR2_RC_DUAL_PORT_ADDED:
7538			snprintf(evStr, EVENT_DESCR_STR_SZ,
7539			    "IR2: Dual Port Added: "
7540			    "id=%d channel=%d phys_num=%d",
7541			    id, channel, phys_num);
7542			break;
7543		case MPI_EVENT_IR2_RC_DUAL_PORT_REMOVED:
7544			snprintf(evStr, EVENT_DESCR_STR_SZ,
7545			    "IR2: Dual Port Removed: "
7546			    "id=%d channel=%d phys_num=%d",
7547			    id, channel, phys_num);
7548			break;
7549		default:
7550			ds = "IR2";
7551		break;
7552		}
7553		break;
7554	}
7555	case MPI_EVENT_SAS_DISCOVERY:
7556	{
7557		if (evData0)
7558			ds = "SAS Discovery: Start";
7559		else
7560			ds = "SAS Discovery: Stop";
7561		break;
7562	}
7563	case MPI_EVENT_LOG_ENTRY_ADDED:
7564		ds = "SAS Log Entry Added";
7565		break;
7566
7567	case MPI_EVENT_SAS_BROADCAST_PRIMITIVE:
7568	{
7569		u8 phy_num = (u8)(evData0);
7570		u8 port_num = (u8)(evData0 >> 8);
7571		u8 port_width = (u8)(evData0 >> 16);
7572		u8 primitive = (u8)(evData0 >> 24);
7573		snprintf(evStr, EVENT_DESCR_STR_SZ,
7574		    "SAS Broadcast Primitive: phy=%d port=%d "
7575		    "width=%d primitive=0x%02x",
7576		    phy_num, port_num, port_width, primitive);
7577		break;
7578	}
7579
7580	case MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE:
7581	{
7582		u8 reason = (u8)(evData0);
7583
7584		switch (reason) {
7585		case MPI_EVENT_SAS_INIT_RC_ADDED:
7586			ds = "SAS Initiator Status Change: Added";
7587			break;
7588		case MPI_EVENT_SAS_INIT_RC_REMOVED:
7589			ds = "SAS Initiator Status Change: Deleted";
7590			break;
7591		default:
7592			ds = "SAS Initiator Status Change";
7593			break;
7594		}
7595		break;
7596	}
7597
7598	case MPI_EVENT_SAS_INIT_TABLE_OVERFLOW:
7599	{
7600		u8 max_init = (u8)(evData0);
7601		u8 current_init = (u8)(evData0 >> 8);
7602
7603		snprintf(evStr, EVENT_DESCR_STR_SZ,
7604		    "SAS Initiator Device Table Overflow: max initiators=%02d "
7605		    "current initiators=%02d",
7606		    max_init, current_init);
7607		break;
7608	}
7609	case MPI_EVENT_SAS_SMP_ERROR:
7610	{
7611		u8 status = (u8)(evData0);
7612		u8 port_num = (u8)(evData0 >> 8);
7613		u8 result = (u8)(evData0 >> 16);
7614
7615		if (status == MPI_EVENT_SAS_SMP_FUNCTION_RESULT_VALID)
7616			snprintf(evStr, EVENT_DESCR_STR_SZ,
7617			    "SAS SMP Error: port=%d result=0x%02x",
7618			    port_num, result);
7619		else if (status == MPI_EVENT_SAS_SMP_CRC_ERROR)
7620			snprintf(evStr, EVENT_DESCR_STR_SZ,
7621			    "SAS SMP Error: port=%d : CRC Error",
7622			    port_num);
7623		else if (status == MPI_EVENT_SAS_SMP_TIMEOUT)
7624			snprintf(evStr, EVENT_DESCR_STR_SZ,
7625			    "SAS SMP Error: port=%d : Timeout",
7626			    port_num);
7627		else if (status == MPI_EVENT_SAS_SMP_NO_DESTINATION)
7628			snprintf(evStr, EVENT_DESCR_STR_SZ,
7629			    "SAS SMP Error: port=%d : No Destination",
7630			    port_num);
7631		else if (status == MPI_EVENT_SAS_SMP_BAD_DESTINATION)
7632			snprintf(evStr, EVENT_DESCR_STR_SZ,
7633			    "SAS SMP Error: port=%d : Bad Destination",
7634			    port_num);
7635		else
7636			snprintf(evStr, EVENT_DESCR_STR_SZ,
7637			    "SAS SMP Error: port=%d : status=0x%02x",
7638			    port_num, status);
7639		break;
7640	}
7641
7642	case MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE:
7643	{
7644		u8 reason = (u8)(evData0);
7645
7646		switch (reason) {
7647		case MPI_EVENT_SAS_EXP_RC_ADDED:
7648			ds = "Expander Status Change: Added";
7649			break;
7650		case MPI_EVENT_SAS_EXP_RC_NOT_RESPONDING:
7651			ds = "Expander Status Change: Deleted";
7652			break;
7653		default:
7654			ds = "Expander Status Change";
7655			break;
7656		}
7657		break;
7658	}
7659
7660	/*
7661	 *  MPT base "custom" events may be added here...
7662	 */
7663	default:
7664		ds = "Unknown";
7665		break;
7666	}
7667	if (ds)
7668		strscpy(evStr, ds, EVENT_DESCR_STR_SZ);
7669
7670
7671	devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7672	    "MPT event:(%02Xh) : %s\n",
7673	    ioc->name, event, evStr));
7674
7675	devtverboseprintk(ioc, printk(KERN_DEBUG MYNAM
7676	    ": Event data:\n"));
7677	for (ii = 0; ii < le16_to_cpu(pEventReply->EventDataLength); ii++)
7678		devtverboseprintk(ioc, printk(" %08x",
7679		    le32_to_cpu(pEventReply->Data[ii])));
7680	devtverboseprintk(ioc, printk(KERN_DEBUG "\n"));
7681}
7682#endif
7683/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7684/**
7685 *	ProcessEventNotification - Route EventNotificationReply to all event handlers
7686 *	@ioc: Pointer to MPT_ADAPTER structure
7687 *	@pEventReply: Pointer to EventNotification reply frame
7688 *	@evHandlers: Pointer to integer, number of event handlers
7689 *
7690 *	Routes a received EventNotificationReply to all currently registered
7691 *	event handlers.
7692 *	Returns sum of event handlers return values.
7693 */
7694static int
7695ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply, int *evHandlers)
7696{
7697	u16 evDataLen;
7698	u32 evData0 = 0;
7699	int ii;
7700	u8 cb_idx;
7701	int r = 0;
7702	int handlers = 0;
7703	u8 event;
7704
7705	/*
7706	 *  Do platform normalization of values
7707	 */
7708	event = le32_to_cpu(pEventReply->Event) & 0xFF;
7709	evDataLen = le16_to_cpu(pEventReply->EventDataLength);
7710	if (evDataLen) {
7711		evData0 = le32_to_cpu(pEventReply->Data[0]);
7712	}
7713
7714#ifdef CONFIG_FUSION_LOGGING
7715	if (evDataLen)
7716		mpt_display_event_info(ioc, pEventReply);
7717#endif
7718
7719	/*
7720	 *  Do general / base driver event processing
7721	 */
7722	switch(event) {
7723	case MPI_EVENT_EVENT_CHANGE:		/* 0A */
7724		if (evDataLen) {
7725			u8 evState = evData0 & 0xFF;
7726
7727			/* CHECKME! What if evState unexpectedly says OFF (0)? */
7728
7729			/* Update EventState field in cached IocFacts */
7730			if (ioc->facts.Function) {
7731				ioc->facts.EventState = evState;
7732			}
7733		}
7734		break;
7735	case MPI_EVENT_INTEGRATED_RAID:
7736		mptbase_raid_process_event_data(ioc,
7737		    (MpiEventDataRaid_t *)pEventReply->Data);
7738		break;
7739	default:
7740		break;
7741	}
7742
7743	/*
7744	 * Should this event be logged? Events are written sequentially.
7745	 * When buffer is full, start again at the top.
7746	 */
7747	if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
7748		int idx;
7749
7750		idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
7751
7752		ioc->events[idx].event = event;
7753		ioc->events[idx].eventContext = ioc->eventContext;
7754
7755		for (ii = 0; ii < 2; ii++) {
7756			if (ii < evDataLen)
7757				ioc->events[idx].data[ii] = le32_to_cpu(pEventReply->Data[ii]);
7758			else
7759				ioc->events[idx].data[ii] =  0;
7760		}
7761
7762		ioc->eventContext++;
7763	}
7764
7765
7766	/*
7767	 *  Call each currently registered protocol event handler.
7768	 */
7769	for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
7770		if (MptEvHandlers[cb_idx]) {
7771			devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7772			    "Routing Event to event handler #%d\n",
7773			    ioc->name, cb_idx));
7774			r += (*(MptEvHandlers[cb_idx]))(ioc, pEventReply);
7775			handlers++;
7776		}
7777	}
7778	/* FIXME?  Examine results here? */
7779
7780	/*
7781	 *  If needed, send (a single) EventAck.
7782	 */
7783	if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) {
7784		devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7785			"EventAck required\n",ioc->name));
7786		if ((ii = SendEventAck(ioc, pEventReply)) != 0) {
7787			devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SendEventAck returned %d\n",
7788					ioc->name, ii));
7789		}
7790	}
7791
7792	*evHandlers = handlers;
7793	return r;
7794}
7795
7796/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7797/**
7798 *	mpt_fc_log_info - Log information returned from Fibre Channel IOC.
7799 *	@ioc: Pointer to MPT_ADAPTER structure
7800 *	@log_info: U32 LogInfo reply word from the IOC
7801 *
7802 *	Refer to lsi/mpi_log_fc.h.
7803 */
7804static void
7805mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
7806{
7807	char *desc = "unknown";
7808
7809	switch (log_info & 0xFF000000) {
7810	case MPI_IOCLOGINFO_FC_INIT_BASE:
7811		desc = "FCP Initiator";
7812		break;
7813	case MPI_IOCLOGINFO_FC_TARGET_BASE:
7814		desc = "FCP Target";
7815		break;
7816	case MPI_IOCLOGINFO_FC_LAN_BASE:
7817		desc = "LAN";
7818		break;
7819	case MPI_IOCLOGINFO_FC_MSG_BASE:
7820		desc = "MPI Message Layer";
7821		break;
7822	case MPI_IOCLOGINFO_FC_LINK_BASE:
7823		desc = "FC Link";
7824		break;
7825	case MPI_IOCLOGINFO_FC_CTX_BASE:
7826		desc = "Context Manager";
7827		break;
7828	case MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET:
7829		desc = "Invalid Field Offset";
7830		break;
7831	case MPI_IOCLOGINFO_FC_STATE_CHANGE:
7832		desc = "State Change Info";
7833		break;
7834	}
7835
7836	printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubClass={%s}, Value=(0x%06x)\n",
7837			ioc->name, log_info, desc, (log_info & 0xFFFFFF));
7838}
7839
7840/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7841/**
7842 *	mpt_spi_log_info - Log information returned from SCSI Parallel IOC.
7843 *	@ioc: Pointer to MPT_ADAPTER structure
7844 *	@log_info: U32 LogInfo word from the IOC
7845 *
7846 *	Refer to lsi/sp_log.h.
7847 */
7848static void
7849mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
7850{
7851	u32 info = log_info & 0x00FF0000;
7852	char *desc = "unknown";
7853
7854	switch (info) {
7855	case 0x00010000:
7856		desc = "bug! MID not found";
7857		break;
7858
7859	case 0x00020000:
7860		desc = "Parity Error";
7861		break;
7862
7863	case 0x00030000:
7864		desc = "ASYNC Outbound Overrun";
7865		break;
7866
7867	case 0x00040000:
7868		desc = "SYNC Offset Error";
7869		break;
7870
7871	case 0x00050000:
7872		desc = "BM Change";
7873		break;
7874
7875	case 0x00060000:
7876		desc = "Msg In Overflow";
7877		break;
7878
7879	case 0x00070000:
7880		desc = "DMA Error";
7881		break;
7882
7883	case 0x00080000:
7884		desc = "Outbound DMA Overrun";
7885		break;
7886
7887	case 0x00090000:
7888		desc = "Task Management";
7889		break;
7890
7891	case 0x000A0000:
7892		desc = "Device Problem";
7893		break;
7894
7895	case 0x000B0000:
7896		desc = "Invalid Phase Change";
7897		break;
7898
7899	case 0x000C0000:
7900		desc = "Untagged Table Size";
7901		break;
7902
7903	}
7904
7905	printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc);
7906}
7907
7908/* strings for sas loginfo */
7909	static char *originator_str[] = {
7910		"IOP",						/* 00h */
7911		"PL",						/* 01h */
7912		"IR"						/* 02h */
7913	};
7914	static char *iop_code_str[] = {
7915		NULL,						/* 00h */
7916		"Invalid SAS Address",				/* 01h */
7917		NULL,						/* 02h */
7918		"Invalid Page",					/* 03h */
7919		"Diag Message Error",				/* 04h */
7920		"Task Terminated",				/* 05h */
7921		"Enclosure Management",				/* 06h */
7922		"Target Mode"					/* 07h */
7923	};
7924	static char *pl_code_str[] = {
7925		NULL,						/* 00h */
7926		"Open Failure",					/* 01h */
7927		"Invalid Scatter Gather List",			/* 02h */
7928		"Wrong Relative Offset or Frame Length",	/* 03h */
7929		"Frame Transfer Error",				/* 04h */
7930		"Transmit Frame Connected Low",			/* 05h */
7931		"SATA Non-NCQ RW Error Bit Set",		/* 06h */
7932		"SATA Read Log Receive Data Error",		/* 07h */
7933		"SATA NCQ Fail All Commands After Error",	/* 08h */
7934		"SATA Error in Receive Set Device Bit FIS",	/* 09h */
7935		"Receive Frame Invalid Message",		/* 0Ah */
7936		"Receive Context Message Valid Error",		/* 0Bh */
7937		"Receive Frame Current Frame Error",		/* 0Ch */
7938		"SATA Link Down",				/* 0Dh */
7939		"Discovery SATA Init W IOS",			/* 0Eh */
7940		"Config Invalid Page",				/* 0Fh */
7941		"Discovery SATA Init Timeout",			/* 10h */
7942		"Reset",					/* 11h */
7943		"Abort",					/* 12h */
7944		"IO Not Yet Executed",				/* 13h */
7945		"IO Executed",					/* 14h */
7946		"Persistent Reservation Out Not Affiliation "
7947		    "Owner", 					/* 15h */
7948		"Open Transmit DMA Abort",			/* 16h */
7949		"IO Device Missing Delay Retry",		/* 17h */
7950		"IO Cancelled Due to Receive Error",		/* 18h */
7951		NULL,						/* 19h */
7952		NULL,						/* 1Ah */
7953		NULL,						/* 1Bh */
7954		NULL,						/* 1Ch */
7955		NULL,						/* 1Dh */
7956		NULL,						/* 1Eh */
7957		NULL,						/* 1Fh */
7958		"Enclosure Management"				/* 20h */
7959	};
7960	static char *ir_code_str[] = {
7961		"Raid Action Error",				/* 00h */
7962		NULL,						/* 00h */
7963		NULL,						/* 01h */
7964		NULL,						/* 02h */
7965		NULL,						/* 03h */
7966		NULL,						/* 04h */
7967		NULL,						/* 05h */
7968		NULL,						/* 06h */
7969		NULL						/* 07h */
7970	};
7971	static char *raid_sub_code_str[] = {
7972		NULL, 						/* 00h */
7973		"Volume Creation Failed: Data Passed too "
7974		    "Large", 					/* 01h */
7975		"Volume Creation Failed: Duplicate Volumes "
7976		    "Attempted", 				/* 02h */
7977		"Volume Creation Failed: Max Number "
7978		    "Supported Volumes Exceeded",		/* 03h */
7979		"Volume Creation Failed: DMA Error",		/* 04h */
7980		"Volume Creation Failed: Invalid Volume Type",	/* 05h */
7981		"Volume Creation Failed: Error Reading "
7982		    "MFG Page 4", 				/* 06h */
7983		"Volume Creation Failed: Creating Internal "
7984		    "Structures", 				/* 07h */
7985		NULL,						/* 08h */
7986		NULL,						/* 09h */
7987		NULL,						/* 0Ah */
7988		NULL,						/* 0Bh */
7989		NULL,						/* 0Ch */
7990		NULL,						/* 0Dh */
7991		NULL,						/* 0Eh */
7992		NULL,						/* 0Fh */
7993		"Activation failed: Already Active Volume", 	/* 10h */
7994		"Activation failed: Unsupported Volume Type", 	/* 11h */
7995		"Activation failed: Too Many Active Volumes", 	/* 12h */
7996		"Activation failed: Volume ID in Use", 		/* 13h */
7997		"Activation failed: Reported Failure", 		/* 14h */
7998		"Activation failed: Importing a Volume", 	/* 15h */
7999		NULL,						/* 16h */
8000		NULL,						/* 17h */
8001		NULL,						/* 18h */
8002		NULL,						/* 19h */
8003		NULL,						/* 1Ah */
8004		NULL,						/* 1Bh */
8005		NULL,						/* 1Ch */
8006		NULL,						/* 1Dh */
8007		NULL,						/* 1Eh */
8008		NULL,						/* 1Fh */
8009		"Phys Disk failed: Too Many Phys Disks", 	/* 20h */
8010		"Phys Disk failed: Data Passed too Large",	/* 21h */
8011		"Phys Disk failed: DMA Error", 			/* 22h */
8012		"Phys Disk failed: Invalid <channel:id>", 	/* 23h */
8013		"Phys Disk failed: Creating Phys Disk Config "
8014		    "Page", 					/* 24h */
8015		NULL,						/* 25h */
8016		NULL,						/* 26h */
8017		NULL,						/* 27h */
8018		NULL,						/* 28h */
8019		NULL,						/* 29h */
8020		NULL,						/* 2Ah */
8021		NULL,						/* 2Bh */
8022		NULL,						/* 2Ch */
8023		NULL,						/* 2Dh */
8024		NULL,						/* 2Eh */
8025		NULL,						/* 2Fh */
8026		"Compatibility Error: IR Disabled",		/* 30h */
8027		"Compatibility Error: Inquiry Command Failed",	/* 31h */
8028		"Compatibility Error: Device not Direct Access "
8029		    "Device ",					/* 32h */
8030		"Compatibility Error: Removable Device Found",	/* 33h */
8031		"Compatibility Error: Device SCSI Version not "
8032		    "2 or Higher", 				/* 34h */
8033		"Compatibility Error: SATA Device, 48 BIT LBA "
8034		    "not Supported", 				/* 35h */
8035		"Compatibility Error: Device doesn't have "
8036		    "512 Byte Block Sizes", 			/* 36h */
8037		"Compatibility Error: Volume Type Check Failed", /* 37h */
8038		"Compatibility Error: Volume Type is "
8039		    "Unsupported by FW", 			/* 38h */
8040		"Compatibility Error: Disk Drive too Small for "
8041		    "use in Volume", 				/* 39h */
8042		"Compatibility Error: Phys Disk for Create "
8043		    "Volume not Found", 			/* 3Ah */
8044		"Compatibility Error: Too Many or too Few "
8045		    "Disks for Volume Type", 			/* 3Bh */
8046		"Compatibility Error: Disk stripe Sizes "
8047		    "Must be 64KB", 				/* 3Ch */
8048		"Compatibility Error: IME Size Limited to < 2TB", /* 3Dh */
8049	};
8050
8051/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8052/**
8053 *	mpt_sas_log_info - Log information returned from SAS IOC.
8054 *	@ioc: Pointer to MPT_ADAPTER structure
8055 *	@log_info: U32 LogInfo reply word from the IOC
8056 *	@cb_idx: callback function's handle
8057 *
8058 *	Refer to lsi/mpi_log_sas.h.
8059 **/
8060static void
8061mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info, u8 cb_idx)
8062{
8063	union loginfo_type {
8064		u32	loginfo;
8065		struct {
8066			u32	subcode:16;
8067			u32	code:8;
8068			u32	originator:4;
8069			u32	bus_type:4;
8070		} dw;
8071	};
8072	union loginfo_type sas_loginfo;
8073	char *originator_desc = NULL;
8074	char *code_desc = NULL;
8075	char *sub_code_desc = NULL;
8076
8077	sas_loginfo.loginfo = log_info;
8078	if ((sas_loginfo.dw.bus_type != 3 /*SAS*/) &&
8079	    (sas_loginfo.dw.originator < ARRAY_SIZE(originator_str)))
8080		return;
8081
8082	originator_desc = originator_str[sas_loginfo.dw.originator];
8083
8084	switch (sas_loginfo.dw.originator) {
8085
8086		case 0:  /* IOP */
8087			if (sas_loginfo.dw.code <
8088			    ARRAY_SIZE(iop_code_str))
8089				code_desc = iop_code_str[sas_loginfo.dw.code];
8090			break;
8091		case 1:  /* PL */
8092			if (sas_loginfo.dw.code <
8093			    ARRAY_SIZE(pl_code_str))
8094				code_desc = pl_code_str[sas_loginfo.dw.code];
8095			break;
8096		case 2:  /* IR */
8097			if (sas_loginfo.dw.code >=
8098			    ARRAY_SIZE(ir_code_str))
8099				break;
8100			code_desc = ir_code_str[sas_loginfo.dw.code];
8101			if (sas_loginfo.dw.subcode >=
8102			    ARRAY_SIZE(raid_sub_code_str))
8103				break;
8104			if (sas_loginfo.dw.code == 0)
8105				sub_code_desc =
8106				    raid_sub_code_str[sas_loginfo.dw.subcode];
8107			break;
8108		default:
8109			return;
8110	}
8111
8112	if (sub_code_desc != NULL)
8113		printk(MYIOC_s_INFO_FMT
8114			"LogInfo(0x%08x): Originator={%s}, Code={%s},"
8115			" SubCode={%s} cb_idx %s\n",
8116			ioc->name, log_info, originator_desc, code_desc,
8117			sub_code_desc, MptCallbacksName[cb_idx]);
8118	else if (code_desc != NULL)
8119		printk(MYIOC_s_INFO_FMT
8120			"LogInfo(0x%08x): Originator={%s}, Code={%s},"
8121			" SubCode(0x%04x) cb_idx %s\n",
8122			ioc->name, log_info, originator_desc, code_desc,
8123			sas_loginfo.dw.subcode, MptCallbacksName[cb_idx]);
8124	else
8125		printk(MYIOC_s_INFO_FMT
8126			"LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
8127			" SubCode(0x%04x) cb_idx %s\n",
8128			ioc->name, log_info, originator_desc,
8129			sas_loginfo.dw.code, sas_loginfo.dw.subcode,
8130			MptCallbacksName[cb_idx]);
8131}
8132
8133/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8134/**
8135 *	mpt_iocstatus_info_config - IOCSTATUS information for config pages
8136 *	@ioc: Pointer to MPT_ADAPTER structure
8137 *	@ioc_status: U32 IOCStatus word from IOC
8138 *	@mf: Pointer to MPT request frame
8139 *
8140 *	Refer to lsi/mpi.h.
8141 **/
8142static void
8143mpt_iocstatus_info_config(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
8144{
8145	Config_t *pReq = (Config_t *)mf;
8146	char extend_desc[EVENT_DESCR_STR_SZ];
8147	char *desc = NULL;
8148	u32 form;
8149	u8 page_type;
8150
8151	if (pReq->Header.PageType == MPI_CONFIG_PAGETYPE_EXTENDED)
8152		page_type = pReq->ExtPageType;
8153	else
8154		page_type = pReq->Header.PageType;
8155
8156	/*
8157	 * ignore invalid page messages for GET_NEXT_HANDLE
8158	 */
8159	form = le32_to_cpu(pReq->PageAddress);
8160	if (ioc_status == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
8161		if (page_type == MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE ||
8162		    page_type == MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER ||
8163		    page_type == MPI_CONFIG_EXTPAGETYPE_ENCLOSURE) {
8164			if ((form >> MPI_SAS_DEVICE_PGAD_FORM_SHIFT) ==
8165				MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE)
8166				return;
8167		}
8168		if (page_type == MPI_CONFIG_PAGETYPE_FC_DEVICE)
8169			if ((form & MPI_FC_DEVICE_PGAD_FORM_MASK) ==
8170				MPI_FC_DEVICE_PGAD_FORM_NEXT_DID)
8171				return;
8172	}
8173
8174	snprintf(extend_desc, EVENT_DESCR_STR_SZ,
8175	    "type=%02Xh, page=%02Xh, action=%02Xh, form=%08Xh",
8176	    page_type, pReq->Header.PageNumber, pReq->Action, form);
8177
8178	switch (ioc_status) {
8179
8180	case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
8181		desc = "Config Page Invalid Action";
8182		break;
8183
8184	case MPI_IOCSTATUS_CONFIG_INVALID_TYPE:   /* 0x0021 */
8185		desc = "Config Page Invalid Type";
8186		break;
8187
8188	case MPI_IOCSTATUS_CONFIG_INVALID_PAGE:   /* 0x0022 */
8189		desc = "Config Page Invalid Page";
8190		break;
8191
8192	case MPI_IOCSTATUS_CONFIG_INVALID_DATA:   /* 0x0023 */
8193		desc = "Config Page Invalid Data";
8194		break;
8195
8196	case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS:    /* 0x0024 */
8197		desc = "Config Page No Defaults";
8198		break;
8199
8200	case MPI_IOCSTATUS_CONFIG_CANT_COMMIT:    /* 0x0025 */
8201		desc = "Config Page Can't Commit";
8202		break;
8203	}
8204
8205	if (!desc)
8206		return;
8207
8208	dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOCStatus(0x%04X): %s: %s\n",
8209	    ioc->name, ioc_status, desc, extend_desc));
8210}
8211
8212/**
8213 *	mpt_iocstatus_info - IOCSTATUS information returned from IOC.
8214 *	@ioc: Pointer to MPT_ADAPTER structure
8215 *	@ioc_status: U32 IOCStatus word from IOC
8216 *	@mf: Pointer to MPT request frame
8217 *
8218 *	Refer to lsi/mpi.h.
8219 **/
8220static void
8221mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
8222{
8223	u32 status = ioc_status & MPI_IOCSTATUS_MASK;
8224	char *desc = NULL;
8225
8226	switch (status) {
8227
8228/****************************************************************************/
8229/*  Common IOCStatus values for all replies                                 */
8230/****************************************************************************/
8231
8232	case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
8233		desc = "Invalid Function";
8234		break;
8235
8236	case MPI_IOCSTATUS_BUSY: /* 0x0002 */
8237		desc = "Busy";
8238		break;
8239
8240	case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
8241		desc = "Invalid SGL";
8242		break;
8243
8244	case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
8245		desc = "Internal Error";
8246		break;
8247
8248	case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
8249		desc = "Reserved";
8250		break;
8251
8252	case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
8253		desc = "Insufficient Resources";
8254		break;
8255
8256	case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
8257		desc = "Invalid Field";
8258		break;
8259
8260	case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
8261		desc = "Invalid State";
8262		break;
8263
8264/****************************************************************************/
8265/*  Config IOCStatus values                                                 */
8266/****************************************************************************/
8267
8268	case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
8269	case MPI_IOCSTATUS_CONFIG_INVALID_TYPE:   /* 0x0021 */
8270	case MPI_IOCSTATUS_CONFIG_INVALID_PAGE:   /* 0x0022 */
8271	case MPI_IOCSTATUS_CONFIG_INVALID_DATA:   /* 0x0023 */
8272	case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS:    /* 0x0024 */
8273	case MPI_IOCSTATUS_CONFIG_CANT_COMMIT:    /* 0x0025 */
8274		mpt_iocstatus_info_config(ioc, status, mf);
8275		break;
8276
8277/****************************************************************************/
8278/*  SCSIIO Reply (SPI, FCP, SAS) initiator values                           */
8279/*                                                                          */
8280/*  Look at mptscsih_iocstatus_info_scsiio in mptscsih.c */
8281/*                                                                          */
8282/****************************************************************************/
8283
8284	case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
8285	case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
8286	case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
8287	case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
8288	case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
8289	case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
8290	case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
8291	case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
8292	case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
8293	case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
8294	case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
8295	case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
8296	case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
8297		break;
8298
8299/****************************************************************************/
8300/*  SCSI Target values                                                      */
8301/****************************************************************************/
8302
8303	case MPI_IOCSTATUS_TARGET_PRIORITY_IO: /* 0x0060 */
8304		desc = "Target: Priority IO";
8305		break;
8306
8307	case MPI_IOCSTATUS_TARGET_INVALID_PORT: /* 0x0061 */
8308		desc = "Target: Invalid Port";
8309		break;
8310
8311	case MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX: /* 0x0062 */
8312		desc = "Target Invalid IO Index:";
8313		break;
8314
8315	case MPI_IOCSTATUS_TARGET_ABORTED: /* 0x0063 */
8316		desc = "Target: Aborted";
8317		break;
8318
8319	case MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE: /* 0x0064 */
8320		desc = "Target: No Conn Retryable";
8321		break;
8322
8323	case MPI_IOCSTATUS_TARGET_NO_CONNECTION: /* 0x0065 */
8324		desc = "Target: No Connection";
8325		break;
8326
8327	case MPI_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH: /* 0x006A */
8328		desc = "Target: Transfer Count Mismatch";
8329		break;
8330
8331	case MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT: /* 0x006B */
8332		desc = "Target: STS Data not Sent";
8333		break;
8334
8335	case MPI_IOCSTATUS_TARGET_DATA_OFFSET_ERROR: /* 0x006D */
8336		desc = "Target: Data Offset Error";
8337		break;
8338
8339	case MPI_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA: /* 0x006E */
8340		desc = "Target: Too Much Write Data";
8341		break;
8342
8343	case MPI_IOCSTATUS_TARGET_IU_TOO_SHORT: /* 0x006F */
8344		desc = "Target: IU Too Short";
8345		break;
8346
8347	case MPI_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT: /* 0x0070 */
8348		desc = "Target: ACK NAK Timeout";
8349		break;
8350
8351	case MPI_IOCSTATUS_TARGET_NAK_RECEIVED: /* 0x0071 */
8352		desc = "Target: Nak Received";
8353		break;
8354
8355/****************************************************************************/
8356/*  Fibre Channel Direct Access values                                      */
8357/****************************************************************************/
8358
8359	case MPI_IOCSTATUS_FC_ABORTED: /* 0x0066 */
8360		desc = "FC: Aborted";
8361		break;
8362
8363	case MPI_IOCSTATUS_FC_RX_ID_INVALID: /* 0x0067 */
8364		desc = "FC: RX ID Invalid";
8365		break;
8366
8367	case MPI_IOCSTATUS_FC_DID_INVALID: /* 0x0068 */
8368		desc = "FC: DID Invalid";
8369		break;
8370
8371	case MPI_IOCSTATUS_FC_NODE_LOGGED_OUT: /* 0x0069 */
8372		desc = "FC: Node Logged Out";
8373		break;
8374
8375	case MPI_IOCSTATUS_FC_EXCHANGE_CANCELED: /* 0x006C */
8376		desc = "FC: Exchange Canceled";
8377		break;
8378
8379/****************************************************************************/
8380/*  LAN values                                                              */
8381/****************************************************************************/
8382
8383	case MPI_IOCSTATUS_LAN_DEVICE_NOT_FOUND: /* 0x0080 */
8384		desc = "LAN: Device not Found";
8385		break;
8386
8387	case MPI_IOCSTATUS_LAN_DEVICE_FAILURE: /* 0x0081 */
8388		desc = "LAN: Device Failure";
8389		break;
8390
8391	case MPI_IOCSTATUS_LAN_TRANSMIT_ERROR: /* 0x0082 */
8392		desc = "LAN: Transmit Error";
8393		break;
8394
8395	case MPI_IOCSTATUS_LAN_TRANSMIT_ABORTED: /* 0x0083 */
8396		desc = "LAN: Transmit Aborted";
8397		break;
8398
8399	case MPI_IOCSTATUS_LAN_RECEIVE_ERROR: /* 0x0084 */
8400		desc = "LAN: Receive Error";
8401		break;
8402
8403	case MPI_IOCSTATUS_LAN_RECEIVE_ABORTED: /* 0x0085 */
8404		desc = "LAN: Receive Aborted";
8405		break;
8406
8407	case MPI_IOCSTATUS_LAN_PARTIAL_PACKET: /* 0x0086 */
8408		desc = "LAN: Partial Packet";
8409		break;
8410
8411	case MPI_IOCSTATUS_LAN_CANCELED: /* 0x0087 */
8412		desc = "LAN: Canceled";
8413		break;
8414
8415/****************************************************************************/
8416/*  Serial Attached SCSI values                                             */
8417/****************************************************************************/
8418
8419	case MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED: /* 0x0090 */
8420		desc = "SAS: SMP Request Failed";
8421		break;
8422
8423	case MPI_IOCSTATUS_SAS_SMP_DATA_OVERRUN: /* 0x0090 */
8424		desc = "SAS: SMP Data Overrun";
8425		break;
8426
8427	default:
8428		desc = "Others";
8429		break;
8430	}
8431
8432	if (!desc)
8433		return;
8434
8435	dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOCStatus(0x%04X): %s\n",
8436	    ioc->name, status, desc));
8437}
8438
8439/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8440EXPORT_SYMBOL(mpt_attach);
8441EXPORT_SYMBOL(mpt_detach);
8442#ifdef CONFIG_PM
8443EXPORT_SYMBOL(mpt_resume);
8444EXPORT_SYMBOL(mpt_suspend);
8445#endif
8446EXPORT_SYMBOL(ioc_list);
8447EXPORT_SYMBOL(mpt_register);
8448EXPORT_SYMBOL(mpt_deregister);
8449EXPORT_SYMBOL(mpt_event_register);
8450EXPORT_SYMBOL(mpt_event_deregister);
8451EXPORT_SYMBOL(mpt_reset_register);
8452EXPORT_SYMBOL(mpt_reset_deregister);
8453EXPORT_SYMBOL(mpt_device_driver_register);
8454EXPORT_SYMBOL(mpt_device_driver_deregister);
8455EXPORT_SYMBOL(mpt_get_msg_frame);
8456EXPORT_SYMBOL(mpt_put_msg_frame);
8457EXPORT_SYMBOL(mpt_put_msg_frame_hi_pri);
8458EXPORT_SYMBOL(mpt_free_msg_frame);
8459EXPORT_SYMBOL(mpt_send_handshake_request);
8460EXPORT_SYMBOL(mpt_verify_adapter);
8461EXPORT_SYMBOL(mpt_GetIocState);
8462EXPORT_SYMBOL(mpt_print_ioc_summary);
8463EXPORT_SYMBOL(mpt_HardResetHandler);
8464EXPORT_SYMBOL(mpt_config);
8465EXPORT_SYMBOL(mpt_findImVolumes);
8466EXPORT_SYMBOL(mpt_alloc_fw_memory);
8467EXPORT_SYMBOL(mpt_free_fw_memory);
8468EXPORT_SYMBOL(mptbase_sas_persist_operation);
8469EXPORT_SYMBOL(mpt_raid_phys_disk_pg0);
8470
8471/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8472/**
8473 *	fusion_init - Fusion MPT base driver initialization routine.
8474 *
8475 *	Returns 0 for success, non-zero for failure.
8476 */
8477static int __init
8478fusion_init(void)
8479{
8480	u8 cb_idx;
8481
8482	show_mptmod_ver(my_NAME, my_VERSION);
8483	printk(KERN_INFO COPYRIGHT "\n");
8484
8485	for (cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
8486		MptCallbacks[cb_idx] = NULL;
8487		MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
8488		MptEvHandlers[cb_idx] = NULL;
8489		MptResetHandlers[cb_idx] = NULL;
8490	}
8491
8492	/*  Register ourselves (mptbase) in order to facilitate
8493	 *  EventNotification handling.
8494	 */
8495	mpt_base_index = mpt_register(mptbase_reply, MPTBASE_DRIVER,
8496	    "mptbase_reply");
8497
8498	/* Register for hard reset handling callbacks.
8499	 */
8500	mpt_reset_register(mpt_base_index, mpt_ioc_reset);
8501
8502#ifdef CONFIG_PROC_FS
8503	(void) procmpt_create();
8504#endif
8505	return 0;
8506}
8507
8508/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8509/**
8510 *	fusion_exit - Perform driver unload cleanup.
8511 *
8512 *	This routine frees all resources associated with each MPT adapter
8513 *	and removes all %MPT_PROCFS_MPTBASEDIR entries.
8514 */
8515static void __exit
8516fusion_exit(void)
8517{
8518
8519	mpt_reset_deregister(mpt_base_index);
8520
8521#ifdef CONFIG_PROC_FS
8522	procmpt_destroy();
8523#endif
8524}
8525
8526module_init(fusion_init);
8527module_exit(fusion_exit);
~/ Read-only file preview.