blob: 951537e3029406eeabcb669d7ee4b75da7299ee9 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
Andrew Vasquezfa90c542005-10-27 11:10:08 -07002 * QLogic Fibre Channel HBA Driver
Andrew Vasquez01e58d82008-04-03 13:13:13 -07003 * Copyright (c) 2003-2008 QLogic Corporation
Linus Torvalds1da177e2005-04-16 15:20:36 -07004 *
Andrew Vasquezfa90c542005-10-27 11:10:08 -07005 * See LICENSE.qla2xxx for copyright and licensing details.
Linus Torvalds1da177e2005-04-16 15:20:36 -07006 */
7#include "qla_def.h"
8
9#include <linux/delay.h>
10
Linus Torvalds1da177e2005-04-16 15:20:36 -070011
12/*
13 * qla2x00_mailbox_command
14 * Issue mailbox command and waits for completion.
15 *
16 * Input:
17 * ha = adapter block pointer.
18 * mcp = driver internal mbx struct pointer.
19 *
20 * Output:
21 * mb[MAX_MAILBOX_REGISTER_COUNT] = returned mailbox data.
22 *
23 * Returns:
24 * 0 : QLA_SUCCESS = cmd performed success
25 * 1 : QLA_FUNCTION_FAILED (error encountered)
26 * 6 : QLA_FUNCTION_TIMEOUT (timeout condition encountered)
27 *
28 * Context:
29 * Kernel context.
30 */
31static int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -080032qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
Linus Torvalds1da177e2005-04-16 15:20:36 -070033{
34 int rval;
35 unsigned long flags = 0;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -070036 device_reg_t __iomem *reg;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -070037 uint8_t abort_active;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -070038 uint8_t io_lock_on;
Linus Torvalds1da177e2005-04-16 15:20:36 -070039 uint16_t command;
40 uint16_t *iptr;
41 uint16_t __iomem *optr;
42 uint32_t cnt;
43 uint32_t mboxes;
Linus Torvalds1da177e2005-04-16 15:20:36 -070044 unsigned long wait_time;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -080045 struct qla_hw_data *ha = vha->hw;
46 scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -070047
48 reg = ha->iobase;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -080049 io_lock_on = base_vha->flags.init_done;
Linus Torvalds1da177e2005-04-16 15:20:36 -070050
51 rval = QLA_SUCCESS;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -080052 abort_active = test_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -070053
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -080054 DEBUG11(printk("%s(%ld): entered.\n", __func__, base_vha->host_no));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -070055
Linus Torvalds1da177e2005-04-16 15:20:36 -070056 /*
Andrew Vasquez1c7c6352005-07-06 10:30:57 -070057 * Wait for active mailbox commands to finish by waiting at most tov
58 * seconds. This is to serialize actual issuing of mailbox cmds during
59 * non ISP abort time.
Linus Torvalds1da177e2005-04-16 15:20:36 -070060 */
Andrew Vasquez8eca3f32009-01-22 09:45:31 -080061 if (!wait_for_completion_timeout(&ha->mbx_cmd_comp, mcp->tov * HZ)) {
62 /* Timeout occurred. Return error. */
63 DEBUG2_3_11(printk("%s(%ld): cmd access timeout. "
64 "Exiting.\n", __func__, base_vha->host_no));
65 return QLA_FUNCTION_TIMEOUT;
Linus Torvalds1da177e2005-04-16 15:20:36 -070066 }
67
68 ha->flags.mbox_busy = 1;
69 /* Save mailbox command for debug */
70 ha->mcp = mcp;
71
Andrew Vasquez1c7c6352005-07-06 10:30:57 -070072 DEBUG11(printk("scsi(%ld): prepare to issue mbox cmd=0x%x.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -080073 base_vha->host_no, mcp->mb[0]));
Linus Torvalds1da177e2005-04-16 15:20:36 -070074
75 spin_lock_irqsave(&ha->hardware_lock, flags);
76
77 /* Load mailbox registers. */
Andrew Vasqueze4289242007-07-19 15:05:56 -070078 if (IS_FWI2_CAPABLE(ha))
Andrew Vasquez1c7c6352005-07-06 10:30:57 -070079 optr = (uint16_t __iomem *)&reg->isp24.mailbox0;
80 else
81 optr = (uint16_t __iomem *)MAILBOX_REG(ha, &reg->isp, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -070082
83 iptr = mcp->mb;
84 command = mcp->mb[0];
85 mboxes = mcp->out_mb;
86
87 for (cnt = 0; cnt < ha->mbx_count; cnt++) {
88 if (IS_QLA2200(ha) && cnt == 8)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -070089 optr =
90 (uint16_t __iomem *)MAILBOX_REG(ha, &reg->isp, 8);
Linus Torvalds1da177e2005-04-16 15:20:36 -070091 if (mboxes & BIT_0)
92 WRT_REG_WORD(optr, *iptr);
93
94 mboxes >>= 1;
95 optr++;
96 iptr++;
97 }
98
99#if defined(QL_DEBUG_LEVEL_1)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700100 printk("%s(%ld): Loaded MBX registers (displayed in bytes) = \n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800101 __func__, base_vha->host_no);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700102 qla2x00_dump_buffer((uint8_t *)mcp->mb, 16);
103 printk("\n");
104 qla2x00_dump_buffer(((uint8_t *)mcp->mb + 0x10), 16);
105 printk("\n");
106 qla2x00_dump_buffer(((uint8_t *)mcp->mb + 0x20), 8);
107 printk("\n");
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800108 printk("%s(%ld): I/O address = %p.\n", __func__, base_vha->host_no,
109 optr);
110 qla2x00_dump_regs(base_vha);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700111#endif
112
113 /* Issue set host interrupt command to send cmd out. */
114 ha->flags.mbox_int = 0;
115 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
116
117 /* Unlock mbx registers and wait for interrupt */
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700118 DEBUG11(printk("%s(%ld): going to unlock irq & waiting for interrupt. "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800119 "jiffies=%lx.\n", __func__, base_vha->host_no, jiffies));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700120
121 /* Wait for mbx cmd completion until timeout */
122
Andrew Vasquez124f85e2009-01-05 11:18:06 -0800123 if ((!abort_active && io_lock_on) || IS_NOPOLLING_TYPE(ha)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700124 set_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
125
Andrew Vasqueze4289242007-07-19 15:05:56 -0700126 if (IS_FWI2_CAPABLE(ha))
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700127 WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_SET_HOST_INT);
128 else
129 WRT_REG_WORD(&reg->isp.hccr, HCCR_SET_HOST_INT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700130 spin_unlock_irqrestore(&ha->hardware_lock, flags);
131
Marcus Barrow0b05a1f2008-01-17 09:02:13 -0800132 wait_for_completion_timeout(&ha->mbx_intr_comp, mcp->tov * HZ);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700133
Linus Torvalds1da177e2005-04-16 15:20:36 -0700134 clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
135
Linus Torvalds1da177e2005-04-16 15:20:36 -0700136 } else {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700137 DEBUG3_11(printk("%s(%ld): cmd=%x POLLING MODE.\n", __func__,
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800138 base_vha->host_no, command));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700139
Andrew Vasqueze4289242007-07-19 15:05:56 -0700140 if (IS_FWI2_CAPABLE(ha))
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700141 WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_SET_HOST_INT);
142 else
143 WRT_REG_WORD(&reg->isp.hccr, HCCR_SET_HOST_INT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700144 spin_unlock_irqrestore(&ha->hardware_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700145
146 wait_time = jiffies + mcp->tov * HZ; /* wait at most tov secs */
147 while (!ha->flags.mbox_int) {
148 if (time_after(jiffies, wait_time))
149 break;
150
151 /* Check for pending interrupts. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800152 qla2x00_poll(ha->rsp_q_map[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700153
andrew.vasquez@qlogic.com59989832006-01-13 17:05:10 -0800154 if (command != MBC_LOAD_RISC_RAM_EXTENDED &&
155 !ha->flags.mbox_int)
156 msleep(10);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700157 } /* while */
158 }
159
Linus Torvalds1da177e2005-04-16 15:20:36 -0700160 /* Check whether we timed out */
161 if (ha->flags.mbox_int) {
162 uint16_t *iptr2;
163
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700164 DEBUG3_11(printk("%s(%ld): cmd %x completed.\n", __func__,
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800165 base_vha->host_no, command));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700166
167 /* Got interrupt. Clear the flag. */
168 ha->flags.mbox_int = 0;
169 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
170
Andrew Vasquez 354d6b22005-04-23 02:47:27 -0400171 if (ha->mailbox_out[0] != MBS_COMMAND_COMPLETE)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700172 rval = QLA_FUNCTION_FAILED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700173
174 /* Load return mailbox registers. */
175 iptr2 = mcp->mb;
176 iptr = (uint16_t *)&ha->mailbox_out[0];
177 mboxes = mcp->in_mb;
178 for (cnt = 0; cnt < ha->mbx_count; cnt++) {
179 if (mboxes & BIT_0)
180 *iptr2 = *iptr;
181
182 mboxes >>= 1;
183 iptr2++;
184 iptr++;
185 }
186 } else {
187
188#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3) || \
189 defined(QL_DEBUG_LEVEL_11)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700190 uint16_t mb0;
191 uint32_t ictrl;
192
Andrew Vasqueze4289242007-07-19 15:05:56 -0700193 if (IS_FWI2_CAPABLE(ha)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700194 mb0 = RD_REG_WORD(&reg->isp24.mailbox0);
195 ictrl = RD_REG_DWORD(&reg->isp24.ictrl);
196 } else {
Andrew Vasquezcca53352005-08-26 19:08:30 -0700197 mb0 = RD_MAILBOX_REG(ha, &reg->isp, 0);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700198 ictrl = RD_REG_WORD(&reg->isp.ictrl);
199 }
200 printk("%s(%ld): **** MB Command Timeout for cmd %x ****\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800201 __func__, base_vha->host_no, command);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700202 printk("%s(%ld): icontrol=%x jiffies=%lx\n", __func__,
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800203 base_vha->host_no, ictrl, jiffies);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700204 printk("%s(%ld): *** mailbox[0] = 0x%x ***\n", __func__,
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800205 base_vha->host_no, mb0);
206 qla2x00_dump_regs(base_vha);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700207#endif
208
Linus Torvalds1da177e2005-04-16 15:20:36 -0700209 rval = QLA_FUNCTION_TIMEOUT;
210 }
211
Linus Torvalds1da177e2005-04-16 15:20:36 -0700212 ha->flags.mbox_busy = 0;
213
214 /* Clean up */
215 ha->mcp = NULL;
216
Andrew Vasquez124f85e2009-01-05 11:18:06 -0800217 if ((abort_active || !io_lock_on) && !IS_NOPOLLING_TYPE(ha)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700218 DEBUG11(printk("%s(%ld): checking for additional resp "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800219 "interrupt.\n", __func__, base_vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700220
221 /* polling mode for non isp_abort commands. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800222 qla2x00_poll(ha->rsp_q_map[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700223 }
224
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700225 if (rval == QLA_FUNCTION_TIMEOUT &&
226 mcp->mb[0] != MBC_GEN_SYSTEM_ERROR) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700227 if (!io_lock_on || (mcp->flags & IOCTL_CMD)) {
228 /* not in dpc. schedule it for dpc to take over. */
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700229 DEBUG(printk("%s(%ld): timeout schedule "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800230 "isp_abort_needed.\n", __func__,
231 base_vha->host_no));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700232 DEBUG2_3_11(printk("%s(%ld): timeout schedule "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800233 "isp_abort_needed.\n", __func__,
234 base_vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700235 qla_printk(KERN_WARNING, ha,
Bjorn Helgaascc3ef7b2008-09-11 21:22:51 -0700236 "Mailbox command timeout occurred. Scheduling ISP "
Linus Torvalds1da177e2005-04-16 15:20:36 -0700237 "abort.\n");
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800238 set_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags);
239 qla2xxx_wake_dpc(vha);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700240 } else if (!abort_active) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700241 /* call abort directly since we are in the DPC thread */
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700242 DEBUG(printk("%s(%ld): timeout calling abort_isp\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800243 __func__, base_vha->host_no));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700244 DEBUG2_3_11(printk("%s(%ld): timeout calling "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800245 "abort_isp\n", __func__, base_vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700246 qla_printk(KERN_WARNING, ha,
Bjorn Helgaascc3ef7b2008-09-11 21:22:51 -0700247 "Mailbox command timeout occurred. Issuing ISP "
Linus Torvalds1da177e2005-04-16 15:20:36 -0700248 "abort.\n");
249
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800250 set_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags);
251 clear_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags);
252 if (qla2x00_abort_isp(base_vha)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700253 /* Failed. retry later. */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800254 set_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700255 }
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800256 clear_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700257 DEBUG(printk("%s(%ld): finished abort_isp\n", __func__,
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800258 base_vha->host_no));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700259 DEBUG2_3_11(printk("%s(%ld): finished abort_isp\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800260 __func__, base_vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700261 }
262 }
263
264 /* Allow next mbx cmd to come in. */
Andrew Vasquez8eca3f32009-01-22 09:45:31 -0800265 complete(&ha->mbx_cmd_comp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700266
267 if (rval) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700268 DEBUG2_3_11(printk("%s(%ld): **** FAILED. mbx0=%x, mbx1=%x, "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800269 "mbx2=%x, cmd=%x ****\n", __func__, base_vha->host_no,
Andrew Vasquez744f11fd2006-06-23 16:11:05 -0700270 mcp->mb[0], mcp->mb[1], mcp->mb[2], command));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700271 } else {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800272 DEBUG11(printk("%s(%ld): done.\n", __func__,
273 base_vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700274 }
275
Linus Torvalds1da177e2005-04-16 15:20:36 -0700276 return rval;
277}
278
Linus Torvalds1da177e2005-04-16 15:20:36 -0700279int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800280qla2x00_load_ram(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t risc_addr,
andrew.vasquez@qlogic.com590f98e2006-01-13 17:05:37 -0800281 uint32_t risc_code_size)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700282{
283 int rval;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800284 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700285 mbx_cmd_t mc;
286 mbx_cmd_t *mcp = &mc;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700287
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800288 DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700289
Andrew Vasqueze4289242007-07-19 15:05:56 -0700290 if (MSW(risc_addr) || IS_FWI2_CAPABLE(ha)) {
andrew.vasquez@qlogic.com590f98e2006-01-13 17:05:37 -0800291 mcp->mb[0] = MBC_LOAD_RISC_RAM_EXTENDED;
292 mcp->mb[8] = MSW(risc_addr);
293 mcp->out_mb = MBX_8|MBX_0;
294 } else {
295 mcp->mb[0] = MBC_LOAD_RISC_RAM;
296 mcp->out_mb = MBX_0;
297 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700298 mcp->mb[1] = LSW(risc_addr);
299 mcp->mb[2] = MSW(req_dma);
300 mcp->mb[3] = LSW(req_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700301 mcp->mb[6] = MSW(MSD(req_dma));
302 mcp->mb[7] = LSW(MSD(req_dma));
andrew.vasquez@qlogic.com590f98e2006-01-13 17:05:37 -0800303 mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_1;
Andrew Vasqueze4289242007-07-19 15:05:56 -0700304 if (IS_FWI2_CAPABLE(ha)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700305 mcp->mb[4] = MSW(risc_code_size);
306 mcp->mb[5] = LSW(risc_code_size);
307 mcp->out_mb |= MBX_5|MBX_4;
308 } else {
309 mcp->mb[4] = LSW(risc_code_size);
310 mcp->out_mb |= MBX_4;
311 }
312
Linus Torvalds1da177e2005-04-16 15:20:36 -0700313 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -0700314 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700315 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800316 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700317
Linus Torvalds1da177e2005-04-16 15:20:36 -0700318 if (rval != QLA_SUCCESS) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700319 DEBUG2_3_11(printk("%s(%ld): failed=%x mb[0]=%x.\n", __func__,
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800320 vha->host_no, rval, mcp->mb[0]));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700321 } else {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800322 DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700323 }
324
325 return rval;
326}
327
328/*
329 * qla2x00_execute_fw
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700330 * Start adapter firmware.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700331 *
332 * Input:
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700333 * ha = adapter block pointer.
334 * TARGET_QUEUE_LOCK must be released.
335 * ADAPTER_STATE_LOCK must be released.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700336 *
337 * Returns:
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700338 * qla2x00 local function return status code.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700339 *
340 * Context:
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700341 * Kernel context.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700342 */
343int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800344qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700345{
346 int rval;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800347 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700348 mbx_cmd_t mc;
349 mbx_cmd_t *mcp = &mc;
350
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800351 DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700352
353 mcp->mb[0] = MBC_EXECUTE_FIRMWARE;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700354 mcp->out_mb = MBX_0;
355 mcp->in_mb = MBX_0;
Andrew Vasqueze4289242007-07-19 15:05:56 -0700356 if (IS_FWI2_CAPABLE(ha)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700357 mcp->mb[1] = MSW(risc_addr);
358 mcp->mb[2] = LSW(risc_addr);
359 mcp->mb[3] = 0;
Andrew Vasquez8b3253d2007-09-20 14:07:48 -0700360 mcp->mb[4] = 0;
361 mcp->out_mb |= MBX_4|MBX_3|MBX_2|MBX_1;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700362 mcp->in_mb |= MBX_1;
363 } else {
364 mcp->mb[1] = LSW(risc_addr);
365 mcp->out_mb |= MBX_1;
366 if (IS_QLA2322(ha) || IS_QLA6322(ha)) {
367 mcp->mb[2] = 0;
368 mcp->out_mb |= MBX_2;
369 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700370 }
371
Ravi Anandb93480e2008-04-03 13:13:25 -0700372 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700373 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800374 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700375
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700376 if (rval != QLA_SUCCESS) {
377 DEBUG2_3_11(printk("%s(%ld): failed=%x mb[0]=%x.\n", __func__,
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800378 vha->host_no, rval, mcp->mb[0]));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700379 } else {
Andrew Vasqueze4289242007-07-19 15:05:56 -0700380 if (IS_FWI2_CAPABLE(ha)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700381 DEBUG11(printk("%s(%ld): done exchanges=%x.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800382 __func__, vha->host_no, mcp->mb[1]));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700383 } else {
384 DEBUG11(printk("%s(%ld): done.\n", __func__,
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800385 vha->host_no));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700386 }
387 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700388
389 return rval;
390}
391
392/*
393 * qla2x00_get_fw_version
394 * Get firmware version.
395 *
396 * Input:
397 * ha: adapter state pointer.
398 * major: pointer for major number.
399 * minor: pointer for minor number.
400 * subminor: pointer for subminor number.
401 *
402 * Returns:
403 * qla2x00 local function return status code.
404 *
405 * Context:
406 * Kernel context.
407 */
408void
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800409qla2x00_get_fw_version(scsi_qla_host_t *vha, uint16_t *major, uint16_t *minor,
Andrew Vasquez3a03eb72009-01-05 11:18:11 -0800410 uint16_t *subminor, uint16_t *attributes, uint32_t *memory, uint8_t *mpi,
Andrew Vasquez55a96152009-03-24 09:08:03 -0700411 uint32_t *mpi_caps, uint8_t *phy)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700412{
413 int rval;
414 mbx_cmd_t mc;
415 mbx_cmd_t *mcp = &mc;
416
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800417 DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700418
419 mcp->mb[0] = MBC_GET_FIRMWARE_VERSION;
420 mcp->out_mb = MBX_0;
421 mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
Andrew Vasquez3a03eb72009-01-05 11:18:11 -0800422 if (IS_QLA81XX(vha->hw))
Andrew Vasquez55a96152009-03-24 09:08:03 -0700423 mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700424 mcp->flags = 0;
Ravi Anandb93480e2008-04-03 13:13:25 -0700425 mcp->tov = MBX_TOV_SECONDS;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800426 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700427
428 /* Return mailbox data. */
429 *major = mcp->mb[1];
430 *minor = mcp->mb[2];
431 *subminor = mcp->mb[3];
432 *attributes = mcp->mb[6];
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800433 if (IS_QLA2100(vha->hw) || IS_QLA2200(vha->hw))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700434 *memory = 0x1FFFF; /* Defaults to 128KB. */
435 else
436 *memory = (mcp->mb[5] << 16) | mcp->mb[4];
Andrew Vasquez3a03eb72009-01-05 11:18:11 -0800437 if (IS_QLA81XX(vha->hw)) {
Andrew Vasquez55a96152009-03-24 09:08:03 -0700438 mpi[0] = mcp->mb[10] & 0xff;
439 mpi[1] = mcp->mb[11] >> 8;
440 mpi[2] = mcp->mb[11] & 0xff;
Andrew Vasquez3a03eb72009-01-05 11:18:11 -0800441 *mpi_caps = (mcp->mb[12] << 16) | mcp->mb[13];
Andrew Vasquez55a96152009-03-24 09:08:03 -0700442 phy[0] = mcp->mb[8] & 0xff;
443 phy[1] = mcp->mb[9] >> 8;
444 phy[2] = mcp->mb[9] & 0xff;
Andrew Vasquez3a03eb72009-01-05 11:18:11 -0800445 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700446
447 if (rval != QLA_SUCCESS) {
448 /*EMPTY*/
449 DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__,
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800450 vha->host_no, rval));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700451 } else {
452 /*EMPTY*/
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800453 DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700454 }
455}
456
457/*
458 * qla2x00_get_fw_options
459 * Set firmware options.
460 *
461 * Input:
462 * ha = adapter block pointer.
463 * fwopt = pointer for firmware options.
464 *
465 * Returns:
466 * qla2x00 local function return status code.
467 *
468 * Context:
469 * Kernel context.
470 */
471int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800472qla2x00_get_fw_options(scsi_qla_host_t *vha, uint16_t *fwopts)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700473{
474 int rval;
475 mbx_cmd_t mc;
476 mbx_cmd_t *mcp = &mc;
477
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800478 DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700479
480 mcp->mb[0] = MBC_GET_FIRMWARE_OPTION;
481 mcp->out_mb = MBX_0;
482 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -0700483 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700484 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800485 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700486
487 if (rval != QLA_SUCCESS) {
488 /*EMPTY*/
489 DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__,
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800490 vha->host_no, rval));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700491 } else {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700492 fwopts[0] = mcp->mb[0];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700493 fwopts[1] = mcp->mb[1];
494 fwopts[2] = mcp->mb[2];
495 fwopts[3] = mcp->mb[3];
496
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800497 DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700498 }
499
500 return rval;
501}
502
503
504/*
505 * qla2x00_set_fw_options
506 * Set firmware options.
507 *
508 * Input:
509 * ha = adapter block pointer.
510 * fwopt = pointer for firmware options.
511 *
512 * Returns:
513 * qla2x00 local function return status code.
514 *
515 * Context:
516 * Kernel context.
517 */
518int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800519qla2x00_set_fw_options(scsi_qla_host_t *vha, uint16_t *fwopts)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700520{
521 int rval;
522 mbx_cmd_t mc;
523 mbx_cmd_t *mcp = &mc;
524
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800525 DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700526
527 mcp->mb[0] = MBC_SET_FIRMWARE_OPTION;
528 mcp->mb[1] = fwopts[1];
529 mcp->mb[2] = fwopts[2];
530 mcp->mb[3] = fwopts[3];
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700531 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700532 mcp->in_mb = MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800533 if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700534 mcp->in_mb |= MBX_1;
535 } else {
536 mcp->mb[10] = fwopts[10];
537 mcp->mb[11] = fwopts[11];
538 mcp->mb[12] = 0; /* Undocumented, but used */
539 mcp->out_mb |= MBX_12|MBX_11|MBX_10;
540 }
Ravi Anandb93480e2008-04-03 13:13:25 -0700541 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700542 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800543 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700544
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700545 fwopts[0] = mcp->mb[0];
546
Linus Torvalds1da177e2005-04-16 15:20:36 -0700547 if (rval != QLA_SUCCESS) {
548 /*EMPTY*/
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700549 DEBUG2_3_11(printk("%s(%ld): failed=%x (%x/%x).\n", __func__,
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800550 vha->host_no, rval, mcp->mb[0], mcp->mb[1]));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700551 } else {
552 /*EMPTY*/
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800553 DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700554 }
555
556 return rval;
557}
558
559/*
560 * qla2x00_mbx_reg_test
561 * Mailbox register wrap test.
562 *
563 * Input:
564 * ha = adapter block pointer.
565 * TARGET_QUEUE_LOCK must be released.
566 * ADAPTER_STATE_LOCK must be released.
567 *
568 * Returns:
569 * qla2x00 local function return status code.
570 *
571 * Context:
572 * Kernel context.
573 */
574int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800575qla2x00_mbx_reg_test(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700576{
577 int rval;
578 mbx_cmd_t mc;
579 mbx_cmd_t *mcp = &mc;
580
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800581 DEBUG11(printk("qla2x00_mbx_reg_test(%ld): entered.\n", vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700582
583 mcp->mb[0] = MBC_MAILBOX_REGISTER_TEST;
584 mcp->mb[1] = 0xAAAA;
585 mcp->mb[2] = 0x5555;
586 mcp->mb[3] = 0xAA55;
587 mcp->mb[4] = 0x55AA;
588 mcp->mb[5] = 0xA5A5;
589 mcp->mb[6] = 0x5A5A;
590 mcp->mb[7] = 0x2525;
591 mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
592 mcp->in_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -0700593 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700594 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800595 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700596
597 if (rval == QLA_SUCCESS) {
598 if (mcp->mb[1] != 0xAAAA || mcp->mb[2] != 0x5555 ||
599 mcp->mb[3] != 0xAA55 || mcp->mb[4] != 0x55AA)
600 rval = QLA_FUNCTION_FAILED;
601 if (mcp->mb[5] != 0xA5A5 || mcp->mb[6] != 0x5A5A ||
602 mcp->mb[7] != 0x2525)
603 rval = QLA_FUNCTION_FAILED;
604 }
605
606 if (rval != QLA_SUCCESS) {
607 /*EMPTY*/
608 DEBUG2_3_11(printk("qla2x00_mbx_reg_test(%ld): failed=%x.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800609 vha->host_no, rval));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700610 } else {
611 /*EMPTY*/
612 DEBUG11(printk("qla2x00_mbx_reg_test(%ld): done.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800613 vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700614 }
615
616 return rval;
617}
618
619/*
620 * qla2x00_verify_checksum
621 * Verify firmware checksum.
622 *
623 * Input:
624 * ha = adapter block pointer.
625 * TARGET_QUEUE_LOCK must be released.
626 * ADAPTER_STATE_LOCK must be released.
627 *
628 * Returns:
629 * qla2x00 local function return status code.
630 *
631 * Context:
632 * Kernel context.
633 */
634int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800635qla2x00_verify_checksum(scsi_qla_host_t *vha, uint32_t risc_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700636{
637 int rval;
638 mbx_cmd_t mc;
639 mbx_cmd_t *mcp = &mc;
640
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800641 DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700642
643 mcp->mb[0] = MBC_VERIFY_CHECKSUM;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700644 mcp->out_mb = MBX_0;
645 mcp->in_mb = MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800646 if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700647 mcp->mb[1] = MSW(risc_addr);
648 mcp->mb[2] = LSW(risc_addr);
649 mcp->out_mb |= MBX_2|MBX_1;
650 mcp->in_mb |= MBX_2|MBX_1;
651 } else {
652 mcp->mb[1] = LSW(risc_addr);
653 mcp->out_mb |= MBX_1;
654 mcp->in_mb |= MBX_1;
655 }
656
Ravi Anandb93480e2008-04-03 13:13:25 -0700657 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700658 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800659 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700660
661 if (rval != QLA_SUCCESS) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700662 DEBUG2_3_11(printk("%s(%ld): failed=%x chk sum=%x.\n", __func__,
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800663 vha->host_no, rval, IS_FWI2_CAPABLE(vha->hw) ?
Andrew Vasqueze4289242007-07-19 15:05:56 -0700664 (mcp->mb[2] << 16) | mcp->mb[1]: mcp->mb[1]));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700665 } else {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800666 DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700667 }
668
669 return rval;
670}
671
672/*
673 * qla2x00_issue_iocb
674 * Issue IOCB using mailbox command
675 *
676 * Input:
677 * ha = adapter state pointer.
678 * buffer = buffer pointer.
679 * phys_addr = physical address of buffer.
680 * size = size of buffer.
681 * TARGET_QUEUE_LOCK must be released.
682 * ADAPTER_STATE_LOCK must be released.
683 *
684 * Returns:
685 * qla2x00 local function return status code.
686 *
687 * Context:
688 * Kernel context.
689 */
Adrian Bunk3b8117b2008-04-24 15:21:28 -0700690static int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800691qla2x00_issue_iocb_timeout(scsi_qla_host_t *vha, void *buffer,
Harihara Kadayam4d4df192008-04-03 13:13:26 -0700692 dma_addr_t phys_addr, size_t size, uint32_t tov)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700693{
694 int rval;
695 mbx_cmd_t mc;
696 mbx_cmd_t *mcp = &mc;
697
698 mcp->mb[0] = MBC_IOCB_COMMAND_A64;
699 mcp->mb[1] = 0;
700 mcp->mb[2] = MSW(phys_addr);
701 mcp->mb[3] = LSW(phys_addr);
702 mcp->mb[6] = MSW(MSD(phys_addr));
703 mcp->mb[7] = LSW(MSD(phys_addr));
704 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
705 mcp->in_mb = MBX_2|MBX_0;
Harihara Kadayam4d4df192008-04-03 13:13:26 -0700706 mcp->tov = tov;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700707 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800708 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700709
710 if (rval != QLA_SUCCESS) {
711 /*EMPTY*/
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700712 DEBUG(printk("qla2x00_issue_iocb(%ld): failed rval 0x%x\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800713 vha->host_no, rval));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700714 } else {
Andrew Vasquez8c958a92005-07-06 10:30:47 -0700715 sts_entry_t *sts_entry = (sts_entry_t *) buffer;
716
717 /* Mask reserved bits. */
718 sts_entry->entry_status &=
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800719 IS_FWI2_CAPABLE(vha->hw) ? RF_MASK_24XX : RF_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700720 }
721
722 return rval;
723}
724
Harihara Kadayam4d4df192008-04-03 13:13:26 -0700725int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800726qla2x00_issue_iocb(scsi_qla_host_t *vha, void *buffer, dma_addr_t phys_addr,
Harihara Kadayam4d4df192008-04-03 13:13:26 -0700727 size_t size)
728{
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800729 return qla2x00_issue_iocb_timeout(vha, buffer, phys_addr, size,
Harihara Kadayam4d4df192008-04-03 13:13:26 -0700730 MBX_TOV_SECONDS);
731}
732
Linus Torvalds1da177e2005-04-16 15:20:36 -0700733/*
734 * qla2x00_abort_command
735 * Abort command aborts a specified IOCB.
736 *
737 * Input:
738 * ha = adapter block pointer.
739 * sp = SB structure pointer.
740 *
741 * Returns:
742 * qla2x00 local function return status code.
743 *
744 * Context:
745 * Kernel context.
746 */
747int
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800748qla2x00_abort_command(scsi_qla_host_t *vha, srb_t *sp, struct req_que *req)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700749{
750 unsigned long flags = 0;
751 fc_port_t *fcport;
752 int rval;
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800753 uint32_t handle = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700754 mbx_cmd_t mc;
755 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800756 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700757
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800758 DEBUG11(printk("qla2x00_abort_command(%ld): entered.\n", vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700759
bdf79622005-04-17 15:06:53 -0500760 fcport = sp->fcport;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700761
Andrew Vasquezc9c5ced2008-07-24 08:31:49 -0700762 spin_lock_irqsave(&ha->hardware_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700763 for (handle = 1; handle < MAX_OUTSTANDING_COMMANDS; handle++) {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800764 if (req->outstanding_cmds[handle] == sp)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700765 break;
766 }
Andrew Vasquezc9c5ced2008-07-24 08:31:49 -0700767 spin_unlock_irqrestore(&ha->hardware_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700768
769 if (handle == MAX_OUTSTANDING_COMMANDS) {
770 /* command not found */
771 return QLA_FUNCTION_FAILED;
772 }
773
774 mcp->mb[0] = MBC_ABORT_COMMAND;
775 if (HAS_EXTENDED_IDS(ha))
776 mcp->mb[1] = fcport->loop_id;
777 else
778 mcp->mb[1] = fcport->loop_id << 8;
779 mcp->mb[2] = (uint16_t)handle;
780 mcp->mb[3] = (uint16_t)(handle >> 16);
bdf79622005-04-17 15:06:53 -0500781 mcp->mb[6] = (uint16_t)sp->cmd->device->lun;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700782 mcp->out_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
783 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -0700784 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700785 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800786 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700787
788 if (rval != QLA_SUCCESS) {
789 DEBUG2_3_11(printk("qla2x00_abort_command(%ld): failed=%x.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800790 vha->host_no, rval));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700791 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700792 DEBUG11(printk("qla2x00_abort_command(%ld): done.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800793 vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700794 }
795
796 return rval;
797}
798
Linus Torvalds1da177e2005-04-16 15:20:36 -0700799int
Andrew Vasquez523ec772008-04-03 13:13:24 -0700800qla2x00_abort_target(struct fc_port *fcport, unsigned int l)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700801{
Andrew Vasquez523ec772008-04-03 13:13:24 -0700802 int rval, rval2;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700803 mbx_cmd_t mc;
804 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800805 scsi_qla_host_t *vha;
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800806 struct req_que *req;
807 struct rsp_que *rsp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700808
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800809 DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->vha->host_no));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700810
Andrew Vasquez523ec772008-04-03 13:13:24 -0700811 l = l;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800812 vha = fcport->vha;
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800813 req = vha->hw->req_q_map[0];
814 rsp = vha->hw->rsp_q_map[0];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700815 mcp->mb[0] = MBC_ABORT_TARGET;
Andrew Vasquez523ec772008-04-03 13:13:24 -0700816 mcp->out_mb = MBX_9|MBX_2|MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800817 if (HAS_EXTENDED_IDS(vha->hw)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700818 mcp->mb[1] = fcport->loop_id;
819 mcp->mb[10] = 0;
820 mcp->out_mb |= MBX_10;
821 } else {
822 mcp->mb[1] = fcport->loop_id << 8;
823 }
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800824 mcp->mb[2] = vha->hw->loop_reset_delay;
825 mcp->mb[9] = vha->vp_idx;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700826
827 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -0700828 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700829 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800830 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700831 if (rval != QLA_SUCCESS) {
Andrew Vasquez523ec772008-04-03 13:13:24 -0700832 DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__,
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800833 vha->host_no, rval));
Andrew Vasquez523ec772008-04-03 13:13:24 -0700834 }
835
836 /* Issue marker IOCB. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800837 rval2 = qla2x00_marker(vha, req, rsp, fcport->loop_id, 0,
838 MK_SYNC_ID);
Andrew Vasquez523ec772008-04-03 13:13:24 -0700839 if (rval2 != QLA_SUCCESS) {
840 DEBUG2_3_11(printk("%s(%ld): failed to issue Marker IOCB "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800841 "(%x).\n", __func__, vha->host_no, rval2));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700842 } else {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800843 DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
Andrew Vasquez523ec772008-04-03 13:13:24 -0700844 }
845
846 return rval;
847}
848
849int
850qla2x00_lun_reset(struct fc_port *fcport, unsigned int l)
851{
852 int rval, rval2;
853 mbx_cmd_t mc;
854 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800855 scsi_qla_host_t *vha;
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800856 struct req_que *req;
857 struct rsp_que *rsp;
Andrew Vasquez523ec772008-04-03 13:13:24 -0700858
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800859 DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->vha->host_no));
Andrew Vasquez523ec772008-04-03 13:13:24 -0700860
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800861 vha = fcport->vha;
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800862 req = vha->hw->req_q_map[0];
863 rsp = vha->hw->rsp_q_map[0];
Andrew Vasquez523ec772008-04-03 13:13:24 -0700864 mcp->mb[0] = MBC_LUN_RESET;
865 mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800866 if (HAS_EXTENDED_IDS(vha->hw))
Andrew Vasquez523ec772008-04-03 13:13:24 -0700867 mcp->mb[1] = fcport->loop_id;
868 else
869 mcp->mb[1] = fcport->loop_id << 8;
870 mcp->mb[2] = l;
871 mcp->mb[3] = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800872 mcp->mb[9] = vha->vp_idx;
Andrew Vasquez523ec772008-04-03 13:13:24 -0700873
874 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -0700875 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez523ec772008-04-03 13:13:24 -0700876 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800877 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez523ec772008-04-03 13:13:24 -0700878 if (rval != QLA_SUCCESS) {
879 DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__,
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800880 vha->host_no, rval));
Andrew Vasquez523ec772008-04-03 13:13:24 -0700881 }
882
883 /* Issue marker IOCB. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800884 rval2 = qla2x00_marker(vha, req, rsp, fcport->loop_id, l,
885 MK_SYNC_ID_LUN);
Andrew Vasquez523ec772008-04-03 13:13:24 -0700886 if (rval2 != QLA_SUCCESS) {
887 DEBUG2_3_11(printk("%s(%ld): failed to issue Marker IOCB "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800888 "(%x).\n", __func__, vha->host_no, rval2));
Andrew Vasquez523ec772008-04-03 13:13:24 -0700889 } else {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800890 DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700891 }
892
893 return rval;
894}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700895
896/*
Linus Torvalds1da177e2005-04-16 15:20:36 -0700897 * qla2x00_get_adapter_id
898 * Get adapter ID and topology.
899 *
900 * Input:
901 * ha = adapter block pointer.
902 * id = pointer for loop ID.
903 * al_pa = pointer for AL_PA.
904 * area = pointer for area.
905 * domain = pointer for domain.
906 * top = pointer for topology.
907 * TARGET_QUEUE_LOCK must be released.
908 * ADAPTER_STATE_LOCK must be released.
909 *
910 * Returns:
911 * qla2x00 local function return status code.
912 *
913 * Context:
914 * Kernel context.
915 */
916int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800917qla2x00_get_adapter_id(scsi_qla_host_t *vha, uint16_t *id, uint8_t *al_pa,
Seokmann Ju2c3dfe32007-07-05 13:16:51 -0700918 uint8_t *area, uint8_t *domain, uint16_t *top, uint16_t *sw_cap)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700919{
920 int rval;
921 mbx_cmd_t mc;
922 mbx_cmd_t *mcp = &mc;
923
924 DEBUG11(printk("qla2x00_get_adapter_id(%ld): entered.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800925 vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700926
927 mcp->mb[0] = MBC_GET_ADAPTER_LOOP_ID;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800928 mcp->mb[9] = vha->vp_idx;
Andrew Vasquezeb66dc62007-11-12 10:30:58 -0800929 mcp->out_mb = MBX_9|MBX_0;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -0700930 mcp->in_mb = MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -0700931 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700932 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800933 rval = qla2x00_mailbox_command(vha, mcp);
Ravi Anand33135aa2005-11-08 14:37:20 -0800934 if (mcp->mb[0] == MBS_COMMAND_ERROR)
935 rval = QLA_COMMAND_ERROR;
Andrew Vasquez42e421b2008-07-10 16:56:01 -0700936 else if (mcp->mb[0] == MBS_INVALID_COMMAND)
937 rval = QLA_INVALID_COMMAND;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700938
939 /* Return data. */
940 *id = mcp->mb[1];
941 *al_pa = LSB(mcp->mb[2]);
942 *area = MSB(mcp->mb[2]);
943 *domain = LSB(mcp->mb[3]);
944 *top = mcp->mb[6];
Seokmann Ju2c3dfe32007-07-05 13:16:51 -0700945 *sw_cap = mcp->mb[7];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700946
947 if (rval != QLA_SUCCESS) {
948 /*EMPTY*/
949 DEBUG2_3_11(printk("qla2x00_get_adapter_id(%ld): failed=%x.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800950 vha->host_no, rval));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700951 } else {
952 /*EMPTY*/
953 DEBUG11(printk("qla2x00_get_adapter_id(%ld): done.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800954 vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700955 }
956
957 return rval;
958}
959
960/*
961 * qla2x00_get_retry_cnt
962 * Get current firmware login retry count and delay.
963 *
964 * Input:
965 * ha = adapter block pointer.
966 * retry_cnt = pointer to login retry count.
967 * tov = pointer to login timeout value.
968 *
969 * Returns:
970 * qla2x00 local function return status code.
971 *
972 * Context:
973 * Kernel context.
974 */
975int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800976qla2x00_get_retry_cnt(scsi_qla_host_t *vha, uint8_t *retry_cnt, uint8_t *tov,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700977 uint16_t *r_a_tov)
978{
979 int rval;
980 uint16_t ratov;
981 mbx_cmd_t mc;
982 mbx_cmd_t *mcp = &mc;
983
984 DEBUG11(printk("qla2x00_get_retry_cnt(%ld): entered.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800985 vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700986
987 mcp->mb[0] = MBC_GET_RETRY_COUNT;
988 mcp->out_mb = MBX_0;
989 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -0700990 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700991 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800992 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700993
994 if (rval != QLA_SUCCESS) {
995 /*EMPTY*/
996 DEBUG2_3_11(printk("qla2x00_get_retry_cnt(%ld): failed = %x.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800997 vha->host_no, mcp->mb[0]));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700998 } else {
999 /* Convert returned data and check our values. */
1000 *r_a_tov = mcp->mb[3] / 2;
1001 ratov = (mcp->mb[3]/2) / 10; /* mb[3] value is in 100ms */
1002 if (mcp->mb[1] * ratov > (*retry_cnt) * (*tov)) {
1003 /* Update to the larger values */
1004 *retry_cnt = (uint8_t)mcp->mb[1];
1005 *tov = ratov;
1006 }
1007
1008 DEBUG11(printk("qla2x00_get_retry_cnt(%ld): done. mb3=%d "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001009 "ratov=%d.\n", vha->host_no, mcp->mb[3], ratov));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001010 }
1011
1012 return rval;
1013}
1014
1015/*
1016 * qla2x00_init_firmware
1017 * Initialize adapter firmware.
1018 *
1019 * Input:
1020 * ha = adapter block pointer.
1021 * dptr = Initialization control block pointer.
1022 * size = size of initialization control block.
1023 * TARGET_QUEUE_LOCK must be released.
1024 * ADAPTER_STATE_LOCK must be released.
1025 *
1026 * Returns:
1027 * qla2x00 local function return status code.
1028 *
1029 * Context:
1030 * Kernel context.
1031 */
1032int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001033qla2x00_init_firmware(scsi_qla_host_t *vha, uint16_t size)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001034{
1035 int rval;
1036 mbx_cmd_t mc;
1037 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001038 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001039
1040 DEBUG11(printk("qla2x00_init_firmware(%ld): entered.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001041 vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001042
Andrew Vasqueze6e074f2008-01-31 12:33:53 -08001043 if (ha->flags.npiv_supported)
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001044 mcp->mb[0] = MBC_MID_INITIALIZE_FIRMWARE;
1045 else
1046 mcp->mb[0] = MBC_INITIALIZE_FIRMWARE;
1047
Andrew Vasquezb64b0e82009-03-24 09:08:01 -07001048 mcp->mb[1] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001049 mcp->mb[2] = MSW(ha->init_cb_dma);
1050 mcp->mb[3] = LSW(ha->init_cb_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001051 mcp->mb[6] = MSW(MSD(ha->init_cb_dma));
1052 mcp->mb[7] = LSW(MSD(ha->init_cb_dma));
Andrew Vasquezb64b0e82009-03-24 09:08:01 -07001053 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
1054 if (IS_QLA81XX(ha) && ha->ex_init_cb->ex_version) {
1055 mcp->mb[1] = BIT_0;
1056 mcp->mb[10] = MSW(ha->ex_init_cb_dma);
1057 mcp->mb[11] = LSW(ha->ex_init_cb_dma);
1058 mcp->mb[12] = MSW(MSD(ha->ex_init_cb_dma));
1059 mcp->mb[13] = LSW(MSD(ha->ex_init_cb_dma));
1060 mcp->mb[14] = sizeof(*ha->ex_init_cb);
1061 mcp->out_mb |= MBX_14|MBX_13|MBX_12|MBX_11|MBX_10;
1062 }
1063 mcp->in_mb = MBX_0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001064 mcp->buf_size = size;
1065 mcp->flags = MBX_DMA_OUT;
Ravi Anandb93480e2008-04-03 13:13:25 -07001066 mcp->tov = MBX_TOV_SECONDS;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001067 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001068
1069 if (rval != QLA_SUCCESS) {
1070 /*EMPTY*/
1071 DEBUG2_3_11(printk("qla2x00_init_firmware(%ld): failed=%x "
1072 "mb0=%x.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001073 vha->host_no, rval, mcp->mb[0]));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001074 } else {
1075 /*EMPTY*/
1076 DEBUG11(printk("qla2x00_init_firmware(%ld): done.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001077 vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001078 }
1079
1080 return rval;
1081}
1082
1083/*
1084 * qla2x00_get_port_database
1085 * Issue normal/enhanced get port database mailbox command
1086 * and copy device name as necessary.
1087 *
1088 * Input:
1089 * ha = adapter state pointer.
1090 * dev = structure pointer.
1091 * opt = enhanced cmd option byte.
1092 *
1093 * Returns:
1094 * qla2x00 local function return status code.
1095 *
1096 * Context:
1097 * Kernel context.
1098 */
1099int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001100qla2x00_get_port_database(scsi_qla_host_t *vha, fc_port_t *fcport, uint8_t opt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001101{
1102 int rval;
1103 mbx_cmd_t mc;
1104 mbx_cmd_t *mcp = &mc;
1105 port_database_t *pd;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001106 struct port_database_24xx *pd24;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001107 dma_addr_t pd_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001108 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001109
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001110 DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001111
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001112 pd24 = NULL;
1113 pd = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &pd_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001114 if (pd == NULL) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001115 DEBUG2_3(printk("%s(%ld): failed to allocate Port Database "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001116 "structure.\n", __func__, vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001117 return QLA_MEMORY_ALLOC_FAILED;
1118 }
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001119 memset(pd, 0, max(PORT_DATABASE_SIZE, PORT_DATABASE_24XX_SIZE));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001120
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001121 mcp->mb[0] = MBC_GET_PORT_DATABASE;
Andrew Vasqueze4289242007-07-19 15:05:56 -07001122 if (opt != 0 && !IS_FWI2_CAPABLE(ha))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001123 mcp->mb[0] = MBC_ENHANCED_GET_PORT_DATABASE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001124 mcp->mb[2] = MSW(pd_dma);
1125 mcp->mb[3] = LSW(pd_dma);
1126 mcp->mb[6] = MSW(MSD(pd_dma));
1127 mcp->mb[7] = LSW(MSD(pd_dma));
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001128 mcp->mb[9] = vha->vp_idx;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001129 mcp->out_mb = MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001130 mcp->in_mb = MBX_0;
Andrew Vasqueze4289242007-07-19 15:05:56 -07001131 if (IS_FWI2_CAPABLE(ha)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001132 mcp->mb[1] = fcport->loop_id;
1133 mcp->mb[10] = opt;
1134 mcp->out_mb |= MBX_10|MBX_1;
1135 mcp->in_mb |= MBX_1;
1136 } else if (HAS_EXTENDED_IDS(ha)) {
1137 mcp->mb[1] = fcport->loop_id;
1138 mcp->mb[10] = opt;
1139 mcp->out_mb |= MBX_10|MBX_1;
1140 } else {
1141 mcp->mb[1] = fcport->loop_id << 8 | opt;
1142 mcp->out_mb |= MBX_1;
1143 }
Andrew Vasqueze4289242007-07-19 15:05:56 -07001144 mcp->buf_size = IS_FWI2_CAPABLE(ha) ?
1145 PORT_DATABASE_24XX_SIZE : PORT_DATABASE_SIZE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001146 mcp->flags = MBX_DMA_IN;
1147 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001148 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001149 if (rval != QLA_SUCCESS)
1150 goto gpd_error_out;
1151
Andrew Vasqueze4289242007-07-19 15:05:56 -07001152 if (IS_FWI2_CAPABLE(ha)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001153 pd24 = (struct port_database_24xx *) pd;
1154
1155 /* Check for logged in state. */
1156 if (pd24->current_login_state != PDS_PRLI_COMPLETE &&
1157 pd24->last_login_state != PDS_PRLI_COMPLETE) {
1158 DEBUG2(printk("%s(%ld): Unable to verify "
1159 "login-state (%x/%x) for loop_id %x\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001160 __func__, vha->host_no,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001161 pd24->current_login_state,
1162 pd24->last_login_state, fcport->loop_id));
1163 rval = QLA_FUNCTION_FAILED;
1164 goto gpd_error_out;
1165 }
1166
1167 /* Names are little-endian. */
1168 memcpy(fcport->node_name, pd24->node_name, WWN_SIZE);
1169 memcpy(fcport->port_name, pd24->port_name, WWN_SIZE);
1170
1171 /* Get port_id of device. */
1172 fcport->d_id.b.domain = pd24->port_id[0];
1173 fcport->d_id.b.area = pd24->port_id[1];
1174 fcport->d_id.b.al_pa = pd24->port_id[2];
1175 fcport->d_id.b.rsvd_1 = 0;
1176
1177 /* If not target must be initiator or unknown type. */
1178 if ((pd24->prli_svc_param_word_3[0] & BIT_4) == 0)
1179 fcport->port_type = FCT_INITIATOR;
1180 else
1181 fcport->port_type = FCT_TARGET;
1182 } else {
1183 /* Check for logged in state. */
1184 if (pd->master_state != PD_STATE_PORT_LOGGED_IN &&
1185 pd->slave_state != PD_STATE_PORT_LOGGED_IN) {
1186 rval = QLA_FUNCTION_FAILED;
1187 goto gpd_error_out;
1188 }
1189
1190 /* Names are little-endian. */
1191 memcpy(fcport->node_name, pd->node_name, WWN_SIZE);
1192 memcpy(fcport->port_name, pd->port_name, WWN_SIZE);
1193
1194 /* Get port_id of device. */
1195 fcport->d_id.b.domain = pd->port_id[0];
1196 fcport->d_id.b.area = pd->port_id[3];
1197 fcport->d_id.b.al_pa = pd->port_id[2];
1198 fcport->d_id.b.rsvd_1 = 0;
1199
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001200 /* If not target must be initiator or unknown type. */
1201 if ((pd->prli_svc_param_word_3[0] & BIT_4) == 0)
1202 fcport->port_type = FCT_INITIATOR;
1203 else
1204 fcport->port_type = FCT_TARGET;
Andrew Vasquezad3e0ed2005-08-26 19:08:10 -07001205
1206 /* Passback COS information. */
1207 fcport->supported_classes = (pd->options & BIT_4) ?
1208 FC_COS_CLASS2: FC_COS_CLASS3;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001209 }
1210
Linus Torvalds1da177e2005-04-16 15:20:36 -07001211gpd_error_out:
1212 dma_pool_free(ha->s_dma_pool, pd, pd_dma);
1213
1214 if (rval != QLA_SUCCESS) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001215 DEBUG2_3_11(printk("%s(%ld): failed=%x mb[0]=%x mb[1]=%x.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001216 __func__, vha->host_no, rval, mcp->mb[0], mcp->mb[1]));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001217 } else {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001218 DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001219 }
1220
1221 return rval;
1222}
1223
1224/*
1225 * qla2x00_get_firmware_state
1226 * Get adapter firmware state.
1227 *
1228 * Input:
1229 * ha = adapter block pointer.
1230 * dptr = pointer for firmware state.
1231 * TARGET_QUEUE_LOCK must be released.
1232 * ADAPTER_STATE_LOCK must be released.
1233 *
1234 * Returns:
1235 * qla2x00 local function return status code.
1236 *
1237 * Context:
1238 * Kernel context.
1239 */
1240int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001241qla2x00_get_firmware_state(scsi_qla_host_t *vha, uint16_t *states)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001242{
1243 int rval;
1244 mbx_cmd_t mc;
1245 mbx_cmd_t *mcp = &mc;
1246
1247 DEBUG11(printk("qla2x00_get_firmware_state(%ld): entered.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001248 vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001249
1250 mcp->mb[0] = MBC_GET_FIRMWARE_STATE;
1251 mcp->out_mb = MBX_0;
Harihara Kadayam4d4df192008-04-03 13:13:26 -07001252 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001253 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001254 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001255 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001256
Harihara Kadayam4d4df192008-04-03 13:13:26 -07001257 /* Return firmware states. */
1258 states[0] = mcp->mb[1];
1259 states[1] = mcp->mb[2];
1260 states[2] = mcp->mb[3];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001261
1262 if (rval != QLA_SUCCESS) {
1263 /*EMPTY*/
1264 DEBUG2_3_11(printk("qla2x00_get_firmware_state(%ld): "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001265 "failed=%x.\n", vha->host_no, rval));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001266 } else {
1267 /*EMPTY*/
1268 DEBUG11(printk("qla2x00_get_firmware_state(%ld): done.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001269 vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001270 }
1271
1272 return rval;
1273}
1274
1275/*
1276 * qla2x00_get_port_name
1277 * Issue get port name mailbox command.
1278 * Returned name is in big endian format.
1279 *
1280 * Input:
1281 * ha = adapter block pointer.
1282 * loop_id = loop ID of device.
1283 * name = pointer for name.
1284 * TARGET_QUEUE_LOCK must be released.
1285 * ADAPTER_STATE_LOCK must be released.
1286 *
1287 * Returns:
1288 * qla2x00 local function return status code.
1289 *
1290 * Context:
1291 * Kernel context.
1292 */
1293int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001294qla2x00_get_port_name(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t *name,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001295 uint8_t opt)
1296{
1297 int rval;
1298 mbx_cmd_t mc;
1299 mbx_cmd_t *mcp = &mc;
1300
1301 DEBUG11(printk("qla2x00_get_port_name(%ld): entered.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001302 vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001303
1304 mcp->mb[0] = MBC_GET_PORT_NAME;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001305 mcp->mb[9] = vha->vp_idx;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001306 mcp->out_mb = MBX_9|MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001307 if (HAS_EXTENDED_IDS(vha->hw)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001308 mcp->mb[1] = loop_id;
1309 mcp->mb[10] = opt;
1310 mcp->out_mb |= MBX_10;
1311 } else {
1312 mcp->mb[1] = loop_id << 8 | opt;
1313 }
1314
1315 mcp->in_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001316 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001317 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001318 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001319
1320 if (rval != QLA_SUCCESS) {
1321 /*EMPTY*/
1322 DEBUG2_3_11(printk("qla2x00_get_port_name(%ld): failed=%x.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001323 vha->host_no, rval));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001324 } else {
1325 if (name != NULL) {
1326 /* This function returns name in big endian. */
Richard Lary1196ae02007-03-22 10:53:19 -05001327 name[0] = MSB(mcp->mb[2]);
1328 name[1] = LSB(mcp->mb[2]);
1329 name[2] = MSB(mcp->mb[3]);
1330 name[3] = LSB(mcp->mb[3]);
1331 name[4] = MSB(mcp->mb[6]);
1332 name[5] = LSB(mcp->mb[6]);
1333 name[6] = MSB(mcp->mb[7]);
1334 name[7] = LSB(mcp->mb[7]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001335 }
1336
1337 DEBUG11(printk("qla2x00_get_port_name(%ld): done.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001338 vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001339 }
1340
1341 return rval;
1342}
1343
1344/*
1345 * qla2x00_lip_reset
1346 * Issue LIP reset mailbox command.
1347 *
1348 * Input:
1349 * ha = adapter block pointer.
1350 * TARGET_QUEUE_LOCK must be released.
1351 * ADAPTER_STATE_LOCK must be released.
1352 *
1353 * Returns:
1354 * qla2x00 local function return status code.
1355 *
1356 * Context:
1357 * Kernel context.
1358 */
1359int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001360qla2x00_lip_reset(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001361{
1362 int rval;
1363 mbx_cmd_t mc;
1364 mbx_cmd_t *mcp = &mc;
1365
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001366 DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001367
Andrew Vasquez3a03eb72009-01-05 11:18:11 -08001368 if (IS_QLA81XX(vha->hw)) {
1369 /* Logout across all FCFs. */
1370 mcp->mb[0] = MBC_LIP_FULL_LOGIN;
1371 mcp->mb[1] = BIT_1;
1372 mcp->mb[2] = 0;
1373 mcp->out_mb = MBX_2|MBX_1|MBX_0;
1374 } else if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001375 mcp->mb[0] = MBC_LIP_FULL_LOGIN;
Andrew Vasquez0c8c39a2006-12-13 19:20:30 -08001376 mcp->mb[1] = BIT_6;
1377 mcp->mb[2] = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001378 mcp->mb[3] = vha->hw->loop_reset_delay;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001379 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001380 } else {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001381 mcp->mb[0] = MBC_LIP_RESET;
1382 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001383 if (HAS_EXTENDED_IDS(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001384 mcp->mb[1] = 0x00ff;
1385 mcp->mb[10] = 0;
1386 mcp->out_mb |= MBX_10;
1387 } else {
1388 mcp->mb[1] = 0xff00;
1389 }
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001390 mcp->mb[2] = vha->hw->loop_reset_delay;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001391 mcp->mb[3] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001392 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001393 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001394 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001395 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001396 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001397
1398 if (rval != QLA_SUCCESS) {
1399 /*EMPTY*/
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001400 DEBUG2_3_11(printk("%s(%ld): failed=%x.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001401 __func__, vha->host_no, rval));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001402 } else {
1403 /*EMPTY*/
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001404 DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001405 }
1406
1407 return rval;
1408}
1409
1410/*
1411 * qla2x00_send_sns
1412 * Send SNS command.
1413 *
1414 * Input:
1415 * ha = adapter block pointer.
1416 * sns = pointer for command.
1417 * cmd_size = command size.
1418 * buf_size = response/command size.
1419 * TARGET_QUEUE_LOCK must be released.
1420 * ADAPTER_STATE_LOCK must be released.
1421 *
1422 * Returns:
1423 * qla2x00 local function return status code.
1424 *
1425 * Context:
1426 * Kernel context.
1427 */
1428int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001429qla2x00_send_sns(scsi_qla_host_t *vha, dma_addr_t sns_phys_address,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001430 uint16_t cmd_size, size_t buf_size)
1431{
1432 int rval;
1433 mbx_cmd_t mc;
1434 mbx_cmd_t *mcp = &mc;
1435
1436 DEBUG11(printk("qla2x00_send_sns(%ld): entered.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001437 vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001438
1439 DEBUG11(printk("qla2x00_send_sns: retry cnt=%d ratov=%d total "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001440 "tov=%d.\n", vha->hw->retry_count, vha->hw->login_timeout,
1441 mcp->tov));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001442
1443 mcp->mb[0] = MBC_SEND_SNS_COMMAND;
1444 mcp->mb[1] = cmd_size;
1445 mcp->mb[2] = MSW(sns_phys_address);
1446 mcp->mb[3] = LSW(sns_phys_address);
1447 mcp->mb[6] = MSW(MSD(sns_phys_address));
1448 mcp->mb[7] = LSW(MSD(sns_phys_address));
1449 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
1450 mcp->in_mb = MBX_0|MBX_1;
1451 mcp->buf_size = buf_size;
1452 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001453 mcp->tov = (vha->hw->login_timeout * 2) + (vha->hw->login_timeout / 2);
1454 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001455
1456 if (rval != QLA_SUCCESS) {
1457 /*EMPTY*/
1458 DEBUG(printk("qla2x00_send_sns(%ld): failed=%x mb[0]=%x "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001459 "mb[1]=%x.\n", vha->host_no, rval, mcp->mb[0], mcp->mb[1]));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001460 DEBUG2_3_11(printk("qla2x00_send_sns(%ld): failed=%x mb[0]=%x "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001461 "mb[1]=%x.\n", vha->host_no, rval, mcp->mb[0], mcp->mb[1]));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001462 } else {
1463 /*EMPTY*/
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001464 DEBUG11(printk("qla2x00_send_sns(%ld): done.\n", vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001465 }
1466
1467 return rval;
1468}
1469
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001470int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001471qla24xx_login_fabric(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001472 uint8_t area, uint8_t al_pa, uint16_t *mb, uint8_t opt)
1473{
1474 int rval;
1475
1476 struct logio_entry_24xx *lg;
1477 dma_addr_t lg_dma;
1478 uint32_t iop[2];
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001479 struct qla_hw_data *ha = vha->hw;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001480
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001481 DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001482
1483 lg = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &lg_dma);
1484 if (lg == NULL) {
1485 DEBUG2_3(printk("%s(%ld): failed to allocate Login IOCB.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001486 __func__, vha->host_no));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001487 return QLA_MEMORY_ALLOC_FAILED;
1488 }
1489 memset(lg, 0, sizeof(struct logio_entry_24xx));
1490
1491 lg->entry_type = LOGINOUT_PORT_IOCB_TYPE;
1492 lg->entry_count = 1;
1493 lg->nport_handle = cpu_to_le16(loop_id);
1494 lg->control_flags = __constant_cpu_to_le16(LCF_COMMAND_PLOGI);
1495 if (opt & BIT_0)
1496 lg->control_flags |= __constant_cpu_to_le16(LCF_COND_PLOGI);
Andrew Vasquez8baa51a2006-06-23 16:10:44 -07001497 if (opt & BIT_1)
1498 lg->control_flags |= __constant_cpu_to_le16(LCF_SKIP_PRLI);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001499 lg->port_id[0] = al_pa;
1500 lg->port_id[1] = area;
1501 lg->port_id[2] = domain;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001502 lg->vp_index = vha->vp_idx;
1503 rval = qla2x00_issue_iocb(vha, lg, lg_dma, 0);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001504 if (rval != QLA_SUCCESS) {
1505 DEBUG2_3_11(printk("%s(%ld): failed to issue Login IOCB "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001506 "(%x).\n", __func__, vha->host_no, rval));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001507 } else if (lg->entry_status != 0) {
1508 DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001509 "-- error status (%x).\n", __func__, vha->host_no,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001510 lg->entry_status));
1511 rval = QLA_FUNCTION_FAILED;
1512 } else if (lg->comp_status != __constant_cpu_to_le16(CS_COMPLETE)) {
1513 iop[0] = le32_to_cpu(lg->io_parameter[0]);
1514 iop[1] = le32_to_cpu(lg->io_parameter[1]);
1515
1516 DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB "
1517 "-- completion status (%x) ioparam=%x/%x.\n", __func__,
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001518 vha->host_no, le16_to_cpu(lg->comp_status), iop[0],
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001519 iop[1]));
1520
1521 switch (iop[0]) {
1522 case LSC_SCODE_PORTID_USED:
1523 mb[0] = MBS_PORT_ID_USED;
1524 mb[1] = LSW(iop[1]);
1525 break;
1526 case LSC_SCODE_NPORT_USED:
1527 mb[0] = MBS_LOOP_ID_USED;
1528 break;
1529 case LSC_SCODE_NOLINK:
1530 case LSC_SCODE_NOIOCB:
1531 case LSC_SCODE_NOXCB:
1532 case LSC_SCODE_CMD_FAILED:
1533 case LSC_SCODE_NOFABRIC:
1534 case LSC_SCODE_FW_NOT_READY:
1535 case LSC_SCODE_NOT_LOGGED_IN:
1536 case LSC_SCODE_NOPCB:
1537 case LSC_SCODE_ELS_REJECT:
1538 case LSC_SCODE_CMD_PARAM_ERR:
1539 case LSC_SCODE_NONPORT:
1540 case LSC_SCODE_LOGGED_IN:
1541 case LSC_SCODE_NOFLOGI_ACC:
1542 default:
1543 mb[0] = MBS_COMMAND_ERROR;
1544 break;
1545 }
1546 } else {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001547 DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001548
1549 iop[0] = le32_to_cpu(lg->io_parameter[0]);
1550
1551 mb[0] = MBS_COMMAND_COMPLETE;
1552 mb[1] = 0;
1553 if (iop[0] & BIT_4) {
1554 if (iop[0] & BIT_8)
1555 mb[1] |= BIT_1;
1556 } else
1557 mb[1] = BIT_0;
Andrew Vasquezad3e0ed2005-08-26 19:08:10 -07001558
1559 /* Passback COS information. */
1560 mb[10] = 0;
1561 if (lg->io_parameter[7] || lg->io_parameter[8])
1562 mb[10] |= BIT_0; /* Class 2. */
1563 if (lg->io_parameter[9] || lg->io_parameter[10])
1564 mb[10] |= BIT_1; /* Class 3. */
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001565 }
1566
1567 dma_pool_free(ha->s_dma_pool, lg, lg_dma);
1568
1569 return rval;
1570}
1571
Linus Torvalds1da177e2005-04-16 15:20:36 -07001572/*
1573 * qla2x00_login_fabric
1574 * Issue login fabric port mailbox command.
1575 *
1576 * Input:
1577 * ha = adapter block pointer.
1578 * loop_id = device loop ID.
1579 * domain = device domain.
1580 * area = device area.
1581 * al_pa = device AL_PA.
1582 * status = pointer for return status.
1583 * opt = command options.
1584 * TARGET_QUEUE_LOCK must be released.
1585 * ADAPTER_STATE_LOCK must be released.
1586 *
1587 * Returns:
1588 * qla2x00 local function return status code.
1589 *
1590 * Context:
1591 * Kernel context.
1592 */
1593int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001594qla2x00_login_fabric(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001595 uint8_t area, uint8_t al_pa, uint16_t *mb, uint8_t opt)
1596{
1597 int rval;
1598 mbx_cmd_t mc;
1599 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001600 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001601
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001602 DEBUG11(printk("qla2x00_login_fabric(%ld): entered.\n", vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001603
1604 mcp->mb[0] = MBC_LOGIN_FABRIC_PORT;
1605 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
1606 if (HAS_EXTENDED_IDS(ha)) {
1607 mcp->mb[1] = loop_id;
1608 mcp->mb[10] = opt;
1609 mcp->out_mb |= MBX_10;
1610 } else {
1611 mcp->mb[1] = (loop_id << 8) | opt;
1612 }
1613 mcp->mb[2] = domain;
1614 mcp->mb[3] = area << 8 | al_pa;
1615
1616 mcp->in_mb = MBX_7|MBX_6|MBX_2|MBX_1|MBX_0;
1617 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
1618 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001619 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001620
1621 /* Return mailbox statuses. */
1622 if (mb != NULL) {
1623 mb[0] = mcp->mb[0];
1624 mb[1] = mcp->mb[1];
1625 mb[2] = mcp->mb[2];
1626 mb[6] = mcp->mb[6];
1627 mb[7] = mcp->mb[7];
Andrew Vasquezad3e0ed2005-08-26 19:08:10 -07001628 /* COS retrieved from Get-Port-Database mailbox command. */
1629 mb[10] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001630 }
1631
1632 if (rval != QLA_SUCCESS) {
1633 /* RLU tmp code: need to change main mailbox_command function to
1634 * return ok even when the mailbox completion value is not
1635 * SUCCESS. The caller needs to be responsible to interpret
1636 * the return values of this mailbox command if we're not
1637 * to change too much of the existing code.
1638 */
1639 if (mcp->mb[0] == 0x4001 || mcp->mb[0] == 0x4002 ||
1640 mcp->mb[0] == 0x4003 || mcp->mb[0] == 0x4005 ||
1641 mcp->mb[0] == 0x4006)
1642 rval = QLA_SUCCESS;
1643
1644 /*EMPTY*/
1645 DEBUG2_3_11(printk("qla2x00_login_fabric(%ld): failed=%x "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001646 "mb[0]=%x mb[1]=%x mb[2]=%x.\n", vha->host_no, rval,
Andrew Vasquez744f11fd2006-06-23 16:11:05 -07001647 mcp->mb[0], mcp->mb[1], mcp->mb[2]));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001648 } else {
1649 /*EMPTY*/
1650 DEBUG11(printk("qla2x00_login_fabric(%ld): done.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001651 vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001652 }
1653
1654 return rval;
1655}
1656
1657/*
1658 * qla2x00_login_local_device
1659 * Issue login loop port mailbox command.
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07001660 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07001661 * Input:
1662 * ha = adapter block pointer.
1663 * loop_id = device loop ID.
1664 * opt = command options.
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07001665 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07001666 * Returns:
1667 * Return status code.
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07001668 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07001669 * Context:
1670 * Kernel context.
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07001671 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07001672 */
1673int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001674qla2x00_login_local_device(scsi_qla_host_t *vha, fc_port_t *fcport,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001675 uint16_t *mb_ret, uint8_t opt)
1676{
1677 int rval;
1678 mbx_cmd_t mc;
1679 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001680 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001681
Andrew Vasqueze4289242007-07-19 15:05:56 -07001682 if (IS_FWI2_CAPABLE(ha))
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001683 return qla24xx_login_fabric(vha, fcport->loop_id,
andrew.vasquez@qlogic.com9a52a572006-03-09 14:27:44 -08001684 fcport->d_id.b.domain, fcport->d_id.b.area,
1685 fcport->d_id.b.al_pa, mb_ret, opt);
1686
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001687 DEBUG3(printk("%s(%ld): entered.\n", __func__, vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001688
1689 mcp->mb[0] = MBC_LOGIN_LOOP_PORT;
1690 if (HAS_EXTENDED_IDS(ha))
andrew.vasquez@qlogic.com9a52a572006-03-09 14:27:44 -08001691 mcp->mb[1] = fcport->loop_id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001692 else
andrew.vasquez@qlogic.com9a52a572006-03-09 14:27:44 -08001693 mcp->mb[1] = fcport->loop_id << 8;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001694 mcp->mb[2] = opt;
1695 mcp->out_mb = MBX_2|MBX_1|MBX_0;
1696 mcp->in_mb = MBX_7|MBX_6|MBX_1|MBX_0;
1697 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
1698 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001699 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001700
1701 /* Return mailbox statuses. */
1702 if (mb_ret != NULL) {
1703 mb_ret[0] = mcp->mb[0];
1704 mb_ret[1] = mcp->mb[1];
1705 mb_ret[6] = mcp->mb[6];
1706 mb_ret[7] = mcp->mb[7];
1707 }
1708
1709 if (rval != QLA_SUCCESS) {
1710 /* AV tmp code: need to change main mailbox_command function to
1711 * return ok even when the mailbox completion value is not
1712 * SUCCESS. The caller needs to be responsible to interpret
1713 * the return values of this mailbox command if we're not
1714 * to change too much of the existing code.
1715 */
1716 if (mcp->mb[0] == 0x4005 || mcp->mb[0] == 0x4006)
1717 rval = QLA_SUCCESS;
1718
1719 DEBUG(printk("%s(%ld): failed=%x mb[0]=%x mb[1]=%x "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001720 "mb[6]=%x mb[7]=%x.\n", __func__, vha->host_no, rval,
Andrew Vasquez744f11fd2006-06-23 16:11:05 -07001721 mcp->mb[0], mcp->mb[1], mcp->mb[6], mcp->mb[7]));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001722 DEBUG2_3(printk("%s(%ld): failed=%x mb[0]=%x mb[1]=%x "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001723 "mb[6]=%x mb[7]=%x.\n", __func__, vha->host_no, rval,
Andrew Vasquez744f11fd2006-06-23 16:11:05 -07001724 mcp->mb[0], mcp->mb[1], mcp->mb[6], mcp->mb[7]));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001725 } else {
1726 /*EMPTY*/
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001727 DEBUG3(printk("%s(%ld): done.\n", __func__, vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001728 }
1729
1730 return (rval);
1731}
1732
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001733int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001734qla24xx_fabric_logout(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001735 uint8_t area, uint8_t al_pa)
1736{
1737 int rval;
1738 struct logio_entry_24xx *lg;
1739 dma_addr_t lg_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001740 struct qla_hw_data *ha = vha->hw;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001741
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001742 DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001743
1744 lg = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &lg_dma);
1745 if (lg == NULL) {
1746 DEBUG2_3(printk("%s(%ld): failed to allocate Logout IOCB.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001747 __func__, vha->host_no));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001748 return QLA_MEMORY_ALLOC_FAILED;
1749 }
1750 memset(lg, 0, sizeof(struct logio_entry_24xx));
1751
1752 lg->entry_type = LOGINOUT_PORT_IOCB_TYPE;
1753 lg->entry_count = 1;
1754 lg->nport_handle = cpu_to_le16(loop_id);
1755 lg->control_flags =
Lalit Chandivadeb1372bc2007-01-29 10:22:22 -08001756 __constant_cpu_to_le16(LCF_COMMAND_LOGO|LCF_IMPL_LOGO);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001757 lg->port_id[0] = al_pa;
1758 lg->port_id[1] = area;
1759 lg->port_id[2] = domain;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001760 lg->vp_index = vha->vp_idx;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08001761
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001762 rval = qla2x00_issue_iocb(vha, lg, lg_dma, 0);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001763 if (rval != QLA_SUCCESS) {
1764 DEBUG2_3_11(printk("%s(%ld): failed to issue Logout IOCB "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001765 "(%x).\n", __func__, vha->host_no, rval));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001766 } else if (lg->entry_status != 0) {
1767 DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001768 "-- error status (%x).\n", __func__, vha->host_no,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001769 lg->entry_status));
1770 rval = QLA_FUNCTION_FAILED;
1771 } else if (lg->comp_status != __constant_cpu_to_le16(CS_COMPLETE)) {
Anirban Chakraborty73208df2008-12-09 16:45:39 -08001772 DEBUG2_3_11(printk("%s(%ld %d): failed to complete IOCB "
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001773 "-- completion status (%x) ioparam=%x/%x.\n", __func__,
Anirban Chakraborty73208df2008-12-09 16:45:39 -08001774 vha->host_no, vha->vp_idx, le16_to_cpu(lg->comp_status),
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001775 le32_to_cpu(lg->io_parameter[0]),
Andrew Vasquez744f11fd2006-06-23 16:11:05 -07001776 le32_to_cpu(lg->io_parameter[1])));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001777 } else {
1778 /*EMPTY*/
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001779 DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001780 }
1781
1782 dma_pool_free(ha->s_dma_pool, lg, lg_dma);
1783
1784 return rval;
1785}
1786
Linus Torvalds1da177e2005-04-16 15:20:36 -07001787/*
1788 * qla2x00_fabric_logout
1789 * Issue logout fabric port mailbox command.
1790 *
1791 * Input:
1792 * ha = adapter block pointer.
1793 * loop_id = device loop ID.
1794 * TARGET_QUEUE_LOCK must be released.
1795 * ADAPTER_STATE_LOCK must be released.
1796 *
1797 * Returns:
1798 * qla2x00 local function return status code.
1799 *
1800 * Context:
1801 * Kernel context.
1802 */
1803int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001804qla2x00_fabric_logout(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001805 uint8_t area, uint8_t al_pa)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001806{
1807 int rval;
1808 mbx_cmd_t mc;
1809 mbx_cmd_t *mcp = &mc;
1810
1811 DEBUG11(printk("qla2x00_fabric_logout(%ld): entered.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001812 vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001813
1814 mcp->mb[0] = MBC_LOGOUT_FABRIC_PORT;
1815 mcp->out_mb = MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001816 if (HAS_EXTENDED_IDS(vha->hw)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001817 mcp->mb[1] = loop_id;
1818 mcp->mb[10] = 0;
1819 mcp->out_mb |= MBX_10;
1820 } else {
1821 mcp->mb[1] = loop_id << 8;
1822 }
1823
1824 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001825 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001826 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001827 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001828
1829 if (rval != QLA_SUCCESS) {
1830 /*EMPTY*/
1831 DEBUG2_3_11(printk("qla2x00_fabric_logout(%ld): failed=%x "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001832 "mbx1=%x.\n", vha->host_no, rval, mcp->mb[1]));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001833 } else {
1834 /*EMPTY*/
1835 DEBUG11(printk("qla2x00_fabric_logout(%ld): done.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001836 vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001837 }
1838
1839 return rval;
1840}
1841
1842/*
1843 * qla2x00_full_login_lip
1844 * Issue full login LIP mailbox command.
1845 *
1846 * Input:
1847 * ha = adapter block pointer.
1848 * TARGET_QUEUE_LOCK must be released.
1849 * ADAPTER_STATE_LOCK must be released.
1850 *
1851 * Returns:
1852 * qla2x00 local function return status code.
1853 *
1854 * Context:
1855 * Kernel context.
1856 */
1857int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001858qla2x00_full_login_lip(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001859{
1860 int rval;
1861 mbx_cmd_t mc;
1862 mbx_cmd_t *mcp = &mc;
1863
Andrew Vasquez3a03eb72009-01-05 11:18:11 -08001864 if (IS_QLA81XX(vha->hw))
1865 return QLA_SUCCESS;
1866
Linus Torvalds1da177e2005-04-16 15:20:36 -07001867 DEBUG11(printk("qla2x00_full_login_lip(%ld): entered.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001868 vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001869
1870 mcp->mb[0] = MBC_LIP_FULL_LOGIN;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001871 mcp->mb[1] = IS_FWI2_CAPABLE(vha->hw) ? BIT_3 : 0;
Andrew Vasquez0c8c39a2006-12-13 19:20:30 -08001872 mcp->mb[2] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001873 mcp->mb[3] = 0;
1874 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
1875 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001876 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001877 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001878 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001879
1880 if (rval != QLA_SUCCESS) {
1881 /*EMPTY*/
1882 DEBUG2_3_11(printk("qla2x00_full_login_lip(%ld): failed=%x.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001883 vha->host_no, rval));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001884 } else {
1885 /*EMPTY*/
1886 DEBUG11(printk("qla2x00_full_login_lip(%ld): done.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001887 vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001888 }
1889
1890 return rval;
1891}
1892
1893/*
1894 * qla2x00_get_id_list
1895 *
1896 * Input:
1897 * ha = adapter block pointer.
1898 *
1899 * Returns:
1900 * qla2x00 local function return status code.
1901 *
1902 * Context:
1903 * Kernel context.
1904 */
1905int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001906qla2x00_get_id_list(scsi_qla_host_t *vha, void *id_list, dma_addr_t id_list_dma,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001907 uint16_t *entries)
1908{
1909 int rval;
1910 mbx_cmd_t mc;
1911 mbx_cmd_t *mcp = &mc;
1912
1913 DEBUG11(printk("qla2x00_get_id_list(%ld): entered.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001914 vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001915
1916 if (id_list == NULL)
1917 return QLA_FUNCTION_FAILED;
1918
1919 mcp->mb[0] = MBC_GET_ID_LIST;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001920 mcp->out_mb = MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001921 if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001922 mcp->mb[2] = MSW(id_list_dma);
1923 mcp->mb[3] = LSW(id_list_dma);
1924 mcp->mb[6] = MSW(MSD(id_list_dma));
1925 mcp->mb[7] = LSW(MSD(id_list_dma));
andrew.vasquez@qlogic.com247ec452006-02-07 08:45:40 -08001926 mcp->mb[8] = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001927 mcp->mb[9] = vha->vp_idx;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001928 mcp->out_mb |= MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001929 } else {
1930 mcp->mb[1] = MSW(id_list_dma);
1931 mcp->mb[2] = LSW(id_list_dma);
1932 mcp->mb[3] = MSW(MSD(id_list_dma));
1933 mcp->mb[6] = LSW(MSD(id_list_dma));
1934 mcp->out_mb |= MBX_6|MBX_3|MBX_2|MBX_1;
1935 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001936 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001937 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001938 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001939 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001940
1941 if (rval != QLA_SUCCESS) {
1942 /*EMPTY*/
1943 DEBUG2_3_11(printk("qla2x00_get_id_list(%ld): failed=%x.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001944 vha->host_no, rval));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001945 } else {
1946 *entries = mcp->mb[1];
1947 DEBUG11(printk("qla2x00_get_id_list(%ld): done.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001948 vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001949 }
1950
1951 return rval;
1952}
1953
1954/*
1955 * qla2x00_get_resource_cnts
1956 * Get current firmware resource counts.
1957 *
1958 * Input:
1959 * ha = adapter block pointer.
1960 *
1961 * Returns:
1962 * qla2x00 local function return status code.
1963 *
1964 * Context:
1965 * Kernel context.
1966 */
1967int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001968qla2x00_get_resource_cnts(scsi_qla_host_t *vha, uint16_t *cur_xchg_cnt,
Seokmann Ju4d0ea242007-09-20 14:07:43 -07001969 uint16_t *orig_xchg_cnt, uint16_t *cur_iocb_cnt,
1970 uint16_t *orig_iocb_cnt, uint16_t *max_npiv_vports)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001971{
1972 int rval;
1973 mbx_cmd_t mc;
1974 mbx_cmd_t *mcp = &mc;
1975
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001976 DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001977
1978 mcp->mb[0] = MBC_GET_RESOURCE_COUNTS;
1979 mcp->out_mb = MBX_0;
Seokmann Ju4d0ea242007-09-20 14:07:43 -07001980 mcp->in_mb = MBX_11|MBX_10|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001981 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001982 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001983 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001984
1985 if (rval != QLA_SUCCESS) {
1986 /*EMPTY*/
1987 DEBUG2_3_11(printk("%s(%ld): failed = %x.\n", __func__,
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001988 vha->host_no, mcp->mb[0]));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001989 } else {
1990 DEBUG11(printk("%s(%ld): done. mb1=%x mb2=%x mb3=%x mb6=%x "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001991 "mb7=%x mb10=%x mb11=%x.\n", __func__, vha->host_no,
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07001992 mcp->mb[1], mcp->mb[2], mcp->mb[3], mcp->mb[6], mcp->mb[7],
Seokmann Ju4d0ea242007-09-20 14:07:43 -07001993 mcp->mb[10], mcp->mb[11]));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001994
1995 if (cur_xchg_cnt)
1996 *cur_xchg_cnt = mcp->mb[3];
1997 if (orig_xchg_cnt)
1998 *orig_xchg_cnt = mcp->mb[6];
1999 if (cur_iocb_cnt)
2000 *cur_iocb_cnt = mcp->mb[7];
2001 if (orig_iocb_cnt)
2002 *orig_iocb_cnt = mcp->mb[10];
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002003 if (vha->hw->flags.npiv_supported && max_npiv_vports)
Seokmann Ju4d0ea242007-09-20 14:07:43 -07002004 *max_npiv_vports = mcp->mb[11];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002005 }
2006
2007 return (rval);
2008}
2009
2010#if defined(QL_DEBUG_LEVEL_3)
2011/*
2012 * qla2x00_get_fcal_position_map
2013 * Get FCAL (LILP) position map using mailbox command
2014 *
2015 * Input:
2016 * ha = adapter state pointer.
2017 * pos_map = buffer pointer (can be NULL).
2018 *
2019 * Returns:
2020 * qla2x00 local function return status code.
2021 *
2022 * Context:
2023 * Kernel context.
2024 */
2025int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002026qla2x00_get_fcal_position_map(scsi_qla_host_t *vha, char *pos_map)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002027{
2028 int rval;
2029 mbx_cmd_t mc;
2030 mbx_cmd_t *mcp = &mc;
2031 char *pmap;
2032 dma_addr_t pmap_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002033 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002034
Andrew Vasquez4b892582008-09-11 21:22:48 -07002035 pmap = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &pmap_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002036 if (pmap == NULL) {
2037 DEBUG2_3_11(printk("%s(%ld): **** Mem Alloc Failed ****",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002038 __func__, vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002039 return QLA_MEMORY_ALLOC_FAILED;
2040 }
2041 memset(pmap, 0, FCAL_MAP_SIZE);
2042
2043 mcp->mb[0] = MBC_GET_FC_AL_POSITION_MAP;
2044 mcp->mb[2] = MSW(pmap_dma);
2045 mcp->mb[3] = LSW(pmap_dma);
2046 mcp->mb[6] = MSW(MSD(pmap_dma));
2047 mcp->mb[7] = LSW(MSD(pmap_dma));
2048 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
2049 mcp->in_mb = MBX_1|MBX_0;
2050 mcp->buf_size = FCAL_MAP_SIZE;
2051 mcp->flags = MBX_DMA_IN;
2052 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002053 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002054
2055 if (rval == QLA_SUCCESS) {
2056 DEBUG11(printk("%s(%ld): (mb0=%x/mb1=%x) FC/AL Position Map "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002057 "size (%x)\n", __func__, vha->host_no, mcp->mb[0],
Linus Torvalds1da177e2005-04-16 15:20:36 -07002058 mcp->mb[1], (unsigned)pmap[0]));
2059 DEBUG11(qla2x00_dump_buffer(pmap, pmap[0] + 1));
2060
2061 if (pos_map)
2062 memcpy(pos_map, pmap, FCAL_MAP_SIZE);
2063 }
2064 dma_pool_free(ha->s_dma_pool, pmap, pmap_dma);
2065
2066 if (rval != QLA_SUCCESS) {
2067 DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__,
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002068 vha->host_no, rval));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002069 } else {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002070 DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002071 }
2072
2073 return rval;
2074}
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002075#endif
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002076
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002077/*
2078 * qla2x00_get_link_status
2079 *
2080 * Input:
2081 * ha = adapter block pointer.
2082 * loop_id = device loop ID.
2083 * ret_buf = pointer to link status return buffer.
2084 *
2085 * Returns:
2086 * 0 = success.
2087 * BIT_0 = mem alloc error.
2088 * BIT_1 = mailbox error.
2089 */
2090int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002091qla2x00_get_link_status(scsi_qla_host_t *vha, uint16_t loop_id,
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002092 struct link_statistics *stats, dma_addr_t stats_dma)
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002093{
2094 int rval;
2095 mbx_cmd_t mc;
2096 mbx_cmd_t *mcp = &mc;
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002097 uint32_t *siter, *diter, dwords;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002098 struct qla_hw_data *ha = vha->hw;
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002099
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002100 DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002101
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002102 mcp->mb[0] = MBC_GET_LINK_STATUS;
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002103 mcp->mb[2] = MSW(stats_dma);
2104 mcp->mb[3] = LSW(stats_dma);
2105 mcp->mb[6] = MSW(MSD(stats_dma));
2106 mcp->mb[7] = LSW(MSD(stats_dma));
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002107 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
2108 mcp->in_mb = MBX_0;
Andrew Vasqueze4289242007-07-19 15:05:56 -07002109 if (IS_FWI2_CAPABLE(ha)) {
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002110 mcp->mb[1] = loop_id;
2111 mcp->mb[4] = 0;
2112 mcp->mb[10] = 0;
2113 mcp->out_mb |= MBX_10|MBX_4|MBX_1;
2114 mcp->in_mb |= MBX_1;
2115 } else if (HAS_EXTENDED_IDS(ha)) {
2116 mcp->mb[1] = loop_id;
2117 mcp->mb[10] = 0;
2118 mcp->out_mb |= MBX_10|MBX_1;
2119 } else {
2120 mcp->mb[1] = loop_id << 8;
2121 mcp->out_mb |= MBX_1;
2122 }
Ravi Anandb93480e2008-04-03 13:13:25 -07002123 mcp->tov = MBX_TOV_SECONDS;
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002124 mcp->flags = IOCTL_CMD;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002125 rval = qla2x00_mailbox_command(vha, mcp);
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002126
2127 if (rval == QLA_SUCCESS) {
2128 if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {
2129 DEBUG2_3_11(printk("%s(%ld): cmd failed. mbx0=%x.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002130 __func__, vha->host_no, mcp->mb[0]));
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002131 rval = QLA_FUNCTION_FAILED;
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002132 } else {
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002133 /* Copy over data -- firmware data is LE. */
2134 dwords = offsetof(struct link_statistics, unused1) / 4;
2135 siter = diter = &stats->link_fail_cnt;
2136 while (dwords--)
2137 *diter++ = le32_to_cpu(*siter++);
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002138 }
2139 } else {
2140 /* Failed. */
2141 DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__,
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002142 vha->host_no, rval));
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002143 }
2144
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002145 return rval;
2146}
2147
2148int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002149qla24xx_get_isp_stats(scsi_qla_host_t *vha, struct link_statistics *stats,
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002150 dma_addr_t stats_dma)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002151{
2152 int rval;
2153 mbx_cmd_t mc;
2154 mbx_cmd_t *mcp = &mc;
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002155 uint32_t *siter, *diter, dwords;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002156
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002157 DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002158
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002159 mcp->mb[0] = MBC_GET_LINK_PRIV_STATS;
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002160 mcp->mb[2] = MSW(stats_dma);
2161 mcp->mb[3] = LSW(stats_dma);
2162 mcp->mb[6] = MSW(MSD(stats_dma));
2163 mcp->mb[7] = LSW(MSD(stats_dma));
2164 mcp->mb[8] = sizeof(struct link_statistics) / 4;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002165 mcp->mb[9] = vha->vp_idx;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002166 mcp->mb[10] = 0;
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002167 mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002168 mcp->in_mb = MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002169 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002170 mcp->flags = IOCTL_CMD;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002171 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002172
2173 if (rval == QLA_SUCCESS) {
2174 if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {
2175 DEBUG2_3_11(printk("%s(%ld): cmd failed. mbx0=%x.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002176 __func__, vha->host_no, mcp->mb[0]));
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002177 rval = QLA_FUNCTION_FAILED;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002178 } else {
2179 /* Copy over data -- firmware data is LE. */
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002180 dwords = sizeof(struct link_statistics) / 4;
2181 siter = diter = &stats->link_fail_cnt;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002182 while (dwords--)
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002183 *diter++ = le32_to_cpu(*siter++);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002184 }
2185 } else {
2186 /* Failed. */
2187 DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__,
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002188 vha->host_no, rval));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002189 }
2190
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002191 return rval;
2192}
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002193
2194int
Anirban Chakraborty73208df2008-12-09 16:45:39 -08002195qla24xx_abort_command(scsi_qla_host_t *vha, srb_t *sp, struct req_que *req)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002196{
2197 int rval;
2198 fc_port_t *fcport;
2199 unsigned long flags = 0;
2200
2201 struct abort_entry_24xx *abt;
2202 dma_addr_t abt_dma;
2203 uint32_t handle;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002204 struct qla_hw_data *ha = vha->hw;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002205
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002206 DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002207
2208 fcport = sp->fcport;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002209
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002210 spin_lock_irqsave(&ha->hardware_lock, flags);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002211 for (handle = 1; handle < MAX_OUTSTANDING_COMMANDS; handle++) {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002212 if (req->outstanding_cmds[handle] == sp)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002213 break;
2214 }
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002215 spin_unlock_irqrestore(&ha->hardware_lock, flags);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002216 if (handle == MAX_OUTSTANDING_COMMANDS) {
2217 /* Command not found. */
2218 return QLA_FUNCTION_FAILED;
2219 }
2220
2221 abt = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &abt_dma);
2222 if (abt == NULL) {
2223 DEBUG2_3(printk("%s(%ld): failed to allocate Abort IOCB.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002224 __func__, vha->host_no));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002225 return QLA_MEMORY_ALLOC_FAILED;
2226 }
2227 memset(abt, 0, sizeof(struct abort_entry_24xx));
2228
2229 abt->entry_type = ABORT_IOCB_TYPE;
2230 abt->entry_count = 1;
2231 abt->nport_handle = cpu_to_le16(fcport->loop_id);
2232 abt->handle_to_abort = handle;
2233 abt->port_id[0] = fcport->d_id.b.al_pa;
2234 abt->port_id[1] = fcport->d_id.b.area;
2235 abt->port_id[2] = fcport->d_id.b.domain;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002236 abt->vp_index = fcport->vp_idx;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08002237
2238 abt->req_que_no = cpu_to_le16(req->id);
2239
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002240 rval = qla2x00_issue_iocb(vha, abt, abt_dma, 0);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002241 if (rval != QLA_SUCCESS) {
2242 DEBUG2_3_11(printk("%s(%ld): failed to issue IOCB (%x).\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002243 __func__, vha->host_no, rval));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002244 } else if (abt->entry_status != 0) {
2245 DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002246 "-- error status (%x).\n", __func__, vha->host_no,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002247 abt->entry_status));
2248 rval = QLA_FUNCTION_FAILED;
2249 } else if (abt->nport_handle != __constant_cpu_to_le16(0)) {
2250 DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002251 "-- completion status (%x).\n", __func__, vha->host_no,
Andrew Vasquez744f11fd2006-06-23 16:11:05 -07002252 le16_to_cpu(abt->nport_handle)));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002253 rval = QLA_FUNCTION_FAILED;
2254 } else {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002255 DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002256 }
2257
2258 dma_pool_free(ha->s_dma_pool, abt, abt_dma);
2259
2260 return rval;
2261}
2262
2263struct tsk_mgmt_cmd {
2264 union {
2265 struct tsk_mgmt_entry tsk;
2266 struct sts_entry_24xx sts;
2267 } p;
2268};
2269
Andrew Vasquez523ec772008-04-03 13:13:24 -07002270static int
2271__qla24xx_issue_tmf(char *name, uint32_t type, struct fc_port *fcport,
2272 unsigned int l)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002273{
Andrew Vasquez523ec772008-04-03 13:13:24 -07002274 int rval, rval2;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002275 struct tsk_mgmt_cmd *tsk;
2276 dma_addr_t tsk_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002277 scsi_qla_host_t *vha;
2278 struct qla_hw_data *ha;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08002279 struct req_que *req;
2280 struct rsp_que *rsp;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002281
Anirban Chakraborty749af3d2008-11-14 13:48:12 -08002282 DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->vha->host_no));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002283
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002284 vha = fcport->vha;
2285 ha = vha->hw;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08002286 req = ha->req_q_map[0];
2287 rsp = ha->rsp_q_map[0];
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002288 tsk = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &tsk_dma);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002289 if (tsk == NULL) {
2290 DEBUG2_3(printk("%s(%ld): failed to allocate Task Management "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002291 "IOCB.\n", __func__, vha->host_no));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002292 return QLA_MEMORY_ALLOC_FAILED;
2293 }
2294 memset(tsk, 0, sizeof(struct tsk_mgmt_cmd));
2295
2296 tsk->p.tsk.entry_type = TSK_MGMT_IOCB_TYPE;
2297 tsk->p.tsk.entry_count = 1;
2298 tsk->p.tsk.nport_handle = cpu_to_le16(fcport->loop_id);
Andrew Vasquez00a537b2008-02-28 14:06:11 -08002299 tsk->p.tsk.timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
Andrew Vasquez523ec772008-04-03 13:13:24 -07002300 tsk->p.tsk.control_flags = cpu_to_le32(type);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002301 tsk->p.tsk.port_id[0] = fcport->d_id.b.al_pa;
2302 tsk->p.tsk.port_id[1] = fcport->d_id.b.area;
2303 tsk->p.tsk.port_id[2] = fcport->d_id.b.domain;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002304 tsk->p.tsk.vp_index = fcport->vp_idx;
Andrew Vasquez523ec772008-04-03 13:13:24 -07002305 if (type == TCF_LUN_RESET) {
2306 int_to_scsilun(l, &tsk->p.tsk.lun);
2307 host_to_fcp_swap((uint8_t *)&tsk->p.tsk.lun,
2308 sizeof(tsk->p.tsk.lun));
2309 }
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002310
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002311 rval = qla2x00_issue_iocb(vha, tsk, tsk_dma, 0);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002312 if (rval != QLA_SUCCESS) {
Andrew Vasquez523ec772008-04-03 13:13:24 -07002313 DEBUG2_3_11(printk("%s(%ld): failed to issue %s Reset IOCB "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002314 "(%x).\n", __func__, vha->host_no, name, rval));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002315 } else if (tsk->p.sts.entry_status != 0) {
2316 DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002317 "-- error status (%x).\n", __func__, vha->host_no,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002318 tsk->p.sts.entry_status));
2319 rval = QLA_FUNCTION_FAILED;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002320 } else if (tsk->p.sts.comp_status !=
2321 __constant_cpu_to_le16(CS_COMPLETE)) {
2322 DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB "
2323 "-- completion status (%x).\n", __func__,
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002324 vha->host_no, le16_to_cpu(tsk->p.sts.comp_status)));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002325 rval = QLA_FUNCTION_FAILED;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002326 }
2327
2328 /* Issue marker IOCB. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -08002329 rval2 = qla2x00_marker(vha, req, rsp, fcport->loop_id, l,
Andrew Vasquez523ec772008-04-03 13:13:24 -07002330 type == TCF_LUN_RESET ? MK_SYNC_ID_LUN: MK_SYNC_ID);
2331 if (rval2 != QLA_SUCCESS) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002332 DEBUG2_3_11(printk("%s(%ld): failed to issue Marker IOCB "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002333 "(%x).\n", __func__, vha->host_no, rval2));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002334 } else {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002335 DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002336 }
2337
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002338 dma_pool_free(ha->s_dma_pool, tsk, tsk_dma);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002339
2340 return rval;
2341}
2342
Andrew Vasquez523ec772008-04-03 13:13:24 -07002343int
2344qla24xx_abort_target(struct fc_port *fcport, unsigned int l)
2345{
2346 return __qla24xx_issue_tmf("Target", TCF_TARGET_RESET, fcport, l);
2347}
2348
2349int
2350qla24xx_lun_reset(struct fc_port *fcport, unsigned int l)
2351{
2352 return __qla24xx_issue_tmf("Lun", TCF_LUN_RESET, fcport, l);
2353}
2354
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002355int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002356qla2x00_system_error(scsi_qla_host_t *vha)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002357{
2358 int rval;
2359 mbx_cmd_t mc;
2360 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002361 struct qla_hw_data *ha = vha->hw;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002362
Andrew Vasquez68af0812008-05-12 22:21:13 -07002363 if (!IS_QLA23XX(ha) && !IS_FWI2_CAPABLE(ha))
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002364 return QLA_FUNCTION_FAILED;
2365
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002366 DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002367
2368 mcp->mb[0] = MBC_GEN_SYSTEM_ERROR;
2369 mcp->out_mb = MBX_0;
2370 mcp->in_mb = MBX_0;
2371 mcp->tov = 5;
2372 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002373 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002374
2375 if (rval != QLA_SUCCESS) {
2376 DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__,
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002377 vha->host_no, rval));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002378 } else {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002379 DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002380 }
2381
2382 return rval;
2383}
2384
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002385/**
2386 * qla2x00_set_serdes_params() -
2387 * @ha: HA context
2388 *
2389 * Returns
2390 */
2391int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002392qla2x00_set_serdes_params(scsi_qla_host_t *vha, uint16_t sw_em_1g,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002393 uint16_t sw_em_2g, uint16_t sw_em_4g)
2394{
2395 int rval;
2396 mbx_cmd_t mc;
2397 mbx_cmd_t *mcp = &mc;
2398
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002399 DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002400
2401 mcp->mb[0] = MBC_SERDES_PARAMS;
2402 mcp->mb[1] = BIT_0;
andrew.vasquez@qlogic.comfdbc6832006-03-09 14:27:29 -08002403 mcp->mb[2] = sw_em_1g | BIT_15;
2404 mcp->mb[3] = sw_em_2g | BIT_15;
2405 mcp->mb[4] = sw_em_4g | BIT_15;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002406 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
2407 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002408 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002409 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002410 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002411
2412 if (rval != QLA_SUCCESS) {
2413 /*EMPTY*/
2414 DEBUG2_3_11(printk("%s(%ld): failed=%x (%x).\n", __func__,
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002415 vha->host_no, rval, mcp->mb[0]));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002416 } else {
2417 /*EMPTY*/
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002418 DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002419 }
2420
2421 return rval;
2422}
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002423
2424int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002425qla2x00_stop_firmware(scsi_qla_host_t *vha)
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002426{
2427 int rval;
2428 mbx_cmd_t mc;
2429 mbx_cmd_t *mcp = &mc;
2430
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002431 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002432 return QLA_FUNCTION_FAILED;
2433
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002434 DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002435
2436 mcp->mb[0] = MBC_STOP_FIRMWARE;
2437 mcp->out_mb = MBX_0;
2438 mcp->in_mb = MBX_0;
2439 mcp->tov = 5;
2440 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002441 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002442
2443 if (rval != QLA_SUCCESS) {
2444 DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__,
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002445 vha->host_no, rval));
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002446 } else {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002447 DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002448 }
2449
2450 return rval;
2451}
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002452
2453int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002454qla2x00_enable_eft_trace(scsi_qla_host_t *vha, dma_addr_t eft_dma,
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002455 uint16_t buffers)
2456{
2457 int rval;
2458 mbx_cmd_t mc;
2459 mbx_cmd_t *mcp = &mc;
2460
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002461 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002462 return QLA_FUNCTION_FAILED;
2463
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002464 DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002465
2466 mcp->mb[0] = MBC_TRACE_CONTROL;
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002467 mcp->mb[1] = TC_EFT_ENABLE;
2468 mcp->mb[2] = LSW(eft_dma);
2469 mcp->mb[3] = MSW(eft_dma);
2470 mcp->mb[4] = LSW(MSD(eft_dma));
2471 mcp->mb[5] = MSW(MSD(eft_dma));
2472 mcp->mb[6] = buffers;
2473 mcp->mb[7] = TC_AEN_DISABLE;
2474 mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002475 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002476 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002477 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002478 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002479 if (rval != QLA_SUCCESS) {
2480 DEBUG2_3_11(printk("%s(%ld): failed=%x mb[0]=%x mb[1]=%x.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002481 __func__, vha->host_no, rval, mcp->mb[0], mcp->mb[1]));
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002482 } else {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002483 DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002484 }
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002485
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002486 return rval;
2487}
2488
2489int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002490qla2x00_disable_eft_trace(scsi_qla_host_t *vha)
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002491{
2492 int rval;
2493 mbx_cmd_t mc;
2494 mbx_cmd_t *mcp = &mc;
2495
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002496 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002497 return QLA_FUNCTION_FAILED;
2498
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002499 DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002500
2501 mcp->mb[0] = MBC_TRACE_CONTROL;
2502 mcp->mb[1] = TC_EFT_DISABLE;
2503 mcp->out_mb = MBX_1|MBX_0;
2504 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002505 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002506 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002507 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002508 if (rval != QLA_SUCCESS) {
2509 DEBUG2_3_11(printk("%s(%ld): failed=%x mb[0]=%x mb[1]=%x.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002510 __func__, vha->host_no, rval, mcp->mb[0], mcp->mb[1]));
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002511 } else {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002512 DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002513 }
2514
2515 return rval;
2516}
2517
Andrew Vasquez88729e52006-06-23 16:10:50 -07002518int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002519qla2x00_enable_fce_trace(scsi_qla_host_t *vha, dma_addr_t fce_dma,
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002520 uint16_t buffers, uint16_t *mb, uint32_t *dwords)
2521{
2522 int rval;
2523 mbx_cmd_t mc;
2524 mbx_cmd_t *mcp = &mc;
2525
Andrew Vasquez3a03eb72009-01-05 11:18:11 -08002526 if (!IS_QLA25XX(vha->hw) && !IS_QLA81XX(vha->hw))
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002527 return QLA_FUNCTION_FAILED;
2528
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002529 DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002530
2531 mcp->mb[0] = MBC_TRACE_CONTROL;
2532 mcp->mb[1] = TC_FCE_ENABLE;
2533 mcp->mb[2] = LSW(fce_dma);
2534 mcp->mb[3] = MSW(fce_dma);
2535 mcp->mb[4] = LSW(MSD(fce_dma));
2536 mcp->mb[5] = MSW(MSD(fce_dma));
2537 mcp->mb[6] = buffers;
2538 mcp->mb[7] = TC_AEN_DISABLE;
2539 mcp->mb[8] = 0;
2540 mcp->mb[9] = TC_FCE_DEFAULT_RX_SIZE;
2541 mcp->mb[10] = TC_FCE_DEFAULT_TX_SIZE;
2542 mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|
2543 MBX_1|MBX_0;
2544 mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002545 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002546 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002547 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002548 if (rval != QLA_SUCCESS) {
2549 DEBUG2_3_11(printk("%s(%ld): failed=%x mb[0]=%x mb[1]=%x.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002550 __func__, vha->host_no, rval, mcp->mb[0], mcp->mb[1]));
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002551 } else {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002552 DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002553
2554 if (mb)
2555 memcpy(mb, mcp->mb, 8 * sizeof(*mb));
2556 if (dwords)
Andrew Vasquezfa0926d2008-05-12 22:21:12 -07002557 *dwords = buffers;
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002558 }
2559
2560 return rval;
2561}
2562
2563int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002564qla2x00_disable_fce_trace(scsi_qla_host_t *vha, uint64_t *wr, uint64_t *rd)
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002565{
2566 int rval;
2567 mbx_cmd_t mc;
2568 mbx_cmd_t *mcp = &mc;
2569
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002570 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002571 return QLA_FUNCTION_FAILED;
2572
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002573 DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002574
2575 mcp->mb[0] = MBC_TRACE_CONTROL;
2576 mcp->mb[1] = TC_FCE_DISABLE;
2577 mcp->mb[2] = TC_FCE_DISABLE_TRACE;
2578 mcp->out_mb = MBX_2|MBX_1|MBX_0;
2579 mcp->in_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|
2580 MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002581 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002582 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002583 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002584 if (rval != QLA_SUCCESS) {
2585 DEBUG2_3_11(printk("%s(%ld): failed=%x mb[0]=%x mb[1]=%x.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002586 __func__, vha->host_no, rval, mcp->mb[0], mcp->mb[1]));
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002587 } else {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002588 DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002589
2590 if (wr)
2591 *wr = (uint64_t) mcp->mb[5] << 48 |
2592 (uint64_t) mcp->mb[4] << 32 |
2593 (uint64_t) mcp->mb[3] << 16 |
2594 (uint64_t) mcp->mb[2];
2595 if (rd)
2596 *rd = (uint64_t) mcp->mb[9] << 48 |
2597 (uint64_t) mcp->mb[8] << 32 |
2598 (uint64_t) mcp->mb[7] << 16 |
2599 (uint64_t) mcp->mb[6];
2600 }
2601
2602 return rval;
2603}
2604
2605int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002606qla2x00_read_sfp(scsi_qla_host_t *vha, dma_addr_t sfp_dma, uint16_t addr,
Andrew Vasquez88729e52006-06-23 16:10:50 -07002607 uint16_t off, uint16_t count)
2608{
2609 int rval;
2610 mbx_cmd_t mc;
2611 mbx_cmd_t *mcp = &mc;
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002612
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002613 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasquez88729e52006-06-23 16:10:50 -07002614 return QLA_FUNCTION_FAILED;
2615
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002616 DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
Andrew Vasquez88729e52006-06-23 16:10:50 -07002617
2618 mcp->mb[0] = MBC_READ_SFP;
2619 mcp->mb[1] = addr;
2620 mcp->mb[2] = MSW(sfp_dma);
2621 mcp->mb[3] = LSW(sfp_dma);
2622 mcp->mb[6] = MSW(MSD(sfp_dma));
2623 mcp->mb[7] = LSW(MSD(sfp_dma));
2624 mcp->mb[8] = count;
2625 mcp->mb[9] = off;
2626 mcp->mb[10] = 0;
2627 mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2628 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002629 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez88729e52006-06-23 16:10:50 -07002630 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002631 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez88729e52006-06-23 16:10:50 -07002632
2633 if (rval != QLA_SUCCESS) {
2634 DEBUG2_3_11(printk("%s(%ld): failed=%x (%x).\n", __func__,
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002635 vha->host_no, rval, mcp->mb[0]));
Andrew Vasquez88729e52006-06-23 16:10:50 -07002636 } else {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002637 DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
Andrew Vasquez88729e52006-06-23 16:10:50 -07002638 }
2639
2640 return rval;
2641}
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002642
2643int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002644qla2x00_set_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id,
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002645 uint16_t port_speed, uint16_t *mb)
2646{
2647 int rval;
2648 mbx_cmd_t mc;
2649 mbx_cmd_t *mcp = &mc;
2650
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002651 if (!IS_IIDMA_CAPABLE(vha->hw))
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002652 return QLA_FUNCTION_FAILED;
2653
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002654 DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002655
2656 mcp->mb[0] = MBC_PORT_PARAMS;
2657 mcp->mb[1] = loop_id;
2658 mcp->mb[2] = BIT_0;
2659 mcp->mb[3] = port_speed & (BIT_2|BIT_1|BIT_0);
2660 mcp->mb[4] = mcp->mb[5] = 0;
2661 mcp->out_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
2662 mcp->in_mb = MBX_5|MBX_4|MBX_3|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002663 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002664 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002665 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002666
2667 /* Return mailbox statuses. */
2668 if (mb != NULL) {
2669 mb[0] = mcp->mb[0];
2670 mb[1] = mcp->mb[1];
2671 mb[3] = mcp->mb[3];
2672 mb[4] = mcp->mb[4];
2673 mb[5] = mcp->mb[5];
2674 }
2675
2676 if (rval != QLA_SUCCESS) {
2677 DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__,
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002678 vha->host_no, rval));
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002679 } else {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002680 DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002681 }
2682
2683 return rval;
2684}
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002685
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002686void
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002687qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002688 struct vp_rpt_id_entry_24xx *rptid_entry)
2689{
2690 uint8_t vp_idx;
Seokmann Juc6852c42008-04-24 15:21:29 -07002691 uint16_t stat = le16_to_cpu(rptid_entry->vp_idx);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002692 struct qla_hw_data *ha = vha->hw;
2693 scsi_qla_host_t *vp;
Anirban Chakrabortyee546b62009-03-05 11:07:02 -08002694 scsi_qla_host_t *tvp;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002695
2696 if (rptid_entry->entry_status != 0)
2697 return;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002698
2699 if (rptid_entry->format == 0) {
2700 DEBUG15(printk("%s:format 0 : scsi(%ld) number of VPs setup %d,"
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002701 " number of VPs acquired %d\n", __func__, vha->host_no,
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002702 MSB(rptid_entry->vp_count), LSB(rptid_entry->vp_count)));
2703 DEBUG15(printk("%s primary port id %02x%02x%02x\n", __func__,
2704 rptid_entry->port_id[2], rptid_entry->port_id[1],
2705 rptid_entry->port_id[0]));
2706 } else if (rptid_entry->format == 1) {
Seokmann Juc6852c42008-04-24 15:21:29 -07002707 vp_idx = LSB(stat);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002708 DEBUG15(printk("%s:format 1: scsi(%ld): VP[%d] enabled "
2709 "- status %d - "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002710 "with port id %02x%02x%02x\n", __func__, vha->host_no,
Seokmann Juc6852c42008-04-24 15:21:29 -07002711 vp_idx, MSB(stat),
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002712 rptid_entry->port_id[2], rptid_entry->port_id[1],
2713 rptid_entry->port_id[0]));
2714 if (vp_idx == 0)
2715 return;
2716
Seokmann Juc6852c42008-04-24 15:21:29 -07002717 if (MSB(stat) == 1)
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002718 return;
2719
Anirban Chakrabortyee546b62009-03-05 11:07:02 -08002720 list_for_each_entry_safe(vp, tvp, &ha->vp_list, list)
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002721 if (vp_idx == vp->vp_idx)
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002722 break;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002723 if (!vp)
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002724 return;
2725
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002726 vp->d_id.b.domain = rptid_entry->port_id[2];
2727 vp->d_id.b.area = rptid_entry->port_id[1];
2728 vp->d_id.b.al_pa = rptid_entry->port_id[0];
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002729
2730 /*
2731 * Cannot configure here as we are still sitting on the
2732 * response queue. Handle it in dpc context.
2733 */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002734 set_bit(VP_IDX_ACQUIRED, &vp->vp_flags);
2735 set_bit(VP_DPC_NEEDED, &vha->dpc_flags);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002736
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002737 qla2xxx_wake_dpc(vha);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002738 }
2739}
2740
2741/*
2742 * qla24xx_modify_vp_config
2743 * Change VP configuration for vha
2744 *
2745 * Input:
2746 * vha = adapter block pointer.
2747 *
2748 * Returns:
2749 * qla2xxx local function return status code.
2750 *
2751 * Context:
2752 * Kernel context.
2753 */
2754int
2755qla24xx_modify_vp_config(scsi_qla_host_t *vha)
2756{
2757 int rval;
2758 struct vp_config_entry_24xx *vpmod;
2759 dma_addr_t vpmod_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002760 struct qla_hw_data *ha = vha->hw;
2761 struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002762
2763 /* This can be called by the parent */
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002764
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002765 vpmod = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &vpmod_dma);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002766 if (!vpmod) {
2767 DEBUG2_3(printk("%s(%ld): failed to allocate Modify VP "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002768 "IOCB.\n", __func__, vha->host_no));
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002769 return QLA_MEMORY_ALLOC_FAILED;
2770 }
2771
2772 memset(vpmod, 0, sizeof(struct vp_config_entry_24xx));
2773 vpmod->entry_type = VP_CONFIG_IOCB_TYPE;
2774 vpmod->entry_count = 1;
2775 vpmod->command = VCT_COMMAND_MOD_ENABLE_VPS;
2776 vpmod->vp_count = 1;
2777 vpmod->vp_index1 = vha->vp_idx;
2778 vpmod->options_idx1 = BIT_3|BIT_4|BIT_5;
2779 memcpy(vpmod->node_name_idx1, vha->node_name, WWN_SIZE);
2780 memcpy(vpmod->port_name_idx1, vha->port_name, WWN_SIZE);
2781 vpmod->entry_count = 1;
2782
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002783 rval = qla2x00_issue_iocb(base_vha, vpmod, vpmod_dma, 0);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002784 if (rval != QLA_SUCCESS) {
2785 DEBUG2_3_11(printk("%s(%ld): failed to issue VP config IOCB"
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002786 "(%x).\n", __func__, base_vha->host_no, rval));
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002787 } else if (vpmod->comp_status != 0) {
2788 DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002789 "-- error status (%x).\n", __func__, base_vha->host_no,
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002790 vpmod->comp_status));
2791 rval = QLA_FUNCTION_FAILED;
2792 } else if (vpmod->comp_status != __constant_cpu_to_le16(CS_COMPLETE)) {
2793 DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002794 "-- completion status (%x).\n", __func__, base_vha->host_no,
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002795 le16_to_cpu(vpmod->comp_status)));
2796 rval = QLA_FUNCTION_FAILED;
2797 } else {
2798 /* EMPTY */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002799 DEBUG11(printk("%s(%ld): done.\n", __func__,
2800 base_vha->host_no));
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002801 fc_vport_set_state(vha->fc_vport, FC_VPORT_INITIALIZING);
2802 }
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002803 dma_pool_free(ha->s_dma_pool, vpmod, vpmod_dma);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002804
2805 return rval;
2806}
2807
2808/*
2809 * qla24xx_control_vp
2810 * Enable a virtual port for given host
2811 *
2812 * Input:
2813 * ha = adapter block pointer.
2814 * vhba = virtual adapter (unused)
2815 * index = index number for enabled VP
2816 *
2817 * Returns:
2818 * qla2xxx local function return status code.
2819 *
2820 * Context:
2821 * Kernel context.
2822 */
2823int
2824qla24xx_control_vp(scsi_qla_host_t *vha, int cmd)
2825{
2826 int rval;
2827 int map, pos;
2828 struct vp_ctrl_entry_24xx *vce;
2829 dma_addr_t vce_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002830 struct qla_hw_data *ha = vha->hw;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002831 int vp_index = vha->vp_idx;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002832 struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002833
2834 DEBUG11(printk("%s(%ld): entered. Enabling index %d\n", __func__,
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002835 vha->host_no, vp_index));
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002836
Andrew Vasquezeb66dc62007-11-12 10:30:58 -08002837 if (vp_index == 0 || vp_index >= ha->max_npiv_vports)
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002838 return QLA_PARAMETER_ERROR;
2839
2840 vce = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &vce_dma);
2841 if (!vce) {
2842 DEBUG2_3(printk("%s(%ld): "
2843 "failed to allocate VP Control IOCB.\n", __func__,
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002844 base_vha->host_no));
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002845 return QLA_MEMORY_ALLOC_FAILED;
2846 }
2847 memset(vce, 0, sizeof(struct vp_ctrl_entry_24xx));
2848
2849 vce->entry_type = VP_CTRL_IOCB_TYPE;
2850 vce->entry_count = 1;
2851 vce->command = cpu_to_le16(cmd);
2852 vce->vp_count = __constant_cpu_to_le16(1);
2853
2854 /* index map in firmware starts with 1; decrement index
2855 * this is ok as we never use index 0
2856 */
2857 map = (vp_index - 1) / 8;
2858 pos = (vp_index - 1) & 7;
matthias@kaehlcke.net6c2f5272008-05-12 22:21:11 -07002859 mutex_lock(&ha->vport_lock);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002860 vce->vp_idx_map[map] |= 1 << pos;
matthias@kaehlcke.net6c2f5272008-05-12 22:21:11 -07002861 mutex_unlock(&ha->vport_lock);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002862
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002863 rval = qla2x00_issue_iocb(base_vha, vce, vce_dma, 0);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002864 if (rval != QLA_SUCCESS) {
2865 DEBUG2_3_11(printk("%s(%ld): failed to issue VP control IOCB"
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002866 "(%x).\n", __func__, base_vha->host_no, rval));
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002867 printk("%s(%ld): failed to issue VP control IOCB"
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002868 "(%x).\n", __func__, base_vha->host_no, rval);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002869 } else if (vce->entry_status != 0) {
2870 DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002871 "-- error status (%x).\n", __func__, base_vha->host_no,
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002872 vce->entry_status));
2873 printk("%s(%ld): failed to complete IOCB "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002874 "-- error status (%x).\n", __func__, base_vha->host_no,
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002875 vce->entry_status);
2876 rval = QLA_FUNCTION_FAILED;
2877 } else if (vce->comp_status != __constant_cpu_to_le16(CS_COMPLETE)) {
2878 DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002879 "-- completion status (%x).\n", __func__, base_vha->host_no,
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002880 le16_to_cpu(vce->comp_status)));
2881 printk("%s(%ld): failed to complete IOCB "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002882 "-- completion status (%x).\n", __func__, base_vha->host_no,
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002883 le16_to_cpu(vce->comp_status));
2884 rval = QLA_FUNCTION_FAILED;
2885 } else {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002886 DEBUG2(printk("%s(%ld): done.\n", __func__, base_vha->host_no));
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002887 }
2888
2889 dma_pool_free(ha->s_dma_pool, vce, vce_dma);
2890
2891 return rval;
2892}
2893
2894/*
2895 * qla2x00_send_change_request
2896 * Receive or disable RSCN request from fabric controller
2897 *
2898 * Input:
2899 * ha = adapter block pointer
2900 * format = registration format:
2901 * 0 - Reserved
2902 * 1 - Fabric detected registration
2903 * 2 - N_port detected registration
2904 * 3 - Full registration
2905 * FF - clear registration
2906 * vp_idx = Virtual port index
2907 *
2908 * Returns:
2909 * qla2x00 local function return status code.
2910 *
2911 * Context:
2912 * Kernel Context
2913 */
2914
2915int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002916qla2x00_send_change_request(scsi_qla_host_t *vha, uint16_t format,
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002917 uint16_t vp_idx)
2918{
2919 int rval;
2920 mbx_cmd_t mc;
2921 mbx_cmd_t *mcp = &mc;
2922
2923 /*
2924 * This command is implicitly executed by firmware during login for the
2925 * physical hosts
2926 */
2927 if (vp_idx == 0)
2928 return QLA_FUNCTION_FAILED;
2929
2930 mcp->mb[0] = MBC_SEND_CHANGE_REQUEST;
2931 mcp->mb[1] = format;
2932 mcp->mb[9] = vp_idx;
2933 mcp->out_mb = MBX_9|MBX_1|MBX_0;
2934 mcp->in_mb = MBX_0|MBX_1;
2935 mcp->tov = MBX_TOV_SECONDS;
2936 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002937 rval = qla2x00_mailbox_command(vha, mcp);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002938
2939 if (rval == QLA_SUCCESS) {
2940 if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {
2941 rval = BIT_1;
2942 }
2943 } else
2944 rval = BIT_1;
2945
2946 return rval;
2947}
Andrew Vasquez338c9162007-09-20 14:07:33 -07002948
2949int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002950qla2x00_dump_ram(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t addr,
Andrew Vasquez338c9162007-09-20 14:07:33 -07002951 uint32_t size)
2952{
2953 int rval;
2954 mbx_cmd_t mc;
2955 mbx_cmd_t *mcp = &mc;
2956
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002957 DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
Andrew Vasquez338c9162007-09-20 14:07:33 -07002958
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002959 if (MSW(addr) || IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez338c9162007-09-20 14:07:33 -07002960 mcp->mb[0] = MBC_DUMP_RISC_RAM_EXTENDED;
2961 mcp->mb[8] = MSW(addr);
2962 mcp->out_mb = MBX_8|MBX_0;
2963 } else {
2964 mcp->mb[0] = MBC_DUMP_RISC_RAM;
2965 mcp->out_mb = MBX_0;
2966 }
2967 mcp->mb[1] = LSW(addr);
2968 mcp->mb[2] = MSW(req_dma);
2969 mcp->mb[3] = LSW(req_dma);
2970 mcp->mb[6] = MSW(MSD(req_dma));
2971 mcp->mb[7] = LSW(MSD(req_dma));
2972 mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_1;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002973 if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez338c9162007-09-20 14:07:33 -07002974 mcp->mb[4] = MSW(size);
2975 mcp->mb[5] = LSW(size);
2976 mcp->out_mb |= MBX_5|MBX_4;
2977 } else {
2978 mcp->mb[4] = LSW(size);
2979 mcp->out_mb |= MBX_4;
2980 }
2981
2982 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002983 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez338c9162007-09-20 14:07:33 -07002984 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002985 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez338c9162007-09-20 14:07:33 -07002986
2987 if (rval != QLA_SUCCESS) {
2988 DEBUG2_3_11(printk("%s(%ld): failed=%x mb[0]=%x.\n", __func__,
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002989 vha->host_no, rval, mcp->mb[0]));
Andrew Vasquez338c9162007-09-20 14:07:33 -07002990 } else {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002991 DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
Andrew Vasquez338c9162007-09-20 14:07:33 -07002992 }
2993
2994 return rval;
2995}
Harihara Kadayam4d4df192008-04-03 13:13:26 -07002996
2997/* 84XX Support **************************************************************/
2998
2999struct cs84xx_mgmt_cmd {
3000 union {
3001 struct verify_chip_entry_84xx req;
3002 struct verify_chip_rsp_84xx rsp;
3003 } p;
3004};
3005
3006int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003007qla84xx_verify_chip(struct scsi_qla_host *vha, uint16_t *status)
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003008{
3009 int rval, retry;
3010 struct cs84xx_mgmt_cmd *mn;
3011 dma_addr_t mn_dma;
3012 uint16_t options;
3013 unsigned long flags;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003014 struct qla_hw_data *ha = vha->hw;
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003015
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003016 DEBUG16(printk("%s(%ld): entered.\n", __func__, vha->host_no));
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003017
3018 mn = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &mn_dma);
3019 if (mn == NULL) {
3020 DEBUG2_3(printk("%s(%ld): failed to allocate Verify ISP84XX "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003021 "IOCB.\n", __func__, vha->host_no));
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003022 return QLA_MEMORY_ALLOC_FAILED;
3023 }
3024
3025 /* Force Update? */
3026 options = ha->cs84xx->fw_update ? VCO_FORCE_UPDATE : 0;
3027 /* Diagnostic firmware? */
3028 /* options |= MENLO_DIAG_FW; */
3029 /* We update the firmware with only one data sequence. */
3030 options |= VCO_END_OF_DATA;
3031
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003032 do {
Andrew Vasquezc1ec1f12008-04-24 15:21:24 -07003033 retry = 0;
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003034 memset(mn, 0, sizeof(*mn));
3035 mn->p.req.entry_type = VERIFY_CHIP_IOCB_TYPE;
3036 mn->p.req.entry_count = 1;
3037 mn->p.req.options = cpu_to_le16(options);
3038
3039 DEBUG16(printk("%s(%ld): Dump of Verify Request.\n", __func__,
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003040 vha->host_no));
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003041 DEBUG16(qla2x00_dump_buffer((uint8_t *)mn,
3042 sizeof(*mn)));
3043
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003044 rval = qla2x00_issue_iocb_timeout(vha, mn, mn_dma, 0, 120);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003045 if (rval != QLA_SUCCESS) {
3046 DEBUG2_16(printk("%s(%ld): failed to issue Verify "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003047 "IOCB (%x).\n", __func__, vha->host_no, rval));
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003048 goto verify_done;
3049 }
3050
3051 DEBUG16(printk("%s(%ld): Dump of Verify Response.\n", __func__,
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003052 vha->host_no));
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003053 DEBUG16(qla2x00_dump_buffer((uint8_t *)mn,
3054 sizeof(*mn)));
3055
3056 status[0] = le16_to_cpu(mn->p.rsp.comp_status);
3057 status[1] = status[0] == CS_VCS_CHIP_FAILURE ?
3058 le16_to_cpu(mn->p.rsp.failure_code) : 0;
3059 DEBUG2_16(printk("%s(%ld): cs=%x fc=%x\n", __func__,
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003060 vha->host_no, status[0], status[1]));
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003061
3062 if (status[0] != CS_COMPLETE) {
3063 rval = QLA_FUNCTION_FAILED;
3064 if (!(options & VCO_DONT_UPDATE_FW)) {
3065 DEBUG2_16(printk("%s(%ld): Firmware update "
3066 "failed. Retrying without update "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003067 "firmware.\n", __func__, vha->host_no));
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003068 options |= VCO_DONT_UPDATE_FW;
3069 options &= ~VCO_FORCE_UPDATE;
3070 retry = 1;
3071 }
3072 } else {
3073 DEBUG2_16(printk("%s(%ld): firmware updated to %x.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003074 __func__, vha->host_no,
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003075 le32_to_cpu(mn->p.rsp.fw_ver)));
3076
3077 /* NOTE: we only update OP firmware. */
3078 spin_lock_irqsave(&ha->cs84xx->access_lock, flags);
3079 ha->cs84xx->op_fw_version =
3080 le32_to_cpu(mn->p.rsp.fw_ver);
3081 spin_unlock_irqrestore(&ha->cs84xx->access_lock,
3082 flags);
3083 }
3084 } while (retry);
3085
3086verify_done:
3087 dma_pool_free(ha->s_dma_pool, mn, mn_dma);
3088
3089 if (rval != QLA_SUCCESS) {
3090 DEBUG2_16(printk("%s(%ld): failed=%x.\n", __func__,
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003091 vha->host_no, rval));
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003092 } else {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003093 DEBUG16(printk("%s(%ld): done.\n", __func__, vha->host_no));
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003094 }
3095
3096 return rval;
3097}
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003098
3099int
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003100qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req)
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003101{
3102 int rval;
3103 unsigned long flags;
3104 mbx_cmd_t mc;
3105 mbx_cmd_t *mcp = &mc;
3106 struct device_reg_25xxmq __iomem *reg;
3107 struct qla_hw_data *ha = vha->hw;
3108
3109 mcp->mb[0] = MBC_INITIALIZE_MULTIQ;
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003110 mcp->mb[1] = req->options;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003111 mcp->mb[2] = MSW(LSD(req->dma));
3112 mcp->mb[3] = LSW(LSD(req->dma));
3113 mcp->mb[6] = MSW(MSD(req->dma));
3114 mcp->mb[7] = LSW(MSD(req->dma));
3115 mcp->mb[5] = req->length;
3116 if (req->rsp)
3117 mcp->mb[10] = req->rsp->id;
3118 mcp->mb[12] = req->qos;
3119 mcp->mb[11] = req->vp_idx;
3120 mcp->mb[13] = req->rid;
3121
3122 reg = (struct device_reg_25xxmq *)((void *)(ha->mqiobase) +
3123 QLA_QUE_PAGE * req->id);
3124
3125 mcp->mb[4] = req->id;
3126 /* que in ptr index */
3127 mcp->mb[8] = 0;
3128 /* que out ptr index */
3129 mcp->mb[9] = 0;
3130 mcp->out_mb = MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8|MBX_7|
3131 MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3132 mcp->in_mb = MBX_0;
3133 mcp->flags = MBX_DMA_OUT;
3134 mcp->tov = 60;
3135
3136 spin_lock_irqsave(&ha->hardware_lock, flags);
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003137 if (!(req->options & BIT_0)) {
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003138 WRT_REG_DWORD(&reg->req_q_in, 0);
3139 WRT_REG_DWORD(&reg->req_q_out, 0);
3140 }
3141 spin_unlock_irqrestore(&ha->hardware_lock, flags);
3142
Anirban Chakraborty17d98632008-12-18 10:06:15 -08003143 rval = qla2x00_mailbox_command(vha, mcp);
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003144 if (rval != QLA_SUCCESS)
3145 DEBUG2_3_11(printk(KERN_WARNING "%s(%ld): failed=%x mb0=%x.\n",
3146 __func__, vha->host_no, rval, mcp->mb[0]));
3147 return rval;
3148}
3149
3150int
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003151qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp)
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003152{
3153 int rval;
3154 unsigned long flags;
3155 mbx_cmd_t mc;
3156 mbx_cmd_t *mcp = &mc;
3157 struct device_reg_25xxmq __iomem *reg;
3158 struct qla_hw_data *ha = vha->hw;
3159
3160 mcp->mb[0] = MBC_INITIALIZE_MULTIQ;
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003161 mcp->mb[1] = rsp->options;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003162 mcp->mb[2] = MSW(LSD(rsp->dma));
3163 mcp->mb[3] = LSW(LSD(rsp->dma));
3164 mcp->mb[6] = MSW(MSD(rsp->dma));
3165 mcp->mb[7] = LSW(MSD(rsp->dma));
3166 mcp->mb[5] = rsp->length;
3167 mcp->mb[11] = rsp->vp_idx;
Andrew Vasquez444786d2009-01-05 11:18:10 -08003168 mcp->mb[14] = rsp->msix->entry;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003169 mcp->mb[13] = rsp->rid;
3170
3171 reg = (struct device_reg_25xxmq *)((void *)(ha->mqiobase) +
3172 QLA_QUE_PAGE * rsp->id);
3173
3174 mcp->mb[4] = rsp->id;
3175 /* que in ptr index */
3176 mcp->mb[8] = 0;
3177 /* que out ptr index */
3178 mcp->mb[9] = 0;
3179 mcp->out_mb = MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8|MBX_7
3180 |MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3181 mcp->in_mb = MBX_0;
3182 mcp->flags = MBX_DMA_OUT;
3183 mcp->tov = 60;
3184
3185 spin_lock_irqsave(&ha->hardware_lock, flags);
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003186 if (!(rsp->options & BIT_0)) {
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003187 WRT_REG_DWORD(&reg->rsp_q_out, 0);
3188 WRT_REG_DWORD(&reg->rsp_q_in, 0);
3189 }
3190
3191 spin_unlock_irqrestore(&ha->hardware_lock, flags);
3192
Anirban Chakraborty17d98632008-12-18 10:06:15 -08003193 rval = qla2x00_mailbox_command(vha, mcp);
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003194 if (rval != QLA_SUCCESS)
3195 DEBUG2_3_11(printk(KERN_WARNING "%s(%ld): failed=%x "
3196 "mb0=%x.\n", __func__,
3197 vha->host_no, rval, mcp->mb[0]));
3198 return rval;
3199}
3200
Andrew Vasquez8a659572009-02-08 20:50:12 -08003201int
3202qla81xx_idc_ack(scsi_qla_host_t *vha, uint16_t *mb)
3203{
3204 int rval;
3205 mbx_cmd_t mc;
3206 mbx_cmd_t *mcp = &mc;
3207
3208 DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
3209
3210 mcp->mb[0] = MBC_IDC_ACK;
3211 memcpy(&mcp->mb[1], mb, QLA_IDC_ACK_REGS * sizeof(uint16_t));
3212 mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3213 mcp->in_mb = MBX_0;
3214 mcp->tov = MBX_TOV_SECONDS;
3215 mcp->flags = 0;
3216 rval = qla2x00_mailbox_command(vha, mcp);
3217
3218 if (rval != QLA_SUCCESS) {
3219 DEBUG2_3_11(printk("%s(%ld): failed=%x (%x).\n", __func__,
3220 vha->host_no, rval, mcp->mb[0]));
3221 } else {
3222 DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
3223 }
3224
3225 return rval;
3226}
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003227
3228int
3229qla81xx_fac_get_sector_size(scsi_qla_host_t *vha, uint32_t *sector_size)
3230{
3231 int rval;
3232 mbx_cmd_t mc;
3233 mbx_cmd_t *mcp = &mc;
3234
3235 if (!IS_QLA81XX(vha->hw))
3236 return QLA_FUNCTION_FAILED;
3237
3238 DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
3239
3240 mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
3241 mcp->mb[1] = FAC_OPT_CMD_GET_SECTOR_SIZE;
3242 mcp->out_mb = MBX_1|MBX_0;
3243 mcp->in_mb = MBX_1|MBX_0;
3244 mcp->tov = MBX_TOV_SECONDS;
3245 mcp->flags = 0;
3246 rval = qla2x00_mailbox_command(vha, mcp);
3247
3248 if (rval != QLA_SUCCESS) {
3249 DEBUG2_3_11(printk("%s(%ld): failed=%x mb[0]=%x mb[1]=%x.\n",
3250 __func__, vha->host_no, rval, mcp->mb[0], mcp->mb[1]));
3251 } else {
3252 DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
3253 *sector_size = mcp->mb[1];
3254 }
3255
3256 return rval;
3257}
3258
3259int
3260qla81xx_fac_do_write_enable(scsi_qla_host_t *vha, int enable)
3261{
3262 int rval;
3263 mbx_cmd_t mc;
3264 mbx_cmd_t *mcp = &mc;
3265
3266 if (!IS_QLA81XX(vha->hw))
3267 return QLA_FUNCTION_FAILED;
3268
3269 DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
3270
3271 mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
3272 mcp->mb[1] = enable ? FAC_OPT_CMD_WRITE_ENABLE :
3273 FAC_OPT_CMD_WRITE_PROTECT;
3274 mcp->out_mb = MBX_1|MBX_0;
3275 mcp->in_mb = MBX_1|MBX_0;
3276 mcp->tov = MBX_TOV_SECONDS;
3277 mcp->flags = 0;
3278 rval = qla2x00_mailbox_command(vha, mcp);
3279
3280 if (rval != QLA_SUCCESS) {
3281 DEBUG2_3_11(printk("%s(%ld): failed=%x mb[0]=%x mb[1]=%x.\n",
3282 __func__, vha->host_no, rval, mcp->mb[0], mcp->mb[1]));
3283 } else {
3284 DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
3285 }
3286
3287 return rval;
3288}
3289
3290int
3291qla81xx_fac_erase_sector(scsi_qla_host_t *vha, uint32_t start, uint32_t finish)
3292{
3293 int rval;
3294 mbx_cmd_t mc;
3295 mbx_cmd_t *mcp = &mc;
3296
3297 if (!IS_QLA81XX(vha->hw))
3298 return QLA_FUNCTION_FAILED;
3299
3300 DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
3301
3302 mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
3303 mcp->mb[1] = FAC_OPT_CMD_ERASE_SECTOR;
3304 mcp->mb[2] = LSW(start);
3305 mcp->mb[3] = MSW(start);
3306 mcp->mb[4] = LSW(finish);
3307 mcp->mb[5] = MSW(finish);
3308 mcp->out_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3309 mcp->in_mb = MBX_2|MBX_1|MBX_0;
3310 mcp->tov = MBX_TOV_SECONDS;
3311 mcp->flags = 0;
3312 rval = qla2x00_mailbox_command(vha, mcp);
3313
3314 if (rval != QLA_SUCCESS) {
3315 DEBUG2_3_11(printk("%s(%ld): failed=%x mb[0]=%x mb[1]=%x "
3316 "mb[2]=%x.\n", __func__, vha->host_no, rval, mcp->mb[0],
3317 mcp->mb[1], mcp->mb[2]));
3318 } else {
3319 DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
3320 }
3321
3322 return rval;
3323}
Lalit Chandivade6e181be2009-03-26 08:49:17 -07003324
3325int
3326qla81xx_restart_mpi_firmware(scsi_qla_host_t *vha)
3327{
3328 int rval = 0;
3329 mbx_cmd_t mc;
3330 mbx_cmd_t *mcp = &mc;
3331
3332 DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
3333
3334 mcp->mb[0] = MBC_RESTART_MPI_FW;
3335 mcp->out_mb = MBX_0;
3336 mcp->in_mb = MBX_0|MBX_1;
3337 mcp->tov = MBX_TOV_SECONDS;
3338 mcp->flags = 0;
3339 rval = qla2x00_mailbox_command(vha, mcp);
3340
3341 if (rval != QLA_SUCCESS) {
3342 DEBUG2_3_11(printk("%s(%ld): failed=%x mb[0]=0x%x mb[1]=0x%x.\n",
3343 __func__, vha->host_no, rval, mcp->mb[0], mcp->mb[1]));
3344 } else {
3345 DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
3346 }
3347
3348 return rval;
3349}
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003350
3351int
3352qla2x00_read_edc(scsi_qla_host_t *vha, uint16_t dev, uint16_t adr,
3353 dma_addr_t sfp_dma, uint8_t *sfp, uint16_t len, uint16_t opt)
3354{
3355 int rval;
3356 mbx_cmd_t mc;
3357 mbx_cmd_t *mcp = &mc;
3358
3359 DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
3360
3361 mcp->mb[0] = MBC_READ_SFP;
3362 mcp->mb[1] = dev;
3363 mcp->mb[2] = MSW(sfp_dma);
3364 mcp->mb[3] = LSW(sfp_dma);
3365 mcp->mb[6] = MSW(MSD(sfp_dma));
3366 mcp->mb[7] = LSW(MSD(sfp_dma));
3367 mcp->mb[8] = len;
3368 mcp->mb[9] = adr;
3369 mcp->mb[10] = opt;
3370 mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
3371 mcp->in_mb = MBX_0;
3372 mcp->tov = MBX_TOV_SECONDS;
3373 mcp->flags = 0;
3374 rval = qla2x00_mailbox_command(vha, mcp);
3375
3376 if (opt & BIT_0)
3377 if (sfp)
3378 *sfp = mcp->mb[8];
3379
3380 if (rval != QLA_SUCCESS) {
3381 DEBUG2_3_11(printk("%s(%ld): failed=%x (%x).\n", __func__,
3382 vha->host_no, rval, mcp->mb[0]));
3383 } else {
3384 DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no));
3385 }
3386
3387 return rval;
3388}
3389
3390int
3391qla2x00_write_edc(scsi_qla_host_t *vha, uint16_t dev, uint16_t adr,
3392 dma_addr_t sfp_dma, uint8_t *sfp, uint16_t len, uint16_t opt)
3393{
3394 int rval;
3395 mbx_cmd_t mc;
3396 mbx_cmd_t *mcp = &mc;
3397
3398 DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
3399
3400 if (opt & BIT_0)
3401 if (sfp)
3402 len = *sfp;
3403
3404 mcp->mb[0] = MBC_WRITE_SFP;
3405 mcp->mb[1] = dev;
3406 mcp->mb[2] = MSW(sfp_dma);
3407 mcp->mb[3] = LSW(sfp_dma);
3408 mcp->mb[6] = MSW(MSD(sfp_dma));
3409 mcp->mb[7] = LSW(MSD(sfp_dma));
3410 mcp->mb[8] = len;
3411 mcp->mb[9] = adr;
3412 mcp->mb[10] = opt;
3413 mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
3414 mcp->in_mb = MBX_0;
3415 mcp->tov = MBX_TOV_SECONDS;
3416 mcp->flags = 0;
3417 rval = qla2x00_mailbox_command(vha, mcp);
3418
3419 if (rval != QLA_SUCCESS) {
3420 DEBUG2_3_11(printk("%s(%ld): failed=%x (%x).\n", __func__,
3421 vha->host_no, rval, mcp->mb[0]));
3422 } else {
3423 DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
3424 }
3425
3426 return rval;
3427}