blob: b380c6fdbe401bc03d7936b6357af39b5765647a [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
1200 /* Check for device require authentication. */
1201 pd->common_features & BIT_5 ? (fcport->flags |= FCF_AUTH_REQ) :
1202 (fcport->flags &= ~FCF_AUTH_REQ);
1203
1204 /* If not target must be initiator or unknown type. */
1205 if ((pd->prli_svc_param_word_3[0] & BIT_4) == 0)
1206 fcport->port_type = FCT_INITIATOR;
1207 else
1208 fcport->port_type = FCT_TARGET;
Andrew Vasquezad3e0ed2005-08-26 19:08:10 -07001209
1210 /* Passback COS information. */
1211 fcport->supported_classes = (pd->options & BIT_4) ?
1212 FC_COS_CLASS2: FC_COS_CLASS3;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001213 }
1214
Linus Torvalds1da177e2005-04-16 15:20:36 -07001215gpd_error_out:
1216 dma_pool_free(ha->s_dma_pool, pd, pd_dma);
1217
1218 if (rval != QLA_SUCCESS) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001219 DEBUG2_3_11(printk("%s(%ld): failed=%x mb[0]=%x mb[1]=%x.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001220 __func__, vha->host_no, rval, mcp->mb[0], mcp->mb[1]));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001221 } else {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001222 DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001223 }
1224
1225 return rval;
1226}
1227
1228/*
1229 * qla2x00_get_firmware_state
1230 * Get adapter firmware state.
1231 *
1232 * Input:
1233 * ha = adapter block pointer.
1234 * dptr = pointer for firmware state.
1235 * TARGET_QUEUE_LOCK must be released.
1236 * ADAPTER_STATE_LOCK must be released.
1237 *
1238 * Returns:
1239 * qla2x00 local function return status code.
1240 *
1241 * Context:
1242 * Kernel context.
1243 */
1244int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001245qla2x00_get_firmware_state(scsi_qla_host_t *vha, uint16_t *states)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001246{
1247 int rval;
1248 mbx_cmd_t mc;
1249 mbx_cmd_t *mcp = &mc;
1250
1251 DEBUG11(printk("qla2x00_get_firmware_state(%ld): entered.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001252 vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001253
1254 mcp->mb[0] = MBC_GET_FIRMWARE_STATE;
1255 mcp->out_mb = MBX_0;
Harihara Kadayam4d4df192008-04-03 13:13:26 -07001256 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001257 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001258 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001259 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001260
Harihara Kadayam4d4df192008-04-03 13:13:26 -07001261 /* Return firmware states. */
1262 states[0] = mcp->mb[1];
1263 states[1] = mcp->mb[2];
1264 states[2] = mcp->mb[3];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001265
1266 if (rval != QLA_SUCCESS) {
1267 /*EMPTY*/
1268 DEBUG2_3_11(printk("qla2x00_get_firmware_state(%ld): "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001269 "failed=%x.\n", vha->host_no, rval));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001270 } else {
1271 /*EMPTY*/
1272 DEBUG11(printk("qla2x00_get_firmware_state(%ld): done.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001273 vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001274 }
1275
1276 return rval;
1277}
1278
1279/*
1280 * qla2x00_get_port_name
1281 * Issue get port name mailbox command.
1282 * Returned name is in big endian format.
1283 *
1284 * Input:
1285 * ha = adapter block pointer.
1286 * loop_id = loop ID of device.
1287 * name = pointer for name.
1288 * TARGET_QUEUE_LOCK must be released.
1289 * ADAPTER_STATE_LOCK must be released.
1290 *
1291 * Returns:
1292 * qla2x00 local function return status code.
1293 *
1294 * Context:
1295 * Kernel context.
1296 */
1297int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001298qla2x00_get_port_name(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t *name,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001299 uint8_t opt)
1300{
1301 int rval;
1302 mbx_cmd_t mc;
1303 mbx_cmd_t *mcp = &mc;
1304
1305 DEBUG11(printk("qla2x00_get_port_name(%ld): entered.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001306 vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001307
1308 mcp->mb[0] = MBC_GET_PORT_NAME;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001309 mcp->mb[9] = vha->vp_idx;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001310 mcp->out_mb = MBX_9|MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001311 if (HAS_EXTENDED_IDS(vha->hw)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001312 mcp->mb[1] = loop_id;
1313 mcp->mb[10] = opt;
1314 mcp->out_mb |= MBX_10;
1315 } else {
1316 mcp->mb[1] = loop_id << 8 | opt;
1317 }
1318
1319 mcp->in_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001320 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001321 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001322 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001323
1324 if (rval != QLA_SUCCESS) {
1325 /*EMPTY*/
1326 DEBUG2_3_11(printk("qla2x00_get_port_name(%ld): failed=%x.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001327 vha->host_no, rval));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001328 } else {
1329 if (name != NULL) {
1330 /* This function returns name in big endian. */
Richard Lary1196ae02007-03-22 10:53:19 -05001331 name[0] = MSB(mcp->mb[2]);
1332 name[1] = LSB(mcp->mb[2]);
1333 name[2] = MSB(mcp->mb[3]);
1334 name[3] = LSB(mcp->mb[3]);
1335 name[4] = MSB(mcp->mb[6]);
1336 name[5] = LSB(mcp->mb[6]);
1337 name[6] = MSB(mcp->mb[7]);
1338 name[7] = LSB(mcp->mb[7]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001339 }
1340
1341 DEBUG11(printk("qla2x00_get_port_name(%ld): done.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001342 vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001343 }
1344
1345 return rval;
1346}
1347
1348/*
1349 * qla2x00_lip_reset
1350 * Issue LIP reset mailbox command.
1351 *
1352 * Input:
1353 * ha = adapter block pointer.
1354 * TARGET_QUEUE_LOCK must be released.
1355 * ADAPTER_STATE_LOCK must be released.
1356 *
1357 * Returns:
1358 * qla2x00 local function return status code.
1359 *
1360 * Context:
1361 * Kernel context.
1362 */
1363int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001364qla2x00_lip_reset(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001365{
1366 int rval;
1367 mbx_cmd_t mc;
1368 mbx_cmd_t *mcp = &mc;
1369
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001370 DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001371
Andrew Vasquez3a03eb72009-01-05 11:18:11 -08001372 if (IS_QLA81XX(vha->hw)) {
1373 /* Logout across all FCFs. */
1374 mcp->mb[0] = MBC_LIP_FULL_LOGIN;
1375 mcp->mb[1] = BIT_1;
1376 mcp->mb[2] = 0;
1377 mcp->out_mb = MBX_2|MBX_1|MBX_0;
1378 } else if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001379 mcp->mb[0] = MBC_LIP_FULL_LOGIN;
Andrew Vasquez0c8c39a2006-12-13 19:20:30 -08001380 mcp->mb[1] = BIT_6;
1381 mcp->mb[2] = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001382 mcp->mb[3] = vha->hw->loop_reset_delay;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001383 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001384 } else {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001385 mcp->mb[0] = MBC_LIP_RESET;
1386 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001387 if (HAS_EXTENDED_IDS(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001388 mcp->mb[1] = 0x00ff;
1389 mcp->mb[10] = 0;
1390 mcp->out_mb |= MBX_10;
1391 } else {
1392 mcp->mb[1] = 0xff00;
1393 }
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001394 mcp->mb[2] = vha->hw->loop_reset_delay;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001395 mcp->mb[3] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001396 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001397 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001398 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001399 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001400 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001401
1402 if (rval != QLA_SUCCESS) {
1403 /*EMPTY*/
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001404 DEBUG2_3_11(printk("%s(%ld): failed=%x.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001405 __func__, vha->host_no, rval));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001406 } else {
1407 /*EMPTY*/
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001408 DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001409 }
1410
1411 return rval;
1412}
1413
1414/*
1415 * qla2x00_send_sns
1416 * Send SNS command.
1417 *
1418 * Input:
1419 * ha = adapter block pointer.
1420 * sns = pointer for command.
1421 * cmd_size = command size.
1422 * buf_size = response/command size.
1423 * TARGET_QUEUE_LOCK must be released.
1424 * ADAPTER_STATE_LOCK must be released.
1425 *
1426 * Returns:
1427 * qla2x00 local function return status code.
1428 *
1429 * Context:
1430 * Kernel context.
1431 */
1432int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001433qla2x00_send_sns(scsi_qla_host_t *vha, dma_addr_t sns_phys_address,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001434 uint16_t cmd_size, size_t buf_size)
1435{
1436 int rval;
1437 mbx_cmd_t mc;
1438 mbx_cmd_t *mcp = &mc;
1439
1440 DEBUG11(printk("qla2x00_send_sns(%ld): entered.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001441 vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001442
1443 DEBUG11(printk("qla2x00_send_sns: retry cnt=%d ratov=%d total "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001444 "tov=%d.\n", vha->hw->retry_count, vha->hw->login_timeout,
1445 mcp->tov));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001446
1447 mcp->mb[0] = MBC_SEND_SNS_COMMAND;
1448 mcp->mb[1] = cmd_size;
1449 mcp->mb[2] = MSW(sns_phys_address);
1450 mcp->mb[3] = LSW(sns_phys_address);
1451 mcp->mb[6] = MSW(MSD(sns_phys_address));
1452 mcp->mb[7] = LSW(MSD(sns_phys_address));
1453 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
1454 mcp->in_mb = MBX_0|MBX_1;
1455 mcp->buf_size = buf_size;
1456 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001457 mcp->tov = (vha->hw->login_timeout * 2) + (vha->hw->login_timeout / 2);
1458 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001459
1460 if (rval != QLA_SUCCESS) {
1461 /*EMPTY*/
1462 DEBUG(printk("qla2x00_send_sns(%ld): failed=%x mb[0]=%x "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001463 "mb[1]=%x.\n", vha->host_no, rval, mcp->mb[0], mcp->mb[1]));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001464 DEBUG2_3_11(printk("qla2x00_send_sns(%ld): failed=%x mb[0]=%x "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001465 "mb[1]=%x.\n", vha->host_no, rval, mcp->mb[0], mcp->mb[1]));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001466 } else {
1467 /*EMPTY*/
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001468 DEBUG11(printk("qla2x00_send_sns(%ld): done.\n", vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001469 }
1470
1471 return rval;
1472}
1473
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001474int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001475qla24xx_login_fabric(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001476 uint8_t area, uint8_t al_pa, uint16_t *mb, uint8_t opt)
1477{
1478 int rval;
1479
1480 struct logio_entry_24xx *lg;
1481 dma_addr_t lg_dma;
1482 uint32_t iop[2];
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001483 struct qla_hw_data *ha = vha->hw;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001484
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001485 DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001486
1487 lg = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &lg_dma);
1488 if (lg == NULL) {
1489 DEBUG2_3(printk("%s(%ld): failed to allocate Login IOCB.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001490 __func__, vha->host_no));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001491 return QLA_MEMORY_ALLOC_FAILED;
1492 }
1493 memset(lg, 0, sizeof(struct logio_entry_24xx));
1494
1495 lg->entry_type = LOGINOUT_PORT_IOCB_TYPE;
1496 lg->entry_count = 1;
1497 lg->nport_handle = cpu_to_le16(loop_id);
1498 lg->control_flags = __constant_cpu_to_le16(LCF_COMMAND_PLOGI);
1499 if (opt & BIT_0)
1500 lg->control_flags |= __constant_cpu_to_le16(LCF_COND_PLOGI);
Andrew Vasquez8baa51a2006-06-23 16:10:44 -07001501 if (opt & BIT_1)
1502 lg->control_flags |= __constant_cpu_to_le16(LCF_SKIP_PRLI);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001503 lg->port_id[0] = al_pa;
1504 lg->port_id[1] = area;
1505 lg->port_id[2] = domain;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001506 lg->vp_index = vha->vp_idx;
1507 rval = qla2x00_issue_iocb(vha, lg, lg_dma, 0);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001508 if (rval != QLA_SUCCESS) {
1509 DEBUG2_3_11(printk("%s(%ld): failed to issue Login IOCB "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001510 "(%x).\n", __func__, vha->host_no, rval));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001511 } else if (lg->entry_status != 0) {
1512 DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001513 "-- error status (%x).\n", __func__, vha->host_no,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001514 lg->entry_status));
1515 rval = QLA_FUNCTION_FAILED;
1516 } else if (lg->comp_status != __constant_cpu_to_le16(CS_COMPLETE)) {
1517 iop[0] = le32_to_cpu(lg->io_parameter[0]);
1518 iop[1] = le32_to_cpu(lg->io_parameter[1]);
1519
1520 DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB "
1521 "-- completion status (%x) ioparam=%x/%x.\n", __func__,
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001522 vha->host_no, le16_to_cpu(lg->comp_status), iop[0],
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001523 iop[1]));
1524
1525 switch (iop[0]) {
1526 case LSC_SCODE_PORTID_USED:
1527 mb[0] = MBS_PORT_ID_USED;
1528 mb[1] = LSW(iop[1]);
1529 break;
1530 case LSC_SCODE_NPORT_USED:
1531 mb[0] = MBS_LOOP_ID_USED;
1532 break;
1533 case LSC_SCODE_NOLINK:
1534 case LSC_SCODE_NOIOCB:
1535 case LSC_SCODE_NOXCB:
1536 case LSC_SCODE_CMD_FAILED:
1537 case LSC_SCODE_NOFABRIC:
1538 case LSC_SCODE_FW_NOT_READY:
1539 case LSC_SCODE_NOT_LOGGED_IN:
1540 case LSC_SCODE_NOPCB:
1541 case LSC_SCODE_ELS_REJECT:
1542 case LSC_SCODE_CMD_PARAM_ERR:
1543 case LSC_SCODE_NONPORT:
1544 case LSC_SCODE_LOGGED_IN:
1545 case LSC_SCODE_NOFLOGI_ACC:
1546 default:
1547 mb[0] = MBS_COMMAND_ERROR;
1548 break;
1549 }
1550 } else {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001551 DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001552
1553 iop[0] = le32_to_cpu(lg->io_parameter[0]);
1554
1555 mb[0] = MBS_COMMAND_COMPLETE;
1556 mb[1] = 0;
1557 if (iop[0] & BIT_4) {
1558 if (iop[0] & BIT_8)
1559 mb[1] |= BIT_1;
1560 } else
1561 mb[1] = BIT_0;
Andrew Vasquezad3e0ed2005-08-26 19:08:10 -07001562
1563 /* Passback COS information. */
1564 mb[10] = 0;
1565 if (lg->io_parameter[7] || lg->io_parameter[8])
1566 mb[10] |= BIT_0; /* Class 2. */
1567 if (lg->io_parameter[9] || lg->io_parameter[10])
1568 mb[10] |= BIT_1; /* Class 3. */
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001569 }
1570
1571 dma_pool_free(ha->s_dma_pool, lg, lg_dma);
1572
1573 return rval;
1574}
1575
Linus Torvalds1da177e2005-04-16 15:20:36 -07001576/*
1577 * qla2x00_login_fabric
1578 * Issue login fabric port mailbox command.
1579 *
1580 * Input:
1581 * ha = adapter block pointer.
1582 * loop_id = device loop ID.
1583 * domain = device domain.
1584 * area = device area.
1585 * al_pa = device AL_PA.
1586 * status = pointer for return status.
1587 * opt = command options.
1588 * TARGET_QUEUE_LOCK must be released.
1589 * ADAPTER_STATE_LOCK must be released.
1590 *
1591 * Returns:
1592 * qla2x00 local function return status code.
1593 *
1594 * Context:
1595 * Kernel context.
1596 */
1597int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001598qla2x00_login_fabric(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001599 uint8_t area, uint8_t al_pa, uint16_t *mb, uint8_t opt)
1600{
1601 int rval;
1602 mbx_cmd_t mc;
1603 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001604 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001605
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001606 DEBUG11(printk("qla2x00_login_fabric(%ld): entered.\n", vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001607
1608 mcp->mb[0] = MBC_LOGIN_FABRIC_PORT;
1609 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
1610 if (HAS_EXTENDED_IDS(ha)) {
1611 mcp->mb[1] = loop_id;
1612 mcp->mb[10] = opt;
1613 mcp->out_mb |= MBX_10;
1614 } else {
1615 mcp->mb[1] = (loop_id << 8) | opt;
1616 }
1617 mcp->mb[2] = domain;
1618 mcp->mb[3] = area << 8 | al_pa;
1619
1620 mcp->in_mb = MBX_7|MBX_6|MBX_2|MBX_1|MBX_0;
1621 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
1622 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001623 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001624
1625 /* Return mailbox statuses. */
1626 if (mb != NULL) {
1627 mb[0] = mcp->mb[0];
1628 mb[1] = mcp->mb[1];
1629 mb[2] = mcp->mb[2];
1630 mb[6] = mcp->mb[6];
1631 mb[7] = mcp->mb[7];
Andrew Vasquezad3e0ed2005-08-26 19:08:10 -07001632 /* COS retrieved from Get-Port-Database mailbox command. */
1633 mb[10] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001634 }
1635
1636 if (rval != QLA_SUCCESS) {
1637 /* RLU tmp code: need to change main mailbox_command function to
1638 * return ok even when the mailbox completion value is not
1639 * SUCCESS. The caller needs to be responsible to interpret
1640 * the return values of this mailbox command if we're not
1641 * to change too much of the existing code.
1642 */
1643 if (mcp->mb[0] == 0x4001 || mcp->mb[0] == 0x4002 ||
1644 mcp->mb[0] == 0x4003 || mcp->mb[0] == 0x4005 ||
1645 mcp->mb[0] == 0x4006)
1646 rval = QLA_SUCCESS;
1647
1648 /*EMPTY*/
1649 DEBUG2_3_11(printk("qla2x00_login_fabric(%ld): failed=%x "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001650 "mb[0]=%x mb[1]=%x mb[2]=%x.\n", vha->host_no, rval,
Andrew Vasquez744f11fd2006-06-23 16:11:05 -07001651 mcp->mb[0], mcp->mb[1], mcp->mb[2]));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001652 } else {
1653 /*EMPTY*/
1654 DEBUG11(printk("qla2x00_login_fabric(%ld): done.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001655 vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001656 }
1657
1658 return rval;
1659}
1660
1661/*
1662 * qla2x00_login_local_device
1663 * Issue login loop port mailbox command.
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07001664 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07001665 * Input:
1666 * ha = adapter block pointer.
1667 * loop_id = device loop ID.
1668 * opt = command options.
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07001669 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07001670 * Returns:
1671 * Return status code.
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07001672 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07001673 * Context:
1674 * Kernel context.
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07001675 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07001676 */
1677int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001678qla2x00_login_local_device(scsi_qla_host_t *vha, fc_port_t *fcport,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001679 uint16_t *mb_ret, uint8_t opt)
1680{
1681 int rval;
1682 mbx_cmd_t mc;
1683 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001684 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001685
Andrew Vasqueze4289242007-07-19 15:05:56 -07001686 if (IS_FWI2_CAPABLE(ha))
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001687 return qla24xx_login_fabric(vha, fcport->loop_id,
andrew.vasquez@qlogic.com9a52a572006-03-09 14:27:44 -08001688 fcport->d_id.b.domain, fcport->d_id.b.area,
1689 fcport->d_id.b.al_pa, mb_ret, opt);
1690
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001691 DEBUG3(printk("%s(%ld): entered.\n", __func__, vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001692
1693 mcp->mb[0] = MBC_LOGIN_LOOP_PORT;
1694 if (HAS_EXTENDED_IDS(ha))
andrew.vasquez@qlogic.com9a52a572006-03-09 14:27:44 -08001695 mcp->mb[1] = fcport->loop_id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001696 else
andrew.vasquez@qlogic.com9a52a572006-03-09 14:27:44 -08001697 mcp->mb[1] = fcport->loop_id << 8;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001698 mcp->mb[2] = opt;
1699 mcp->out_mb = MBX_2|MBX_1|MBX_0;
1700 mcp->in_mb = MBX_7|MBX_6|MBX_1|MBX_0;
1701 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
1702 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001703 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001704
1705 /* Return mailbox statuses. */
1706 if (mb_ret != NULL) {
1707 mb_ret[0] = mcp->mb[0];
1708 mb_ret[1] = mcp->mb[1];
1709 mb_ret[6] = mcp->mb[6];
1710 mb_ret[7] = mcp->mb[7];
1711 }
1712
1713 if (rval != QLA_SUCCESS) {
1714 /* AV tmp code: need to change main mailbox_command function to
1715 * return ok even when the mailbox completion value is not
1716 * SUCCESS. The caller needs to be responsible to interpret
1717 * the return values of this mailbox command if we're not
1718 * to change too much of the existing code.
1719 */
1720 if (mcp->mb[0] == 0x4005 || mcp->mb[0] == 0x4006)
1721 rval = QLA_SUCCESS;
1722
1723 DEBUG(printk("%s(%ld): failed=%x mb[0]=%x mb[1]=%x "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001724 "mb[6]=%x mb[7]=%x.\n", __func__, vha->host_no, rval,
Andrew Vasquez744f11fd2006-06-23 16:11:05 -07001725 mcp->mb[0], mcp->mb[1], mcp->mb[6], mcp->mb[7]));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001726 DEBUG2_3(printk("%s(%ld): failed=%x mb[0]=%x mb[1]=%x "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001727 "mb[6]=%x mb[7]=%x.\n", __func__, vha->host_no, rval,
Andrew Vasquez744f11fd2006-06-23 16:11:05 -07001728 mcp->mb[0], mcp->mb[1], mcp->mb[6], mcp->mb[7]));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001729 } else {
1730 /*EMPTY*/
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001731 DEBUG3(printk("%s(%ld): done.\n", __func__, vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001732 }
1733
1734 return (rval);
1735}
1736
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001737int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001738qla24xx_fabric_logout(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001739 uint8_t area, uint8_t al_pa)
1740{
1741 int rval;
1742 struct logio_entry_24xx *lg;
1743 dma_addr_t lg_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001744 struct qla_hw_data *ha = vha->hw;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001745
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001746 DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001747
1748 lg = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &lg_dma);
1749 if (lg == NULL) {
1750 DEBUG2_3(printk("%s(%ld): failed to allocate Logout IOCB.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001751 __func__, vha->host_no));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001752 return QLA_MEMORY_ALLOC_FAILED;
1753 }
1754 memset(lg, 0, sizeof(struct logio_entry_24xx));
1755
1756 lg->entry_type = LOGINOUT_PORT_IOCB_TYPE;
1757 lg->entry_count = 1;
1758 lg->nport_handle = cpu_to_le16(loop_id);
1759 lg->control_flags =
Lalit Chandivadeb1372bc2007-01-29 10:22:22 -08001760 __constant_cpu_to_le16(LCF_COMMAND_LOGO|LCF_IMPL_LOGO);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001761 lg->port_id[0] = al_pa;
1762 lg->port_id[1] = area;
1763 lg->port_id[2] = domain;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001764 lg->vp_index = vha->vp_idx;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08001765
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001766 rval = qla2x00_issue_iocb(vha, lg, lg_dma, 0);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001767 if (rval != QLA_SUCCESS) {
1768 DEBUG2_3_11(printk("%s(%ld): failed to issue Logout IOCB "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001769 "(%x).\n", __func__, vha->host_no, rval));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001770 } else if (lg->entry_status != 0) {
1771 DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001772 "-- error status (%x).\n", __func__, vha->host_no,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001773 lg->entry_status));
1774 rval = QLA_FUNCTION_FAILED;
1775 } else if (lg->comp_status != __constant_cpu_to_le16(CS_COMPLETE)) {
Anirban Chakraborty73208df2008-12-09 16:45:39 -08001776 DEBUG2_3_11(printk("%s(%ld %d): failed to complete IOCB "
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001777 "-- completion status (%x) ioparam=%x/%x.\n", __func__,
Anirban Chakraborty73208df2008-12-09 16:45:39 -08001778 vha->host_no, vha->vp_idx, le16_to_cpu(lg->comp_status),
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001779 le32_to_cpu(lg->io_parameter[0]),
Andrew Vasquez744f11fd2006-06-23 16:11:05 -07001780 le32_to_cpu(lg->io_parameter[1])));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001781 } else {
1782 /*EMPTY*/
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001783 DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001784 }
1785
1786 dma_pool_free(ha->s_dma_pool, lg, lg_dma);
1787
1788 return rval;
1789}
1790
Linus Torvalds1da177e2005-04-16 15:20:36 -07001791/*
1792 * qla2x00_fabric_logout
1793 * Issue logout fabric port mailbox command.
1794 *
1795 * Input:
1796 * ha = adapter block pointer.
1797 * loop_id = device loop ID.
1798 * TARGET_QUEUE_LOCK must be released.
1799 * ADAPTER_STATE_LOCK must be released.
1800 *
1801 * Returns:
1802 * qla2x00 local function return status code.
1803 *
1804 * Context:
1805 * Kernel context.
1806 */
1807int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001808qla2x00_fabric_logout(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001809 uint8_t area, uint8_t al_pa)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001810{
1811 int rval;
1812 mbx_cmd_t mc;
1813 mbx_cmd_t *mcp = &mc;
1814
1815 DEBUG11(printk("qla2x00_fabric_logout(%ld): entered.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001816 vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001817
1818 mcp->mb[0] = MBC_LOGOUT_FABRIC_PORT;
1819 mcp->out_mb = MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001820 if (HAS_EXTENDED_IDS(vha->hw)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001821 mcp->mb[1] = loop_id;
1822 mcp->mb[10] = 0;
1823 mcp->out_mb |= MBX_10;
1824 } else {
1825 mcp->mb[1] = loop_id << 8;
1826 }
1827
1828 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001829 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001830 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001831 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001832
1833 if (rval != QLA_SUCCESS) {
1834 /*EMPTY*/
1835 DEBUG2_3_11(printk("qla2x00_fabric_logout(%ld): failed=%x "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001836 "mbx1=%x.\n", vha->host_no, rval, mcp->mb[1]));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001837 } else {
1838 /*EMPTY*/
1839 DEBUG11(printk("qla2x00_fabric_logout(%ld): done.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001840 vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001841 }
1842
1843 return rval;
1844}
1845
1846/*
1847 * qla2x00_full_login_lip
1848 * Issue full login LIP mailbox command.
1849 *
1850 * Input:
1851 * ha = adapter block pointer.
1852 * TARGET_QUEUE_LOCK must be released.
1853 * ADAPTER_STATE_LOCK must be released.
1854 *
1855 * Returns:
1856 * qla2x00 local function return status code.
1857 *
1858 * Context:
1859 * Kernel context.
1860 */
1861int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001862qla2x00_full_login_lip(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001863{
1864 int rval;
1865 mbx_cmd_t mc;
1866 mbx_cmd_t *mcp = &mc;
1867
Andrew Vasquez3a03eb72009-01-05 11:18:11 -08001868 if (IS_QLA81XX(vha->hw))
1869 return QLA_SUCCESS;
1870
Linus Torvalds1da177e2005-04-16 15:20:36 -07001871 DEBUG11(printk("qla2x00_full_login_lip(%ld): entered.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001872 vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001873
1874 mcp->mb[0] = MBC_LIP_FULL_LOGIN;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001875 mcp->mb[1] = IS_FWI2_CAPABLE(vha->hw) ? BIT_3 : 0;
Andrew Vasquez0c8c39a2006-12-13 19:20:30 -08001876 mcp->mb[2] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001877 mcp->mb[3] = 0;
1878 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
1879 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001880 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001881 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001882 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001883
1884 if (rval != QLA_SUCCESS) {
1885 /*EMPTY*/
1886 DEBUG2_3_11(printk("qla2x00_full_login_lip(%ld): failed=%x.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001887 vha->host_no, rval));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001888 } else {
1889 /*EMPTY*/
1890 DEBUG11(printk("qla2x00_full_login_lip(%ld): done.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001891 vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001892 }
1893
1894 return rval;
1895}
1896
1897/*
1898 * qla2x00_get_id_list
1899 *
1900 * Input:
1901 * ha = adapter block pointer.
1902 *
1903 * Returns:
1904 * qla2x00 local function return status code.
1905 *
1906 * Context:
1907 * Kernel context.
1908 */
1909int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001910qla2x00_get_id_list(scsi_qla_host_t *vha, void *id_list, dma_addr_t id_list_dma,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001911 uint16_t *entries)
1912{
1913 int rval;
1914 mbx_cmd_t mc;
1915 mbx_cmd_t *mcp = &mc;
1916
1917 DEBUG11(printk("qla2x00_get_id_list(%ld): entered.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001918 vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001919
1920 if (id_list == NULL)
1921 return QLA_FUNCTION_FAILED;
1922
1923 mcp->mb[0] = MBC_GET_ID_LIST;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001924 mcp->out_mb = MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001925 if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001926 mcp->mb[2] = MSW(id_list_dma);
1927 mcp->mb[3] = LSW(id_list_dma);
1928 mcp->mb[6] = MSW(MSD(id_list_dma));
1929 mcp->mb[7] = LSW(MSD(id_list_dma));
andrew.vasquez@qlogic.com247ec452006-02-07 08:45:40 -08001930 mcp->mb[8] = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001931 mcp->mb[9] = vha->vp_idx;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001932 mcp->out_mb |= MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001933 } else {
1934 mcp->mb[1] = MSW(id_list_dma);
1935 mcp->mb[2] = LSW(id_list_dma);
1936 mcp->mb[3] = MSW(MSD(id_list_dma));
1937 mcp->mb[6] = LSW(MSD(id_list_dma));
1938 mcp->out_mb |= MBX_6|MBX_3|MBX_2|MBX_1;
1939 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001940 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001941 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001942 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001943 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001944
1945 if (rval != QLA_SUCCESS) {
1946 /*EMPTY*/
1947 DEBUG2_3_11(printk("qla2x00_get_id_list(%ld): failed=%x.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001948 vha->host_no, rval));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001949 } else {
1950 *entries = mcp->mb[1];
1951 DEBUG11(printk("qla2x00_get_id_list(%ld): done.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001952 vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001953 }
1954
1955 return rval;
1956}
1957
1958/*
1959 * qla2x00_get_resource_cnts
1960 * Get current firmware resource counts.
1961 *
1962 * Input:
1963 * ha = adapter block pointer.
1964 *
1965 * Returns:
1966 * qla2x00 local function return status code.
1967 *
1968 * Context:
1969 * Kernel context.
1970 */
1971int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001972qla2x00_get_resource_cnts(scsi_qla_host_t *vha, uint16_t *cur_xchg_cnt,
Seokmann Ju4d0ea242007-09-20 14:07:43 -07001973 uint16_t *orig_xchg_cnt, uint16_t *cur_iocb_cnt,
1974 uint16_t *orig_iocb_cnt, uint16_t *max_npiv_vports)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001975{
1976 int rval;
1977 mbx_cmd_t mc;
1978 mbx_cmd_t *mcp = &mc;
1979
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001980 DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001981
1982 mcp->mb[0] = MBC_GET_RESOURCE_COUNTS;
1983 mcp->out_mb = MBX_0;
Seokmann Ju4d0ea242007-09-20 14:07:43 -07001984 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 -07001985 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001986 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001987 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001988
1989 if (rval != QLA_SUCCESS) {
1990 /*EMPTY*/
1991 DEBUG2_3_11(printk("%s(%ld): failed = %x.\n", __func__,
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001992 vha->host_no, mcp->mb[0]));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001993 } else {
1994 DEBUG11(printk("%s(%ld): done. mb1=%x mb2=%x mb3=%x mb6=%x "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001995 "mb7=%x mb10=%x mb11=%x.\n", __func__, vha->host_no,
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07001996 mcp->mb[1], mcp->mb[2], mcp->mb[3], mcp->mb[6], mcp->mb[7],
Seokmann Ju4d0ea242007-09-20 14:07:43 -07001997 mcp->mb[10], mcp->mb[11]));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001998
1999 if (cur_xchg_cnt)
2000 *cur_xchg_cnt = mcp->mb[3];
2001 if (orig_xchg_cnt)
2002 *orig_xchg_cnt = mcp->mb[6];
2003 if (cur_iocb_cnt)
2004 *cur_iocb_cnt = mcp->mb[7];
2005 if (orig_iocb_cnt)
2006 *orig_iocb_cnt = mcp->mb[10];
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002007 if (vha->hw->flags.npiv_supported && max_npiv_vports)
Seokmann Ju4d0ea242007-09-20 14:07:43 -07002008 *max_npiv_vports = mcp->mb[11];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002009 }
2010
2011 return (rval);
2012}
2013
2014#if defined(QL_DEBUG_LEVEL_3)
2015/*
2016 * qla2x00_get_fcal_position_map
2017 * Get FCAL (LILP) position map using mailbox command
2018 *
2019 * Input:
2020 * ha = adapter state pointer.
2021 * pos_map = buffer pointer (can be NULL).
2022 *
2023 * Returns:
2024 * qla2x00 local function return status code.
2025 *
2026 * Context:
2027 * Kernel context.
2028 */
2029int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002030qla2x00_get_fcal_position_map(scsi_qla_host_t *vha, char *pos_map)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002031{
2032 int rval;
2033 mbx_cmd_t mc;
2034 mbx_cmd_t *mcp = &mc;
2035 char *pmap;
2036 dma_addr_t pmap_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002037 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002038
Andrew Vasquez4b892582008-09-11 21:22:48 -07002039 pmap = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &pmap_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002040 if (pmap == NULL) {
2041 DEBUG2_3_11(printk("%s(%ld): **** Mem Alloc Failed ****",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002042 __func__, vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002043 return QLA_MEMORY_ALLOC_FAILED;
2044 }
2045 memset(pmap, 0, FCAL_MAP_SIZE);
2046
2047 mcp->mb[0] = MBC_GET_FC_AL_POSITION_MAP;
2048 mcp->mb[2] = MSW(pmap_dma);
2049 mcp->mb[3] = LSW(pmap_dma);
2050 mcp->mb[6] = MSW(MSD(pmap_dma));
2051 mcp->mb[7] = LSW(MSD(pmap_dma));
2052 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
2053 mcp->in_mb = MBX_1|MBX_0;
2054 mcp->buf_size = FCAL_MAP_SIZE;
2055 mcp->flags = MBX_DMA_IN;
2056 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002057 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002058
2059 if (rval == QLA_SUCCESS) {
2060 DEBUG11(printk("%s(%ld): (mb0=%x/mb1=%x) FC/AL Position Map "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002061 "size (%x)\n", __func__, vha->host_no, mcp->mb[0],
Linus Torvalds1da177e2005-04-16 15:20:36 -07002062 mcp->mb[1], (unsigned)pmap[0]));
2063 DEBUG11(qla2x00_dump_buffer(pmap, pmap[0] + 1));
2064
2065 if (pos_map)
2066 memcpy(pos_map, pmap, FCAL_MAP_SIZE);
2067 }
2068 dma_pool_free(ha->s_dma_pool, pmap, pmap_dma);
2069
2070 if (rval != QLA_SUCCESS) {
2071 DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__,
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002072 vha->host_no, rval));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002073 } else {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002074 DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002075 }
2076
2077 return rval;
2078}
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002079#endif
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002080
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002081/*
2082 * qla2x00_get_link_status
2083 *
2084 * Input:
2085 * ha = adapter block pointer.
2086 * loop_id = device loop ID.
2087 * ret_buf = pointer to link status return buffer.
2088 *
2089 * Returns:
2090 * 0 = success.
2091 * BIT_0 = mem alloc error.
2092 * BIT_1 = mailbox error.
2093 */
2094int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002095qla2x00_get_link_status(scsi_qla_host_t *vha, uint16_t loop_id,
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002096 struct link_statistics *stats, dma_addr_t stats_dma)
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002097{
2098 int rval;
2099 mbx_cmd_t mc;
2100 mbx_cmd_t *mcp = &mc;
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002101 uint32_t *siter, *diter, dwords;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002102 struct qla_hw_data *ha = vha->hw;
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002103
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002104 DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002105
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002106 mcp->mb[0] = MBC_GET_LINK_STATUS;
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002107 mcp->mb[2] = MSW(stats_dma);
2108 mcp->mb[3] = LSW(stats_dma);
2109 mcp->mb[6] = MSW(MSD(stats_dma));
2110 mcp->mb[7] = LSW(MSD(stats_dma));
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002111 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
2112 mcp->in_mb = MBX_0;
Andrew Vasqueze4289242007-07-19 15:05:56 -07002113 if (IS_FWI2_CAPABLE(ha)) {
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002114 mcp->mb[1] = loop_id;
2115 mcp->mb[4] = 0;
2116 mcp->mb[10] = 0;
2117 mcp->out_mb |= MBX_10|MBX_4|MBX_1;
2118 mcp->in_mb |= MBX_1;
2119 } else if (HAS_EXTENDED_IDS(ha)) {
2120 mcp->mb[1] = loop_id;
2121 mcp->mb[10] = 0;
2122 mcp->out_mb |= MBX_10|MBX_1;
2123 } else {
2124 mcp->mb[1] = loop_id << 8;
2125 mcp->out_mb |= MBX_1;
2126 }
Ravi Anandb93480e2008-04-03 13:13:25 -07002127 mcp->tov = MBX_TOV_SECONDS;
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002128 mcp->flags = IOCTL_CMD;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002129 rval = qla2x00_mailbox_command(vha, mcp);
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002130
2131 if (rval == QLA_SUCCESS) {
2132 if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {
2133 DEBUG2_3_11(printk("%s(%ld): cmd failed. mbx0=%x.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002134 __func__, vha->host_no, mcp->mb[0]));
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002135 rval = QLA_FUNCTION_FAILED;
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002136 } else {
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002137 /* Copy over data -- firmware data is LE. */
2138 dwords = offsetof(struct link_statistics, unused1) / 4;
2139 siter = diter = &stats->link_fail_cnt;
2140 while (dwords--)
2141 *diter++ = le32_to_cpu(*siter++);
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002142 }
2143 } else {
2144 /* Failed. */
2145 DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__,
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002146 vha->host_no, rval));
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002147 }
2148
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002149 return rval;
2150}
2151
2152int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002153qla24xx_get_isp_stats(scsi_qla_host_t *vha, struct link_statistics *stats,
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002154 dma_addr_t stats_dma)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002155{
2156 int rval;
2157 mbx_cmd_t mc;
2158 mbx_cmd_t *mcp = &mc;
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002159 uint32_t *siter, *diter, dwords;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002160
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002161 DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002162
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002163 mcp->mb[0] = MBC_GET_LINK_PRIV_STATS;
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002164 mcp->mb[2] = MSW(stats_dma);
2165 mcp->mb[3] = LSW(stats_dma);
2166 mcp->mb[6] = MSW(MSD(stats_dma));
2167 mcp->mb[7] = LSW(MSD(stats_dma));
2168 mcp->mb[8] = sizeof(struct link_statistics) / 4;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002169 mcp->mb[9] = vha->vp_idx;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002170 mcp->mb[10] = 0;
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002171 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 -07002172 mcp->in_mb = MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002173 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002174 mcp->flags = IOCTL_CMD;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002175 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002176
2177 if (rval == QLA_SUCCESS) {
2178 if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {
2179 DEBUG2_3_11(printk("%s(%ld): cmd failed. mbx0=%x.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002180 __func__, vha->host_no, mcp->mb[0]));
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002181 rval = QLA_FUNCTION_FAILED;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002182 } else {
2183 /* Copy over data -- firmware data is LE. */
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002184 dwords = sizeof(struct link_statistics) / 4;
2185 siter = diter = &stats->link_fail_cnt;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002186 while (dwords--)
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002187 *diter++ = le32_to_cpu(*siter++);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002188 }
2189 } else {
2190 /* Failed. */
2191 DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__,
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002192 vha->host_no, rval));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002193 }
2194
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002195 return rval;
2196}
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002197
2198int
Anirban Chakraborty73208df2008-12-09 16:45:39 -08002199qla24xx_abort_command(scsi_qla_host_t *vha, srb_t *sp, struct req_que *req)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002200{
2201 int rval;
2202 fc_port_t *fcport;
2203 unsigned long flags = 0;
2204
2205 struct abort_entry_24xx *abt;
2206 dma_addr_t abt_dma;
2207 uint32_t handle;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002208 struct qla_hw_data *ha = vha->hw;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002209
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002210 DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002211
2212 fcport = sp->fcport;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002213
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002214 spin_lock_irqsave(&ha->hardware_lock, flags);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002215 for (handle = 1; handle < MAX_OUTSTANDING_COMMANDS; handle++) {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002216 if (req->outstanding_cmds[handle] == sp)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002217 break;
2218 }
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002219 spin_unlock_irqrestore(&ha->hardware_lock, flags);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002220 if (handle == MAX_OUTSTANDING_COMMANDS) {
2221 /* Command not found. */
2222 return QLA_FUNCTION_FAILED;
2223 }
2224
2225 abt = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &abt_dma);
2226 if (abt == NULL) {
2227 DEBUG2_3(printk("%s(%ld): failed to allocate Abort IOCB.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002228 __func__, vha->host_no));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002229 return QLA_MEMORY_ALLOC_FAILED;
2230 }
2231 memset(abt, 0, sizeof(struct abort_entry_24xx));
2232
2233 abt->entry_type = ABORT_IOCB_TYPE;
2234 abt->entry_count = 1;
2235 abt->nport_handle = cpu_to_le16(fcport->loop_id);
2236 abt->handle_to_abort = handle;
2237 abt->port_id[0] = fcport->d_id.b.al_pa;
2238 abt->port_id[1] = fcport->d_id.b.area;
2239 abt->port_id[2] = fcport->d_id.b.domain;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002240 abt->vp_index = fcport->vp_idx;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08002241
2242 abt->req_que_no = cpu_to_le16(req->id);
2243
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002244 rval = qla2x00_issue_iocb(vha, abt, abt_dma, 0);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002245 if (rval != QLA_SUCCESS) {
2246 DEBUG2_3_11(printk("%s(%ld): failed to issue IOCB (%x).\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002247 __func__, vha->host_no, rval));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002248 } else if (abt->entry_status != 0) {
2249 DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002250 "-- error status (%x).\n", __func__, vha->host_no,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002251 abt->entry_status));
2252 rval = QLA_FUNCTION_FAILED;
2253 } else if (abt->nport_handle != __constant_cpu_to_le16(0)) {
2254 DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002255 "-- completion status (%x).\n", __func__, vha->host_no,
Andrew Vasquez744f11fd2006-06-23 16:11:05 -07002256 le16_to_cpu(abt->nport_handle)));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002257 rval = QLA_FUNCTION_FAILED;
2258 } else {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002259 DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002260 }
2261
2262 dma_pool_free(ha->s_dma_pool, abt, abt_dma);
2263
2264 return rval;
2265}
2266
2267struct tsk_mgmt_cmd {
2268 union {
2269 struct tsk_mgmt_entry tsk;
2270 struct sts_entry_24xx sts;
2271 } p;
2272};
2273
Andrew Vasquez523ec772008-04-03 13:13:24 -07002274static int
2275__qla24xx_issue_tmf(char *name, uint32_t type, struct fc_port *fcport,
2276 unsigned int l)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002277{
Andrew Vasquez523ec772008-04-03 13:13:24 -07002278 int rval, rval2;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002279 struct tsk_mgmt_cmd *tsk;
2280 dma_addr_t tsk_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002281 scsi_qla_host_t *vha;
2282 struct qla_hw_data *ha;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08002283 struct req_que *req;
2284 struct rsp_que *rsp;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002285
Anirban Chakraborty749af3d2008-11-14 13:48:12 -08002286 DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->vha->host_no));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002287
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002288 vha = fcport->vha;
2289 ha = vha->hw;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08002290 req = ha->req_q_map[0];
2291 rsp = ha->rsp_q_map[0];
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002292 tsk = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &tsk_dma);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002293 if (tsk == NULL) {
2294 DEBUG2_3(printk("%s(%ld): failed to allocate Task Management "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002295 "IOCB.\n", __func__, vha->host_no));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002296 return QLA_MEMORY_ALLOC_FAILED;
2297 }
2298 memset(tsk, 0, sizeof(struct tsk_mgmt_cmd));
2299
2300 tsk->p.tsk.entry_type = TSK_MGMT_IOCB_TYPE;
2301 tsk->p.tsk.entry_count = 1;
2302 tsk->p.tsk.nport_handle = cpu_to_le16(fcport->loop_id);
Andrew Vasquez00a537b2008-02-28 14:06:11 -08002303 tsk->p.tsk.timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
Andrew Vasquez523ec772008-04-03 13:13:24 -07002304 tsk->p.tsk.control_flags = cpu_to_le32(type);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002305 tsk->p.tsk.port_id[0] = fcport->d_id.b.al_pa;
2306 tsk->p.tsk.port_id[1] = fcport->d_id.b.area;
2307 tsk->p.tsk.port_id[2] = fcport->d_id.b.domain;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002308 tsk->p.tsk.vp_index = fcport->vp_idx;
Andrew Vasquez523ec772008-04-03 13:13:24 -07002309 if (type == TCF_LUN_RESET) {
2310 int_to_scsilun(l, &tsk->p.tsk.lun);
2311 host_to_fcp_swap((uint8_t *)&tsk->p.tsk.lun,
2312 sizeof(tsk->p.tsk.lun));
2313 }
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002314
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002315 rval = qla2x00_issue_iocb(vha, tsk, tsk_dma, 0);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002316 if (rval != QLA_SUCCESS) {
Andrew Vasquez523ec772008-04-03 13:13:24 -07002317 DEBUG2_3_11(printk("%s(%ld): failed to issue %s Reset IOCB "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002318 "(%x).\n", __func__, vha->host_no, name, rval));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002319 } else if (tsk->p.sts.entry_status != 0) {
2320 DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002321 "-- error status (%x).\n", __func__, vha->host_no,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002322 tsk->p.sts.entry_status));
2323 rval = QLA_FUNCTION_FAILED;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002324 } else if (tsk->p.sts.comp_status !=
2325 __constant_cpu_to_le16(CS_COMPLETE)) {
2326 DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB "
2327 "-- completion status (%x).\n", __func__,
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002328 vha->host_no, le16_to_cpu(tsk->p.sts.comp_status)));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002329 rval = QLA_FUNCTION_FAILED;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002330 }
2331
2332 /* Issue marker IOCB. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -08002333 rval2 = qla2x00_marker(vha, req, rsp, fcport->loop_id, l,
Andrew Vasquez523ec772008-04-03 13:13:24 -07002334 type == TCF_LUN_RESET ? MK_SYNC_ID_LUN: MK_SYNC_ID);
2335 if (rval2 != QLA_SUCCESS) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002336 DEBUG2_3_11(printk("%s(%ld): failed to issue Marker IOCB "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002337 "(%x).\n", __func__, vha->host_no, rval2));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002338 } else {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002339 DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002340 }
2341
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002342 dma_pool_free(ha->s_dma_pool, tsk, tsk_dma);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002343
2344 return rval;
2345}
2346
Andrew Vasquez523ec772008-04-03 13:13:24 -07002347int
2348qla24xx_abort_target(struct fc_port *fcport, unsigned int l)
2349{
2350 return __qla24xx_issue_tmf("Target", TCF_TARGET_RESET, fcport, l);
2351}
2352
2353int
2354qla24xx_lun_reset(struct fc_port *fcport, unsigned int l)
2355{
2356 return __qla24xx_issue_tmf("Lun", TCF_LUN_RESET, fcport, l);
2357}
2358
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002359int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002360qla2x00_system_error(scsi_qla_host_t *vha)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002361{
2362 int rval;
2363 mbx_cmd_t mc;
2364 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002365 struct qla_hw_data *ha = vha->hw;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002366
Andrew Vasquez68af0812008-05-12 22:21:13 -07002367 if (!IS_QLA23XX(ha) && !IS_FWI2_CAPABLE(ha))
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002368 return QLA_FUNCTION_FAILED;
2369
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002370 DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002371
2372 mcp->mb[0] = MBC_GEN_SYSTEM_ERROR;
2373 mcp->out_mb = MBX_0;
2374 mcp->in_mb = MBX_0;
2375 mcp->tov = 5;
2376 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002377 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002378
2379 if (rval != QLA_SUCCESS) {
2380 DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__,
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002381 vha->host_no, rval));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002382 } else {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002383 DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002384 }
2385
2386 return rval;
2387}
2388
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002389/**
2390 * qla2x00_set_serdes_params() -
2391 * @ha: HA context
2392 *
2393 * Returns
2394 */
2395int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002396qla2x00_set_serdes_params(scsi_qla_host_t *vha, uint16_t sw_em_1g,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002397 uint16_t sw_em_2g, uint16_t sw_em_4g)
2398{
2399 int rval;
2400 mbx_cmd_t mc;
2401 mbx_cmd_t *mcp = &mc;
2402
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002403 DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002404
2405 mcp->mb[0] = MBC_SERDES_PARAMS;
2406 mcp->mb[1] = BIT_0;
andrew.vasquez@qlogic.comfdbc6832006-03-09 14:27:29 -08002407 mcp->mb[2] = sw_em_1g | BIT_15;
2408 mcp->mb[3] = sw_em_2g | BIT_15;
2409 mcp->mb[4] = sw_em_4g | BIT_15;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002410 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
2411 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002412 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002413 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002414 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002415
2416 if (rval != QLA_SUCCESS) {
2417 /*EMPTY*/
2418 DEBUG2_3_11(printk("%s(%ld): failed=%x (%x).\n", __func__,
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002419 vha->host_no, rval, mcp->mb[0]));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002420 } else {
2421 /*EMPTY*/
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002422 DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002423 }
2424
2425 return rval;
2426}
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002427
2428int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002429qla2x00_stop_firmware(scsi_qla_host_t *vha)
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002430{
2431 int rval;
2432 mbx_cmd_t mc;
2433 mbx_cmd_t *mcp = &mc;
2434
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002435 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002436 return QLA_FUNCTION_FAILED;
2437
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002438 DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002439
2440 mcp->mb[0] = MBC_STOP_FIRMWARE;
2441 mcp->out_mb = MBX_0;
2442 mcp->in_mb = MBX_0;
2443 mcp->tov = 5;
2444 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002445 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002446
2447 if (rval != QLA_SUCCESS) {
2448 DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__,
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002449 vha->host_no, rval));
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002450 } else {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002451 DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002452 }
2453
2454 return rval;
2455}
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002456
2457int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002458qla2x00_enable_eft_trace(scsi_qla_host_t *vha, dma_addr_t eft_dma,
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002459 uint16_t buffers)
2460{
2461 int rval;
2462 mbx_cmd_t mc;
2463 mbx_cmd_t *mcp = &mc;
2464
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002465 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002466 return QLA_FUNCTION_FAILED;
2467
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002468 DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002469
2470 mcp->mb[0] = MBC_TRACE_CONTROL;
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002471 mcp->mb[1] = TC_EFT_ENABLE;
2472 mcp->mb[2] = LSW(eft_dma);
2473 mcp->mb[3] = MSW(eft_dma);
2474 mcp->mb[4] = LSW(MSD(eft_dma));
2475 mcp->mb[5] = MSW(MSD(eft_dma));
2476 mcp->mb[6] = buffers;
2477 mcp->mb[7] = TC_AEN_DISABLE;
2478 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 -07002479 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002480 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002481 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002482 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002483 if (rval != QLA_SUCCESS) {
2484 DEBUG2_3_11(printk("%s(%ld): failed=%x mb[0]=%x mb[1]=%x.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002485 __func__, vha->host_no, rval, mcp->mb[0], mcp->mb[1]));
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002486 } else {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002487 DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002488 }
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002489
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002490 return rval;
2491}
2492
2493int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002494qla2x00_disable_eft_trace(scsi_qla_host_t *vha)
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002495{
2496 int rval;
2497 mbx_cmd_t mc;
2498 mbx_cmd_t *mcp = &mc;
2499
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002500 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002501 return QLA_FUNCTION_FAILED;
2502
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002503 DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002504
2505 mcp->mb[0] = MBC_TRACE_CONTROL;
2506 mcp->mb[1] = TC_EFT_DISABLE;
2507 mcp->out_mb = MBX_1|MBX_0;
2508 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002509 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002510 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002511 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002512 if (rval != QLA_SUCCESS) {
2513 DEBUG2_3_11(printk("%s(%ld): failed=%x mb[0]=%x mb[1]=%x.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002514 __func__, vha->host_no, rval, mcp->mb[0], mcp->mb[1]));
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002515 } else {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002516 DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002517 }
2518
2519 return rval;
2520}
2521
Andrew Vasquez88729e52006-06-23 16:10:50 -07002522int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002523qla2x00_enable_fce_trace(scsi_qla_host_t *vha, dma_addr_t fce_dma,
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002524 uint16_t buffers, uint16_t *mb, uint32_t *dwords)
2525{
2526 int rval;
2527 mbx_cmd_t mc;
2528 mbx_cmd_t *mcp = &mc;
2529
Andrew Vasquez3a03eb72009-01-05 11:18:11 -08002530 if (!IS_QLA25XX(vha->hw) && !IS_QLA81XX(vha->hw))
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002531 return QLA_FUNCTION_FAILED;
2532
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002533 DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002534
2535 mcp->mb[0] = MBC_TRACE_CONTROL;
2536 mcp->mb[1] = TC_FCE_ENABLE;
2537 mcp->mb[2] = LSW(fce_dma);
2538 mcp->mb[3] = MSW(fce_dma);
2539 mcp->mb[4] = LSW(MSD(fce_dma));
2540 mcp->mb[5] = MSW(MSD(fce_dma));
2541 mcp->mb[6] = buffers;
2542 mcp->mb[7] = TC_AEN_DISABLE;
2543 mcp->mb[8] = 0;
2544 mcp->mb[9] = TC_FCE_DEFAULT_RX_SIZE;
2545 mcp->mb[10] = TC_FCE_DEFAULT_TX_SIZE;
2546 mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|
2547 MBX_1|MBX_0;
2548 mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002549 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002550 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002551 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002552 if (rval != QLA_SUCCESS) {
2553 DEBUG2_3_11(printk("%s(%ld): failed=%x mb[0]=%x mb[1]=%x.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002554 __func__, vha->host_no, rval, mcp->mb[0], mcp->mb[1]));
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002555 } else {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002556 DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002557
2558 if (mb)
2559 memcpy(mb, mcp->mb, 8 * sizeof(*mb));
2560 if (dwords)
Andrew Vasquezfa0926d2008-05-12 22:21:12 -07002561 *dwords = buffers;
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002562 }
2563
2564 return rval;
2565}
2566
2567int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002568qla2x00_disable_fce_trace(scsi_qla_host_t *vha, uint64_t *wr, uint64_t *rd)
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002569{
2570 int rval;
2571 mbx_cmd_t mc;
2572 mbx_cmd_t *mcp = &mc;
2573
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002574 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002575 return QLA_FUNCTION_FAILED;
2576
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002577 DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002578
2579 mcp->mb[0] = MBC_TRACE_CONTROL;
2580 mcp->mb[1] = TC_FCE_DISABLE;
2581 mcp->mb[2] = TC_FCE_DISABLE_TRACE;
2582 mcp->out_mb = MBX_2|MBX_1|MBX_0;
2583 mcp->in_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|
2584 MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002585 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002586 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002587 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002588 if (rval != QLA_SUCCESS) {
2589 DEBUG2_3_11(printk("%s(%ld): failed=%x mb[0]=%x mb[1]=%x.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002590 __func__, vha->host_no, rval, mcp->mb[0], mcp->mb[1]));
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002591 } else {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002592 DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002593
2594 if (wr)
2595 *wr = (uint64_t) mcp->mb[5] << 48 |
2596 (uint64_t) mcp->mb[4] << 32 |
2597 (uint64_t) mcp->mb[3] << 16 |
2598 (uint64_t) mcp->mb[2];
2599 if (rd)
2600 *rd = (uint64_t) mcp->mb[9] << 48 |
2601 (uint64_t) mcp->mb[8] << 32 |
2602 (uint64_t) mcp->mb[7] << 16 |
2603 (uint64_t) mcp->mb[6];
2604 }
2605
2606 return rval;
2607}
2608
2609int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002610qla2x00_read_sfp(scsi_qla_host_t *vha, dma_addr_t sfp_dma, uint16_t addr,
Andrew Vasquez88729e52006-06-23 16:10:50 -07002611 uint16_t off, uint16_t count)
2612{
2613 int rval;
2614 mbx_cmd_t mc;
2615 mbx_cmd_t *mcp = &mc;
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002616
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002617 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasquez88729e52006-06-23 16:10:50 -07002618 return QLA_FUNCTION_FAILED;
2619
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002620 DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
Andrew Vasquez88729e52006-06-23 16:10:50 -07002621
2622 mcp->mb[0] = MBC_READ_SFP;
2623 mcp->mb[1] = addr;
2624 mcp->mb[2] = MSW(sfp_dma);
2625 mcp->mb[3] = LSW(sfp_dma);
2626 mcp->mb[6] = MSW(MSD(sfp_dma));
2627 mcp->mb[7] = LSW(MSD(sfp_dma));
2628 mcp->mb[8] = count;
2629 mcp->mb[9] = off;
2630 mcp->mb[10] = 0;
2631 mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2632 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002633 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez88729e52006-06-23 16:10:50 -07002634 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002635 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez88729e52006-06-23 16:10:50 -07002636
2637 if (rval != QLA_SUCCESS) {
2638 DEBUG2_3_11(printk("%s(%ld): failed=%x (%x).\n", __func__,
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002639 vha->host_no, rval, mcp->mb[0]));
Andrew Vasquez88729e52006-06-23 16:10:50 -07002640 } else {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002641 DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
Andrew Vasquez88729e52006-06-23 16:10:50 -07002642 }
2643
2644 return rval;
2645}
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002646
2647int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002648qla2x00_set_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id,
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002649 uint16_t port_speed, uint16_t *mb)
2650{
2651 int rval;
2652 mbx_cmd_t mc;
2653 mbx_cmd_t *mcp = &mc;
2654
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002655 if (!IS_IIDMA_CAPABLE(vha->hw))
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002656 return QLA_FUNCTION_FAILED;
2657
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002658 DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002659
2660 mcp->mb[0] = MBC_PORT_PARAMS;
2661 mcp->mb[1] = loop_id;
2662 mcp->mb[2] = BIT_0;
2663 mcp->mb[3] = port_speed & (BIT_2|BIT_1|BIT_0);
2664 mcp->mb[4] = mcp->mb[5] = 0;
2665 mcp->out_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
2666 mcp->in_mb = MBX_5|MBX_4|MBX_3|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002667 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002668 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002669 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002670
2671 /* Return mailbox statuses. */
2672 if (mb != NULL) {
2673 mb[0] = mcp->mb[0];
2674 mb[1] = mcp->mb[1];
2675 mb[3] = mcp->mb[3];
2676 mb[4] = mcp->mb[4];
2677 mb[5] = mcp->mb[5];
2678 }
2679
2680 if (rval != QLA_SUCCESS) {
2681 DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__,
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002682 vha->host_no, rval));
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002683 } else {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002684 DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002685 }
2686
2687 return rval;
2688}
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002689
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002690void
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002691qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002692 struct vp_rpt_id_entry_24xx *rptid_entry)
2693{
2694 uint8_t vp_idx;
Seokmann Juc6852c42008-04-24 15:21:29 -07002695 uint16_t stat = le16_to_cpu(rptid_entry->vp_idx);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002696 struct qla_hw_data *ha = vha->hw;
2697 scsi_qla_host_t *vp;
Anirban Chakrabortyee546b62009-03-05 11:07:02 -08002698 scsi_qla_host_t *tvp;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002699
2700 if (rptid_entry->entry_status != 0)
2701 return;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002702
2703 if (rptid_entry->format == 0) {
2704 DEBUG15(printk("%s:format 0 : scsi(%ld) number of VPs setup %d,"
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002705 " number of VPs acquired %d\n", __func__, vha->host_no,
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002706 MSB(rptid_entry->vp_count), LSB(rptid_entry->vp_count)));
2707 DEBUG15(printk("%s primary port id %02x%02x%02x\n", __func__,
2708 rptid_entry->port_id[2], rptid_entry->port_id[1],
2709 rptid_entry->port_id[0]));
2710 } else if (rptid_entry->format == 1) {
Seokmann Juc6852c42008-04-24 15:21:29 -07002711 vp_idx = LSB(stat);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002712 DEBUG15(printk("%s:format 1: scsi(%ld): VP[%d] enabled "
2713 "- status %d - "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002714 "with port id %02x%02x%02x\n", __func__, vha->host_no,
Seokmann Juc6852c42008-04-24 15:21:29 -07002715 vp_idx, MSB(stat),
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002716 rptid_entry->port_id[2], rptid_entry->port_id[1],
2717 rptid_entry->port_id[0]));
2718 if (vp_idx == 0)
2719 return;
2720
Seokmann Juc6852c42008-04-24 15:21:29 -07002721 if (MSB(stat) == 1)
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002722 return;
2723
Anirban Chakrabortyee546b62009-03-05 11:07:02 -08002724 list_for_each_entry_safe(vp, tvp, &ha->vp_list, list)
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002725 if (vp_idx == vp->vp_idx)
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002726 break;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002727 if (!vp)
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002728 return;
2729
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002730 vp->d_id.b.domain = rptid_entry->port_id[2];
2731 vp->d_id.b.area = rptid_entry->port_id[1];
2732 vp->d_id.b.al_pa = rptid_entry->port_id[0];
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002733
2734 /*
2735 * Cannot configure here as we are still sitting on the
2736 * response queue. Handle it in dpc context.
2737 */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002738 set_bit(VP_IDX_ACQUIRED, &vp->vp_flags);
2739 set_bit(VP_DPC_NEEDED, &vha->dpc_flags);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002740
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002741 qla2xxx_wake_dpc(vha);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002742 }
2743}
2744
2745/*
2746 * qla24xx_modify_vp_config
2747 * Change VP configuration for vha
2748 *
2749 * Input:
2750 * vha = adapter block pointer.
2751 *
2752 * Returns:
2753 * qla2xxx local function return status code.
2754 *
2755 * Context:
2756 * Kernel context.
2757 */
2758int
2759qla24xx_modify_vp_config(scsi_qla_host_t *vha)
2760{
2761 int rval;
2762 struct vp_config_entry_24xx *vpmod;
2763 dma_addr_t vpmod_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002764 struct qla_hw_data *ha = vha->hw;
2765 struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002766
2767 /* This can be called by the parent */
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002768
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002769 vpmod = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &vpmod_dma);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002770 if (!vpmod) {
2771 DEBUG2_3(printk("%s(%ld): failed to allocate Modify VP "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002772 "IOCB.\n", __func__, vha->host_no));
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002773 return QLA_MEMORY_ALLOC_FAILED;
2774 }
2775
2776 memset(vpmod, 0, sizeof(struct vp_config_entry_24xx));
2777 vpmod->entry_type = VP_CONFIG_IOCB_TYPE;
2778 vpmod->entry_count = 1;
2779 vpmod->command = VCT_COMMAND_MOD_ENABLE_VPS;
2780 vpmod->vp_count = 1;
2781 vpmod->vp_index1 = vha->vp_idx;
2782 vpmod->options_idx1 = BIT_3|BIT_4|BIT_5;
2783 memcpy(vpmod->node_name_idx1, vha->node_name, WWN_SIZE);
2784 memcpy(vpmod->port_name_idx1, vha->port_name, WWN_SIZE);
2785 vpmod->entry_count = 1;
2786
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002787 rval = qla2x00_issue_iocb(base_vha, vpmod, vpmod_dma, 0);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002788 if (rval != QLA_SUCCESS) {
2789 DEBUG2_3_11(printk("%s(%ld): failed to issue VP config IOCB"
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002790 "(%x).\n", __func__, base_vha->host_no, rval));
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002791 } else if (vpmod->comp_status != 0) {
2792 DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002793 "-- error status (%x).\n", __func__, base_vha->host_no,
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002794 vpmod->comp_status));
2795 rval = QLA_FUNCTION_FAILED;
2796 } else if (vpmod->comp_status != __constant_cpu_to_le16(CS_COMPLETE)) {
2797 DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002798 "-- completion status (%x).\n", __func__, base_vha->host_no,
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002799 le16_to_cpu(vpmod->comp_status)));
2800 rval = QLA_FUNCTION_FAILED;
2801 } else {
2802 /* EMPTY */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002803 DEBUG11(printk("%s(%ld): done.\n", __func__,
2804 base_vha->host_no));
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002805 fc_vport_set_state(vha->fc_vport, FC_VPORT_INITIALIZING);
2806 }
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002807 dma_pool_free(ha->s_dma_pool, vpmod, vpmod_dma);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002808
2809 return rval;
2810}
2811
2812/*
2813 * qla24xx_control_vp
2814 * Enable a virtual port for given host
2815 *
2816 * Input:
2817 * ha = adapter block pointer.
2818 * vhba = virtual adapter (unused)
2819 * index = index number for enabled VP
2820 *
2821 * Returns:
2822 * qla2xxx local function return status code.
2823 *
2824 * Context:
2825 * Kernel context.
2826 */
2827int
2828qla24xx_control_vp(scsi_qla_host_t *vha, int cmd)
2829{
2830 int rval;
2831 int map, pos;
2832 struct vp_ctrl_entry_24xx *vce;
2833 dma_addr_t vce_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002834 struct qla_hw_data *ha = vha->hw;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002835 int vp_index = vha->vp_idx;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002836 struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002837
2838 DEBUG11(printk("%s(%ld): entered. Enabling index %d\n", __func__,
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002839 vha->host_no, vp_index));
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002840
Andrew Vasquezeb66dc62007-11-12 10:30:58 -08002841 if (vp_index == 0 || vp_index >= ha->max_npiv_vports)
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002842 return QLA_PARAMETER_ERROR;
2843
2844 vce = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &vce_dma);
2845 if (!vce) {
2846 DEBUG2_3(printk("%s(%ld): "
2847 "failed to allocate VP Control IOCB.\n", __func__,
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002848 base_vha->host_no));
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002849 return QLA_MEMORY_ALLOC_FAILED;
2850 }
2851 memset(vce, 0, sizeof(struct vp_ctrl_entry_24xx));
2852
2853 vce->entry_type = VP_CTRL_IOCB_TYPE;
2854 vce->entry_count = 1;
2855 vce->command = cpu_to_le16(cmd);
2856 vce->vp_count = __constant_cpu_to_le16(1);
2857
2858 /* index map in firmware starts with 1; decrement index
2859 * this is ok as we never use index 0
2860 */
2861 map = (vp_index - 1) / 8;
2862 pos = (vp_index - 1) & 7;
matthias@kaehlcke.net6c2f5272008-05-12 22:21:11 -07002863 mutex_lock(&ha->vport_lock);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002864 vce->vp_idx_map[map] |= 1 << pos;
matthias@kaehlcke.net6c2f5272008-05-12 22:21:11 -07002865 mutex_unlock(&ha->vport_lock);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002866
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002867 rval = qla2x00_issue_iocb(base_vha, vce, vce_dma, 0);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002868 if (rval != QLA_SUCCESS) {
2869 DEBUG2_3_11(printk("%s(%ld): failed to issue VP control IOCB"
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002870 "(%x).\n", __func__, base_vha->host_no, rval));
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002871 printk("%s(%ld): failed to issue VP control IOCB"
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002872 "(%x).\n", __func__, base_vha->host_no, rval);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002873 } else if (vce->entry_status != 0) {
2874 DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002875 "-- error status (%x).\n", __func__, base_vha->host_no,
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002876 vce->entry_status));
2877 printk("%s(%ld): failed to complete IOCB "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002878 "-- error status (%x).\n", __func__, base_vha->host_no,
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002879 vce->entry_status);
2880 rval = QLA_FUNCTION_FAILED;
2881 } else if (vce->comp_status != __constant_cpu_to_le16(CS_COMPLETE)) {
2882 DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002883 "-- completion status (%x).\n", __func__, base_vha->host_no,
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002884 le16_to_cpu(vce->comp_status)));
2885 printk("%s(%ld): failed to complete IOCB "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002886 "-- completion status (%x).\n", __func__, base_vha->host_no,
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002887 le16_to_cpu(vce->comp_status));
2888 rval = QLA_FUNCTION_FAILED;
2889 } else {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002890 DEBUG2(printk("%s(%ld): done.\n", __func__, base_vha->host_no));
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002891 }
2892
2893 dma_pool_free(ha->s_dma_pool, vce, vce_dma);
2894
2895 return rval;
2896}
2897
2898/*
2899 * qla2x00_send_change_request
2900 * Receive or disable RSCN request from fabric controller
2901 *
2902 * Input:
2903 * ha = adapter block pointer
2904 * format = registration format:
2905 * 0 - Reserved
2906 * 1 - Fabric detected registration
2907 * 2 - N_port detected registration
2908 * 3 - Full registration
2909 * FF - clear registration
2910 * vp_idx = Virtual port index
2911 *
2912 * Returns:
2913 * qla2x00 local function return status code.
2914 *
2915 * Context:
2916 * Kernel Context
2917 */
2918
2919int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002920qla2x00_send_change_request(scsi_qla_host_t *vha, uint16_t format,
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002921 uint16_t vp_idx)
2922{
2923 int rval;
2924 mbx_cmd_t mc;
2925 mbx_cmd_t *mcp = &mc;
2926
2927 /*
2928 * This command is implicitly executed by firmware during login for the
2929 * physical hosts
2930 */
2931 if (vp_idx == 0)
2932 return QLA_FUNCTION_FAILED;
2933
2934 mcp->mb[0] = MBC_SEND_CHANGE_REQUEST;
2935 mcp->mb[1] = format;
2936 mcp->mb[9] = vp_idx;
2937 mcp->out_mb = MBX_9|MBX_1|MBX_0;
2938 mcp->in_mb = MBX_0|MBX_1;
2939 mcp->tov = MBX_TOV_SECONDS;
2940 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002941 rval = qla2x00_mailbox_command(vha, mcp);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002942
2943 if (rval == QLA_SUCCESS) {
2944 if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {
2945 rval = BIT_1;
2946 }
2947 } else
2948 rval = BIT_1;
2949
2950 return rval;
2951}
Andrew Vasquez338c9162007-09-20 14:07:33 -07002952
2953int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002954qla2x00_dump_ram(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t addr,
Andrew Vasquez338c9162007-09-20 14:07:33 -07002955 uint32_t size)
2956{
2957 int rval;
2958 mbx_cmd_t mc;
2959 mbx_cmd_t *mcp = &mc;
2960
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002961 DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
Andrew Vasquez338c9162007-09-20 14:07:33 -07002962
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002963 if (MSW(addr) || IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez338c9162007-09-20 14:07:33 -07002964 mcp->mb[0] = MBC_DUMP_RISC_RAM_EXTENDED;
2965 mcp->mb[8] = MSW(addr);
2966 mcp->out_mb = MBX_8|MBX_0;
2967 } else {
2968 mcp->mb[0] = MBC_DUMP_RISC_RAM;
2969 mcp->out_mb = MBX_0;
2970 }
2971 mcp->mb[1] = LSW(addr);
2972 mcp->mb[2] = MSW(req_dma);
2973 mcp->mb[3] = LSW(req_dma);
2974 mcp->mb[6] = MSW(MSD(req_dma));
2975 mcp->mb[7] = LSW(MSD(req_dma));
2976 mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_1;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002977 if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez338c9162007-09-20 14:07:33 -07002978 mcp->mb[4] = MSW(size);
2979 mcp->mb[5] = LSW(size);
2980 mcp->out_mb |= MBX_5|MBX_4;
2981 } else {
2982 mcp->mb[4] = LSW(size);
2983 mcp->out_mb |= MBX_4;
2984 }
2985
2986 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002987 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez338c9162007-09-20 14:07:33 -07002988 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002989 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez338c9162007-09-20 14:07:33 -07002990
2991 if (rval != QLA_SUCCESS) {
2992 DEBUG2_3_11(printk("%s(%ld): failed=%x mb[0]=%x.\n", __func__,
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002993 vha->host_no, rval, mcp->mb[0]));
Andrew Vasquez338c9162007-09-20 14:07:33 -07002994 } else {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002995 DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
Andrew Vasquez338c9162007-09-20 14:07:33 -07002996 }
2997
2998 return rval;
2999}
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003000
3001/* 84XX Support **************************************************************/
3002
3003struct cs84xx_mgmt_cmd {
3004 union {
3005 struct verify_chip_entry_84xx req;
3006 struct verify_chip_rsp_84xx rsp;
3007 } p;
3008};
3009
3010int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003011qla84xx_verify_chip(struct scsi_qla_host *vha, uint16_t *status)
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003012{
3013 int rval, retry;
3014 struct cs84xx_mgmt_cmd *mn;
3015 dma_addr_t mn_dma;
3016 uint16_t options;
3017 unsigned long flags;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003018 struct qla_hw_data *ha = vha->hw;
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003019
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003020 DEBUG16(printk("%s(%ld): entered.\n", __func__, vha->host_no));
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003021
3022 mn = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &mn_dma);
3023 if (mn == NULL) {
3024 DEBUG2_3(printk("%s(%ld): failed to allocate Verify ISP84XX "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003025 "IOCB.\n", __func__, vha->host_no));
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003026 return QLA_MEMORY_ALLOC_FAILED;
3027 }
3028
3029 /* Force Update? */
3030 options = ha->cs84xx->fw_update ? VCO_FORCE_UPDATE : 0;
3031 /* Diagnostic firmware? */
3032 /* options |= MENLO_DIAG_FW; */
3033 /* We update the firmware with only one data sequence. */
3034 options |= VCO_END_OF_DATA;
3035
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003036 do {
Andrew Vasquezc1ec1f12008-04-24 15:21:24 -07003037 retry = 0;
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003038 memset(mn, 0, sizeof(*mn));
3039 mn->p.req.entry_type = VERIFY_CHIP_IOCB_TYPE;
3040 mn->p.req.entry_count = 1;
3041 mn->p.req.options = cpu_to_le16(options);
3042
3043 DEBUG16(printk("%s(%ld): Dump of Verify Request.\n", __func__,
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003044 vha->host_no));
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003045 DEBUG16(qla2x00_dump_buffer((uint8_t *)mn,
3046 sizeof(*mn)));
3047
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003048 rval = qla2x00_issue_iocb_timeout(vha, mn, mn_dma, 0, 120);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003049 if (rval != QLA_SUCCESS) {
3050 DEBUG2_16(printk("%s(%ld): failed to issue Verify "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003051 "IOCB (%x).\n", __func__, vha->host_no, rval));
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003052 goto verify_done;
3053 }
3054
3055 DEBUG16(printk("%s(%ld): Dump of Verify Response.\n", __func__,
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003056 vha->host_no));
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003057 DEBUG16(qla2x00_dump_buffer((uint8_t *)mn,
3058 sizeof(*mn)));
3059
3060 status[0] = le16_to_cpu(mn->p.rsp.comp_status);
3061 status[1] = status[0] == CS_VCS_CHIP_FAILURE ?
3062 le16_to_cpu(mn->p.rsp.failure_code) : 0;
3063 DEBUG2_16(printk("%s(%ld): cs=%x fc=%x\n", __func__,
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003064 vha->host_no, status[0], status[1]));
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003065
3066 if (status[0] != CS_COMPLETE) {
3067 rval = QLA_FUNCTION_FAILED;
3068 if (!(options & VCO_DONT_UPDATE_FW)) {
3069 DEBUG2_16(printk("%s(%ld): Firmware update "
3070 "failed. Retrying without update "
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003071 "firmware.\n", __func__, vha->host_no));
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003072 options |= VCO_DONT_UPDATE_FW;
3073 options &= ~VCO_FORCE_UPDATE;
3074 retry = 1;
3075 }
3076 } else {
3077 DEBUG2_16(printk("%s(%ld): firmware updated to %x.\n",
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003078 __func__, vha->host_no,
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003079 le32_to_cpu(mn->p.rsp.fw_ver)));
3080
3081 /* NOTE: we only update OP firmware. */
3082 spin_lock_irqsave(&ha->cs84xx->access_lock, flags);
3083 ha->cs84xx->op_fw_version =
3084 le32_to_cpu(mn->p.rsp.fw_ver);
3085 spin_unlock_irqrestore(&ha->cs84xx->access_lock,
3086 flags);
3087 }
3088 } while (retry);
3089
3090verify_done:
3091 dma_pool_free(ha->s_dma_pool, mn, mn_dma);
3092
3093 if (rval != QLA_SUCCESS) {
3094 DEBUG2_16(printk("%s(%ld): failed=%x.\n", __func__,
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003095 vha->host_no, rval));
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003096 } else {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003097 DEBUG16(printk("%s(%ld): done.\n", __func__, vha->host_no));
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003098 }
3099
3100 return rval;
3101}
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003102
3103int
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003104qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req)
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003105{
3106 int rval;
3107 unsigned long flags;
3108 mbx_cmd_t mc;
3109 mbx_cmd_t *mcp = &mc;
3110 struct device_reg_25xxmq __iomem *reg;
3111 struct qla_hw_data *ha = vha->hw;
3112
3113 mcp->mb[0] = MBC_INITIALIZE_MULTIQ;
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003114 mcp->mb[1] = req->options;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003115 mcp->mb[2] = MSW(LSD(req->dma));
3116 mcp->mb[3] = LSW(LSD(req->dma));
3117 mcp->mb[6] = MSW(MSD(req->dma));
3118 mcp->mb[7] = LSW(MSD(req->dma));
3119 mcp->mb[5] = req->length;
3120 if (req->rsp)
3121 mcp->mb[10] = req->rsp->id;
3122 mcp->mb[12] = req->qos;
3123 mcp->mb[11] = req->vp_idx;
3124 mcp->mb[13] = req->rid;
3125
3126 reg = (struct device_reg_25xxmq *)((void *)(ha->mqiobase) +
3127 QLA_QUE_PAGE * req->id);
3128
3129 mcp->mb[4] = req->id;
3130 /* que in ptr index */
3131 mcp->mb[8] = 0;
3132 /* que out ptr index */
3133 mcp->mb[9] = 0;
3134 mcp->out_mb = MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8|MBX_7|
3135 MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3136 mcp->in_mb = MBX_0;
3137 mcp->flags = MBX_DMA_OUT;
3138 mcp->tov = 60;
3139
3140 spin_lock_irqsave(&ha->hardware_lock, flags);
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003141 if (!(req->options & BIT_0)) {
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003142 WRT_REG_DWORD(&reg->req_q_in, 0);
3143 WRT_REG_DWORD(&reg->req_q_out, 0);
3144 }
3145 spin_unlock_irqrestore(&ha->hardware_lock, flags);
3146
Anirban Chakraborty17d98632008-12-18 10:06:15 -08003147 rval = qla2x00_mailbox_command(vha, mcp);
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003148 if (rval != QLA_SUCCESS)
3149 DEBUG2_3_11(printk(KERN_WARNING "%s(%ld): failed=%x mb0=%x.\n",
3150 __func__, vha->host_no, rval, mcp->mb[0]));
3151 return rval;
3152}
3153
3154int
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003155qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp)
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003156{
3157 int rval;
3158 unsigned long flags;
3159 mbx_cmd_t mc;
3160 mbx_cmd_t *mcp = &mc;
3161 struct device_reg_25xxmq __iomem *reg;
3162 struct qla_hw_data *ha = vha->hw;
3163
3164 mcp->mb[0] = MBC_INITIALIZE_MULTIQ;
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003165 mcp->mb[1] = rsp->options;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003166 mcp->mb[2] = MSW(LSD(rsp->dma));
3167 mcp->mb[3] = LSW(LSD(rsp->dma));
3168 mcp->mb[6] = MSW(MSD(rsp->dma));
3169 mcp->mb[7] = LSW(MSD(rsp->dma));
3170 mcp->mb[5] = rsp->length;
3171 mcp->mb[11] = rsp->vp_idx;
Andrew Vasquez444786d2009-01-05 11:18:10 -08003172 mcp->mb[14] = rsp->msix->entry;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003173 mcp->mb[13] = rsp->rid;
3174
3175 reg = (struct device_reg_25xxmq *)((void *)(ha->mqiobase) +
3176 QLA_QUE_PAGE * rsp->id);
3177
3178 mcp->mb[4] = rsp->id;
3179 /* que in ptr index */
3180 mcp->mb[8] = 0;
3181 /* que out ptr index */
3182 mcp->mb[9] = 0;
3183 mcp->out_mb = MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8|MBX_7
3184 |MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3185 mcp->in_mb = MBX_0;
3186 mcp->flags = MBX_DMA_OUT;
3187 mcp->tov = 60;
3188
3189 spin_lock_irqsave(&ha->hardware_lock, flags);
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003190 if (!(rsp->options & BIT_0)) {
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003191 WRT_REG_DWORD(&reg->rsp_q_out, 0);
3192 WRT_REG_DWORD(&reg->rsp_q_in, 0);
3193 }
3194
3195 spin_unlock_irqrestore(&ha->hardware_lock, flags);
3196
Anirban Chakraborty17d98632008-12-18 10:06:15 -08003197 rval = qla2x00_mailbox_command(vha, mcp);
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003198 if (rval != QLA_SUCCESS)
3199 DEBUG2_3_11(printk(KERN_WARNING "%s(%ld): failed=%x "
3200 "mb0=%x.\n", __func__,
3201 vha->host_no, rval, mcp->mb[0]));
3202 return rval;
3203}
3204
Andrew Vasquez8a659572009-02-08 20:50:12 -08003205int
3206qla81xx_idc_ack(scsi_qla_host_t *vha, uint16_t *mb)
3207{
3208 int rval;
3209 mbx_cmd_t mc;
3210 mbx_cmd_t *mcp = &mc;
3211
3212 DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
3213
3214 mcp->mb[0] = MBC_IDC_ACK;
3215 memcpy(&mcp->mb[1], mb, QLA_IDC_ACK_REGS * sizeof(uint16_t));
3216 mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3217 mcp->in_mb = MBX_0;
3218 mcp->tov = MBX_TOV_SECONDS;
3219 mcp->flags = 0;
3220 rval = qla2x00_mailbox_command(vha, mcp);
3221
3222 if (rval != QLA_SUCCESS) {
3223 DEBUG2_3_11(printk("%s(%ld): failed=%x (%x).\n", __func__,
3224 vha->host_no, rval, mcp->mb[0]));
3225 } else {
3226 DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
3227 }
3228
3229 return rval;
3230}