xref: /linux/drivers/scsi/qla2xxx/qla_mbx.c (revision 60b2737de1b1ddfdb90f3ba622634eb49d6f3603)
1 /*
2  *                  QLOGIC LINUX SOFTWARE
3  *
4  * QLogic ISP2x00 device driver for Linux 2.6.x
5  * Copyright (C) 2003-2004 QLogic Corporation
6  * (www.qlogic.com)
7  *
8  * This program is free software; you can redistribute it and/or modify it
9  * under the terms of the GNU General Public License as published by the
10  * Free Software Foundation; either version 2, or (at your option) any
11  * later version.
12  *
13  * This program is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * General Public License for more details.
17  *
18  */
19 #include "qla_def.h"
20 
21 #include <linux/delay.h>
22 
23 static void
24 qla2x00_mbx_sem_timeout(unsigned long data)
25 {
26 	struct semaphore	*sem_ptr = (struct semaphore *)data;
27 
28 	DEBUG11(printk("qla2x00_sem_timeout: entered.\n");)
29 
30 	if (sem_ptr != NULL) {
31 		up(sem_ptr);
32 	}
33 
34 	DEBUG11(printk("qla2x00_mbx_sem_timeout: exiting.\n");)
35 }
36 
37 /*
38  * qla2x00_mailbox_command
39  *	Issue mailbox command and waits for completion.
40  *
41  * Input:
42  *	ha = adapter block pointer.
43  *	mcp = driver internal mbx struct pointer.
44  *
45  * Output:
46  *	mb[MAX_MAILBOX_REGISTER_COUNT] = returned mailbox data.
47  *
48  * Returns:
49  *	0 : QLA_SUCCESS = cmd performed success
50  *	1 : QLA_FUNCTION_FAILED   (error encountered)
51  *	6 : QLA_FUNCTION_TIMEOUT (timeout condition encountered)
52  *
53  * Context:
54  *	Kernel context.
55  */
56 static int
57 qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp)
58 {
59 	int		rval;
60 	unsigned long    flags = 0;
61 	device_reg_t __iomem *reg = ha->iobase;
62 	struct timer_list	tmp_intr_timer;
63 	uint8_t		abort_active = test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags);
64 	uint8_t		io_lock_on = ha->flags.init_done;
65 	uint16_t	command;
66 	uint16_t	*iptr;
67 	uint16_t __iomem *optr;
68 	uint32_t	cnt;
69 	uint32_t	mboxes;
70 	unsigned long	mbx_flags = 0;
71 	unsigned long	wait_time;
72 
73 	rval = QLA_SUCCESS;
74 
75 	DEBUG11(printk("qla2x00_mailbox_command(%ld): entered.\n",
76 	    ha->host_no);)
77 	/*
78 	 * Wait for active mailbox commands to finish by waiting at most
79 	 * tov seconds. This is to serialize actual issuing of mailbox cmds
80 	 * during non ISP abort time.
81 	 */
82 	if (!abort_active) {
83 		if (qla2x00_down_timeout(&ha->mbx_cmd_sem, mcp->tov * HZ)) {
84 			/* Timeout occurred. Return error. */
85 			DEBUG2_3_11(printk("qla2x00_mailbox_command(%ld): cmd "
86 			    "access timeout. Exiting.\n", ha->host_no);)
87 			return QLA_FUNCTION_TIMEOUT;
88 		}
89 	}
90 
91 	ha->flags.mbox_busy = 1;
92 	/* Save mailbox command for debug */
93 	ha->mcp = mcp;
94 
95 	/* Try to get mailbox register access */
96 	if (!abort_active)
97 		spin_lock_irqsave(&ha->mbx_reg_lock, mbx_flags);
98 
99 	DEBUG11(printk("scsi%d: prepare to issue mbox cmd=0x%x.\n",
100 	    (int)ha->host_no, mcp->mb[0]);)
101 
102 	spin_lock_irqsave(&ha->hardware_lock, flags);
103 
104 	/* Load mailbox registers. */
105 	optr = (uint16_t __iomem *)MAILBOX_REG(ha, reg, 0);
106 
107 	iptr = mcp->mb;
108 	command = mcp->mb[0];
109 	mboxes = mcp->out_mb;
110 
111 	for (cnt = 0; cnt < ha->mbx_count; cnt++) {
112 		if (IS_QLA2200(ha) && cnt == 8)
113 			optr = (uint16_t __iomem *)MAILBOX_REG(ha, reg, 8);
114 		if (mboxes & BIT_0)
115 			WRT_REG_WORD(optr, *iptr);
116 
117 		mboxes >>= 1;
118 		optr++;
119 		iptr++;
120 	}
121 
122 #if defined(QL_DEBUG_LEVEL_1)
123 	printk("qla2x00_mailbox_command: Loaded MBX registers "
124 	    "(displayed in bytes) = \n");
125 	qla2x00_dump_buffer((uint8_t *)mcp->mb, 16);
126 	printk("\n");
127 	qla2x00_dump_buffer(((uint8_t *)mcp->mb + 0x10), 16);
128 	printk("\n");
129 	qla2x00_dump_buffer(((uint8_t *)mcp->mb + 0x20), 8);
130 	printk("\n");
131 	printk("qla2x00_mailbox_command: I/O address = %lx.\n",
132 	    (u_long)optr);
133 	qla2x00_dump_regs(ha);
134 #endif
135 
136 	/* Issue set host interrupt command to send cmd out. */
137 	ha->flags.mbox_int = 0;
138 	clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
139 
140 	/* Unlock mbx registers and wait for interrupt */
141 
142 	DEBUG11(printk("qla2x00_mailbox_command: going to unlock irq & "
143 	    "waiting for interrupt. jiffies=%lx.\n", jiffies);)
144 
145 	/* Wait for mbx cmd completion until timeout */
146 
147 	if (!abort_active && io_lock_on) {
148 		/* sleep on completion semaphore */
149 		DEBUG11(printk("qla2x00_mailbox_command(%ld): "
150 		    "INTERRUPT MODE. Initializing timer.\n",
151 		    ha->host_no);)
152 
153 		init_timer(&tmp_intr_timer);
154 		tmp_intr_timer.data = (unsigned long)&ha->mbx_intr_sem;
155 		tmp_intr_timer.expires = jiffies + mcp->tov * HZ;
156 		tmp_intr_timer.function =
157 		    (void (*)(unsigned long))qla2x00_mbx_sem_timeout;
158 
159 		DEBUG11(printk("qla2x00_mailbox_command(%ld): "
160 		    "Adding timer.\n", ha->host_no);)
161 		add_timer(&tmp_intr_timer);
162 
163 		DEBUG11(printk("qla2x00_mailbox_command: going to "
164 		    "unlock & sleep. time=0x%lx.\n", jiffies);)
165 
166 		set_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
167 
168 		WRT_REG_WORD(&reg->hccr, HCCR_SET_HOST_INT);
169 		spin_unlock_irqrestore(&ha->hardware_lock, flags);
170 
171 		if (!abort_active)
172 			spin_unlock_irqrestore(&ha->mbx_reg_lock, mbx_flags);
173 
174 		/* Wait for either the timer to expire
175 		 * or the mbox completion interrupt
176 		 */
177 		down(&ha->mbx_intr_sem);
178 
179 		DEBUG11(printk("qla2x00_mailbox_command:"
180 		    "waking up."
181 		    "time=0x%lx\n", jiffies);)
182 		clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
183 
184 		/* delete the timer */
185 		del_timer(&tmp_intr_timer);
186 	} else {
187 
188 		DEBUG3_11(printk("qla2x00_mailbox_command(%ld): cmd=%x "
189 			"POLLING MODE.\n", ha->host_no, command);)
190 
191 		WRT_REG_WORD(&reg->hccr, HCCR_SET_HOST_INT);
192 		spin_unlock_irqrestore(&ha->hardware_lock, flags);
193 		if (!abort_active)
194 			spin_unlock_irqrestore(&ha->mbx_reg_lock, mbx_flags);
195 
196 		wait_time = jiffies + mcp->tov * HZ; /* wait at most tov secs */
197 		while (!ha->flags.mbox_int) {
198 			if (time_after(jiffies, wait_time))
199 				break;
200 
201 			/* Check for pending interrupts. */
202 			qla2x00_poll(ha);
203 
204 			udelay(10); /* v4.27 */
205 		} /* while */
206 	}
207 
208 	if (!abort_active)
209 		spin_lock_irqsave(&ha->mbx_reg_lock, mbx_flags);
210 
211 	/* Check whether we timed out */
212 	if (ha->flags.mbox_int) {
213 		uint16_t *iptr2;
214 
215 		DEBUG3_11(printk("qla2x00_mailbox_cmd: cmd %x completed.\n",
216 		    command);)
217 
218 		/* Got interrupt. Clear the flag. */
219 		ha->flags.mbox_int = 0;
220 		clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
221 
222 		if (ha->mailbox_out[0] != MBS_COMMAND_COMPLETE)
223 			rval = QLA_FUNCTION_FAILED;
224 
225 		/* Load return mailbox registers. */
226 		iptr2 = mcp->mb;
227 		iptr = (uint16_t *)&ha->mailbox_out[0];
228 		mboxes = mcp->in_mb;
229 		for (cnt = 0; cnt < ha->mbx_count; cnt++) {
230 			if (mboxes & BIT_0)
231 				*iptr2 = *iptr;
232 
233 			mboxes >>= 1;
234 			iptr2++;
235 			iptr++;
236 		}
237 	} else {
238 
239 #if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3) || \
240 		defined(QL_DEBUG_LEVEL_11)
241 		printk("qla2x00_mailbox_command(%ld): **** MB Command Timeout "
242 		    "for cmd %x ****\n", ha->host_no, command);
243 		printk("qla2x00_mailbox_command: icontrol=%x jiffies=%lx\n",
244 		    RD_REG_WORD(&reg->ictrl), jiffies);
245 		printk("qla2x00_mailbox_command: *** mailbox[0] = 0x%x ***\n",
246 		    RD_REG_WORD(optr));
247 		qla2x00_dump_regs(ha);
248 #endif
249 
250 		rval = QLA_FUNCTION_TIMEOUT;
251 	}
252 
253 	if (!abort_active)
254 		spin_unlock_irqrestore(&ha->mbx_reg_lock, mbx_flags);
255 
256 	ha->flags.mbox_busy = 0;
257 
258 	/* Clean up */
259 	ha->mcp = NULL;
260 
261 	if (!abort_active) {
262 		DEBUG11(printk("qla2x00_mailbox_cmd: checking for additional "
263 		    "resp interrupt.\n");)
264 
265 		/* polling mode for non isp_abort commands. */
266 		qla2x00_poll(ha);
267 	}
268 
269 	if (rval == QLA_FUNCTION_TIMEOUT) {
270 		if (!io_lock_on || (mcp->flags & IOCTL_CMD)) {
271 			/* not in dpc. schedule it for dpc to take over. */
272 			DEBUG(printk("qla2x00_mailbox_command(%ld): timeout "
273 			    "schedule isp_abort_needed.\n",
274 			    ha->host_no);)
275 			DEBUG2_3_11(printk("qla2x00_mailbox_command(%ld): "
276 			    "timeout schedule isp_abort_needed.\n",
277 			    ha->host_no);)
278 			qla_printk(KERN_WARNING, ha,
279 			    "Mailbox command timeout occured. Scheduling ISP "
280 			    "abort.\n");
281 			set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
282 			if (ha->dpc_wait && !ha->dpc_active)
283 				up(ha->dpc_wait);
284 
285 		} else if (!abort_active) {
286 
287 			/* call abort directly since we are in the DPC thread */
288 			DEBUG(printk("qla2x00_mailbox_command(%ld): timeout "
289 			    "calling abort_isp\n", ha->host_no);)
290 			DEBUG2_3_11(printk("qla2x00_mailbox_command(%ld): "
291 			    "timeout calling abort_isp\n", ha->host_no);)
292 			qla_printk(KERN_WARNING, ha,
293 			    "Mailbox command timeout occured. Issuing ISP "
294 			    "abort.\n");
295 
296 			set_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags);
297 			clear_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
298 			if (qla2x00_abort_isp(ha)) {
299 				/* failed. retry later. */
300 				set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
301 			}
302 			clear_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags);
303 
304 			DEBUG(printk("qla2x00_mailbox_command: finished "
305 			    "abort_isp\n");)
306 			DEBUG2_3_11(printk("qla2x00_mailbox_command: finished "
307 			    "abort_isp\n");)
308 		}
309 	}
310 
311 	/* Allow next mbx cmd to come in. */
312 	if (!abort_active)
313 		up(&ha->mbx_cmd_sem);
314 
315 	if (rval) {
316 		DEBUG2_3_11(printk("qla2x00_mailbox_command(%ld): **** FAILED. "
317 		    "mbx0=%x, mbx1=%x, mbx2=%x, cmd=%x ****\n",
318 		ha->host_no, mcp->mb[0], mcp->mb[1], mcp->mb[2], command);)
319 	} else {
320 		DEBUG11(printk("qla2x00_mailbox_command(%ld): done.\n",
321 		    ha->host_no);)
322 	}
323 
324 	DEBUG11(printk("qla2x00_mailbox_command(%ld): exiting.\n",
325 	    ha->host_no);)
326 
327 	return rval;
328 }
329 
330 /*
331  * qla2x00_load_ram
332  *	Load adapter RAM using DMA.
333  *
334  * Input:
335  *	ha = adapter block pointer.
336  *
337  * Returns:
338  *	qla2x00 local function return status code.
339  *
340  * Context:
341  *	Kernel context.
342  */
343 int
344 qla2x00_load_ram(scsi_qla_host_t *ha, dma_addr_t req_dma, uint16_t risc_addr,
345     uint16_t risc_code_size)
346 {
347 	int rval;
348 	mbx_cmd_t mc;
349 	mbx_cmd_t *mcp = &mc;
350 	uint32_t	req_len;
351 	dma_addr_t	nml_dma;
352 	uint32_t	nml_len;
353 	uint32_t	normalized;
354 
355 	DEBUG11(printk("qla2x00_load_ram(%ld): entered.\n",
356 	    ha->host_no);)
357 
358 	req_len = risc_code_size;
359 	nml_dma = 0;
360 	nml_len = 0;
361 
362 	normalized = qla2x00_normalize_dma_addr(&req_dma, &req_len, &nml_dma,
363 	    &nml_len);
364 
365 	/* Load first segment */
366 	mcp->mb[0] = MBC_LOAD_RISC_RAM;
367 	mcp->mb[1] = risc_addr;
368 	mcp->mb[2] = MSW(req_dma);
369 	mcp->mb[3] = LSW(req_dma);
370 	mcp->mb[4] = (uint16_t)req_len;
371 	mcp->mb[6] = MSW(MSD(req_dma));
372 	mcp->mb[7] = LSW(MSD(req_dma));
373 	mcp->out_mb = MBX_7|MBX_6|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
374 	mcp->in_mb = MBX_0;
375 	mcp->tov = 30;
376 	mcp->flags = 0;
377 	rval = qla2x00_mailbox_command(ha, mcp);
378 
379 	/* Load second segment - if necessary */
380 	if (normalized && (rval == QLA_SUCCESS)) {
381 		mcp->mb[0] = MBC_LOAD_RISC_RAM;
382 		mcp->mb[1] = risc_addr + (uint16_t)req_len;
383 		mcp->mb[2] = MSW(nml_dma);
384 		mcp->mb[3] = LSW(nml_dma);
385 		mcp->mb[4] = (uint16_t)nml_len;
386 		mcp->mb[6] = MSW(MSD(nml_dma));
387 		mcp->mb[7] = LSW(MSD(nml_dma));
388 		mcp->out_mb = MBX_7|MBX_6|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
389 		mcp->in_mb = MBX_0;
390 		mcp->tov = 30;
391 		mcp->flags = 0;
392 		rval = qla2x00_mailbox_command(ha, mcp);
393 	}
394 
395 	if (rval == QLA_SUCCESS) {
396 		/* Empty */
397 		DEBUG11(printk("qla2x00_load_ram(%ld): done.\n", ha->host_no);)
398 	} else {
399 		/* Empty */
400 		DEBUG2_3_11(printk("qla2x00_load_ram(%ld): failed. rval=%x "
401 		    "mb[0]=%x.\n", ha->host_no, rval, mcp->mb[0]);)
402 	}
403 	return rval;
404 }
405 
406 /*
407  * qla2x00_load_ram_ext
408  *	Load adapter extended RAM using DMA.
409  *
410  * Input:
411  *	ha = adapter block pointer.
412  *
413  * Returns:
414  *	qla2x00 local function return status code.
415  *
416  * Context:
417  *	Kernel context.
418  */
419 int
420 qla2x00_load_ram_ext(scsi_qla_host_t *ha, dma_addr_t req_dma,
421     uint32_t risc_addr, uint16_t risc_code_size)
422 {
423 	int rval;
424 	mbx_cmd_t mc;
425 	mbx_cmd_t *mcp = &mc;
426 	uint32_t	req_len;
427 	dma_addr_t	nml_dma;
428 	uint32_t	nml_len;
429 	uint32_t	normalized;
430 
431 	DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no));
432 
433 	req_len = risc_code_size;
434 	nml_dma = 0;
435 	nml_len = 0;
436 
437 	normalized = qla2x00_normalize_dma_addr(&req_dma, &req_len, &nml_dma,
438 	    &nml_len);
439 
440 	/* Load first segment */
441 	mcp->mb[0] = MBC_LOAD_RISC_RAM_EXTENDED;
442 	mcp->mb[1] = LSW(risc_addr);
443 	mcp->mb[2] = MSW(req_dma);
444 	mcp->mb[3] = LSW(req_dma);
445 	mcp->mb[4] = (uint16_t)req_len;
446 	mcp->mb[6] = MSW(MSD(req_dma));
447 	mcp->mb[7] = LSW(MSD(req_dma));
448 	mcp->mb[8] = MSW(risc_addr);
449 	mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
450 	mcp->in_mb = MBX_0;
451 	mcp->tov = 30;
452 	mcp->flags = 0;
453 	rval = qla2x00_mailbox_command(ha, mcp);
454 
455 	/* Load second segment - if necessary */
456 	if (normalized && (rval == QLA_SUCCESS)) {
457 		risc_addr += req_len;
458 		mcp->mb[0] = MBC_LOAD_RISC_RAM_EXTENDED;
459 		mcp->mb[1] = LSW(risc_addr);
460 		mcp->mb[2] = MSW(nml_dma);
461 		mcp->mb[3] = LSW(nml_dma);
462 		mcp->mb[4] = (uint16_t)nml_len;
463 		mcp->mb[6] = MSW(MSD(nml_dma));
464 		mcp->mb[7] = LSW(MSD(nml_dma));
465 		mcp->mb[8] = MSW(risc_addr);
466 		mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
467 		mcp->in_mb = MBX_0;
468 		mcp->tov = 30;
469 		mcp->flags = 0;
470 		rval = qla2x00_mailbox_command(ha, mcp);
471 	}
472 
473 	if (rval != QLA_SUCCESS) {
474 		/*EMPTY*/
475 		DEBUG2_3_11(printk("%s(%ld): failed=%x mb[0]=%x.\n",
476 		    __func__, ha->host_no, rval, mcp->mb[0]));
477 	} else {
478 		/*EMPTY*/
479 		DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no));
480 	}
481 
482 	return rval;
483 }
484 
485 /*
486  * qla2x00_execute_fw
487  *	Start adapter firmware.
488  *
489  * Input:
490  *	ha = adapter block pointer.
491  *	TARGET_QUEUE_LOCK must be released.
492  *	ADAPTER_STATE_LOCK must be released.
493  *
494  * Returns:
495  *	qla2x00 local function return status code.
496  *
497  * Context:
498  *	Kernel context.
499  */
500 int
501 qla2x00_execute_fw(scsi_qla_host_t *ha)
502 {
503 	int rval;
504 	mbx_cmd_t mc;
505 	mbx_cmd_t *mcp = &mc;
506 
507 	DEBUG11(printk("qla2x00_execute_fw(%ld): entered.\n", ha->host_no);)
508 
509 	mcp->mb[0] = MBC_EXECUTE_FIRMWARE;
510 	mcp->mb[1] = *ha->brd_info->fw_info[0].fwstart;
511 	mcp->out_mb = MBX_1|MBX_0;
512 	if (IS_QLA2322(ha) || IS_QLA6322(ha)) {
513 		mcp->mb[2] = 0;
514 		mcp->out_mb |= MBX_2;
515 	}
516 
517 	mcp->in_mb = MBX_0;
518 	mcp->tov = 30;
519 	mcp->flags = 0;
520 	rval = qla2x00_mailbox_command(ha, mcp);
521 
522 	DEBUG11(printk("qla2x00_execute_fw(%ld): done.\n", ha->host_no);)
523 
524 	return rval;
525 }
526 
527 /*
528  * qla2x00_get_fw_version
529  *	Get firmware version.
530  *
531  * Input:
532  *	ha:		adapter state pointer.
533  *	major:		pointer for major number.
534  *	minor:		pointer for minor number.
535  *	subminor:	pointer for subminor number.
536  *
537  * Returns:
538  *	qla2x00 local function return status code.
539  *
540  * Context:
541  *	Kernel context.
542  */
543 void
544 qla2x00_get_fw_version(scsi_qla_host_t *ha, uint16_t *major, uint16_t *minor,
545     uint16_t *subminor, uint16_t *attributes, uint32_t *memory)
546 {
547 	int		rval;
548 	mbx_cmd_t	mc;
549 	mbx_cmd_t	*mcp = &mc;
550 
551 	DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no));
552 
553 	mcp->mb[0] = MBC_GET_FIRMWARE_VERSION;
554 	mcp->out_mb = MBX_0;
555 	mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
556 	mcp->flags = 0;
557 	mcp->tov = 30;
558 	rval = qla2x00_mailbox_command(ha, mcp);
559 
560 	/* Return mailbox data. */
561 	*major = mcp->mb[1];
562 	*minor = mcp->mb[2];
563 	*subminor = mcp->mb[3];
564 	*attributes = mcp->mb[6];
565 	if (IS_QLA2100(ha) || IS_QLA2200(ha))
566 		*memory = 0x1FFFF;			/* Defaults to 128KB. */
567 	else
568 		*memory = (mcp->mb[5] << 16) | mcp->mb[4];
569 
570 	if (rval != QLA_SUCCESS) {
571 		/*EMPTY*/
572 		DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__,
573 		    ha->host_no, rval));
574 	} else {
575 		/*EMPTY*/
576 		DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no));
577 	}
578 }
579 
580 /*
581  * qla2x00_get_fw_options
582  *	Set firmware options.
583  *
584  * Input:
585  *	ha = adapter block pointer.
586  *	fwopt = pointer for firmware options.
587  *
588  * Returns:
589  *	qla2x00 local function return status code.
590  *
591  * Context:
592  *	Kernel context.
593  */
594 int
595 qla2x00_get_fw_options(scsi_qla_host_t *ha, uint16_t *fwopts)
596 {
597 	int rval;
598 	mbx_cmd_t mc;
599 	mbx_cmd_t *mcp = &mc;
600 
601 	DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no));
602 
603 	mcp->mb[0] = MBC_GET_FIRMWARE_OPTION;
604 	mcp->out_mb = MBX_0;
605 	mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
606 	mcp->tov = 30;
607 	mcp->flags = 0;
608 	rval = qla2x00_mailbox_command(ha, mcp);
609 
610 	if (rval != QLA_SUCCESS) {
611 		/*EMPTY*/
612 		DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__,
613 		    ha->host_no, rval));
614 	} else {
615 		fwopts[1] = mcp->mb[1];
616 		fwopts[2] = mcp->mb[2];
617 		fwopts[3] = mcp->mb[3];
618 
619 		DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no));
620 	}
621 
622 	return rval;
623 }
624 
625 
626 /*
627  * qla2x00_set_fw_options
628  *	Set firmware options.
629  *
630  * Input:
631  *	ha = adapter block pointer.
632  *	fwopt = pointer for firmware options.
633  *
634  * Returns:
635  *	qla2x00 local function return status code.
636  *
637  * Context:
638  *	Kernel context.
639  */
640 int
641 qla2x00_set_fw_options(scsi_qla_host_t *ha, uint16_t *fwopts)
642 {
643 	int rval;
644 	mbx_cmd_t mc;
645 	mbx_cmd_t *mcp = &mc;
646 
647 	DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no));
648 
649 	mcp->mb[0] = MBC_SET_FIRMWARE_OPTION;
650 	mcp->mb[1] = fwopts[1];
651 	mcp->mb[2] = fwopts[2];
652 	mcp->mb[3] = fwopts[3];
653 	mcp->mb[10] = fwopts[10];
654 	mcp->mb[11] = fwopts[11];
655 	mcp->mb[12] = 0;	/* Undocumented, but used */
656 	mcp->out_mb = MBX_12|MBX_11|MBX_10|MBX_3|MBX_2|MBX_1|MBX_0;
657 	mcp->in_mb = MBX_0;
658 	mcp->tov = 30;
659 	mcp->flags = 0;
660 	rval = qla2x00_mailbox_command(ha, mcp);
661 
662 	if (rval != QLA_SUCCESS) {
663 		/*EMPTY*/
664 		DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__,
665 		    ha->host_no, rval));
666 	} else {
667 		/*EMPTY*/
668 		DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no));
669 	}
670 
671 	return rval;
672 }
673 
674 /*
675  * qla2x00_mbx_reg_test
676  *	Mailbox register wrap test.
677  *
678  * Input:
679  *	ha = adapter block pointer.
680  *	TARGET_QUEUE_LOCK must be released.
681  *	ADAPTER_STATE_LOCK must be released.
682  *
683  * Returns:
684  *	qla2x00 local function return status code.
685  *
686  * Context:
687  *	Kernel context.
688  */
689 int
690 qla2x00_mbx_reg_test(scsi_qla_host_t *ha)
691 {
692 	int rval;
693 	mbx_cmd_t mc;
694 	mbx_cmd_t *mcp = &mc;
695 
696 	DEBUG11(printk("qla2x00_mbx_reg_test(%ld): entered.\n", ha->host_no);)
697 
698 	mcp->mb[0] = MBC_MAILBOX_REGISTER_TEST;
699 	mcp->mb[1] = 0xAAAA;
700 	mcp->mb[2] = 0x5555;
701 	mcp->mb[3] = 0xAA55;
702 	mcp->mb[4] = 0x55AA;
703 	mcp->mb[5] = 0xA5A5;
704 	mcp->mb[6] = 0x5A5A;
705 	mcp->mb[7] = 0x2525;
706 	mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
707 	mcp->in_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
708 	mcp->tov = 30;
709 	mcp->flags = 0;
710 	rval = qla2x00_mailbox_command(ha, mcp);
711 
712 	if (rval == QLA_SUCCESS) {
713 		if (mcp->mb[1] != 0xAAAA || mcp->mb[2] != 0x5555 ||
714 		    mcp->mb[3] != 0xAA55 || mcp->mb[4] != 0x55AA)
715 			rval = QLA_FUNCTION_FAILED;
716 		if (mcp->mb[5] != 0xA5A5 || mcp->mb[6] != 0x5A5A ||
717 		    mcp->mb[7] != 0x2525)
718 			rval = QLA_FUNCTION_FAILED;
719 	}
720 
721 	if (rval != QLA_SUCCESS) {
722 		/*EMPTY*/
723 		DEBUG2_3_11(printk("qla2x00_mbx_reg_test(%ld): failed=%x.\n",
724 		    ha->host_no, rval);)
725 	} else {
726 		/*EMPTY*/
727 		DEBUG11(printk("qla2x00_mbx_reg_test(%ld): done.\n",
728 		    ha->host_no);)
729 	}
730 
731 	return rval;
732 }
733 
734 /*
735  * qla2x00_verify_checksum
736  *	Verify firmware checksum.
737  *
738  * Input:
739  *	ha = adapter block pointer.
740  *	TARGET_QUEUE_LOCK must be released.
741  *	ADAPTER_STATE_LOCK must be released.
742  *
743  * Returns:
744  *	qla2x00 local function return status code.
745  *
746  * Context:
747  *	Kernel context.
748  */
749 int
750 qla2x00_verify_checksum(scsi_qla_host_t *ha)
751 {
752 	int rval;
753 	mbx_cmd_t mc;
754 	mbx_cmd_t *mcp = &mc;
755 
756 	DEBUG11(printk("qla2x00_verify_checksum(%ld): entered.\n",
757 	    ha->host_no);)
758 
759 	mcp->mb[0] = MBC_VERIFY_CHECKSUM;
760 	mcp->mb[1] = *ha->brd_info->fw_info[0].fwstart;
761 	mcp->out_mb = MBX_1|MBX_0;
762 	mcp->in_mb = MBX_2|MBX_0;
763 	mcp->tov = 30;
764 	mcp->flags = 0;
765 	rval = qla2x00_mailbox_command(ha, mcp);
766 
767 	if (rval != QLA_SUCCESS) {
768 		/*EMPTY*/
769 		DEBUG2_3_11(printk("qla2x00_verify_checksum(%ld): failed=%x.\n",
770 		    ha->host_no, rval);)
771 	} else {
772 		/*EMPTY*/
773 		DEBUG11(printk("qla2x00_verify_checksum(%ld): done.\n",
774 		    ha->host_no);)
775 	}
776 
777 	return rval;
778 }
779 
780 /*
781  * qla2x00_issue_iocb
782  *	Issue IOCB using mailbox command
783  *
784  * Input:
785  *	ha = adapter state pointer.
786  *	buffer = buffer pointer.
787  *	phys_addr = physical address of buffer.
788  *	size = size of buffer.
789  *	TARGET_QUEUE_LOCK must be released.
790  *	ADAPTER_STATE_LOCK must be released.
791  *
792  * Returns:
793  *	qla2x00 local function return status code.
794  *
795  * Context:
796  *	Kernel context.
797  */
798 int
799 qla2x00_issue_iocb(scsi_qla_host_t *ha, void*  buffer, dma_addr_t phys_addr,
800     size_t size)
801 {
802 	int		rval;
803 	mbx_cmd_t	mc;
804 	mbx_cmd_t	*mcp = &mc;
805 
806 	mcp->mb[0] = MBC_IOCB_COMMAND_A64;
807 	mcp->mb[1] = 0;
808 	mcp->mb[2] = MSW(phys_addr);
809 	mcp->mb[3] = LSW(phys_addr);
810 	mcp->mb[6] = MSW(MSD(phys_addr));
811 	mcp->mb[7] = LSW(MSD(phys_addr));
812 	mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
813 	mcp->in_mb = MBX_2|MBX_0;
814 	mcp->tov = 30;
815 	mcp->flags = 0;
816 	rval = qla2x00_mailbox_command(ha, mcp);
817 
818 	if (rval != QLA_SUCCESS) {
819 		/*EMPTY*/
820 		DEBUG(printk("qla2x00_issue_iocb(%ld): failed rval 0x%x",
821 		    ha->host_no,rval);)
822 		DEBUG2(printk("qla2x00_issue_iocb(%ld): failed rval 0x%x",
823 		    ha->host_no,rval);)
824 	} else {
825 		/*EMPTY*/
826 	}
827 
828 	return rval;
829 }
830 
831 /*
832  * qla2x00_abort_command
833  *	Abort command aborts a specified IOCB.
834  *
835  * Input:
836  *	ha = adapter block pointer.
837  *	sp = SB structure pointer.
838  *
839  * Returns:
840  *	qla2x00 local function return status code.
841  *
842  * Context:
843  *	Kernel context.
844  */
845 int
846 qla2x00_abort_command(scsi_qla_host_t *ha, srb_t *sp)
847 {
848 	unsigned long   flags = 0;
849 	fc_port_t	*fcport;
850 	int		rval;
851 	uint32_t	handle;
852 	mbx_cmd_t	mc;
853 	mbx_cmd_t	*mcp = &mc;
854 
855 	DEBUG11(printk("qla2x00_abort_command(%ld): entered.\n", ha->host_no);)
856 
857 	fcport = sp->fcport;
858 	if (atomic_read(&ha->loop_state) == LOOP_DOWN ||
859 	    atomic_read(&fcport->state) == FCS_DEVICE_LOST) {
860 		return 1;
861 	}
862 
863 	spin_lock_irqsave(&ha->hardware_lock, flags);
864 	for (handle = 1; handle < MAX_OUTSTANDING_COMMANDS; handle++) {
865 		if (ha->outstanding_cmds[handle] == sp)
866 			break;
867 	}
868 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
869 
870 	if (handle == MAX_OUTSTANDING_COMMANDS) {
871 		/* command not found */
872 		return QLA_FUNCTION_FAILED;
873 	}
874 
875 	mcp->mb[0] = MBC_ABORT_COMMAND;
876 	if (HAS_EXTENDED_IDS(ha))
877 		mcp->mb[1] = fcport->loop_id;
878 	else
879 		mcp->mb[1] = fcport->loop_id << 8;
880 	mcp->mb[2] = (uint16_t)handle;
881 	mcp->mb[3] = (uint16_t)(handle >> 16);
882 	mcp->mb[6] = (uint16_t)sp->cmd->device->lun;
883 	mcp->out_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
884 	mcp->in_mb = MBX_0;
885 	mcp->tov = 30;
886 	mcp->flags = 0;
887 	rval = qla2x00_mailbox_command(ha, mcp);
888 
889 	if (rval != QLA_SUCCESS) {
890 		DEBUG2_3_11(printk("qla2x00_abort_command(%ld): failed=%x.\n",
891 		    ha->host_no, rval);)
892 	} else {
893 		sp->flags |= SRB_ABORT_PENDING;
894 		DEBUG11(printk("qla2x00_abort_command(%ld): done.\n",
895 		    ha->host_no);)
896 	}
897 
898 	return rval;
899 }
900 
901 #if USE_ABORT_TGT
902 /*
903  * qla2x00_abort_target
904  *	Issue abort target mailbox command.
905  *
906  * Input:
907  *	ha = adapter block pointer.
908  *
909  * Returns:
910  *	qla2x00 local function return status code.
911  *
912  * Context:
913  *	Kernel context.
914  */
915 int
916 qla2x00_abort_target(fc_port_t *fcport)
917 {
918 	int        rval;
919 	mbx_cmd_t  mc;
920 	mbx_cmd_t  *mcp = &mc;
921 
922 	DEBUG11(printk("qla2x00_abort_target(%ld): entered.\n",
923 	    fcport->ha->host_no);)
924 
925 	if (fcport == NULL) {
926 		/* no target to abort */
927 		return 0;
928 	}
929 
930 	mcp->mb[0] = MBC_ABORT_TARGET;
931 	mcp->out_mb = MBX_2|MBX_1|MBX_0;
932 	if (HAS_EXTENDED_IDS(fcport->ha)) {
933 		mcp->mb[1] = fcport->loop_id;
934 		mcp->mb[10] = 0;
935 		mcp->out_mb |= MBX_10;
936 	} else {
937 		mcp->mb[1] = fcport->loop_id << 8;
938 	}
939 	mcp->mb[2] = fcport->ha->loop_reset_delay;
940 
941 	mcp->in_mb = MBX_0;
942 	mcp->tov = 30;
943 	mcp->flags = 0;
944 	rval = qla2x00_mailbox_command(fcport->ha, mcp);
945 
946 	/* Issue marker command. */
947 	fcport->ha->marker_needed = 1;
948 
949 	if (rval != QLA_SUCCESS) {
950 		DEBUG2_3_11(printk("qla2x00_abort_target(%ld): failed=%x.\n",
951 		    fcport->ha->host_no, rval);)
952 	} else {
953 		/*EMPTY*/
954 		DEBUG11(printk("qla2x00_abort_target(%ld): done.\n",
955 		    fcport->ha->host_no);)
956 	}
957 
958 	return rval;
959 }
960 #endif
961 
962 /*
963  * qla2x00_target_reset
964  *	Issue target reset mailbox command.
965  *
966  * Input:
967  *	ha = adapter block pointer.
968  *	TARGET_QUEUE_LOCK must be released.
969  *	ADAPTER_STATE_LOCK must be released.
970  *
971  * Returns:
972  *	qla2x00 local function return status code.
973  *
974  * Context:
975  *	Kernel context.
976  */
977 int
978 qla2x00_target_reset(scsi_qla_host_t *ha, struct fc_port *fcport)
979 {
980 	int rval;
981 	mbx_cmd_t mc;
982 	mbx_cmd_t *mcp = &mc;
983 
984 	DEBUG11(printk("qla2x00_target_reset(%ld): entered.\n", ha->host_no);)
985 
986 	if (atomic_read(&fcport->state) != FCS_ONLINE)
987 		return 0;
988 
989 	mcp->mb[0] = MBC_TARGET_RESET;
990 	if (HAS_EXTENDED_IDS(ha))
991 		mcp->mb[1] = fcport->loop_id;
992 	else
993 		mcp->mb[1] = fcport->loop_id << 8;
994 	mcp->mb[2] = ha->loop_reset_delay;
995 	mcp->out_mb = MBX_2|MBX_1|MBX_0;
996 	mcp->in_mb = MBX_0;
997 	mcp->tov = 30;
998 	mcp->flags = 0;
999 	rval = qla2x00_mailbox_command(ha, mcp);
1000 
1001 	if (rval != QLA_SUCCESS) {
1002 		/*EMPTY*/
1003 		DEBUG2_3_11(printk("qla2x00_target_reset(%ld): failed=%x.\n",
1004 		    ha->host_no, rval);)
1005 	} else {
1006 		/*EMPTY*/
1007 		DEBUG11(printk("qla2x00_target_reset(%ld): done.\n",
1008 		    ha->host_no);)
1009 	}
1010 
1011 	return rval;
1012 }
1013 
1014 /*
1015  * qla2x00_get_adapter_id
1016  *	Get adapter ID and topology.
1017  *
1018  * Input:
1019  *	ha = adapter block pointer.
1020  *	id = pointer for loop ID.
1021  *	al_pa = pointer for AL_PA.
1022  *	area = pointer for area.
1023  *	domain = pointer for domain.
1024  *	top = pointer for topology.
1025  *	TARGET_QUEUE_LOCK must be released.
1026  *	ADAPTER_STATE_LOCK must be released.
1027  *
1028  * Returns:
1029  *	qla2x00 local function return status code.
1030  *
1031  * Context:
1032  *	Kernel context.
1033  */
1034 int
1035 qla2x00_get_adapter_id(scsi_qla_host_t *ha, uint16_t *id, uint8_t *al_pa,
1036     uint8_t *area, uint8_t *domain, uint16_t *top)
1037 {
1038 	int rval;
1039 	mbx_cmd_t mc;
1040 	mbx_cmd_t *mcp = &mc;
1041 
1042 	DEBUG11(printk("qla2x00_get_adapter_id(%ld): entered.\n",
1043 	    ha->host_no);)
1044 
1045 	mcp->mb[0] = MBC_GET_ADAPTER_LOOP_ID;
1046 	mcp->out_mb = MBX_0;
1047 	mcp->in_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
1048 	mcp->tov = 30;
1049 	mcp->flags = 0;
1050 	rval = qla2x00_mailbox_command(ha, mcp);
1051 
1052 	/* Return data. */
1053 	*id = mcp->mb[1];
1054 	*al_pa = LSB(mcp->mb[2]);
1055 	*area = MSB(mcp->mb[2]);
1056 	*domain	= LSB(mcp->mb[3]);
1057 	*top = mcp->mb[6];
1058 
1059 	if (rval != QLA_SUCCESS) {
1060 		/*EMPTY*/
1061 		DEBUG2_3_11(printk("qla2x00_get_adapter_id(%ld): failed=%x.\n",
1062 		    ha->host_no, rval);)
1063 	} else {
1064 		/*EMPTY*/
1065 		DEBUG11(printk("qla2x00_get_adapter_id(%ld): done.\n",
1066 		    ha->host_no);)
1067 	}
1068 
1069 	return rval;
1070 }
1071 
1072 /*
1073  * qla2x00_get_retry_cnt
1074  *	Get current firmware login retry count and delay.
1075  *
1076  * Input:
1077  *	ha = adapter block pointer.
1078  *	retry_cnt = pointer to login retry count.
1079  *	tov = pointer to login timeout value.
1080  *
1081  * Returns:
1082  *	qla2x00 local function return status code.
1083  *
1084  * Context:
1085  *	Kernel context.
1086  */
1087 int
1088 qla2x00_get_retry_cnt(scsi_qla_host_t *ha, uint8_t *retry_cnt, uint8_t *tov,
1089     uint16_t *r_a_tov)
1090 {
1091 	int rval;
1092 	uint16_t ratov;
1093 	mbx_cmd_t mc;
1094 	mbx_cmd_t *mcp = &mc;
1095 
1096 	DEBUG11(printk("qla2x00_get_retry_cnt(%ld): entered.\n",
1097 			ha->host_no);)
1098 
1099 	mcp->mb[0] = MBC_GET_RETRY_COUNT;
1100 	mcp->out_mb = MBX_0;
1101 	mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
1102 	mcp->tov = 30;
1103 	mcp->flags = 0;
1104 	rval = qla2x00_mailbox_command(ha, mcp);
1105 
1106 	if (rval != QLA_SUCCESS) {
1107 		/*EMPTY*/
1108 		DEBUG2_3_11(printk("qla2x00_get_retry_cnt(%ld): failed = %x.\n",
1109 		    ha->host_no, mcp->mb[0]);)
1110 	} else {
1111 		/* Convert returned data and check our values. */
1112 		*r_a_tov = mcp->mb[3] / 2;
1113 		ratov = (mcp->mb[3]/2) / 10;  /* mb[3] value is in 100ms */
1114 		if (mcp->mb[1] * ratov > (*retry_cnt) * (*tov)) {
1115 			/* Update to the larger values */
1116 			*retry_cnt = (uint8_t)mcp->mb[1];
1117 			*tov = ratov;
1118 		}
1119 
1120 		DEBUG11(printk("qla2x00_get_retry_cnt(%ld): done. mb3=%d "
1121 		    "ratov=%d.\n", ha->host_no, mcp->mb[3], ratov);)
1122 	}
1123 
1124 	return rval;
1125 }
1126 
1127 /*
1128  * qla2x00_init_firmware
1129  *	Initialize adapter firmware.
1130  *
1131  * Input:
1132  *	ha = adapter block pointer.
1133  *	dptr = Initialization control block pointer.
1134  *	size = size of initialization control block.
1135  *	TARGET_QUEUE_LOCK must be released.
1136  *	ADAPTER_STATE_LOCK must be released.
1137  *
1138  * Returns:
1139  *	qla2x00 local function return status code.
1140  *
1141  * Context:
1142  *	Kernel context.
1143  */
1144 int
1145 qla2x00_init_firmware(scsi_qla_host_t *ha, uint16_t size)
1146 {
1147 	int rval;
1148 	mbx_cmd_t mc;
1149 	mbx_cmd_t *mcp = &mc;
1150 
1151 	DEBUG11(printk("qla2x00_init_firmware(%ld): entered.\n",
1152 	    ha->host_no);)
1153 
1154 	mcp->mb[0] = MBC_INITIALIZE_FIRMWARE;
1155 	mcp->mb[2] = MSW(ha->init_cb_dma);
1156 	mcp->mb[3] = LSW(ha->init_cb_dma);
1157 	mcp->mb[4] = 0;
1158 	mcp->mb[5] = 0;
1159 	mcp->mb[6] = MSW(MSD(ha->init_cb_dma));
1160 	mcp->mb[7] = LSW(MSD(ha->init_cb_dma));
1161 	mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
1162 	mcp->in_mb = MBX_5|MBX_4|MBX_0;
1163 	mcp->buf_size = size;
1164 	mcp->flags = MBX_DMA_OUT;
1165 	mcp->tov = 30;
1166 	rval = qla2x00_mailbox_command(ha, mcp);
1167 
1168 	if (rval != QLA_SUCCESS) {
1169 		/*EMPTY*/
1170 		DEBUG2_3_11(printk("qla2x00_init_firmware(%ld): failed=%x "
1171 		    "mb0=%x.\n",
1172 		    ha->host_no, rval, mcp->mb[0]);)
1173 	} else {
1174 		/*EMPTY*/
1175 		DEBUG11(printk("qla2x00_init_firmware(%ld): done.\n",
1176 		    ha->host_no);)
1177 	}
1178 
1179 	return rval;
1180 }
1181 
1182 /*
1183  * qla2x00_get_port_database
1184  *	Issue normal/enhanced get port database mailbox command
1185  *	and copy device name as necessary.
1186  *
1187  * Input:
1188  *	ha = adapter state pointer.
1189  *	dev = structure pointer.
1190  *	opt = enhanced cmd option byte.
1191  *
1192  * Returns:
1193  *	qla2x00 local function return status code.
1194  *
1195  * Context:
1196  *	Kernel context.
1197  */
1198 int
1199 qla2x00_get_port_database(scsi_qla_host_t *ha, fc_port_t *fcport, uint8_t opt)
1200 {
1201 	int rval;
1202 	mbx_cmd_t mc;
1203 	mbx_cmd_t *mcp = &mc;
1204 	port_database_t *pd;
1205 	dma_addr_t pd_dma;
1206 
1207 	DEBUG11(printk("qla2x00_get_port_database(%ld): entered.\n",
1208 	    ha->host_no);)
1209 
1210 	pd = dma_pool_alloc(ha->s_dma_pool, GFP_ATOMIC, &pd_dma);
1211 	if (pd  == NULL) {
1212 		DEBUG2_3_11(printk("qla2x00_get_port_database(%ld): **** "
1213 		    "Mem Alloc Failed ****", ha->host_no);)
1214 		return QLA_MEMORY_ALLOC_FAILED;
1215 	}
1216 	memset(pd, 0, PORT_DATABASE_SIZE);
1217 
1218 	if (opt != 0)
1219 		mcp->mb[0] = MBC_ENHANCED_GET_PORT_DATABASE;
1220 	else
1221 		mcp->mb[0] = MBC_GET_PORT_DATABASE;
1222 	mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
1223 	if (HAS_EXTENDED_IDS(ha)) {
1224 		mcp->mb[1] = fcport->loop_id;
1225 		mcp->mb[10] = opt;
1226 		mcp->out_mb |= MBX_10;
1227 	} else {
1228 		mcp->mb[1] = fcport->loop_id << 8 | opt;
1229 	}
1230 	mcp->mb[2] = MSW(pd_dma);
1231 	mcp->mb[3] = LSW(pd_dma);
1232 	mcp->mb[6] = MSW(MSD(pd_dma));
1233 	mcp->mb[7] = LSW(MSD(pd_dma));
1234 
1235 	mcp->in_mb = MBX_0;
1236 	mcp->buf_size = PORT_DATABASE_SIZE;
1237 	mcp->flags = MBX_DMA_IN;
1238 	mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
1239 	rval = qla2x00_mailbox_command(ha, mcp);
1240 	if (rval != QLA_SUCCESS)
1241 		goto gpd_error_out;
1242 
1243 	/* Check for logged in state. */
1244 	if (pd->master_state != PD_STATE_PORT_LOGGED_IN &&
1245 	    pd->slave_state != PD_STATE_PORT_LOGGED_IN) {
1246 		rval = QLA_FUNCTION_FAILED;
1247 		goto gpd_error_out;
1248 	}
1249 
1250 	/* Names are little-endian. */
1251 	memcpy(fcport->node_name, pd->node_name, WWN_SIZE);
1252 	memcpy(fcport->port_name, pd->port_name, WWN_SIZE);
1253 
1254 	/* Get port_id of device. */
1255 	fcport->d_id.b.al_pa = pd->port_id[2];
1256 	fcport->d_id.b.area = pd->port_id[3];
1257 	fcport->d_id.b.domain = pd->port_id[0];
1258 	fcport->d_id.b.rsvd_1 = 0;
1259 
1260 	/* Check for device require authentication. */
1261 	pd->common_features & BIT_5 ? (fcport->flags |= FCF_AUTH_REQ) :
1262 	    (fcport->flags &= ~FCF_AUTH_REQ);
1263 
1264 	/* If not target must be initiator or unknown type. */
1265 	if ((pd->prli_svc_param_word_3[0] & BIT_4) == 0)
1266 		fcport->port_type = FCT_INITIATOR;
1267 	else
1268 		fcport->port_type = FCT_TARGET;
1269 
1270 gpd_error_out:
1271 	dma_pool_free(ha->s_dma_pool, pd, pd_dma);
1272 
1273 	if (rval != QLA_SUCCESS) {
1274 		/*EMPTY*/
1275 		DEBUG2_3_11(printk("qla2x00_get_port_database(%ld): "
1276 		    "failed=%x.\n", ha->host_no, rval);)
1277 	} else {
1278 		/*EMPTY*/
1279 		DEBUG11(printk("qla2x00_get_port_database(%ld): done.\n",
1280 		    ha->host_no);)
1281 	}
1282 
1283 	return rval;
1284 }
1285 
1286 /*
1287  * qla2x00_get_firmware_state
1288  *	Get adapter firmware state.
1289  *
1290  * Input:
1291  *	ha = adapter block pointer.
1292  *	dptr = pointer for firmware state.
1293  *	TARGET_QUEUE_LOCK must be released.
1294  *	ADAPTER_STATE_LOCK must be released.
1295  *
1296  * Returns:
1297  *	qla2x00 local function return status code.
1298  *
1299  * Context:
1300  *	Kernel context.
1301  */
1302 int
1303 qla2x00_get_firmware_state(scsi_qla_host_t *ha, uint16_t *dptr)
1304 {
1305 	int rval;
1306 	mbx_cmd_t mc;
1307 	mbx_cmd_t *mcp = &mc;
1308 
1309 	DEBUG11(printk("qla2x00_get_firmware_state(%ld): entered.\n",
1310 	    ha->host_no);)
1311 
1312 	mcp->mb[0] = MBC_GET_FIRMWARE_STATE;
1313 	mcp->out_mb = MBX_0;
1314 	mcp->in_mb = MBX_2|MBX_1|MBX_0;
1315 	mcp->tov = 30;
1316 	mcp->flags = 0;
1317 	rval = qla2x00_mailbox_command(ha, mcp);
1318 
1319 	/* Return firmware state. */
1320 	*dptr = mcp->mb[1];
1321 
1322 	if (rval != QLA_SUCCESS) {
1323 		/*EMPTY*/
1324 		DEBUG2_3_11(printk("qla2x00_get_firmware_state(%ld): "
1325 		    "failed=%x.\n", ha->host_no, rval);)
1326 	} else {
1327 		/*EMPTY*/
1328 		DEBUG11(printk("qla2x00_get_firmware_state(%ld): done.\n",
1329 		    ha->host_no);)
1330 	}
1331 
1332 	return rval;
1333 }
1334 
1335 /*
1336  * qla2x00_get_port_name
1337  *	Issue get port name mailbox command.
1338  *	Returned name is in big endian format.
1339  *
1340  * Input:
1341  *	ha = adapter block pointer.
1342  *	loop_id = loop ID of device.
1343  *	name = pointer for name.
1344  *	TARGET_QUEUE_LOCK must be released.
1345  *	ADAPTER_STATE_LOCK must be released.
1346  *
1347  * Returns:
1348  *	qla2x00 local function return status code.
1349  *
1350  * Context:
1351  *	Kernel context.
1352  */
1353 int
1354 qla2x00_get_port_name(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t *name,
1355     uint8_t opt)
1356 {
1357 	int rval;
1358 	mbx_cmd_t mc;
1359 	mbx_cmd_t *mcp = &mc;
1360 
1361 	DEBUG11(printk("qla2x00_get_port_name(%ld): entered.\n",
1362 	    ha->host_no);)
1363 
1364 	mcp->mb[0] = MBC_GET_PORT_NAME;
1365 	mcp->out_mb = MBX_1|MBX_0;
1366 	if (HAS_EXTENDED_IDS(ha)) {
1367 		mcp->mb[1] = loop_id;
1368 		mcp->mb[10] = opt;
1369 		mcp->out_mb |= MBX_10;
1370 	} else {
1371 		mcp->mb[1] = loop_id << 8 | opt;
1372 	}
1373 
1374 	mcp->in_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
1375 	mcp->tov = 30;
1376 	mcp->flags = 0;
1377 	rval = qla2x00_mailbox_command(ha, mcp);
1378 
1379 	if (rval != QLA_SUCCESS) {
1380 		/*EMPTY*/
1381 		DEBUG2_3_11(printk("qla2x00_get_port_name(%ld): failed=%x.\n",
1382 		    ha->host_no, rval);)
1383 	} else {
1384 		if (name != NULL) {
1385 			/* This function returns name in big endian. */
1386 			name[0] = LSB(mcp->mb[2]);
1387 			name[1] = MSB(mcp->mb[2]);
1388 			name[2] = LSB(mcp->mb[3]);
1389 			name[3] = MSB(mcp->mb[3]);
1390 			name[4] = LSB(mcp->mb[6]);
1391 			name[5] = MSB(mcp->mb[6]);
1392 			name[6] = LSB(mcp->mb[7]);
1393 			name[7] = MSB(mcp->mb[7]);
1394 		}
1395 
1396 		DEBUG11(printk("qla2x00_get_port_name(%ld): done.\n",
1397 		    ha->host_no);)
1398 	}
1399 
1400 	return rval;
1401 }
1402 
1403 /*
1404  * qla2x00_lip_reset
1405  *	Issue LIP reset mailbox command.
1406  *
1407  * Input:
1408  *	ha = adapter block pointer.
1409  *	TARGET_QUEUE_LOCK must be released.
1410  *	ADAPTER_STATE_LOCK must be released.
1411  *
1412  * Returns:
1413  *	qla2x00 local function return status code.
1414  *
1415  * Context:
1416  *	Kernel context.
1417  */
1418 int
1419 qla2x00_lip_reset(scsi_qla_host_t *ha)
1420 {
1421 	int rval;
1422 	mbx_cmd_t mc;
1423 	mbx_cmd_t *mcp = &mc;
1424 
1425 	DEBUG11(printk("qla2x00_lip_reset(%ld): entered.\n",
1426 	    ha->host_no);)
1427 
1428 	mcp->mb[0] = MBC_LIP_RESET;
1429 	mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
1430 	if (HAS_EXTENDED_IDS(ha)) {
1431 		mcp->mb[1] = 0x00ff;
1432 		mcp->mb[10] = 0;
1433 		mcp->out_mb |= MBX_10;
1434 	} else {
1435 		mcp->mb[1] = 0xff00;
1436 	}
1437 	mcp->mb[2] = ha->loop_reset_delay;
1438 	mcp->mb[3] = 0;
1439 
1440 	mcp->in_mb = MBX_0;
1441 	mcp->tov = 30;
1442 	mcp->flags = 0;
1443 	rval = qla2x00_mailbox_command(ha, mcp);
1444 
1445 	if (rval != QLA_SUCCESS) {
1446 		/*EMPTY*/
1447 		DEBUG2_3_11(printk("qla2x00_lip_reset(%ld): failed=%x.\n",
1448 		    ha->host_no, rval);)
1449 	} else {
1450 		/*EMPTY*/
1451 		DEBUG11(printk("qla2x00_lip_reset(%ld): done.\n", ha->host_no);)
1452 	}
1453 
1454 	return rval;
1455 }
1456 
1457 /*
1458  * qla2x00_send_sns
1459  *	Send SNS command.
1460  *
1461  * Input:
1462  *	ha = adapter block pointer.
1463  *	sns = pointer for command.
1464  *	cmd_size = command size.
1465  *	buf_size = response/command size.
1466  *	TARGET_QUEUE_LOCK must be released.
1467  *	ADAPTER_STATE_LOCK must be released.
1468  *
1469  * Returns:
1470  *	qla2x00 local function return status code.
1471  *
1472  * Context:
1473  *	Kernel context.
1474  */
1475 int
1476 qla2x00_send_sns(scsi_qla_host_t *ha, dma_addr_t sns_phys_address,
1477     uint16_t cmd_size, size_t buf_size)
1478 {
1479 	int rval;
1480 	mbx_cmd_t mc;
1481 	mbx_cmd_t *mcp = &mc;
1482 
1483 	DEBUG11(printk("qla2x00_send_sns(%ld): entered.\n",
1484 	    ha->host_no);)
1485 
1486 	DEBUG11(printk("qla2x00_send_sns: retry cnt=%d ratov=%d total "
1487 	    "tov=%d.\n", ha->retry_count, ha->login_timeout, mcp->tov);)
1488 
1489 	mcp->mb[0] = MBC_SEND_SNS_COMMAND;
1490 	mcp->mb[1] = cmd_size;
1491 	mcp->mb[2] = MSW(sns_phys_address);
1492 	mcp->mb[3] = LSW(sns_phys_address);
1493 	mcp->mb[6] = MSW(MSD(sns_phys_address));
1494 	mcp->mb[7] = LSW(MSD(sns_phys_address));
1495 	mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
1496 	mcp->in_mb = MBX_0|MBX_1;
1497 	mcp->buf_size = buf_size;
1498 	mcp->flags = MBX_DMA_OUT|MBX_DMA_IN;
1499 	mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
1500 	rval = qla2x00_mailbox_command(ha, mcp);
1501 
1502 	if (rval != QLA_SUCCESS) {
1503 		/*EMPTY*/
1504 		DEBUG(printk("qla2x00_send_sns(%ld): failed=%x mb[0]=%x "
1505 		    "mb[1]=%x.\n", ha->host_no, rval, mcp->mb[0], mcp->mb[1]);)
1506 		DEBUG2_3_11(printk("qla2x00_send_sns(%ld): failed=%x mb[0]=%x "
1507 		    "mb[1]=%x.\n", ha->host_no, rval, mcp->mb[0], mcp->mb[1]);)
1508 	} else {
1509 		/*EMPTY*/
1510 		DEBUG11(printk("qla2x00_send_sns(%ld): done.\n", ha->host_no);)
1511 	}
1512 
1513 	return rval;
1514 }
1515 
1516 /*
1517  * qla2x00_login_fabric
1518  *	Issue login fabric port mailbox command.
1519  *
1520  * Input:
1521  *	ha = adapter block pointer.
1522  *	loop_id = device loop ID.
1523  *	domain = device domain.
1524  *	area = device area.
1525  *	al_pa = device AL_PA.
1526  *	status = pointer for return status.
1527  *	opt = command options.
1528  *	TARGET_QUEUE_LOCK must be released.
1529  *	ADAPTER_STATE_LOCK must be released.
1530  *
1531  * Returns:
1532  *	qla2x00 local function return status code.
1533  *
1534  * Context:
1535  *	Kernel context.
1536  */
1537 int
1538 qla2x00_login_fabric(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain,
1539     uint8_t area, uint8_t al_pa, uint16_t *mb, uint8_t opt)
1540 {
1541 	int rval;
1542 	mbx_cmd_t mc;
1543 	mbx_cmd_t *mcp = &mc;
1544 
1545 	DEBUG11(printk("qla2x00_login_fabric(%ld): entered.\n", ha->host_no);)
1546 
1547 	mcp->mb[0] = MBC_LOGIN_FABRIC_PORT;
1548 	mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
1549 	if (HAS_EXTENDED_IDS(ha)) {
1550 		mcp->mb[1] = loop_id;
1551 		mcp->mb[10] = opt;
1552 		mcp->out_mb |= MBX_10;
1553 	} else {
1554 		mcp->mb[1] = (loop_id << 8) | opt;
1555 	}
1556 	mcp->mb[2] = domain;
1557 	mcp->mb[3] = area << 8 | al_pa;
1558 
1559 	mcp->in_mb = MBX_7|MBX_6|MBX_2|MBX_1|MBX_0;
1560 	mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
1561 	mcp->flags = 0;
1562 	rval = qla2x00_mailbox_command(ha, mcp);
1563 
1564 	/* Return mailbox statuses. */
1565 	if (mb != NULL) {
1566 		mb[0] = mcp->mb[0];
1567 		mb[1] = mcp->mb[1];
1568 		mb[2] = mcp->mb[2];
1569 		mb[6] = mcp->mb[6];
1570 		mb[7] = mcp->mb[7];
1571 	}
1572 
1573 	if (rval != QLA_SUCCESS) {
1574 		/* RLU tmp code: need to change main mailbox_command function to
1575 		 * return ok even when the mailbox completion value is not
1576 		 * SUCCESS. The caller needs to be responsible to interpret
1577 		 * the return values of this mailbox command if we're not
1578 		 * to change too much of the existing code.
1579 		 */
1580 		if (mcp->mb[0] == 0x4001 || mcp->mb[0] == 0x4002 ||
1581 		    mcp->mb[0] == 0x4003 || mcp->mb[0] == 0x4005 ||
1582 		    mcp->mb[0] == 0x4006)
1583 			rval = QLA_SUCCESS;
1584 
1585 		/*EMPTY*/
1586 		DEBUG2_3_11(printk("qla2x00_login_fabric(%ld): failed=%x "
1587 		    "mb[0]=%x mb[1]=%x mb[2]=%x.\n", ha->host_no, rval,
1588 		    mcp->mb[0], mcp->mb[1], mcp->mb[2]);)
1589 	} else {
1590 		/*EMPTY*/
1591 		DEBUG11(printk("qla2x00_login_fabric(%ld): done.\n",
1592 		    ha->host_no);)
1593 	}
1594 
1595 	return rval;
1596 }
1597 
1598 /*
1599  * qla2x00_login_local_device
1600  *           Issue login loop port mailbox command.
1601  *
1602  * Input:
1603  *           ha = adapter block pointer.
1604  *           loop_id = device loop ID.
1605  *           opt = command options.
1606  *
1607  * Returns:
1608  *            Return status code.
1609  *
1610  * Context:
1611  *            Kernel context.
1612  *
1613  */
1614 int
1615 qla2x00_login_local_device(scsi_qla_host_t *ha, uint16_t loop_id,
1616     uint16_t *mb_ret, uint8_t opt)
1617 {
1618 	int rval;
1619 	mbx_cmd_t mc;
1620 	mbx_cmd_t *mcp = &mc;
1621 
1622 	DEBUG3(printk("%s(%ld): entered.\n", __func__, ha->host_no);)
1623 
1624 	mcp->mb[0] = MBC_LOGIN_LOOP_PORT;
1625 	if (HAS_EXTENDED_IDS(ha))
1626 		mcp->mb[1] = loop_id;
1627 	else
1628 		mcp->mb[1] = loop_id << 8;
1629 	mcp->mb[2] = opt;
1630 	mcp->out_mb = MBX_2|MBX_1|MBX_0;
1631  	mcp->in_mb = MBX_7|MBX_6|MBX_1|MBX_0;
1632 	mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
1633 	mcp->flags = 0;
1634 	rval = qla2x00_mailbox_command(ha, mcp);
1635 
1636  	/* Return mailbox statuses. */
1637  	if (mb_ret != NULL) {
1638  		mb_ret[0] = mcp->mb[0];
1639  		mb_ret[1] = mcp->mb[1];
1640  		mb_ret[6] = mcp->mb[6];
1641  		mb_ret[7] = mcp->mb[7];
1642  	}
1643 
1644 	if (rval != QLA_SUCCESS) {
1645  		/* AV tmp code: need to change main mailbox_command function to
1646  		 * return ok even when the mailbox completion value is not
1647  		 * SUCCESS. The caller needs to be responsible to interpret
1648  		 * the return values of this mailbox command if we're not
1649  		 * to change too much of the existing code.
1650  		 */
1651  		if (mcp->mb[0] == 0x4005 || mcp->mb[0] == 0x4006)
1652  			rval = QLA_SUCCESS;
1653 
1654 		DEBUG(printk("%s(%ld): failed=%x mb[0]=%x mb[1]=%x "
1655 		    "mb[6]=%x mb[7]=%x.\n", __func__, ha->host_no, rval,
1656 		    mcp->mb[0], mcp->mb[1], mcp->mb[6], mcp->mb[7]);)
1657 		DEBUG2_3(printk("%s(%ld): failed=%x mb[0]=%x mb[1]=%x "
1658 		    "mb[6]=%x mb[7]=%x.\n", __func__, ha->host_no, rval,
1659 		    mcp->mb[0], mcp->mb[1], mcp->mb[6], mcp->mb[7]);)
1660 	} else {
1661 		/*EMPTY*/
1662 		DEBUG3(printk("%s(%ld): done.\n", __func__, ha->host_no);)
1663 	}
1664 
1665 	return (rval);
1666 }
1667 
1668 /*
1669  * qla2x00_fabric_logout
1670  *	Issue logout fabric port mailbox command.
1671  *
1672  * Input:
1673  *	ha = adapter block pointer.
1674  *	loop_id = device loop ID.
1675  *	TARGET_QUEUE_LOCK must be released.
1676  *	ADAPTER_STATE_LOCK must be released.
1677  *
1678  * Returns:
1679  *	qla2x00 local function return status code.
1680  *
1681  * Context:
1682  *	Kernel context.
1683  */
1684 int
1685 qla2x00_fabric_logout(scsi_qla_host_t *ha, uint16_t loop_id)
1686 {
1687 	int rval;
1688 	mbx_cmd_t mc;
1689 	mbx_cmd_t *mcp = &mc;
1690 
1691 	DEBUG11(printk("qla2x00_fabric_logout(%ld): entered.\n",
1692 	    ha->host_no);)
1693 
1694 	mcp->mb[0] = MBC_LOGOUT_FABRIC_PORT;
1695 	mcp->out_mb = MBX_1|MBX_0;
1696 	if (HAS_EXTENDED_IDS(ha)) {
1697 		mcp->mb[1] = loop_id;
1698 		mcp->mb[10] = 0;
1699 		mcp->out_mb |= MBX_10;
1700 	} else {
1701 		mcp->mb[1] = loop_id << 8;
1702 	}
1703 
1704 	mcp->in_mb = MBX_1|MBX_0;
1705 	mcp->tov = 30;
1706 	mcp->flags = 0;
1707 	rval = qla2x00_mailbox_command(ha, mcp);
1708 
1709 	if (rval != QLA_SUCCESS) {
1710 		/*EMPTY*/
1711 		DEBUG2_3_11(printk("qla2x00_fabric_logout(%ld): failed=%x "
1712 		    "mbx1=%x.\n", ha->host_no, rval, mcp->mb[1]);)
1713 	} else {
1714 		/*EMPTY*/
1715 		DEBUG11(printk("qla2x00_fabric_logout(%ld): done.\n",
1716 		    ha->host_no);)
1717 	}
1718 
1719 	return rval;
1720 }
1721 
1722 /*
1723  * qla2x00_full_login_lip
1724  *	Issue full login LIP mailbox command.
1725  *
1726  * Input:
1727  *	ha = adapter block pointer.
1728  *	TARGET_QUEUE_LOCK must be released.
1729  *	ADAPTER_STATE_LOCK must be released.
1730  *
1731  * Returns:
1732  *	qla2x00 local function return status code.
1733  *
1734  * Context:
1735  *	Kernel context.
1736  */
1737 int
1738 qla2x00_full_login_lip(scsi_qla_host_t *ha)
1739 {
1740 	int rval;
1741 	mbx_cmd_t mc;
1742 	mbx_cmd_t *mcp = &mc;
1743 
1744 	DEBUG11(printk("qla2x00_full_login_lip(%ld): entered.\n",
1745 	    ha->host_no);)
1746 
1747 	mcp->mb[0] = MBC_LIP_FULL_LOGIN;
1748 	mcp->mb[1] = 0;
1749 	mcp->mb[2] = 0;
1750 	mcp->mb[3] = 0;
1751 	mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
1752 	mcp->in_mb = MBX_0;
1753 	mcp->tov = 30;
1754 	mcp->flags = 0;
1755 	rval = qla2x00_mailbox_command(ha, mcp);
1756 
1757 	if (rval != QLA_SUCCESS) {
1758 		/*EMPTY*/
1759 		DEBUG2_3_11(printk("qla2x00_full_login_lip(%ld): failed=%x.\n",
1760 		    ha->instance, rval);)
1761 	} else {
1762 		/*EMPTY*/
1763 		DEBUG11(printk("qla2x00_full_login_lip(%ld): done.\n",
1764 		    ha->host_no);)
1765 	}
1766 
1767 	return rval;
1768 }
1769 
1770 /*
1771  * qla2x00_get_id_list
1772  *
1773  * Input:
1774  *	ha = adapter block pointer.
1775  *
1776  * Returns:
1777  *	qla2x00 local function return status code.
1778  *
1779  * Context:
1780  *	Kernel context.
1781  */
1782 int
1783 qla2x00_get_id_list(scsi_qla_host_t *ha, void *id_list, dma_addr_t id_list_dma,
1784     uint16_t *entries)
1785 {
1786 	int rval;
1787 	mbx_cmd_t mc;
1788 	mbx_cmd_t *mcp = &mc;
1789 
1790 	DEBUG11(printk("qla2x00_get_id_list(%ld): entered.\n",
1791 	    ha->host_no);)
1792 
1793 	if (id_list == NULL)
1794 		return QLA_FUNCTION_FAILED;
1795 
1796 	mcp->mb[0] = MBC_GET_ID_LIST;
1797 	mcp->mb[1] = MSW(id_list_dma);
1798 	mcp->mb[2] = LSW(id_list_dma);
1799 	mcp->mb[3] = MSW(MSD(id_list_dma));
1800 	mcp->mb[6] = LSW(MSD(id_list_dma));
1801 	mcp->out_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
1802 	mcp->in_mb = MBX_1|MBX_0;
1803 	mcp->tov = 30;
1804 	mcp->flags = 0;
1805 	rval = qla2x00_mailbox_command(ha, mcp);
1806 
1807 	if (rval != QLA_SUCCESS) {
1808 		/*EMPTY*/
1809 		DEBUG2_3_11(printk("qla2x00_get_id_list(%ld): failed=%x.\n",
1810 		    ha->host_no, rval);)
1811 	} else {
1812 		*entries = mcp->mb[1];
1813 		DEBUG11(printk("qla2x00_get_id_list(%ld): done.\n",
1814 		    ha->host_no);)
1815 	}
1816 
1817 	return rval;
1818 }
1819 
1820 /*
1821  * qla2x00_get_resource_cnts
1822  *	Get current firmware resource counts.
1823  *
1824  * Input:
1825  *	ha = adapter block pointer.
1826  *
1827  * Returns:
1828  *	qla2x00 local function return status code.
1829  *
1830  * Context:
1831  *	Kernel context.
1832  */
1833 int
1834 qla2x00_get_resource_cnts(scsi_qla_host_t *ha, uint16_t *cur_xchg_cnt,
1835     uint16_t *orig_xchg_cnt, uint16_t *cur_iocb_cnt, uint16_t *orig_iocb_cnt)
1836 {
1837 	int rval;
1838 	mbx_cmd_t mc;
1839 	mbx_cmd_t *mcp = &mc;
1840 
1841 	DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no));
1842 
1843 	mcp->mb[0] = MBC_GET_RESOURCE_COUNTS;
1844 	mcp->out_mb = MBX_0;
1845 	mcp->in_mb = MBX_10|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
1846 	mcp->tov = 30;
1847 	mcp->flags = 0;
1848 	rval = qla2x00_mailbox_command(ha, mcp);
1849 
1850 	if (rval != QLA_SUCCESS) {
1851 		/*EMPTY*/
1852 		DEBUG2_3_11(printk("%s(%ld): failed = %x.\n", __func__,
1853 		    ha->host_no, mcp->mb[0]);)
1854 	} else {
1855 		DEBUG11(printk("%s(%ld): done. mb1=%x mb2=%x mb3=%x mb6=%x "
1856 		    "mb7=%x mb10=%x.\n", __func__, ha->host_no,
1857 		    mcp->mb[1], mcp->mb[2], mcp->mb[3], mcp->mb[6], mcp->mb[7],
1858 		    mcp->mb[10]));
1859 
1860 		if (cur_xchg_cnt)
1861 			*cur_xchg_cnt = mcp->mb[3];
1862 		if (orig_xchg_cnt)
1863 			*orig_xchg_cnt = mcp->mb[6];
1864 		if (cur_iocb_cnt)
1865 			*cur_iocb_cnt = mcp->mb[7];
1866 		if (orig_iocb_cnt)
1867 			*orig_iocb_cnt = mcp->mb[10];
1868 	}
1869 
1870 	return (rval);
1871 }
1872 
1873 #if defined(QL_DEBUG_LEVEL_3)
1874 /*
1875  * qla2x00_get_fcal_position_map
1876  *	Get FCAL (LILP) position map using mailbox command
1877  *
1878  * Input:
1879  *	ha = adapter state pointer.
1880  *	pos_map = buffer pointer (can be NULL).
1881  *
1882  * Returns:
1883  *	qla2x00 local function return status code.
1884  *
1885  * Context:
1886  *	Kernel context.
1887  */
1888 int
1889 qla2x00_get_fcal_position_map(scsi_qla_host_t *ha, char *pos_map)
1890 {
1891 	int rval;
1892 	mbx_cmd_t mc;
1893 	mbx_cmd_t *mcp = &mc;
1894 	char *pmap;
1895 	dma_addr_t pmap_dma;
1896 
1897 	pmap = dma_pool_alloc(ha->s_dma_pool, GFP_ATOMIC, &pmap_dma);
1898 	if (pmap  == NULL) {
1899 		DEBUG2_3_11(printk("%s(%ld): **** Mem Alloc Failed ****",
1900 		    __func__, ha->host_no));
1901 		return QLA_MEMORY_ALLOC_FAILED;
1902 	}
1903 	memset(pmap, 0, FCAL_MAP_SIZE);
1904 
1905 	mcp->mb[0] = MBC_GET_FC_AL_POSITION_MAP;
1906 	mcp->mb[2] = MSW(pmap_dma);
1907 	mcp->mb[3] = LSW(pmap_dma);
1908 	mcp->mb[6] = MSW(MSD(pmap_dma));
1909 	mcp->mb[7] = LSW(MSD(pmap_dma));
1910 	mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
1911 	mcp->in_mb = MBX_1|MBX_0;
1912 	mcp->buf_size = FCAL_MAP_SIZE;
1913 	mcp->flags = MBX_DMA_IN;
1914 	mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
1915 	rval = qla2x00_mailbox_command(ha, mcp);
1916 
1917 	if (rval == QLA_SUCCESS) {
1918 		DEBUG11(printk("%s(%ld): (mb0=%x/mb1=%x) FC/AL Position Map "
1919 		    "size (%x)\n", __func__, ha->host_no, mcp->mb[0],
1920 		    mcp->mb[1], (unsigned)pmap[0]));
1921 		DEBUG11(qla2x00_dump_buffer(pmap, pmap[0] + 1));
1922 
1923 		if (pos_map)
1924 			memcpy(pos_map, pmap, FCAL_MAP_SIZE);
1925 	}
1926 	dma_pool_free(ha->s_dma_pool, pmap, pmap_dma);
1927 
1928 	if (rval != QLA_SUCCESS) {
1929 		DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__,
1930 		    ha->host_no, rval));
1931 	} else {
1932 		DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no));
1933 	}
1934 
1935 	return rval;
1936 }
1937 #endif
1938