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