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