VServer 1.9.2 (patch-2.6.8.1-vs1.9.2.diff)
[linux-2.6.git] / drivers / scsi / qla2xxx / qla_mbx.c
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 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     *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, *optr;
67         uint32_t        cnt;
68         uint32_t        mboxes;
69         unsigned long   mbx_flags = 0;
70         unsigned long   wait_time;
71
72         rval = QLA_SUCCESS;
73
74         DEBUG11(printk("qla2x00_mailbox_command(%ld): entered.\n",
75             ha->host_no);)
76         /*
77          * Wait for active mailbox commands to finish by waiting at most
78          * tov seconds. This is to serialize actual issuing of mailbox cmds
79          * during non ISP abort time.
80          */
81         if (!abort_active) {
82                 if (qla2x00_down_timeout(&ha->mbx_cmd_sem, mcp->tov * HZ)) {
83                         /* Timeout occurred. Return error. */
84                         DEBUG2_3_11(printk("qla2x00_mailbox_command(%ld): cmd "
85                             "access timeout. Exiting.\n", ha->host_no);)
86                         return QLA_FUNCTION_TIMEOUT;
87                 }
88         }
89
90         ha->flags.mbox_busy = 1;
91         /* Save mailbox command for debug */
92         ha->mcp = mcp;
93
94         /* Try to get mailbox register access */
95         if (!abort_active)
96                 spin_lock_irqsave(&ha->mbx_reg_lock, mbx_flags);
97
98         DEBUG11(printk("scsi%d: prepare to issue mbox cmd=0x%x.\n",
99             (int)ha->host_no, mcp->mb[0]);)
100
101         spin_lock_irqsave(&ha->hardware_lock, flags);
102
103         /* Load mailbox registers. */
104         optr = (uint16_t *)MAILBOX_REG(ha, reg, 0);
105
106         iptr = mcp->mb;
107         command = mcp->mb[0];
108         mboxes = mcp->out_mb;
109
110         for (cnt = 0; cnt < ha->mbx_count; cnt++) {
111                 if (IS_QLA2200(ha) && cnt == 8)
112                         optr = (uint16_t *)MAILBOX_REG(ha, reg, 8);
113                 if (mboxes & BIT_0)
114                         WRT_REG_WORD(optr, *iptr);
115
116                 mboxes >>= 1;
117                 optr++;
118                 iptr++;
119         }
120
121 #if defined(QL_DEBUG_LEVEL_1)
122         printk("qla2x00_mailbox_command: Loaded MBX registers "
123             "(displayed in bytes) = \n");
124         qla2x00_dump_buffer((uint8_t *)mcp->mb, 16);
125         printk("\n");
126         qla2x00_dump_buffer(((uint8_t *)mcp->mb + 0x10), 16);
127         printk("\n");
128         qla2x00_dump_buffer(((uint8_t *)mcp->mb + 0x20), 8);
129         printk("\n");
130         printk("qla2x00_mailbox_command: I/O address = %lx.\n",
131             (u_long)optr);
132         qla2x00_dump_regs(ha);
133 #endif
134
135         /* Issue set host interrupt command to send cmd out. */
136         ha->flags.mbox_int = 0;
137         clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
138
139         /* Unlock mbx registers and wait for interrupt */
140
141         DEBUG11(printk("qla2x00_mailbox_command: going to unlock irq & "
142             "waiting for interrupt. jiffies=%lx.\n", jiffies);)
143
144         /* Wait for mbx cmd completion until timeout */
145
146         if (!abort_active && io_lock_on) {
147                 /* sleep on completion semaphore */
148                 DEBUG11(printk("qla2x00_mailbox_command(%ld): "
149                     "INTERRUPT MODE. Initializing timer.\n",
150                     ha->host_no);)
151
152                 init_timer(&tmp_intr_timer);
153                 tmp_intr_timer.data = (unsigned long)&ha->mbx_intr_sem;
154                 tmp_intr_timer.expires = jiffies + mcp->tov * HZ;
155                 tmp_intr_timer.function =
156                     (void (*)(unsigned long))qla2x00_mbx_sem_timeout;
157
158                 DEBUG11(printk("qla2x00_mailbox_command(%ld): "
159                     "Adding timer.\n", ha->host_no);)
160                 add_timer(&tmp_intr_timer);
161
162                 DEBUG11(printk("qla2x00_mailbox_command: going to "
163                     "unlock & sleep. time=0x%lx.\n", jiffies);)
164
165                 set_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
166
167                 WRT_REG_WORD(&reg->hccr, HCCR_SET_HOST_INT);
168                 spin_unlock_irqrestore(&ha->hardware_lock, flags);
169
170                 if (!abort_active)
171                         spin_unlock_irqrestore(&ha->mbx_reg_lock, mbx_flags);
172
173                 /* Wait for either the timer to expire
174                  * or the mbox completion interrupt
175                  */
176                 down(&ha->mbx_intr_sem);
177
178                 DEBUG11(printk("qla2x00_mailbox_command:"
179                     "waking up."
180                     "time=0x%lx\n", jiffies);)
181                 clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
182
183                 /* delete the timer */
184                 del_timer(&tmp_intr_timer);
185         } else {
186
187                 DEBUG3_11(printk("qla2x00_mailbox_command(%ld): cmd=%x "
188                         "POLLING MODE.\n", ha->host_no, command);)
189
190                 WRT_REG_WORD(&reg->hccr, HCCR_SET_HOST_INT);
191                 spin_unlock_irqrestore(&ha->hardware_lock, flags);
192                 if (!abort_active)
193                         spin_unlock_irqrestore(&ha->mbx_reg_lock, mbx_flags);
194
195                 wait_time = jiffies + mcp->tov * HZ; /* wait at most tov secs */
196                 while (!ha->flags.mbox_int) {
197                         if (time_after(jiffies, wait_time))
198                                 break;
199
200                         /* Check for pending interrupts. */
201                         qla2x00_poll(ha);
202
203                         udelay(10); /* v4.27 */
204                 } /* while */
205         }
206
207         if (!abort_active)
208                 spin_lock_irqsave(&ha->mbx_reg_lock, mbx_flags);
209
210         /* Check whether we timed out */
211         if (ha->flags.mbox_int) {
212
213                 DEBUG3_11(printk("qla2x00_mailbox_cmd: cmd %x completed.\n",
214                     command);)
215
216                 /* Got interrupt. Clear the flag. */
217                 ha->flags.mbox_int = 0;
218                 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
219
220                 if (ha->mailbox_out[0] != MBS_COMMAND_COMPLETE) {
221                         qla2x00_stats.mboxerr++;
222                         rval = QLA_FUNCTION_FAILED;
223                 }
224
225                 /* Load return mailbox registers. */
226                 optr = 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                                 *optr = *iptr;
232
233                         mboxes >>= 1;
234                         optr++;
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                 qla2x00_stats.mboxtout++;
251                 ha->total_mbx_timeout++;
252                 rval = QLA_FUNCTION_TIMEOUT;
253         }
254
255         if (!abort_active)
256                 spin_unlock_irqrestore(&ha->mbx_reg_lock, mbx_flags);
257
258         ha->flags.mbox_busy = 0;
259
260         /* Clean up */
261         ha->mcp = NULL;
262
263         if (!abort_active) {
264                 DEBUG11(printk("qla2x00_mailbox_cmd: checking for additional "
265                     "resp interrupt.\n");)
266
267                 /* polling mode for non isp_abort commands. */
268                 qla2x00_poll(ha);
269         }
270
271         if (rval == QLA_FUNCTION_TIMEOUT) {
272                 if (!io_lock_on || (mcp->flags & IOCTL_CMD)) {
273                         /* not in dpc. schedule it for dpc to take over. */
274                         DEBUG(printk("qla2x00_mailbox_command(%ld): timeout "
275                             "schedule isp_abort_needed.\n",
276                             ha->host_no);)
277                         DEBUG2_3_11(printk("qla2x00_mailbox_command(%ld): "
278                             "timeout schedule isp_abort_needed.\n",
279                             ha->host_no);)
280                         qla_printk(KERN_WARNING, ha,
281                             "Mailbox command timeout occured. Scheduling ISP "
282                             "abort.\n");
283                         set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
284                         if (ha->dpc_wait && !ha->dpc_active) 
285                                 up(ha->dpc_wait);
286
287                 } else if (!abort_active) {
288
289                         /* call abort directly since we are in the DPC thread */
290                         DEBUG(printk("qla2x00_mailbox_command(%ld): timeout "
291                             "calling abort_isp\n", ha->host_no);)
292                         DEBUG2_3_11(printk("qla2x00_mailbox_command(%ld): "
293                             "timeout calling abort_isp\n", ha->host_no);)
294                         qla_printk(KERN_WARNING, ha,
295                             "Mailbox command timeout occured. Issuing ISP "
296                             "abort.\n");
297
298                         set_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags);
299                         clear_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
300                         if (qla2x00_abort_isp(ha)) {
301                                 /* failed. retry later. */
302                                 set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
303                         }
304                         clear_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags);
305
306                         DEBUG(printk("qla2x00_mailbox_command: finished "
307                             "abort_isp\n");)
308                         DEBUG2_3_11(printk("qla2x00_mailbox_command: finished "
309                             "abort_isp\n");)
310                 }
311         }
312
313         /* Allow next mbx cmd to come in. */
314         if (!abort_active)
315                 up(&ha->mbx_cmd_sem);
316
317         if (rval) {
318                 DEBUG2_3_11(printk("qla2x00_mailbox_command(%ld): **** FAILED. "
319                     "mbx0=%x, mbx1=%x, mbx2=%x, cmd=%x ****\n",
320                 ha->host_no, mcp->mb[0], mcp->mb[1], mcp->mb[2], command);)
321         } else {
322                 DEBUG11(printk("qla2x00_mailbox_command(%ld): done.\n",
323                     ha->host_no);)
324         }
325
326         DEBUG11(printk("qla2x00_mailbox_command(%ld): exiting.\n",
327             ha->host_no);)
328
329         return rval;
330 }
331
332 /*
333  * qla2x00_load_ram
334  *      Load adapter RAM using DMA.
335  *
336  * Input:
337  *      ha = adapter block pointer.
338  *
339  * Returns:
340  *      qla2x00 local function return status code.
341  *
342  * Context:
343  *      Kernel context.
344  */
345 int
346 qla2x00_load_ram(scsi_qla_host_t *ha, dma_addr_t req_dma, uint16_t risc_addr,
347     uint16_t risc_code_size)
348 {
349         int rval;
350         mbx_cmd_t mc;
351         mbx_cmd_t *mcp = &mc;
352         uint32_t        req_len;
353         dma_addr_t      nml_dma;
354         uint32_t        nml_len;
355         uint32_t        normalized;
356
357         DEBUG11(printk("qla2x00_load_ram(%ld): entered.\n",
358             ha->host_no);)
359
360         req_len = risc_code_size;
361         nml_dma = 0;
362         nml_len = 0;
363
364         normalized = qla2x00_normalize_dma_addr(&req_dma, &req_len, &nml_dma,
365             &nml_len);
366
367         /* Load first segment */
368         mcp->mb[0] = MBC_LOAD_RISC_RAM;
369         mcp->mb[1] = risc_addr;
370         mcp->mb[2] = MSW(req_dma);
371         mcp->mb[3] = LSW(req_dma);
372         mcp->mb[4] = (uint16_t)req_len;
373         mcp->mb[6] = MSW(MSD(req_dma));
374         mcp->mb[7] = LSW(MSD(req_dma));
375         mcp->out_mb = MBX_7|MBX_6|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
376         mcp->in_mb = MBX_0;
377         mcp->tov = 30;
378         mcp->flags = 0;
379         rval = qla2x00_mailbox_command(ha, mcp);
380
381         /* Load second segment - if necessary */
382         if (normalized && (rval == QLA_SUCCESS)) {
383                 mcp->mb[0] = MBC_LOAD_RISC_RAM;
384                 mcp->mb[1] = risc_addr + (uint16_t)req_len;
385                 mcp->mb[2] = MSW(nml_dma);
386                 mcp->mb[3] = LSW(nml_dma);
387                 mcp->mb[4] = (uint16_t)nml_len;
388                 mcp->mb[6] = MSW(MSD(nml_dma));
389                 mcp->mb[7] = LSW(MSD(nml_dma));
390                 mcp->out_mb = MBX_7|MBX_6|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
391                 mcp->in_mb = MBX_0;
392                 mcp->tov = 30;
393                 mcp->flags = 0;
394                 rval = qla2x00_mailbox_command(ha, mcp);
395         }
396
397         if (rval == QLA_SUCCESS) {
398                 /* Empty */
399                 DEBUG11(printk("qla2x00_load_ram(%ld): done.\n", ha->host_no);)
400         } else {
401                 /* Empty */
402                 DEBUG2_3_11(printk("qla2x00_load_ram(%ld): failed. rval=%x "
403                     "mb[0]=%x.\n", ha->host_no, rval, mcp->mb[0]);)
404         }
405         return rval;
406 }
407
408 /*
409  * qla2x00_load_ram_ext
410  *      Load adapter extended RAM using DMA.
411  *
412  * Input:
413  *      ha = adapter block pointer.
414  *
415  * Returns:
416  *      qla2x00 local function return status code.
417  *
418  * Context:
419  *      Kernel context.
420  */
421 int
422 qla2x00_load_ram_ext(scsi_qla_host_t *ha, dma_addr_t req_dma,
423     uint32_t risc_addr, uint16_t risc_code_size)
424 {
425         int rval;
426         mbx_cmd_t mc;
427         mbx_cmd_t *mcp = &mc;
428         uint32_t        req_len;
429         dma_addr_t      nml_dma;
430         uint32_t        nml_len;
431         uint32_t        normalized;
432
433         DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no));
434
435         req_len = risc_code_size;
436         nml_dma = 0;
437         nml_len = 0;
438
439         normalized = qla2x00_normalize_dma_addr(&req_dma, &req_len, &nml_dma,
440             &nml_len);
441
442         /* Load first segment */
443         mcp->mb[0] = MBC_LOAD_RISC_RAM_EXTENDED;
444         mcp->mb[1] = LSW(risc_addr);
445         mcp->mb[2] = MSW(req_dma);
446         mcp->mb[3] = LSW(req_dma);
447         mcp->mb[4] = (uint16_t)req_len;
448         mcp->mb[6] = MSW(MSD(req_dma));
449         mcp->mb[7] = LSW(MSD(req_dma));
450         mcp->mb[8] = MSW(risc_addr);
451         mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
452         mcp->in_mb = MBX_0;
453         mcp->tov = 30;
454         mcp->flags = 0;
455         rval = qla2x00_mailbox_command(ha, mcp);
456
457         /* Load second segment - if necessary */
458         if (normalized && (rval == QLA_SUCCESS)) {
459                 risc_addr += req_len;
460                 mcp->mb[0] = MBC_LOAD_RISC_RAM_EXTENDED;
461                 mcp->mb[1] = LSW(risc_addr);
462                 mcp->mb[2] = MSW(nml_dma);
463                 mcp->mb[3] = LSW(nml_dma);
464                 mcp->mb[4] = (uint16_t)nml_len;
465                 mcp->mb[6] = MSW(MSD(nml_dma));
466                 mcp->mb[7] = LSW(MSD(nml_dma));
467                 mcp->mb[8] = MSW(risc_addr);
468                 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
469                 mcp->in_mb = MBX_0;
470                 mcp->tov = 30;
471                 mcp->flags = 0;
472                 rval = qla2x00_mailbox_command(ha, mcp);
473         }
474
475         if (rval != QLA_SUCCESS) {
476                 /*EMPTY*/
477                 DEBUG2_3_11(printk("%s(%ld): failed=%x mb[0]=%x.\n",
478                     __func__, ha->host_no, rval, mcp->mb[0]));
479         } else {
480                 /*EMPTY*/
481                 DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no));
482         }
483
484         return rval;
485 }
486
487 /*
488  * qla2x00_execute_fw
489  *      Start adapter firmware.
490  *
491  * Input:
492  *      ha = adapter block pointer.
493  *      TARGET_QUEUE_LOCK must be released.
494  *      ADAPTER_STATE_LOCK must be released.
495  *
496  * Returns:
497  *      qla2x00 local function return status code.
498  *
499  * Context:
500  *      Kernel context.
501  */
502 int
503 qla2x00_execute_fw(scsi_qla_host_t *ha)
504 {
505         int rval;
506         mbx_cmd_t mc;
507         mbx_cmd_t *mcp = &mc;
508
509         DEBUG11(printk("qla2x00_execute_fw(%ld): entered.\n", ha->host_no);)
510
511         mcp->mb[0] = MBC_EXECUTE_FIRMWARE;
512         mcp->mb[1] = *ha->brd_info->fw_info[0].fwstart;
513         mcp->out_mb = MBX_1|MBX_0;
514         if (IS_QLA2322(ha) || IS_QLA6322(ha)) {
515                 mcp->mb[2] = 0;
516                 mcp->out_mb |= MBX_2;
517         }
518
519         mcp->in_mb = MBX_0;
520         mcp->tov = 30;
521         mcp->flags = 0;
522         rval = qla2x00_mailbox_command(ha, mcp);
523
524         DEBUG11(printk("qla2x00_execute_fw(%ld): done.\n", ha->host_no);)
525
526         return rval;
527 }
528
529 /*
530  * qla2x00_get_fw_version
531  *      Get firmware version.
532  *
533  * Input:
534  *      ha:             adapter state pointer.
535  *      major:          pointer for major number.
536  *      minor:          pointer for minor number.
537  *      subminor:       pointer for subminor number.
538  *
539  * Returns:
540  *      qla2x00 local function return status code.
541  *
542  * Context:
543  *      Kernel context.
544  */
545 void
546 qla2x00_get_fw_version(scsi_qla_host_t *ha, uint16_t *major, uint16_t *minor,
547     uint16_t *subminor, uint16_t *attributes, uint32_t *memory)
548 {
549         int             rval;
550         mbx_cmd_t       mc;
551         mbx_cmd_t       *mcp = &mc;
552
553         DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no));
554
555         mcp->mb[0] = MBC_GET_FIRMWARE_VERSION;
556         mcp->out_mb = MBX_0;
557         mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
558         mcp->flags = 0;
559         mcp->tov = 30;
560         rval = qla2x00_mailbox_command(ha, mcp);
561
562         /* Return mailbox data. */
563         *major = mcp->mb[1];
564         *minor = mcp->mb[2];
565         *subminor = mcp->mb[3];
566         *attributes = mcp->mb[6];
567         if (IS_QLA2100(ha) || IS_QLA2200(ha))
568                 *memory = 0x1FFFF;                      /* Defaults to 128KB. */
569         else
570                 *memory = (mcp->mb[5] << 16) | mcp->mb[4];
571
572         if (rval != QLA_SUCCESS) {
573                 /*EMPTY*/
574                 DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__,
575                     ha->host_no, rval));
576         } else {
577                 /*EMPTY*/
578                 DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no));
579         }
580 }
581
582 /*
583  * qla2x00_get_fw_options
584  *      Set firmware options.
585  *
586  * Input:
587  *      ha = adapter block pointer.
588  *      fwopt = pointer for firmware options.
589  *
590  * Returns:
591  *      qla2x00 local function return status code.
592  *
593  * Context:
594  *      Kernel context.
595  */
596 int
597 qla2x00_get_fw_options(scsi_qla_host_t *ha, uint16_t *fwopts)
598 {
599         int rval;
600         mbx_cmd_t mc;
601         mbx_cmd_t *mcp = &mc;
602
603         DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no));
604
605         mcp->mb[0] = MBC_GET_FIRMWARE_OPTION;
606         mcp->out_mb = MBX_0;
607         mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
608         mcp->tov = 30;
609         mcp->flags = 0;
610         rval = qla2x00_mailbox_command(ha, mcp);
611
612         if (rval != QLA_SUCCESS) {
613                 /*EMPTY*/
614                 DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__,
615                     ha->host_no, rval));
616         } else {
617                 fwopts[1] = mcp->mb[1];
618                 fwopts[2] = mcp->mb[2];
619                 fwopts[3] = mcp->mb[3];
620
621                 DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no));
622         }
623
624         return rval;
625 }
626
627
628 /*
629  * qla2x00_set_fw_options
630  *      Set firmware options.
631  *
632  * Input:
633  *      ha = adapter block pointer.
634  *      fwopt = pointer for firmware options.
635  *
636  * Returns:
637  *      qla2x00 local function return status code.
638  *
639  * Context:
640  *      Kernel context.
641  */
642 int
643 qla2x00_set_fw_options(scsi_qla_host_t *ha, uint16_t *fwopts)
644 {
645         int rval;
646         mbx_cmd_t mc;
647         mbx_cmd_t *mcp = &mc;
648
649         DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no));
650
651         mcp->mb[0] = MBC_SET_FIRMWARE_OPTION;
652         mcp->mb[1] = fwopts[1];
653         mcp->mb[2] = fwopts[2];
654         mcp->mb[3] = fwopts[3];
655         mcp->mb[10] = fwopts[10];
656         mcp->mb[11] = fwopts[11];
657         mcp->mb[12] = 0;        /* Undocumented, but used */
658         mcp->out_mb = MBX_12|MBX_11|MBX_10|MBX_3|MBX_2|MBX_1|MBX_0;
659         mcp->in_mb = MBX_0;
660         mcp->tov = 30;
661         mcp->flags = 0;
662         rval = qla2x00_mailbox_command(ha, mcp);
663
664         if (rval != QLA_SUCCESS) {
665                 /*EMPTY*/
666                 DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__,
667                     ha->host_no, rval));
668         } else {
669                 /*EMPTY*/
670                 DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no));
671         }
672
673         return rval;
674 }
675
676 /*
677  * qla2x00_read_ram_word
678  *
679  * Input:
680  *      ha = adapter block pointer.
681  *
682  * Returns:
683  *      qla2x00 local function return status code.
684  *
685  * Context:
686  *      Kernel context.
687  */
688 int
689 qla2x00_read_ram_word(scsi_qla_host_t *ha, uint16_t addr, uint16_t *data)
690 {
691         int rval;
692         mbx_cmd_t mc;
693         mbx_cmd_t *mcp = &mc;
694
695         DEBUG11(printk("qla2x00_read_ram_word(%ld): entered.\n", ha->host_no);)
696
697         mcp->mb[0] = MBC_READ_RAM_WORD;
698         mcp->mb[1] = addr;
699         mcp->out_mb = MBX_1|MBX_0;
700         mcp->in_mb = MBX_0|MBX_2;
701         mcp->tov = 30;
702         mcp->flags = 0;
703         rval = qla2x00_mailbox_command(ha, mcp);
704
705         if (rval != QLA_SUCCESS) {
706                 /*EMPTY*/
707                 DEBUG2_3_11(printk("qla2x00_read_ram_word(%ld): failed=%x.\n",
708                     ha->host_no, rval);)
709         } else {
710                 *data = mcp->mb[2];
711                 DEBUG11(printk("qla2x00_read_ram_word(%ld): done.\n",
712                     ha->host_no);)
713         }
714
715         return rval;
716 }
717
718 /*
719  * qla2x00_write_ram_word
720  *
721  * Input:
722  *      ha = adapter block pointer.
723  *
724  * Returns:
725  *      qla2x00 local function return status code.
726  *
727  * Context:
728  *      Kernel context.
729  */
730 int
731 qla2x00_write_ram_word(scsi_qla_host_t *ha, uint16_t addr, uint16_t data)
732 {
733         int rval;
734         mbx_cmd_t mc;
735         mbx_cmd_t *mcp = &mc;
736
737         DEBUG11(printk("qla2x00_write_ram_word(%ld): entered.\n",
738             ha->host_no);)
739
740         mcp->mb[0] = MBC_WRITE_RAM_WORD;
741         mcp->mb[1] = addr;
742         mcp->mb[2] = data;
743         mcp->out_mb = MBX_2|MBX_1|MBX_0;
744         mcp->in_mb = MBX_0;
745         mcp->tov = 30;
746         mcp->flags = 0;
747         rval = qla2x00_mailbox_command(ha, mcp);
748
749         if (rval != QLA_SUCCESS) {
750                 /*EMPTY*/
751                 DEBUG2_3_11(printk("qla2x00_write_ram_word(%ld): failed=%x.\n",
752                     ha->host_no, rval);)
753         } else {
754                 /*EMPTY*/
755                 DEBUG11(printk("qla2x00_write_ram_word(%ld): done.\n",
756                     ha->host_no);)
757         }
758
759         return rval;
760 }
761
762 /*
763  * qla2x00_write_ram_word_ext
764  *
765  * Input:
766  *      ha = adapter block pointer.
767  *
768  * Returns:
769  *      qla2x00 local function return status code.
770  *
771  * Context:
772  *      Kernel context.
773  */
774 int
775 qla2x00_write_ram_word_ext(scsi_qla_host_t *ha, uint32_t addr, uint16_t data)
776 {
777         int rval;
778         mbx_cmd_t mc;
779         mbx_cmd_t *mcp = &mc;
780
781         DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no));
782
783         mcp->mb[0] = MBC_WRITE_RAM_WORD_EXTENDED;
784         mcp->mb[1] = LSW(addr);
785         mcp->mb[2] = data;
786         mcp->mb[8] = MSW(addr);
787         mcp->out_mb = MBX_8|MBX_2|MBX_1|MBX_0;
788         mcp->in_mb = MBX_0;
789         mcp->tov = 30;
790         mcp->flags = 0;
791         rval = qla2x00_mailbox_command(ha, mcp);
792
793         if (rval != QLA_SUCCESS) {
794                 /*EMPTY*/
795                 DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__,
796                     ha->host_no, rval));
797         } else {
798                 /*EMPTY*/
799                 DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no));
800         }
801
802         return rval;
803 }
804
805 /*
806  * qla2x00_mbx_reg_test
807  *      Mailbox register wrap test.
808  *
809  * Input:
810  *      ha = adapter block pointer.
811  *      TARGET_QUEUE_LOCK must be released.
812  *      ADAPTER_STATE_LOCK must be released.
813  *
814  * Returns:
815  *      qla2x00 local function return status code.
816  *
817  * Context:
818  *      Kernel context.
819  */
820 int
821 qla2x00_mbx_reg_test(scsi_qla_host_t *ha)
822 {
823         int rval;
824         mbx_cmd_t mc;
825         mbx_cmd_t *mcp = &mc;
826
827         DEBUG11(printk("qla2x00_mbx_reg_test(%ld): entered.\n", ha->host_no);)
828
829         mcp->mb[0] = MBC_MAILBOX_REGISTER_TEST;
830         mcp->mb[1] = 0xAAAA;
831         mcp->mb[2] = 0x5555;
832         mcp->mb[3] = 0xAA55;
833         mcp->mb[4] = 0x55AA;
834         mcp->mb[5] = 0xA5A5;
835         mcp->mb[6] = 0x5A5A;
836         mcp->mb[7] = 0x2525;
837         mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
838         mcp->in_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
839         mcp->tov = 30;
840         mcp->flags = 0;
841         rval = qla2x00_mailbox_command(ha, mcp);
842
843         if (rval == QLA_SUCCESS) {
844                 if (mcp->mb[1] != 0xAAAA || mcp->mb[2] != 0x5555 ||
845                     mcp->mb[3] != 0xAA55 || mcp->mb[4] != 0x55AA)
846                         rval = QLA_FUNCTION_FAILED;
847                 if (mcp->mb[5] != 0xA5A5 || mcp->mb[6] != 0x5A5A ||
848                     mcp->mb[7] != 0x2525)
849                         rval = QLA_FUNCTION_FAILED;
850         }
851
852         if (rval != QLA_SUCCESS) {
853                 /*EMPTY*/
854                 DEBUG2_3_11(printk("qla2x00_mbx_reg_test(%ld): failed=%x.\n",
855                     ha->host_no, rval);)
856         } else {
857                 /*EMPTY*/
858                 DEBUG11(printk("qla2x00_mbx_reg_test(%ld): done.\n",
859                     ha->host_no);)
860         }
861
862         return rval;
863 }
864
865 /*
866  * qla2x00_verify_checksum
867  *      Verify firmware checksum.
868  *
869  * Input:
870  *      ha = adapter block pointer.
871  *      TARGET_QUEUE_LOCK must be released.
872  *      ADAPTER_STATE_LOCK must be released.
873  *
874  * Returns:
875  *      qla2x00 local function return status code.
876  *
877  * Context:
878  *      Kernel context.
879  */
880 int
881 qla2x00_verify_checksum(scsi_qla_host_t *ha)
882 {
883         int rval;
884         mbx_cmd_t mc;
885         mbx_cmd_t *mcp = &mc;
886
887         DEBUG11(printk("qla2x00_verify_checksum(%ld): entered.\n",
888             ha->host_no);)
889
890         mcp->mb[0] = MBC_VERIFY_CHECKSUM;
891         mcp->mb[1] = *ha->brd_info->fw_info[0].fwstart;
892         mcp->out_mb = MBX_1|MBX_0;
893         mcp->in_mb = MBX_2|MBX_0;
894         mcp->tov = 30;
895         mcp->flags = 0;
896         rval = qla2x00_mailbox_command(ha, mcp);
897
898         if (rval != QLA_SUCCESS) {
899                 /*EMPTY*/
900                 DEBUG2_3_11(printk("qla2x00_verify_checksum(%ld): failed=%x.\n",
901                     ha->host_no, rval);)
902         } else {
903                 /*EMPTY*/
904                 DEBUG11(printk("qla2x00_verify_checksum(%ld): done.\n",
905                     ha->host_no);)
906         }
907
908         return rval;
909 }
910
911 /*
912  * qla2x00_issue_iocb
913  *      Issue IOCB using mailbox command
914  *
915  * Input:
916  *      ha = adapter state pointer.
917  *      buffer = buffer pointer.
918  *      phys_addr = physical address of buffer.
919  *      size = size of buffer.
920  *      TARGET_QUEUE_LOCK must be released.
921  *      ADAPTER_STATE_LOCK must be released.
922  *
923  * Returns:
924  *      qla2x00 local function return status code.
925  *
926  * Context:
927  *      Kernel context.
928  */
929 int
930 qla2x00_issue_iocb(scsi_qla_host_t *ha, void*  buffer, dma_addr_t phys_addr,
931     size_t size)
932 {
933         int             rval;
934         mbx_cmd_t       mc;
935         mbx_cmd_t       *mcp = &mc;
936
937         mcp->mb[0] = MBC_IOCB_COMMAND_A64;
938         mcp->mb[1] = 0;
939         mcp->mb[2] = MSW(phys_addr);
940         mcp->mb[3] = LSW(phys_addr);
941         mcp->mb[6] = MSW(MSD(phys_addr));
942         mcp->mb[7] = LSW(MSD(phys_addr));
943         mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
944         mcp->in_mb = MBX_2|MBX_0;
945         mcp->tov = 30;
946         mcp->flags = 0;
947         rval = qla2x00_mailbox_command(ha, mcp);
948
949         if (rval != QLA_SUCCESS) {
950                 /*EMPTY*/
951                 DEBUG(printk("qla2x00_issue_iocb(%ld): failed rval 0x%x",
952                     ha->host_no,rval);)
953                 DEBUG2(printk("qla2x00_issue_iocb(%ld): failed rval 0x%x",
954                     ha->host_no,rval);)
955         } else {
956                 /*EMPTY*/
957         }
958
959         return rval;
960 }
961
962 /*
963  * qla2x00_abort_command
964  *      Abort command aborts a specified IOCB.
965  *
966  * Input:
967  *      ha = adapter block pointer.
968  *      sp = SB structure pointer.
969  *
970  * Returns:
971  *      qla2x00 local function return status code.
972  *
973  * Context:
974  *      Kernel context.
975  */
976 int
977 qla2x00_abort_command(scsi_qla_host_t *ha, srb_t *sp)
978 {
979         unsigned long   flags = 0;
980         fc_port_t       *fcport;
981         int             rval;
982         uint32_t        handle;
983         mbx_cmd_t       mc;
984         mbx_cmd_t       *mcp = &mc;
985
986         DEBUG11(printk("qla2x00_abort_command(%ld): entered.\n", ha->host_no);)
987
988         fcport = sp->fclun->fcport;
989
990         if (atomic_read(&ha->loop_state) == LOOP_DOWN ||
991             atomic_read(&fcport->state) == FCS_DEVICE_LOST) {
992                 return 1;
993         }
994
995         spin_lock_irqsave(&ha->hardware_lock, flags);
996         for (handle = 1; handle < MAX_OUTSTANDING_COMMANDS; handle++) {
997                 if (ha->outstanding_cmds[handle] == sp)
998                         break;
999         }
1000         spin_unlock_irqrestore(&ha->hardware_lock, flags);
1001
1002         if (handle == MAX_OUTSTANDING_COMMANDS) {
1003                 /* command not found */
1004                 return QLA_FUNCTION_FAILED;
1005         }
1006
1007         mcp->mb[0] = MBC_ABORT_COMMAND;
1008         if (HAS_EXTENDED_IDS(ha))
1009                 mcp->mb[1] = fcport->loop_id;
1010         else
1011                 mcp->mb[1] = fcport->loop_id << 8;
1012         mcp->mb[2] = (uint16_t)handle;
1013         mcp->mb[3] = (uint16_t)(handle >> 16);
1014         mcp->mb[6] = (uint16_t)sp->fclun->lun;
1015         mcp->out_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
1016         mcp->in_mb = MBX_0;
1017         mcp->tov = 30;
1018         mcp->flags = 0;
1019         rval = qla2x00_mailbox_command(ha, mcp);
1020
1021         if (rval != QLA_SUCCESS) {
1022                 DEBUG2_3_11(printk("qla2x00_abort_command(%ld): failed=%x.\n",
1023                     ha->host_no, rval);)
1024         } else {
1025                 sp->flags |= SRB_ABORT_PENDING;
1026                 DEBUG11(printk("qla2x00_abort_command(%ld): done.\n",
1027                     ha->host_no);)
1028         }
1029
1030         return rval;
1031 }
1032
1033 /*
1034  * qla2x00_abort_device
1035  *
1036  * Input:
1037  *      ha = adapter block pointer.
1038  *      loop_id  = FC loop ID
1039  *      lun  = SCSI LUN.
1040  *
1041  * Returns:
1042  *      qla2x00 local function return status code.
1043  *
1044  * Context:
1045  *      Kernel context.
1046  */
1047 int
1048 qla2x00_abort_device(scsi_qla_host_t *ha, uint16_t loop_id, uint16_t lun)
1049 {
1050         int rval;
1051         mbx_cmd_t mc;
1052         mbx_cmd_t *mcp = &mc;
1053
1054         DEBUG11(printk("qla2x00_abort_device(%ld): entered.\n", ha->host_no);)
1055
1056         mcp->mb[0] = MBC_ABORT_DEVICE;
1057         if (HAS_EXTENDED_IDS(ha))
1058                 mcp->mb[1] = loop_id;
1059         else
1060                 mcp->mb[1] = loop_id << 8;
1061         mcp->mb[2] = lun;
1062         mcp->out_mb = MBX_2|MBX_1|MBX_0;
1063         mcp->in_mb = MBX_0;
1064         mcp->tov = 30;
1065         mcp->flags = 0;
1066         rval = qla2x00_mailbox_command(ha, mcp);
1067
1068         /* Issue marker command. */
1069         qla2x00_marker(ha, loop_id, lun, MK_SYNC_ID_LUN);
1070
1071         if (rval != QLA_SUCCESS) {
1072                 qla_printk(KERN_WARNING, ha,
1073                     "Failed Abort Device Mailbox command. Scheduling ISP "
1074                     "abort.\n");
1075                 set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
1076                 if (ha->dpc_wait && !ha->dpc_active) 
1077                         up(ha->dpc_wait);
1078                 DEBUG2_3_11(printk("qla2x00_abort_device(%ld): failed=%x.\n",
1079                     ha->host_no, rval);)
1080         } else {
1081                 /*EMPTY*/
1082                 DEBUG11(printk("qla2x00_abort_device(%ld): done.\n",
1083                     ha->host_no);)
1084         }
1085
1086         return rval;
1087 }
1088
1089 #if USE_ABORT_TGT
1090 /*
1091  * qla2x00_abort_target
1092  *      Issue abort target mailbox command.
1093  *
1094  * Input:
1095  *      ha = adapter block pointer.
1096  *
1097  * Returns:
1098  *      qla2x00 local function return status code.
1099  *
1100  * Context:
1101  *      Kernel context.
1102  */
1103 int
1104 qla2x00_abort_target(fc_port_t *fcport)
1105 {
1106         int        rval;
1107         mbx_cmd_t  mc;
1108         mbx_cmd_t  *mcp = &mc;
1109
1110         DEBUG11(printk("qla2x00_abort_target(%ld): entered.\n",
1111             fcport->ha->host_no);)
1112
1113         if (fcport == NULL) {
1114                 /* no target to abort */
1115                 return 0;
1116         }
1117
1118         mcp->mb[0] = MBC_ABORT_TARGET;
1119         mcp->out_mb = MBX_2|MBX_1|MBX_0;
1120         if (HAS_EXTENDED_IDS(fcport->ha)) {
1121                 mcp->mb[1] = fcport->loop_id;
1122                 mcp->mb[10] = 0;
1123                 mcp->out_mb |= MBX_10;
1124         } else {
1125                 mcp->mb[1] = fcport->loop_id << 8;
1126         }
1127         mcp->mb[2] = fcport->ha->loop_reset_delay;
1128
1129         mcp->in_mb = MBX_0;
1130         mcp->tov = 30;
1131         mcp->flags = 0;
1132         rval = qla2x00_mailbox_command(fcport->ha, mcp);
1133
1134         /* Issue marker command. */
1135         fcport->ha->marker_needed = 1;
1136
1137         if (rval != QLA_SUCCESS) {
1138                 DEBUG2_3_11(printk("qla2x00_abort_target(%ld): failed=%x.\n",
1139                     fcport->ha->host_no, rval);)
1140         } else {
1141                 /*EMPTY*/
1142                 DEBUG11(printk("qla2x00_abort_target(%ld): done.\n",
1143                     fcport->ha->host_no);)
1144         }
1145
1146         return rval;
1147 }
1148 #endif
1149
1150 /*
1151  * qla2x00_target_reset
1152  *      Issue target reset mailbox command.
1153  *
1154  * Input:
1155  *      ha = adapter block pointer.
1156  *      TARGET_QUEUE_LOCK must be released.
1157  *      ADAPTER_STATE_LOCK must be released.
1158  *
1159  * Returns:
1160  *      qla2x00 local function return status code.
1161  *
1162  * Context:
1163  *      Kernel context.
1164  */
1165 int
1166 qla2x00_target_reset(scsi_qla_host_t *ha, uint16_t b, uint16_t t)
1167 {
1168         int rval;
1169         mbx_cmd_t mc;
1170         mbx_cmd_t *mcp = &mc;
1171         os_tgt_t *tgt;
1172
1173         DEBUG11(printk("qla2x00_target_reset(%ld): entered.\n", ha->host_no);)
1174
1175         tgt = TGT_Q(ha, t);
1176         if (tgt->fcport == NULL) {
1177                 /* no target to abort */
1178                 return 0;
1179         }
1180         if (atomic_read(&tgt->fcport->state) != FCS_ONLINE) {
1181                 /* target not online */
1182                 return 0;
1183         }
1184
1185         mcp->mb[0] = MBC_TARGET_RESET;
1186         if (HAS_EXTENDED_IDS(ha))
1187                 mcp->mb[1] = tgt->fcport->loop_id;
1188         else
1189                 mcp->mb[1] = tgt->fcport->loop_id << 8;
1190         mcp->mb[2] = ha->loop_reset_delay;
1191         mcp->out_mb = MBX_2|MBX_1|MBX_0;
1192         mcp->in_mb = MBX_0;
1193         mcp->tov = 30;
1194         mcp->flags = 0;
1195         rval = qla2x00_mailbox_command(ha, mcp);
1196
1197         if (rval != QLA_SUCCESS) {
1198                 /*EMPTY*/
1199                 DEBUG2_3_11(printk("qla2x00_target_reset(%ld): failed=%x.\n",
1200                     ha->host_no, rval);)
1201         } else {
1202                 /*EMPTY*/
1203                 DEBUG11(printk("qla2x00_target_reset(%ld): done.\n",
1204                     ha->host_no);)
1205         }
1206
1207         return rval;
1208 }
1209
1210 /*
1211  * qla2x00_get_adapter_id
1212  *      Get adapter ID and topology.
1213  *
1214  * Input:
1215  *      ha = adapter block pointer.
1216  *      id = pointer for loop ID.
1217  *      al_pa = pointer for AL_PA.
1218  *      area = pointer for area.
1219  *      domain = pointer for domain.
1220  *      top = pointer for topology.
1221  *      TARGET_QUEUE_LOCK must be released.
1222  *      ADAPTER_STATE_LOCK must be released.
1223  *
1224  * Returns:
1225  *      qla2x00 local function return status code.
1226  *
1227  * Context:
1228  *      Kernel context.
1229  */
1230 int
1231 qla2x00_get_adapter_id(scsi_qla_host_t *ha, uint16_t *id, uint8_t *al_pa,
1232     uint8_t *area, uint8_t *domain, uint16_t *top)
1233 {
1234         int rval;
1235         mbx_cmd_t mc;
1236         mbx_cmd_t *mcp = &mc;
1237
1238         DEBUG11(printk("qla2x00_get_adapter_id(%ld): entered.\n",
1239             ha->host_no);)
1240
1241         mcp->mb[0] = MBC_GET_ADAPTER_LOOP_ID;
1242         mcp->out_mb = MBX_0;
1243         mcp->in_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
1244         mcp->tov = 30;
1245         mcp->flags = 0;
1246         rval = qla2x00_mailbox_command(ha, mcp);
1247
1248         /* Return data. */
1249         *id = mcp->mb[1];
1250         *al_pa = LSB(mcp->mb[2]);
1251         *area = MSB(mcp->mb[2]);
1252         *domain = LSB(mcp->mb[3]);
1253         *top = mcp->mb[6];
1254
1255         if (rval != QLA_SUCCESS) {
1256                 /*EMPTY*/
1257                 DEBUG2_3_11(printk("qla2x00_get_adapter_id(%ld): failed=%x.\n",
1258                     ha->host_no, rval);)
1259         } else {
1260                 /*EMPTY*/
1261                 DEBUG11(printk("qla2x00_get_adapter_id(%ld): done.\n",
1262                     ha->host_no);)
1263         }
1264
1265         return rval;
1266 }
1267
1268 /*
1269  * qla2x00_get_retry_cnt
1270  *      Get current firmware login retry count and delay.
1271  *
1272  * Input:
1273  *      ha = adapter block pointer.
1274  *      retry_cnt = pointer to login retry count.
1275  *      tov = pointer to login timeout value.
1276  *
1277  * Returns:
1278  *      qla2x00 local function return status code.
1279  *
1280  * Context:
1281  *      Kernel context.
1282  */
1283 int
1284 qla2x00_get_retry_cnt(scsi_qla_host_t *ha, uint8_t *retry_cnt, uint8_t *tov,
1285     uint16_t *r_a_tov)
1286 {
1287         int rval;
1288         uint16_t ratov;
1289         mbx_cmd_t mc;
1290         mbx_cmd_t *mcp = &mc;
1291
1292         DEBUG11(printk("qla2x00_get_retry_cnt(%ld): entered.\n",
1293                         ha->host_no);)
1294
1295         mcp->mb[0] = MBC_GET_RETRY_COUNT;
1296         mcp->out_mb = MBX_0;
1297         mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
1298         mcp->tov = 30;
1299         mcp->flags = 0;
1300         rval = qla2x00_mailbox_command(ha, mcp);
1301
1302         if (rval != QLA_SUCCESS) {
1303                 /*EMPTY*/
1304                 DEBUG2_3_11(printk("qla2x00_get_retry_cnt(%ld): failed = %x.\n",
1305                     ha->host_no, mcp->mb[0]);)
1306         } else {
1307                 /* Convert returned data and check our values. */
1308                 *r_a_tov = mcp->mb[3] / 2;
1309                 ratov = (mcp->mb[3]/2) / 10;  /* mb[3] value is in 100ms */
1310                 if (mcp->mb[1] * ratov > (*retry_cnt) * (*tov)) {
1311                         /* Update to the larger values */
1312                         *retry_cnt = (uint8_t)mcp->mb[1];
1313                         *tov = ratov;
1314                 }
1315
1316                 DEBUG11(printk("qla2x00_get_retry_cnt(%ld): done. mb3=%d "
1317                     "ratov=%d.\n", ha->host_no, mcp->mb[3], ratov);)
1318         }
1319
1320         return rval;
1321 }
1322
1323 /*
1324  * qla2x00_init_firmware
1325  *      Initialize adapter firmware.
1326  *
1327  * Input:
1328  *      ha = adapter block pointer.
1329  *      dptr = Initialization control block pointer.
1330  *      size = size of initialization control block.
1331  *      TARGET_QUEUE_LOCK must be released.
1332  *      ADAPTER_STATE_LOCK must be released.
1333  *
1334  * Returns:
1335  *      qla2x00 local function return status code.
1336  *
1337  * Context:
1338  *      Kernel context.
1339  */
1340 int
1341 qla2x00_init_firmware(scsi_qla_host_t *ha, uint16_t size)
1342 {
1343         int rval;
1344         mbx_cmd_t mc;
1345         mbx_cmd_t *mcp = &mc;
1346
1347         DEBUG11(printk("qla2x00_init_firmware(%ld): entered.\n",
1348             ha->host_no);)
1349
1350         mcp->mb[0] = MBC_INITIALIZE_FIRMWARE;
1351         mcp->mb[2] = MSW(ha->init_cb_dma);
1352         mcp->mb[3] = LSW(ha->init_cb_dma);
1353         mcp->mb[4] = 0;
1354         mcp->mb[5] = 0;
1355         mcp->mb[6] = MSW(MSD(ha->init_cb_dma));
1356         mcp->mb[7] = LSW(MSD(ha->init_cb_dma));
1357         mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
1358         mcp->in_mb = MBX_5|MBX_4|MBX_0;
1359         mcp->buf_size = size;
1360         mcp->flags = MBX_DMA_OUT;
1361         mcp->tov = 30;
1362         rval = qla2x00_mailbox_command(ha, mcp);
1363
1364         if (rval != QLA_SUCCESS) {
1365                 /*EMPTY*/
1366                 DEBUG2_3_11(printk("qla2x00_init_firmware(%ld): failed=%x "
1367                     "mb0=%x.\n",
1368                     ha->host_no, rval, mcp->mb[0]);)
1369         } else {
1370                 /*EMPTY*/
1371                 DEBUG11(printk("qla2x00_init_firmware(%ld): done.\n",
1372                     ha->host_no);)
1373         }
1374
1375         return rval;
1376 }
1377
1378 /*
1379  * qla2x00_get_port_database
1380  *      Issue normal/enhanced get port database mailbox command
1381  *      and copy device name as necessary.
1382  *
1383  * Input:
1384  *      ha = adapter state pointer.
1385  *      dev = structure pointer.
1386  *      opt = enhanced cmd option byte.
1387  *
1388  * Returns:
1389  *      qla2x00 local function return status code.
1390  *
1391  * Context:
1392  *      Kernel context.
1393  */
1394 int
1395 qla2x00_get_port_database(scsi_qla_host_t *ha, fc_port_t *fcport, uint8_t opt)
1396 {
1397         int rval;
1398         mbx_cmd_t mc;
1399         mbx_cmd_t *mcp = &mc;
1400         port_database_t *pd;
1401         dma_addr_t pd_dma;
1402
1403         DEBUG11(printk("qla2x00_get_port_database(%ld): entered.\n",
1404             ha->host_no);)
1405
1406         pd = pci_alloc_consistent(ha->pdev, PORT_DATABASE_SIZE, &pd_dma);
1407         if (pd  == NULL) {
1408                 DEBUG2_3_11(printk("qla2x00_get_port_database(%ld): **** "
1409                     "Mem Alloc Failed ****", ha->host_no);)
1410                 return QLA_MEMORY_ALLOC_FAILED;
1411         }
1412         memset(pd, 0, PORT_DATABASE_SIZE);
1413
1414         if (opt != 0)
1415                 mcp->mb[0] = MBC_ENHANCED_GET_PORT_DATABASE;
1416         else
1417                 mcp->mb[0] = MBC_GET_PORT_DATABASE;
1418         mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
1419         if (HAS_EXTENDED_IDS(ha)) {
1420                 mcp->mb[1] = fcport->loop_id;
1421                 mcp->mb[10] = opt;
1422                 mcp->out_mb |= MBX_10;
1423         } else {
1424                 mcp->mb[1] = fcport->loop_id << 8 | opt;
1425         }
1426         mcp->mb[2] = MSW(pd_dma);
1427         mcp->mb[3] = LSW(pd_dma);
1428         mcp->mb[6] = MSW(MSD(pd_dma));
1429         mcp->mb[7] = LSW(MSD(pd_dma));
1430
1431         mcp->in_mb = MBX_0;
1432         mcp->buf_size = PORT_DATABASE_SIZE;
1433         mcp->flags = MBX_DMA_IN;
1434         mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
1435         rval = qla2x00_mailbox_command(ha, mcp);
1436         if (rval != QLA_SUCCESS)
1437                 goto gpd_error_out;
1438
1439         /* Check for logged in state. */
1440         if (pd->master_state != PD_STATE_PORT_LOGGED_IN &&
1441             pd->slave_state != PD_STATE_PORT_LOGGED_IN) {
1442                 rval = QLA_FUNCTION_FAILED;
1443                 goto gpd_error_out;
1444         }
1445
1446         /* Names are little-endian. */
1447         memcpy(fcport->node_name, pd->node_name, WWN_SIZE);
1448         memcpy(fcport->port_name, pd->port_name, WWN_SIZE);
1449
1450         /* Get port_id of device. */
1451         fcport->d_id.b.al_pa = pd->port_id[2];
1452         fcport->d_id.b.area = pd->port_id[3];
1453         fcport->d_id.b.domain = pd->port_id[0];
1454         fcport->d_id.b.rsvd_1 = 0;
1455
1456         /* Check for device require authentication. */
1457         pd->common_features & BIT_5 ? (fcport->flags |= FCF_AUTH_REQ) :
1458             (fcport->flags &= ~FCF_AUTH_REQ);
1459
1460         /* If not target must be initiator or unknown type. */
1461         if ((pd->prli_svc_param_word_3[0] & BIT_4) == 0)
1462                 fcport->port_type = FCT_INITIATOR;
1463         else
1464                 fcport->port_type = FCT_TARGET;
1465
1466 gpd_error_out:
1467         pci_free_consistent(ha->pdev, PORT_DATABASE_SIZE, pd, pd_dma);
1468
1469         if (rval != QLA_SUCCESS) {
1470                 /*EMPTY*/
1471                 DEBUG2_3_11(printk("qla2x00_get_port_database(%ld): "
1472                     "failed=%x.\n", ha->host_no, rval);)
1473         } else {
1474                 /*EMPTY*/
1475                 DEBUG11(printk("qla2x00_get_port_database(%ld): done.\n",
1476                     ha->host_no);)
1477         }
1478
1479         return rval;
1480 }
1481
1482 /*
1483  * qla2x00_get_firmware_state
1484  *      Get adapter firmware state.
1485  *
1486  * Input:
1487  *      ha = adapter block pointer.
1488  *      dptr = pointer for firmware state.
1489  *      TARGET_QUEUE_LOCK must be released.
1490  *      ADAPTER_STATE_LOCK must be released.
1491  *
1492  * Returns:
1493  *      qla2x00 local function return status code.
1494  *
1495  * Context:
1496  *      Kernel context.
1497  */
1498 int
1499 qla2x00_get_firmware_state(scsi_qla_host_t *ha, uint16_t *dptr)
1500 {
1501         int rval;
1502         mbx_cmd_t mc;
1503         mbx_cmd_t *mcp = &mc;
1504
1505         DEBUG11(printk("qla2x00_get_firmware_state(%ld): entered.\n",
1506             ha->host_no);)
1507
1508         mcp->mb[0] = MBC_GET_FIRMWARE_STATE;
1509         mcp->out_mb = MBX_0;
1510         mcp->in_mb = MBX_2|MBX_1|MBX_0;
1511         mcp->tov = 30;
1512         mcp->flags = 0;
1513         rval = qla2x00_mailbox_command(ha, mcp);
1514
1515         /* Return firmware state. */
1516         *dptr = mcp->mb[1];
1517
1518         if (rval != QLA_SUCCESS) {
1519                 /*EMPTY*/
1520                 DEBUG2_3_11(printk("qla2x00_get_firmware_state(%ld): "
1521                     "failed=%x.\n", ha->host_no, rval);)
1522         } else {
1523                 /*EMPTY*/
1524                 DEBUG11(printk("qla2x00_get_firmware_state(%ld): done.\n",
1525                     ha->host_no);)
1526         }
1527
1528         return rval;
1529 }
1530
1531 /*
1532  * qla2x00_get_port_name
1533  *      Issue get port name mailbox command.
1534  *      Returned name is in big endian format.
1535  *
1536  * Input:
1537  *      ha = adapter block pointer.
1538  *      loop_id = loop ID of device.
1539  *      name = pointer for name.
1540  *      TARGET_QUEUE_LOCK must be released.
1541  *      ADAPTER_STATE_LOCK must be released.
1542  *
1543  * Returns:
1544  *      qla2x00 local function return status code.
1545  *
1546  * Context:
1547  *      Kernel context.
1548  */
1549 int
1550 qla2x00_get_port_name(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t *name,
1551     uint8_t opt)
1552 {
1553         int rval;
1554         mbx_cmd_t mc;
1555         mbx_cmd_t *mcp = &mc;
1556
1557         DEBUG11(printk("qla2x00_get_port_name(%ld): entered.\n",
1558             ha->host_no);)
1559
1560         mcp->mb[0] = MBC_GET_PORT_NAME;
1561         mcp->out_mb = MBX_1|MBX_0;
1562         if (HAS_EXTENDED_IDS(ha)) {
1563                 mcp->mb[1] = loop_id;
1564                 mcp->mb[10] = opt;
1565                 mcp->out_mb |= MBX_10;
1566         } else {
1567                 mcp->mb[1] = loop_id << 8 | opt;
1568         }
1569
1570         mcp->in_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
1571         mcp->tov = 30;
1572         mcp->flags = 0;
1573         rval = qla2x00_mailbox_command(ha, mcp);
1574
1575         if (rval != QLA_SUCCESS) {
1576                 /*EMPTY*/
1577                 DEBUG2_3_11(printk("qla2x00_get_port_name(%ld): failed=%x.\n",
1578                     ha->host_no, rval);)
1579         } else {
1580                 if (name != NULL) {
1581                         /* This function returns name in big endian. */
1582                         name[0] = LSB(mcp->mb[2]);
1583                         name[1] = MSB(mcp->mb[2]);
1584                         name[2] = LSB(mcp->mb[3]);
1585                         name[3] = MSB(mcp->mb[3]);
1586                         name[4] = LSB(mcp->mb[6]);
1587                         name[5] = MSB(mcp->mb[6]);
1588                         name[6] = LSB(mcp->mb[7]);
1589                         name[7] = MSB(mcp->mb[7]);
1590                 }
1591
1592                 DEBUG11(printk("qla2x00_get_port_name(%ld): done.\n",
1593                     ha->host_no);)
1594         }
1595
1596         return rval;
1597 }
1598
1599 /*
1600  * qla2x00_get_link_status
1601  *
1602  * Input:
1603  *      ha = adapter block pointer.
1604  *      loop_id = device loop ID.
1605  *      ret_buf = pointer to link status return buffer.
1606  *
1607  * Returns:
1608  *      0 = success.
1609  *      BIT_0 = mem alloc error.
1610  *      BIT_1 = mailbox error.
1611  */
1612 uint8_t
1613 qla2x00_get_link_status(scsi_qla_host_t *ha, uint16_t loop_id,
1614     link_stat_t *ret_buf, uint16_t *status)
1615 {
1616         int rval;
1617         mbx_cmd_t mc;
1618         mbx_cmd_t *mcp = &mc;
1619         link_stat_t *stat_buf;
1620         dma_addr_t phys_address = 0;
1621
1622
1623         DEBUG11(printk("qla2x00_get_link_status(%ld): entered.\n",
1624             ha->host_no);)
1625
1626         stat_buf = pci_alloc_consistent(ha->pdev, sizeof(link_stat_t),
1627             &phys_address);
1628         if (stat_buf == NULL) {
1629                 DEBUG2_3_11(printk("qla2x00_get_link_status(%ld): Failed to "
1630                     "allocate memory.\n", ha->host_no));
1631                 return BIT_0;
1632         }
1633         memset(stat_buf, 0, sizeof(link_stat_t));
1634
1635         mcp->mb[0] = MBC_GET_LINK_STATUS;
1636         mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
1637         if (HAS_EXTENDED_IDS(ha)) {
1638                 mcp->mb[1] = loop_id;
1639                 mcp->mb[10] = 0;
1640                 mcp->out_mb |= MBX_10;
1641         } else {
1642                 mcp->mb[1] = loop_id << 8;
1643         }
1644         mcp->mb[2] = MSW(phys_address);
1645         mcp->mb[3] = LSW(phys_address);
1646         mcp->mb[6] = MSW(MSD(phys_address));
1647         mcp->mb[7] = LSW(MSD(phys_address));
1648
1649         mcp->in_mb = MBX_0;
1650         mcp->tov = 30;
1651         mcp->flags = IOCTL_CMD;
1652         rval = qla2x00_mailbox_command(ha, mcp);
1653
1654         if (rval == QLA_SUCCESS) {
1655                 if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {
1656                         DEBUG2_3_11(printk("qla2x00_get_link_status(%ld): cmd "
1657                             "failed. mbx0=%x.\n", ha->host_no, mcp->mb[0]);)
1658                         status[0] = mcp->mb[0];
1659                         rval = BIT_1;
1660                 } else {
1661                         /* copy over data -- firmware data is LE. */
1662                         ret_buf->link_fail_cnt =
1663                             le32_to_cpu(stat_buf->link_fail_cnt);
1664                         ret_buf->loss_sync_cnt =
1665                             le32_to_cpu(stat_buf->loss_sync_cnt);
1666                         ret_buf->loss_sig_cnt =
1667                             le32_to_cpu(stat_buf->loss_sig_cnt);
1668                         ret_buf->prim_seq_err_cnt =
1669                             le32_to_cpu(stat_buf->prim_seq_err_cnt);
1670                         ret_buf->inval_xmit_word_cnt =
1671                             le32_to_cpu(stat_buf->inval_xmit_word_cnt);
1672                         ret_buf->inval_crc_cnt =
1673                             le32_to_cpu(stat_buf->inval_crc_cnt);
1674
1675                         DEBUG11(printk("qla2x00_get_link_status(%ld): stat "
1676                             "dump: fail_cnt=%d loss_sync=%d loss_sig=%d "
1677                             "seq_err=%d inval_xmt_word=%d inval_crc=%d.\n",
1678                             ha->host_no,
1679                             stat_buf->link_fail_cnt, stat_buf->loss_sync_cnt,
1680                             stat_buf->loss_sig_cnt, stat_buf->prim_seq_err_cnt,
1681                             stat_buf->inval_xmit_word_cnt,
1682                             stat_buf->inval_crc_cnt);)
1683                 }
1684         } else {
1685                 /* Failed. */
1686                 DEBUG2_3_11(printk("qla2x00_get_link_status(%ld): failed=%x.\n",
1687                     ha->host_no, rval);)
1688                 rval = BIT_1;
1689         }
1690
1691         pci_free_consistent(ha->pdev, sizeof(link_stat_t), stat_buf,
1692             phys_address);
1693
1694         return rval;
1695 }
1696
1697 /*
1698  * qla2x00_lip_reset
1699  *      Issue LIP reset mailbox command.
1700  *
1701  * Input:
1702  *      ha = adapter block pointer.
1703  *      TARGET_QUEUE_LOCK must be released.
1704  *      ADAPTER_STATE_LOCK must be released.
1705  *
1706  * Returns:
1707  *      qla2x00 local function return status code.
1708  *
1709  * Context:
1710  *      Kernel context.
1711  */
1712 int
1713 qla2x00_lip_reset(scsi_qla_host_t *ha)
1714 {
1715         int rval;
1716         mbx_cmd_t mc;
1717         mbx_cmd_t *mcp = &mc;
1718
1719         DEBUG11(printk("qla2x00_lip_reset(%ld): entered.\n",
1720             ha->host_no);)
1721
1722         mcp->mb[0] = MBC_LIP_RESET;
1723         mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
1724         if (HAS_EXTENDED_IDS(ha)) {
1725                 mcp->mb[1] = 0x00ff;
1726                 mcp->mb[10] = 0;
1727                 mcp->out_mb |= MBX_10;
1728         } else {
1729                 mcp->mb[1] = 0xff00;
1730         }
1731         mcp->mb[2] = ha->loop_reset_delay;
1732         mcp->mb[3] = 0;
1733
1734         mcp->in_mb = MBX_0;
1735         mcp->tov = 30;
1736         mcp->flags = 0;
1737         rval = qla2x00_mailbox_command(ha, mcp);
1738
1739         if (rval != QLA_SUCCESS) {
1740                 /*EMPTY*/
1741                 DEBUG2_3_11(printk("qla2x00_lip_reset(%ld): failed=%x.\n",
1742                     ha->host_no, rval);)
1743         } else {
1744                 /*EMPTY*/
1745                 DEBUG11(printk("qla2x00_lip_reset(%ld): done.\n", ha->host_no);)
1746         }
1747
1748         return rval;
1749 }
1750
1751 /*
1752  * qla2x00_send_sns
1753  *      Send SNS command.
1754  *
1755  * Input:
1756  *      ha = adapter block pointer.
1757  *      sns = pointer for command.
1758  *      cmd_size = command size.
1759  *      buf_size = response/command size.
1760  *      TARGET_QUEUE_LOCK must be released.
1761  *      ADAPTER_STATE_LOCK must be released.
1762  *
1763  * Returns:
1764  *      qla2x00 local function return status code.
1765  *
1766  * Context:
1767  *      Kernel context.
1768  */
1769 int
1770 qla2x00_send_sns(scsi_qla_host_t *ha, dma_addr_t sns_phys_address,
1771     uint16_t cmd_size, size_t buf_size)
1772 {
1773         int rval;
1774         mbx_cmd_t mc;
1775         mbx_cmd_t *mcp = &mc;
1776
1777         DEBUG11(printk("qla2x00_send_sns(%ld): entered.\n",
1778             ha->host_no);)
1779
1780         DEBUG11(printk("qla2x00_send_sns: retry cnt=%d ratov=%d total "
1781             "tov=%d.\n", ha->retry_count, ha->login_timeout, mcp->tov);)
1782
1783         mcp->mb[0] = MBC_SEND_SNS_COMMAND;
1784         mcp->mb[1] = cmd_size;
1785         mcp->mb[2] = MSW(sns_phys_address);
1786         mcp->mb[3] = LSW(sns_phys_address);
1787         mcp->mb[6] = MSW(MSD(sns_phys_address));
1788         mcp->mb[7] = LSW(MSD(sns_phys_address));
1789         mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
1790         mcp->in_mb = MBX_0|MBX_1;
1791         mcp->buf_size = buf_size;
1792         mcp->flags = MBX_DMA_OUT|MBX_DMA_IN;
1793         mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
1794         rval = qla2x00_mailbox_command(ha, mcp);
1795
1796         if (rval != QLA_SUCCESS) {
1797                 /*EMPTY*/
1798                 DEBUG(printk("qla2x00_send_sns(%ld): failed=%x mb[0]=%x "
1799                     "mb[1]=%x.\n", ha->host_no, rval, mcp->mb[0], mcp->mb[1]);)
1800                 DEBUG2_3_11(printk("qla2x00_send_sns(%ld): failed=%x mb[0]=%x "
1801                     "mb[1]=%x.\n", ha->host_no, rval, mcp->mb[0], mcp->mb[1]);)
1802         } else {
1803                 /*EMPTY*/
1804                 DEBUG11(printk("qla2x00_send_sns(%ld): done.\n", ha->host_no);)
1805         }
1806
1807         return rval;
1808 }
1809
1810 /*
1811  * qla2x00_login_fabric
1812  *      Issue login fabric port mailbox command.
1813  *
1814  * Input:
1815  *      ha = adapter block pointer.
1816  *      loop_id = device loop ID.
1817  *      domain = device domain.
1818  *      area = device area.
1819  *      al_pa = device AL_PA.
1820  *      status = pointer for return status.
1821  *      opt = command options.
1822  *      TARGET_QUEUE_LOCK must be released.
1823  *      ADAPTER_STATE_LOCK must be released.
1824  *
1825  * Returns:
1826  *      qla2x00 local function return status code.
1827  *
1828  * Context:
1829  *      Kernel context.
1830  */
1831 int
1832 qla2x00_login_fabric(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain,
1833     uint8_t area, uint8_t al_pa, uint16_t *mb, uint8_t opt)
1834 {
1835         int rval;
1836         mbx_cmd_t mc;
1837         mbx_cmd_t *mcp = &mc;
1838
1839         DEBUG11(printk("qla2x00_login_fabric(%ld): entered.\n", ha->host_no);)
1840
1841         mcp->mb[0] = MBC_LOGIN_FABRIC_PORT;
1842         mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
1843         if (HAS_EXTENDED_IDS(ha)) {
1844                 mcp->mb[1] = loop_id;
1845                 mcp->mb[10] = opt;
1846                 mcp->out_mb |= MBX_10;
1847         } else {
1848                 mcp->mb[1] = (loop_id << 8) | opt;
1849         }
1850         mcp->mb[2] = domain;
1851         mcp->mb[3] = area << 8 | al_pa;
1852
1853         mcp->in_mb = MBX_7|MBX_6|MBX_2|MBX_1|MBX_0;
1854         mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
1855         mcp->flags = 0;
1856         rval = qla2x00_mailbox_command(ha, mcp);
1857
1858         /* Return mailbox statuses. */
1859         if (mb != NULL) {
1860                 mb[0] = mcp->mb[0];
1861                 mb[1] = mcp->mb[1];
1862                 mb[2] = mcp->mb[2];
1863                 mb[6] = mcp->mb[6];
1864                 mb[7] = mcp->mb[7];
1865         }
1866
1867         if (rval != QLA_SUCCESS) {
1868                 /* RLU tmp code: need to change main mailbox_command function to
1869                  * return ok even when the mailbox completion value is not
1870                  * SUCCESS. The caller needs to be responsible to interpret
1871                  * the return values of this mailbox command if we're not
1872                  * to change too much of the existing code.
1873                  */
1874                 if (mcp->mb[0] == 0x4001 || mcp->mb[0] == 0x4002 ||
1875                     mcp->mb[0] == 0x4003 || mcp->mb[0] == 0x4005 ||
1876                     mcp->mb[0] == 0x4006)
1877                         rval = QLA_SUCCESS;
1878
1879                 /*EMPTY*/
1880                 DEBUG2_3_11(printk("qla2x00_login_fabric(%ld): failed=%x "
1881                     "mb[0]=%x mb[1]=%x mb[2]=%x.\n", ha->host_no, rval,
1882                     mcp->mb[0], mcp->mb[1], mcp->mb[2]);)
1883         } else {
1884                 /*EMPTY*/
1885                 DEBUG11(printk("qla2x00_login_fabric(%ld): done.\n",
1886                     ha->host_no);)
1887         }
1888
1889         return rval;
1890 }
1891
1892 /*
1893  * qla2x00_login_local_device
1894  *           Issue login loop port mailbox command.
1895  *    
1896  * Input:
1897  *           ha = adapter block pointer.
1898  *           loop_id = device loop ID.
1899  *           opt = command options.
1900  *          
1901  * Returns:
1902  *            Return status code.
1903  *             
1904  * Context:
1905  *            Kernel context.
1906  *             
1907  */
1908 int
1909 qla2x00_login_local_device(scsi_qla_host_t *ha, uint16_t loop_id,
1910     uint16_t *mb_ret, uint8_t opt)
1911 {
1912         int rval;
1913         mbx_cmd_t mc;
1914         mbx_cmd_t *mcp = &mc;
1915
1916         DEBUG3(printk("%s(%ld): entered.\n", __func__, ha->host_no);)
1917
1918         mcp->mb[0] = MBC_LOGIN_LOOP_PORT;
1919         if (HAS_EXTENDED_IDS(ha))
1920                 mcp->mb[1] = loop_id;
1921         else
1922                 mcp->mb[1] = loop_id << 8;
1923         mcp->mb[2] = opt;
1924         mcp->out_mb = MBX_2|MBX_1|MBX_0;
1925         mcp->in_mb = MBX_7|MBX_6|MBX_1|MBX_0;
1926         mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
1927         mcp->flags = 0;
1928         rval = qla2x00_mailbox_command(ha, mcp);
1929
1930         /* Return mailbox statuses. */
1931         if (mb_ret != NULL) {
1932                 mb_ret[0] = mcp->mb[0];
1933                 mb_ret[1] = mcp->mb[1];
1934                 mb_ret[6] = mcp->mb[6];
1935                 mb_ret[7] = mcp->mb[7];
1936         }
1937
1938         if (rval != QLA_SUCCESS) {
1939                 /* AV tmp code: need to change main mailbox_command function to
1940                  * return ok even when the mailbox completion value is not
1941                  * SUCCESS. The caller needs to be responsible to interpret
1942                  * the return values of this mailbox command if we're not
1943                  * to change too much of the existing code.
1944                  */
1945                 if (mcp->mb[0] == 0x4005 || mcp->mb[0] == 0x4006)
1946                         rval = QLA_SUCCESS;
1947
1948                 DEBUG(printk("%s(%ld): failed=%x mb[0]=%x mb[1]=%x "
1949                     "mb[6]=%x mb[7]=%x.\n", __func__, ha->host_no, rval,
1950                     mcp->mb[0], mcp->mb[1], mcp->mb[6], mcp->mb[7]);)
1951                 DEBUG2_3(printk("%s(%ld): failed=%x mb[0]=%x mb[1]=%x "
1952                     "mb[6]=%x mb[7]=%x.\n", __func__, ha->host_no, rval,
1953                     mcp->mb[0], mcp->mb[1], mcp->mb[6], mcp->mb[7]);)
1954         } else {
1955                 /*EMPTY*/
1956                 DEBUG3(printk("%s(%ld): done.\n", __func__, ha->host_no);)
1957         }
1958
1959         return (rval);
1960 }
1961
1962 /*
1963  * qla2x00_fabric_logout
1964  *      Issue logout fabric port mailbox command.
1965  *
1966  * Input:
1967  *      ha = adapter block pointer.
1968  *      loop_id = device loop ID.
1969  *      TARGET_QUEUE_LOCK must be released.
1970  *      ADAPTER_STATE_LOCK must be released.
1971  *
1972  * Returns:
1973  *      qla2x00 local function return status code.
1974  *
1975  * Context:
1976  *      Kernel context.
1977  */
1978 int
1979 qla2x00_fabric_logout(scsi_qla_host_t *ha, uint16_t loop_id)
1980 {
1981         int rval;
1982         mbx_cmd_t mc;
1983         mbx_cmd_t *mcp = &mc;
1984
1985         DEBUG11(printk("qla2x00_fabric_logout(%ld): entered.\n",
1986             ha->host_no);)
1987
1988         mcp->mb[0] = MBC_LOGOUT_FABRIC_PORT;
1989         mcp->out_mb = MBX_1|MBX_0;
1990         if (HAS_EXTENDED_IDS(ha)) {
1991                 mcp->mb[1] = loop_id;
1992                 mcp->mb[10] = 0;
1993                 mcp->out_mb |= MBX_10;
1994         } else {
1995                 mcp->mb[1] = loop_id << 8;
1996         }
1997
1998         mcp->in_mb = MBX_1|MBX_0;
1999         mcp->tov = 30;
2000         mcp->flags = 0;
2001         rval = qla2x00_mailbox_command(ha, mcp);
2002
2003         if (rval != QLA_SUCCESS) {
2004                 /*EMPTY*/
2005                 DEBUG2_3_11(printk("qla2x00_fabric_logout(%ld): failed=%x "
2006                     "mbx1=%x.\n", ha->host_no, rval, mcp->mb[1]);)
2007         } else {
2008                 /*EMPTY*/
2009                 DEBUG11(printk("qla2x00_fabric_logout(%ld): done.\n",
2010                     ha->host_no);)
2011         }
2012
2013         return rval;
2014 }
2015
2016 /*
2017  * qla2x00_full_login_lip
2018  *      Issue full login LIP mailbox command.
2019  *
2020  * Input:
2021  *      ha = adapter block pointer.
2022  *      TARGET_QUEUE_LOCK must be released.
2023  *      ADAPTER_STATE_LOCK must be released.
2024  *
2025  * Returns:
2026  *      qla2x00 local function return status code.
2027  *
2028  * Context:
2029  *      Kernel context.
2030  */
2031 int
2032 qla2x00_full_login_lip(scsi_qla_host_t *ha)
2033 {
2034         int rval;
2035         mbx_cmd_t mc;
2036         mbx_cmd_t *mcp = &mc;
2037
2038         DEBUG11(printk("qla2x00_full_login_lip(%ld): entered.\n",
2039             ha->host_no);)
2040
2041         mcp->mb[0] = MBC_LIP_FULL_LOGIN;
2042         mcp->mb[1] = 0;
2043         mcp->mb[2] = 0;
2044         mcp->mb[3] = 0;
2045         mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2046         mcp->in_mb = MBX_0;
2047         mcp->tov = 30;
2048         mcp->flags = 0;
2049         rval = qla2x00_mailbox_command(ha, mcp);
2050
2051         if (rval != QLA_SUCCESS) {
2052                 /*EMPTY*/
2053                 DEBUG2_3_11(printk("qla2x00_full_login_lip(%ld): failed=%x.\n",
2054                     ha->instance, rval);)
2055         } else {
2056                 /*EMPTY*/
2057                 DEBUG11(printk("qla2x00_full_login_lip(%ld): done.\n",
2058                     ha->host_no);)
2059         }
2060
2061         return rval;
2062 }
2063
2064 /*
2065  * qla2x00_get_id_list
2066  *
2067  * Input:
2068  *      ha = adapter block pointer.
2069  *
2070  * Returns:
2071  *      qla2x00 local function return status code.
2072  *
2073  * Context:
2074  *      Kernel context.
2075  */
2076 int
2077 qla2x00_get_id_list(scsi_qla_host_t *ha, void *id_list, dma_addr_t id_list_dma,
2078     uint16_t *entries)
2079 {
2080         int rval;
2081         mbx_cmd_t mc;
2082         mbx_cmd_t *mcp = &mc;
2083
2084         DEBUG11(printk("qla2x00_get_id_list(%ld): entered.\n",
2085             ha->host_no);)
2086
2087         if (id_list == NULL)
2088                 return QLA_FUNCTION_FAILED;
2089
2090         mcp->mb[0] = MBC_GET_ID_LIST;
2091         mcp->mb[1] = MSW(id_list_dma);
2092         mcp->mb[2] = LSW(id_list_dma);
2093         mcp->mb[3] = MSW(MSD(id_list_dma));
2094         mcp->mb[6] = LSW(MSD(id_list_dma));
2095         mcp->out_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2096         mcp->in_mb = MBX_1|MBX_0;
2097         mcp->tov = 30;
2098         mcp->flags = 0;
2099         rval = qla2x00_mailbox_command(ha, mcp);
2100
2101         if (rval != QLA_SUCCESS) {
2102                 /*EMPTY*/
2103                 DEBUG2_3_11(printk("qla2x00_get_id_list(%ld): failed=%x.\n",
2104                     ha->host_no, rval);)
2105         } else {
2106                 *entries = mcp->mb[1];
2107                 DEBUG11(printk("qla2x00_get_id_list(%ld): done.\n",
2108                     ha->host_no);)
2109         }
2110
2111         return rval;
2112 }
2113
2114 /*
2115  * qla2x00_lun_reset
2116  *      Issue lun reset mailbox command.
2117  *
2118  * Input:
2119  *      ha = adapter block pointer.
2120  *      loop_id = device loop ID.
2121  *      lun = lun to be reset.
2122  *      TARGET_QUEUE_LOCK must be released.
2123  *      ADAPTER_STATE_LOCK must be released.
2124  *
2125  * Returns:
2126  *      qla2x00 local function return status code.
2127  *
2128  * Context:
2129  *      Kernel context.
2130  */
2131 int
2132 qla2x00_lun_reset(scsi_qla_host_t *ha, uint16_t loop_id, uint16_t lun)
2133 {
2134         int             rval;
2135         mbx_cmd_t       mc;
2136         mbx_cmd_t       *mcp = &mc;
2137
2138         mcp->mb[0] = MBC_LUN_RESET;
2139         if (HAS_EXTENDED_IDS(ha))
2140                 mcp->mb[1] = loop_id;
2141         else
2142                 mcp->mb[1] = loop_id << 8;
2143         mcp->mb[2] = lun;
2144         mcp->out_mb = MBX_2|MBX_1|MBX_0;
2145         mcp->in_mb = MBX_0;
2146         mcp->tov = 30;
2147         mcp->flags = 0;
2148         rval = qla2x00_mailbox_command(ha, mcp);
2149
2150         if (rval != QLA_SUCCESS) {
2151                 /*EMPTY*/
2152                 printk(KERN_WARNING "qla2x00_lun_reset(%d): failed = %d",
2153                     (int)ha->instance, rval);
2154         } else {
2155                 /*EMPTY*/
2156         }
2157
2158         return rval;
2159 }
2160
2161 /*
2162  * qla2x00_send_rnid_mbx
2163  *      Issue RNID ELS using mailbox command
2164  *
2165  * Input:
2166  *      ha = adapter state pointer.
2167  *      loop_id = loop ID of the target device.
2168  *      data_fmt = currently supports only 0xDF.
2169  *      buffer = buffer pointer.
2170  *      buf_size = size of buffer.
2171  *      mb_reg = pointer to return mailbox registers.
2172  *
2173  * Returns:
2174  *      qla2x00 local function return status code.
2175  *
2176  * Context:
2177  *      Kernel context.
2178  */
2179 int
2180 qla2x00_send_rnid_mbx(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t data_fmt,
2181     dma_addr_t buf_phys_addr, size_t buf_size, uint16_t *mb_reg)
2182 {
2183         int             rval;
2184         mbx_cmd_t       mc;
2185         mbx_cmd_t       *mcp = &mc;
2186
2187         DEBUG11(printk("qla2x00_send_rnid_mbx(%ld): entered.\n",
2188             ha->host_no);)
2189
2190         mcp->mb[0] = MBC_SEND_RNID_ELS;
2191         mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2192         if (HAS_EXTENDED_IDS(ha)) {
2193                 mcp->mb[1] = loop_id;
2194                 mcp->mb[10] = data_fmt;
2195                 mcp->out_mb |= MBX_10;
2196         } else {
2197                 mcp->mb[1] = (loop_id << 8) | data_fmt;
2198         }
2199         mcp->mb[2] = MSW(buf_phys_addr);
2200         mcp->mb[3] = LSW(buf_phys_addr);
2201         mcp->mb[6] = MSW(MSD(buf_phys_addr));
2202         mcp->mb[7] = LSW(MSD(buf_phys_addr));
2203
2204         mcp->in_mb = MBX_1|MBX_0;
2205         mcp->buf_size = buf_size;
2206         mcp->flags = MBX_DMA_IN;
2207         mcp->tov = 30;
2208         rval = qla2x00_mailbox_command(ha, mcp);
2209
2210         if (rval != QLA_SUCCESS) {
2211                 memcpy(mb_reg, mcp->mb, 2 * 2); /* 2 status regs */
2212
2213                 DEBUG2_3_11(printk("qla2x00_send_rnid_mbx(%ld): failed=%x "
2214                     "mb[1]=%x.\n",
2215                     ha->host_no, mcp->mb[0], mcp->mb[1]);)
2216         } else {
2217                 /*EMPTY*/
2218                 DEBUG11(printk("qla2x00_send_rnid_mbx(%ld): done.\n",
2219                      ha->host_no);)
2220         }
2221
2222         return (rval);
2223 }
2224
2225 /*
2226  * qla2x00_set_rnid_params_mbx
2227  *      Set RNID parameters using mailbox command
2228  *
2229  * Input:
2230  *      ha = adapter state pointer.
2231  *      buffer = buffer pointer.
2232  *      buf_size = size of buffer.
2233  *      mb_reg = pointer to return mailbox registers.
2234  *
2235  * Returns:
2236  *      qla2x00 local function return status code.
2237  *
2238  * Context:
2239  *      Kernel context.
2240  */
2241 int
2242 qla2x00_set_rnid_params_mbx(scsi_qla_host_t *ha, dma_addr_t buf_phys_addr,
2243     size_t buf_size, uint16_t *mb_reg)
2244 {
2245         int             rval;
2246         mbx_cmd_t       mc;
2247         mbx_cmd_t       *mcp = &mc;
2248
2249         DEBUG11(printk("qla2x00_set_rnid_params_mbx(%ld): entered.\n",
2250             ha->host_no);)
2251
2252         mcp->mb[0] = MBC_SET_RNID_PARAMS;
2253         mcp->mb[1] = 0;
2254         mcp->mb[2] = MSW(buf_phys_addr);
2255         mcp->mb[3] = LSW(buf_phys_addr);
2256         mcp->mb[6] = MSW(MSD(buf_phys_addr));
2257         mcp->mb[7] = LSW(MSD(buf_phys_addr));
2258         mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2259         mcp->in_mb = MBX_1|MBX_0;
2260         mcp->buf_size = buf_size;
2261         mcp->flags = MBX_DMA_OUT;
2262         mcp->tov = 30;
2263         rval = qla2x00_mailbox_command(ha, mcp);
2264
2265         if (rval != QLA_SUCCESS) {
2266                 memcpy(mb_reg, mcp->mb, 2 * 2); /* 2 status regs */
2267
2268                 DEBUG2_3_11(printk("qla2x00_set_rnid_params_mbx(%ld): "
2269                     "failed=%x mb[1]=%x.\n", ha->host_no, mcp->mb[0],
2270                     mcp->mb[1]);)
2271         } else {
2272                 /*EMPTY*/
2273                 DEBUG11(printk("qla2x00_set_rnid_params_mbx(%ld): done.\n",
2274                     ha->host_no);)
2275         }
2276
2277         return (rval);
2278 }
2279
2280 /*
2281  * qla2x00_get_rnid_params_mbx
2282  *      Get RNID parameters using mailbox command
2283  *
2284  * Input:
2285  *      ha = adapter state pointer.
2286  *      buffer = buffer pointer.
2287  *      buf_size = size of buffer.
2288  *      mb_reg = pointer to return mailbox registers.
2289  *
2290  * Returns:
2291  *      qla2x00 local function return status code.
2292  *
2293  * Context:
2294  *      Kernel context.
2295  */
2296 int
2297 qla2x00_get_rnid_params_mbx(scsi_qla_host_t *ha, dma_addr_t buf_phys_addr,
2298     size_t buf_size, uint16_t *mb_reg)
2299 {
2300         int             rval;
2301         mbx_cmd_t       mc;
2302         mbx_cmd_t       *mcp = &mc;
2303
2304         DEBUG11(printk("qla2x00_get_rnid_params_mbx(%ld): entered.\n",
2305             ha->host_no);)
2306
2307         mcp->mb[0] = MBC_GET_RNID_PARAMS;
2308         mcp->mb[1] = 0;
2309         mcp->mb[2] = MSW(buf_phys_addr);
2310         mcp->mb[3] = LSW(buf_phys_addr);
2311         mcp->mb[6] = MSW(MSD(buf_phys_addr));
2312         mcp->mb[7] = LSW(MSD(buf_phys_addr));
2313         mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2314         mcp->in_mb = MBX_1|MBX_0;
2315         mcp->buf_size = buf_size;
2316         mcp->flags = MBX_DMA_IN;
2317         mcp->tov = 30;
2318         rval = qla2x00_mailbox_command(ha, mcp);
2319
2320         if (rval != QLA_SUCCESS) {
2321                 memcpy(mb_reg, mcp->mb, 2 * 2); /* 2 status regs */
2322
2323                 DEBUG2_3_11(printk("qla2x00_get_rnid_params_mbx(%ld): "
2324                     "failed=%x mb[1]=%x.\n", ha->host_no, mcp->mb[0],
2325                     mcp->mb[1]);)
2326         } else {
2327                 /*EMPTY*/
2328                 DEBUG11(printk("qla2x00_get_rnid_params_mbx(%ld): done.\n",
2329                     ha->host_no);)
2330         }
2331
2332         return (rval);
2333 }
2334
2335 /*
2336  * qla2x00_get_resource_cnts
2337  *      Get current firmware resource counts.
2338  *
2339  * Input:
2340  *      ha = adapter block pointer.
2341  *
2342  * Returns:
2343  *      qla2x00 local function return status code.
2344  *
2345  * Context:
2346  *      Kernel context.
2347  */
2348 int
2349 qla2x00_get_resource_cnts(scsi_qla_host_t *ha, uint16_t *cur_xchg_cnt,
2350     uint16_t *orig_xchg_cnt, uint16_t *cur_iocb_cnt, uint16_t *orig_iocb_cnt)
2351 {
2352         int rval;
2353         mbx_cmd_t mc;
2354         mbx_cmd_t *mcp = &mc;
2355
2356         DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no));
2357
2358         mcp->mb[0] = MBC_GET_RESOURCE_COUNTS;
2359         mcp->out_mb = MBX_0;
2360         mcp->in_mb = MBX_10|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2361         mcp->tov = 30;
2362         mcp->flags = 0;
2363         rval = qla2x00_mailbox_command(ha, mcp);
2364
2365         if (rval != QLA_SUCCESS) {
2366                 /*EMPTY*/
2367                 DEBUG2_3_11(printk("%s(%ld): failed = %x.\n", __func__,
2368                     ha->host_no, mcp->mb[0]);)
2369         } else {
2370                 DEBUG11(printk("%s(%ld): done. mb1=%x mb2=%x mb3=%x mb6=%x "
2371                     "mb7=%x mb10=%x.\n", __func__, ha->host_no,
2372                     mcp->mb[1], mcp->mb[2], mcp->mb[3], mcp->mb[6], mcp->mb[7], 
2373                     mcp->mb[10]));
2374
2375                 if (cur_xchg_cnt)
2376                         *cur_xchg_cnt = mcp->mb[3];
2377                 if (orig_xchg_cnt)
2378                         *orig_xchg_cnt = mcp->mb[6];
2379                 if (cur_iocb_cnt)
2380                         *cur_iocb_cnt = mcp->mb[7];
2381                 if (orig_iocb_cnt)
2382                         *orig_iocb_cnt = mcp->mb[10];
2383         }
2384
2385         return (rval);
2386 }
2387
2388 #if defined(QL_DEBUG_LEVEL_3)
2389 /*
2390  * qla2x00_get_fcal_position_map
2391  *      Get FCAL (LILP) position map using mailbox command
2392  *
2393  * Input:
2394  *      ha = adapter state pointer.
2395  *      pos_map = buffer pointer (can be NULL).
2396  *
2397  * Returns:
2398  *      qla2x00 local function return status code.
2399  *
2400  * Context:
2401  *      Kernel context.
2402  */
2403 int
2404 qla2x00_get_fcal_position_map(scsi_qla_host_t *ha, char *pos_map)
2405 {
2406         int rval;
2407         mbx_cmd_t mc;
2408         mbx_cmd_t *mcp = &mc;
2409         char *pmap;
2410         dma_addr_t pmap_dma;
2411
2412         pmap = pci_alloc_consistent(ha->pdev, FCAL_MAP_SIZE, &pmap_dma);
2413         if (pmap  == NULL) {
2414                 DEBUG2_3_11(printk("%s(%ld): **** Mem Alloc Failed ****",
2415                     __func__, ha->host_no));
2416                 return QLA_MEMORY_ALLOC_FAILED;
2417         }
2418         memset(pmap, 0, FCAL_MAP_SIZE);
2419
2420         mcp->mb[0] = MBC_GET_FC_AL_POSITION_MAP;
2421         mcp->mb[2] = MSW(pmap_dma);
2422         mcp->mb[3] = LSW(pmap_dma);
2423         mcp->mb[6] = MSW(MSD(pmap_dma));
2424         mcp->mb[7] = LSW(MSD(pmap_dma));
2425         mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
2426         mcp->in_mb = MBX_1|MBX_0;
2427         mcp->buf_size = FCAL_MAP_SIZE;
2428         mcp->flags = MBX_DMA_IN;
2429         mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
2430         rval = qla2x00_mailbox_command(ha, mcp);
2431
2432         if (rval == QLA_SUCCESS) {
2433                 DEBUG11(printk("%s(%ld): (mb0=%x/mb1=%x) FC/AL Position Map "
2434                     "size (%x)\n", __func__, ha->host_no, mcp->mb[0],
2435                     mcp->mb[1], (unsigned)pmap[0]));
2436                 DEBUG11(qla2x00_dump_buffer(pmap, pmap[0] + 1));
2437
2438                 if (pos_map)
2439                         memcpy(pos_map, pmap, FCAL_MAP_SIZE);
2440         }
2441         pci_free_consistent(ha->pdev, FCAL_MAP_SIZE, pmap, pmap_dma);
2442
2443         if (rval != QLA_SUCCESS) {
2444                 DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__,
2445                     ha->host_no, rval));
2446         } else {
2447                 DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no));
2448         }
2449
2450         return rval;
2451 }
2452 #endif