Merge branches 'x86-rwsem-for-linus' and 'x86-gcc46-for-linus' of git://git.kernel...
[firefly-linux-kernel-4.4.55.git] / drivers / scsi / qla4xxx / ql4_mbx.c
1 /*
2  * QLogic iSCSI HBA Driver
3  * Copyright (c)  2003-2006 QLogic Corporation
4  *
5  * See LICENSE.qla4xxx for copyright and licensing details.
6  */
7
8 #include "ql4_def.h"
9 #include "ql4_glbl.h"
10 #include "ql4_dbg.h"
11 #include "ql4_inline.h"
12
13
14 /**
15  * qla4xxx_mailbox_command - issues mailbox commands
16  * @ha: Pointer to host adapter structure.
17  * @inCount: number of mailbox registers to load.
18  * @outCount: number of mailbox registers to return.
19  * @mbx_cmd: data pointer for mailbox in registers.
20  * @mbx_sts: data pointer for mailbox out registers.
21  *
22  * This routine isssue mailbox commands and waits for completion.
23  * If outCount is 0, this routine completes successfully WITHOUT waiting
24  * for the mailbox command to complete.
25  **/
26 int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount,
27                             uint8_t outCount, uint32_t *mbx_cmd,
28                             uint32_t *mbx_sts)
29 {
30         int status = QLA_ERROR;
31         uint8_t i;
32         u_long wait_count;
33         uint32_t intr_status;
34         unsigned long flags = 0;
35
36         /* Make sure that pointers are valid */
37         if (!mbx_cmd || !mbx_sts) {
38                 DEBUG2(printk("scsi%ld: %s: Invalid mbx_cmd or mbx_sts "
39                               "pointer\n", ha->host_no, __func__));
40                 return status;
41         }
42         /* Mailbox code active */
43         wait_count = MBOX_TOV * 100;
44
45         while (wait_count--) {
46                 mutex_lock(&ha->mbox_sem);
47                 if (!test_bit(AF_MBOX_COMMAND, &ha->flags)) {
48                         set_bit(AF_MBOX_COMMAND, &ha->flags);
49                         mutex_unlock(&ha->mbox_sem);
50                         break;
51                 }
52                 mutex_unlock(&ha->mbox_sem);
53                 if (!wait_count) {
54                         DEBUG2(printk("scsi%ld: %s: mbox_sem failed\n",
55                                 ha->host_no, __func__));
56                         return status;
57                 }
58                 msleep(10);
59         }
60
61         /* To prevent overwriting mailbox registers for a command that has
62          * not yet been serviced, check to see if an active command
63          * (AEN, IOCB, etc.) is interrupting, then service it.
64          * -----------------------------------------------------------------
65          */
66         spin_lock_irqsave(&ha->hardware_lock, flags);
67
68         if (is_qla8022(ha)) {
69                 intr_status = readl(&ha->qla4_8xxx_reg->host_int);
70                 if (intr_status & ISRX_82XX_RISC_INT) {
71                         /* Service existing interrupt */
72                         DEBUG2(printk("scsi%ld: %s: "
73                             "servicing existing interrupt\n",
74                             ha->host_no, __func__));
75                         intr_status = readl(&ha->qla4_8xxx_reg->host_status);
76                         ha->isp_ops->interrupt_service_routine(ha, intr_status);
77                         clear_bit(AF_MBOX_COMMAND_DONE, &ha->flags);
78                         if (test_bit(AF_INTERRUPTS_ON, &ha->flags) &&
79                             test_bit(AF_INTx_ENABLED, &ha->flags))
80                                 qla4_8xxx_wr_32(ha,
81                                     ha->nx_legacy_intr.tgt_mask_reg,
82                                     0xfbff);
83                 }
84         } else {
85                 intr_status = readl(&ha->reg->ctrl_status);
86                 if (intr_status & CSR_SCSI_PROCESSOR_INTR) {
87                         /* Service existing interrupt */
88                         ha->isp_ops->interrupt_service_routine(ha, intr_status);
89                         clear_bit(AF_MBOX_COMMAND_DONE, &ha->flags);
90                 }
91         }
92
93         ha->mbox_status_count = outCount;
94         for (i = 0; i < outCount; i++)
95                 ha->mbox_status[i] = 0;
96
97         if (is_qla8022(ha)) {
98                 /* Load all mailbox registers, except mailbox 0. */
99                 DEBUG5(
100                     printk("scsi%ld: %s: Cmd ", ha->host_no, __func__);
101                     for (i = 0; i < inCount; i++)
102                         printk("mb%d=%04x ", i, mbx_cmd[i]);
103                     printk("\n"));
104
105                 for (i = 1; i < inCount; i++)
106                         writel(mbx_cmd[i], &ha->qla4_8xxx_reg->mailbox_in[i]);
107                 writel(mbx_cmd[0], &ha->qla4_8xxx_reg->mailbox_in[0]);
108                 readl(&ha->qla4_8xxx_reg->mailbox_in[0]);
109                 writel(HINT_MBX_INT_PENDING, &ha->qla4_8xxx_reg->hint);
110         } else {
111                 /* Load all mailbox registers, except mailbox 0. */
112                 for (i = 1; i < inCount; i++)
113                         writel(mbx_cmd[i], &ha->reg->mailbox[i]);
114
115                 /* Wakeup firmware  */
116                 writel(mbx_cmd[0], &ha->reg->mailbox[0]);
117                 readl(&ha->reg->mailbox[0]);
118                 writel(set_rmask(CSR_INTR_RISC), &ha->reg->ctrl_status);
119                 readl(&ha->reg->ctrl_status);
120         }
121
122         spin_unlock_irqrestore(&ha->hardware_lock, flags);
123
124         /* Wait for completion */
125
126         /*
127          * If we don't want status, don't wait for the mailbox command to
128          * complete.  For example, MBOX_CMD_RESET_FW doesn't return status,
129          * you must poll the inbound Interrupt Mask for completion.
130          */
131         if (outCount == 0) {
132                 status = QLA_SUCCESS;
133                 goto mbox_exit;
134         }
135
136         /*
137          * Wait for completion: Poll or completion queue
138          */
139         if (test_bit(AF_IRQ_ATTACHED, &ha->flags) &&
140             test_bit(AF_INTERRUPTS_ON, &ha->flags) &&
141             test_bit(AF_ONLINE, &ha->flags) &&
142             !test_bit(AF_HBA_GOING_AWAY, &ha->flags)) {
143                 /* Do not poll for completion. Use completion queue */
144                 set_bit(AF_MBOX_COMMAND_NOPOLL, &ha->flags);
145                 wait_for_completion_timeout(&ha->mbx_intr_comp, MBOX_TOV * HZ);
146                 clear_bit(AF_MBOX_COMMAND_NOPOLL, &ha->flags);
147         } else {
148                 /* Poll for command to complete */
149                 wait_count = jiffies + MBOX_TOV * HZ;
150                 while (test_bit(AF_MBOX_COMMAND_DONE, &ha->flags) == 0) {
151                         if (time_after_eq(jiffies, wait_count))
152                                 break;
153                         /*
154                          * Service the interrupt.
155                          * The ISR will save the mailbox status registers
156                          * to a temporary storage location in the adapter
157                          * structure.
158                          */
159
160                         spin_lock_irqsave(&ha->hardware_lock, flags);
161                         if (is_qla8022(ha)) {
162                                 intr_status =
163                                     readl(&ha->qla4_8xxx_reg->host_int);
164                                 if (intr_status & ISRX_82XX_RISC_INT) {
165                                         ha->mbox_status_count = outCount;
166                                         intr_status =
167                                          readl(&ha->qla4_8xxx_reg->host_status);
168                                         ha->isp_ops->interrupt_service_routine(
169                                             ha, intr_status);
170                                         if (test_bit(AF_INTERRUPTS_ON,
171                                             &ha->flags) &&
172                                             test_bit(AF_INTx_ENABLED,
173                                             &ha->flags))
174                                                 qla4_8xxx_wr_32(ha,
175                                                 ha->nx_legacy_intr.tgt_mask_reg,
176                                                 0xfbff);
177                                 }
178                         } else {
179                                 intr_status = readl(&ha->reg->ctrl_status);
180                                 if (intr_status & INTR_PENDING) {
181                                         /*
182                                          * Service the interrupt.
183                                          * The ISR will save the mailbox status
184                                          * registers to a temporary storage
185                                          * location in the adapter structure.
186                                          */
187                                         ha->mbox_status_count = outCount;
188                                         ha->isp_ops->interrupt_service_routine(
189                                             ha, intr_status);
190                                 }
191                         }
192                         spin_unlock_irqrestore(&ha->hardware_lock, flags);
193                         msleep(10);
194                 }
195         }
196
197         /* Check for mailbox timeout. */
198         if (!test_bit(AF_MBOX_COMMAND_DONE, &ha->flags)) {
199                 DEBUG2(printk("scsi%ld: Mailbox Cmd 0x%08X timed out ...,"
200                               " Scheduling Adapter Reset\n", ha->host_no,
201                               mbx_cmd[0]));
202                 ha->mailbox_timeout_count++;
203                 mbx_sts[0] = (-1);
204                 set_bit(DPC_RESET_HA, &ha->dpc_flags);
205                 goto mbox_exit;
206         }
207
208         /*
209          * Copy the mailbox out registers to the caller's mailbox in/out
210          * structure.
211          */
212         spin_lock_irqsave(&ha->hardware_lock, flags);
213         for (i = 0; i < outCount; i++)
214                 mbx_sts[i] = ha->mbox_status[i];
215
216         /* Set return status and error flags (if applicable). */
217         switch (ha->mbox_status[0]) {
218         case MBOX_STS_COMMAND_COMPLETE:
219                 status = QLA_SUCCESS;
220                 break;
221
222         case MBOX_STS_INTERMEDIATE_COMPLETION:
223                 status = QLA_SUCCESS;
224                 break;
225
226         case MBOX_STS_BUSY:
227                 DEBUG2( printk("scsi%ld: %s: Cmd = %08X, ISP BUSY\n",
228                                ha->host_no, __func__, mbx_cmd[0]));
229                 ha->mailbox_timeout_count++;
230                 break;
231
232         default:
233                 DEBUG2(printk("scsi%ld: %s: **** FAILED, cmd = %08X, "
234                               "sts = %08X ****\n", ha->host_no, __func__,
235                               mbx_cmd[0], mbx_sts[0]));
236                 break;
237         }
238         spin_unlock_irqrestore(&ha->hardware_lock, flags);
239
240 mbox_exit:
241         mutex_lock(&ha->mbox_sem);
242         clear_bit(AF_MBOX_COMMAND, &ha->flags);
243         mutex_unlock(&ha->mbox_sem);
244         clear_bit(AF_MBOX_COMMAND_DONE, &ha->flags);
245
246         return status;
247 }
248
249 static uint8_t
250 qla4xxx_set_ifcb(struct scsi_qla_host *ha, uint32_t *mbox_cmd,
251                  uint32_t *mbox_sts, dma_addr_t init_fw_cb_dma)
252 {
253         memset(mbox_cmd, 0, sizeof(mbox_cmd[0]) * MBOX_REG_COUNT);
254         memset(mbox_sts, 0, sizeof(mbox_sts[0]) * MBOX_REG_COUNT);
255         mbox_cmd[0] = MBOX_CMD_INITIALIZE_FIRMWARE;
256         mbox_cmd[1] = 0;
257         mbox_cmd[2] = LSDW(init_fw_cb_dma);
258         mbox_cmd[3] = MSDW(init_fw_cb_dma);
259         mbox_cmd[4] = sizeof(struct addr_ctrl_blk);
260         mbox_cmd[5] = (IFCB_VER_MAX << 8) | IFCB_VER_MIN;
261
262         if (qla4xxx_mailbox_command(ha, 6, 6, mbox_cmd, mbox_sts) !=
263             QLA_SUCCESS) {
264                 DEBUG2(printk(KERN_WARNING "scsi%ld: %s: "
265                               "MBOX_CMD_INITIALIZE_FIRMWARE"
266                               " failed w/ status %04X\n",
267                               ha->host_no, __func__, mbox_sts[0]));
268                 return QLA_ERROR;
269         }
270         return QLA_SUCCESS;
271 }
272
273 static uint8_t
274 qla4xxx_get_ifcb(struct scsi_qla_host *ha, uint32_t *mbox_cmd,
275                  uint32_t *mbox_sts, dma_addr_t init_fw_cb_dma)
276 {
277         memset(mbox_cmd, 0, sizeof(mbox_cmd[0]) * MBOX_REG_COUNT);
278         memset(mbox_sts, 0, sizeof(mbox_sts[0]) * MBOX_REG_COUNT);
279         mbox_cmd[0] = MBOX_CMD_GET_INIT_FW_CTRL_BLOCK;
280         mbox_cmd[2] = LSDW(init_fw_cb_dma);
281         mbox_cmd[3] = MSDW(init_fw_cb_dma);
282         mbox_cmd[4] = sizeof(struct addr_ctrl_blk);
283
284         if (qla4xxx_mailbox_command(ha, 5, 5, mbox_cmd, mbox_sts) !=
285             QLA_SUCCESS) {
286                 DEBUG2(printk(KERN_WARNING "scsi%ld: %s: "
287                               "MBOX_CMD_GET_INIT_FW_CTRL_BLOCK"
288                               " failed w/ status %04X\n",
289                               ha->host_no, __func__, mbox_sts[0]));
290                 return QLA_ERROR;
291         }
292         return QLA_SUCCESS;
293 }
294
295 static void
296 qla4xxx_update_local_ip(struct scsi_qla_host *ha,
297                          struct addr_ctrl_blk  *init_fw_cb)
298 {
299         /* Save IPv4 Address Info */
300         memcpy(ha->ip_address, init_fw_cb->ipv4_addr,
301                 min(sizeof(ha->ip_address), sizeof(init_fw_cb->ipv4_addr)));
302         memcpy(ha->subnet_mask, init_fw_cb->ipv4_subnet,
303                 min(sizeof(ha->subnet_mask), sizeof(init_fw_cb->ipv4_subnet)));
304         memcpy(ha->gateway, init_fw_cb->ipv4_gw_addr,
305                 min(sizeof(ha->gateway), sizeof(init_fw_cb->ipv4_gw_addr)));
306
307         if (is_ipv6_enabled(ha)) {
308                 /* Save IPv6 Address */
309                 ha->ipv6_link_local_state = init_fw_cb->ipv6_lnk_lcl_addr_state;
310                 ha->ipv6_addr0_state = init_fw_cb->ipv6_addr0_state;
311                 ha->ipv6_addr1_state = init_fw_cb->ipv6_addr1_state;
312                 ha->ipv6_default_router_state = init_fw_cb->ipv6_dflt_rtr_state;
313                 ha->ipv6_link_local_addr.in6_u.u6_addr8[0] = 0xFE;
314                 ha->ipv6_link_local_addr.in6_u.u6_addr8[1] = 0x80;
315
316                 memcpy(&ha->ipv6_link_local_addr.in6_u.u6_addr8[8],
317                         init_fw_cb->ipv6_if_id,
318                         min(sizeof(ha->ipv6_link_local_addr)/2,
319                         sizeof(init_fw_cb->ipv6_if_id)));
320                 memcpy(&ha->ipv6_addr0, init_fw_cb->ipv6_addr0,
321                         min(sizeof(ha->ipv6_addr0),
322                         sizeof(init_fw_cb->ipv6_addr0)));
323                 memcpy(&ha->ipv6_addr1, init_fw_cb->ipv6_addr1,
324                         min(sizeof(ha->ipv6_addr1),
325                         sizeof(init_fw_cb->ipv6_addr1)));
326                 memcpy(&ha->ipv6_default_router_addr,
327                         init_fw_cb->ipv6_dflt_rtr_addr,
328                         min(sizeof(ha->ipv6_default_router_addr),
329                         sizeof(init_fw_cb->ipv6_dflt_rtr_addr)));
330         }
331 }
332
333 static uint8_t
334 qla4xxx_update_local_ifcb(struct scsi_qla_host *ha,
335                           uint32_t *mbox_cmd,
336                           uint32_t *mbox_sts,
337                           struct addr_ctrl_blk  *init_fw_cb,
338                           dma_addr_t init_fw_cb_dma)
339 {
340         if (qla4xxx_get_ifcb(ha, mbox_cmd, mbox_sts, init_fw_cb_dma)
341             != QLA_SUCCESS) {
342                 DEBUG2(printk(KERN_WARNING
343                               "scsi%ld: %s: Failed to get init_fw_ctrl_blk\n",
344                               ha->host_no, __func__));
345                 return QLA_ERROR;
346         }
347
348         DEBUG2(qla4xxx_dump_buffer(init_fw_cb, sizeof(struct addr_ctrl_blk)));
349
350         /* Save some info in adapter structure. */
351         ha->acb_version = init_fw_cb->acb_version;
352         ha->firmware_options = le16_to_cpu(init_fw_cb->fw_options);
353         ha->tcp_options = le16_to_cpu(init_fw_cb->ipv4_tcp_opts);
354         ha->ipv4_options = le16_to_cpu(init_fw_cb->ipv4_ip_opts);
355         ha->ipv4_addr_state = le16_to_cpu(init_fw_cb->ipv4_addr_state);
356         ha->heartbeat_interval = init_fw_cb->hb_interval;
357         memcpy(ha->name_string, init_fw_cb->iscsi_name,
358                 min(sizeof(ha->name_string),
359                 sizeof(init_fw_cb->iscsi_name)));
360         /*memcpy(ha->alias, init_fw_cb->Alias,
361                min(sizeof(ha->alias), sizeof(init_fw_cb->Alias)));*/
362
363         /* Save Command Line Paramater info */
364         ha->port_down_retry_count = le16_to_cpu(init_fw_cb->conn_ka_timeout);
365         ha->discovery_wait = ql4xdiscoverywait;
366
367         if (ha->acb_version == ACB_SUPPORTED) {
368                 ha->ipv6_options = init_fw_cb->ipv6_opts;
369                 ha->ipv6_addl_options = init_fw_cb->ipv6_addtl_opts;
370         }
371         qla4xxx_update_local_ip(ha, init_fw_cb);
372
373         return QLA_SUCCESS;
374 }
375
376 /**
377  * qla4xxx_initialize_fw_cb - initializes firmware control block.
378  * @ha: Pointer to host adapter structure.
379  **/
380 int qla4xxx_initialize_fw_cb(struct scsi_qla_host * ha)
381 {
382         struct addr_ctrl_blk *init_fw_cb;
383         dma_addr_t init_fw_cb_dma;
384         uint32_t mbox_cmd[MBOX_REG_COUNT];
385         uint32_t mbox_sts[MBOX_REG_COUNT];
386         int status = QLA_ERROR;
387
388         init_fw_cb = dma_alloc_coherent(&ha->pdev->dev,
389                                         sizeof(struct addr_ctrl_blk),
390                                         &init_fw_cb_dma, GFP_KERNEL);
391         if (init_fw_cb == NULL) {
392                 DEBUG2(printk("scsi%ld: %s: Unable to alloc init_cb\n",
393                               ha->host_no, __func__));
394                 goto exit_init_fw_cb_no_free;
395         }
396         memset(init_fw_cb, 0, sizeof(struct addr_ctrl_blk));
397
398         /* Get Initialize Firmware Control Block. */
399         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
400         memset(&mbox_sts, 0, sizeof(mbox_sts));
401
402         if (qla4xxx_get_ifcb(ha, &mbox_cmd[0], &mbox_sts[0], init_fw_cb_dma) !=
403             QLA_SUCCESS) {
404                 dma_free_coherent(&ha->pdev->dev,
405                                   sizeof(struct addr_ctrl_blk),
406                                   init_fw_cb, init_fw_cb_dma);
407                 goto exit_init_fw_cb;
408         }
409
410         /* Initialize request and response queues. */
411         qla4xxx_init_rings(ha);
412
413         /* Fill in the request and response queue information. */
414         init_fw_cb->rqq_consumer_idx = cpu_to_le16(ha->request_out);
415         init_fw_cb->compq_producer_idx = cpu_to_le16(ha->response_in);
416         init_fw_cb->rqq_len = __constant_cpu_to_le16(REQUEST_QUEUE_DEPTH);
417         init_fw_cb->compq_len = __constant_cpu_to_le16(RESPONSE_QUEUE_DEPTH);
418         init_fw_cb->rqq_addr_lo = cpu_to_le32(LSDW(ha->request_dma));
419         init_fw_cb->rqq_addr_hi = cpu_to_le32(MSDW(ha->request_dma));
420         init_fw_cb->compq_addr_lo = cpu_to_le32(LSDW(ha->response_dma));
421         init_fw_cb->compq_addr_hi = cpu_to_le32(MSDW(ha->response_dma));
422         init_fw_cb->shdwreg_addr_lo = cpu_to_le32(LSDW(ha->shadow_regs_dma));
423         init_fw_cb->shdwreg_addr_hi = cpu_to_le32(MSDW(ha->shadow_regs_dma));
424
425         /* Set up required options. */
426         init_fw_cb->fw_options |=
427                 __constant_cpu_to_le16(FWOPT_SESSION_MODE |
428                                        FWOPT_INITIATOR_MODE);
429         init_fw_cb->fw_options &= __constant_cpu_to_le16(~FWOPT_TARGET_MODE);
430
431         if (qla4xxx_set_ifcb(ha, &mbox_cmd[0], &mbox_sts[0], init_fw_cb_dma)
432                 != QLA_SUCCESS) {
433                 DEBUG2(printk(KERN_WARNING
434                               "scsi%ld: %s: Failed to set init_fw_ctrl_blk\n",
435                               ha->host_no, __func__));
436                 goto exit_init_fw_cb;
437         }
438
439         if (qla4xxx_update_local_ifcb(ha, &mbox_cmd[0], &mbox_sts[0],
440                 init_fw_cb, init_fw_cb_dma) != QLA_SUCCESS) {
441                 DEBUG2(printk("scsi%ld: %s: Failed to update local ifcb\n",
442                                 ha->host_no, __func__));
443                 goto exit_init_fw_cb;
444         }
445         status = QLA_SUCCESS;
446
447 exit_init_fw_cb:
448         dma_free_coherent(&ha->pdev->dev, sizeof(struct addr_ctrl_blk),
449                                 init_fw_cb, init_fw_cb_dma);
450 exit_init_fw_cb_no_free:
451         return status;
452 }
453
454 /**
455  * qla4xxx_get_dhcp_ip_address - gets HBA ip address via DHCP
456  * @ha: Pointer to host adapter structure.
457  **/
458 int qla4xxx_get_dhcp_ip_address(struct scsi_qla_host * ha)
459 {
460         struct addr_ctrl_blk *init_fw_cb;
461         dma_addr_t init_fw_cb_dma;
462         uint32_t mbox_cmd[MBOX_REG_COUNT];
463         uint32_t mbox_sts[MBOX_REG_COUNT];
464
465         init_fw_cb = dma_alloc_coherent(&ha->pdev->dev,
466                                         sizeof(struct addr_ctrl_blk),
467                                         &init_fw_cb_dma, GFP_KERNEL);
468         if (init_fw_cb == NULL) {
469                 printk("scsi%ld: %s: Unable to alloc init_cb\n", ha->host_no,
470                        __func__);
471                 return QLA_ERROR;
472         }
473
474         /* Get Initialize Firmware Control Block. */
475         memset(init_fw_cb, 0, sizeof(struct addr_ctrl_blk));
476         if (qla4xxx_get_ifcb(ha, &mbox_cmd[0], &mbox_sts[0], init_fw_cb_dma) !=
477             QLA_SUCCESS) {
478                 DEBUG2(printk("scsi%ld: %s: Failed to get init_fw_ctrl_blk\n",
479                               ha->host_no, __func__));
480                 dma_free_coherent(&ha->pdev->dev,
481                                   sizeof(struct addr_ctrl_blk),
482                                   init_fw_cb, init_fw_cb_dma);
483                 return QLA_ERROR;
484         }
485
486         /* Save IP Address. */
487         qla4xxx_update_local_ip(ha, init_fw_cb);
488         dma_free_coherent(&ha->pdev->dev, sizeof(struct addr_ctrl_blk),
489                                 init_fw_cb, init_fw_cb_dma);
490
491         return QLA_SUCCESS;
492 }
493
494 /**
495  * qla4xxx_get_firmware_state - gets firmware state of HBA
496  * @ha: Pointer to host adapter structure.
497  **/
498 int qla4xxx_get_firmware_state(struct scsi_qla_host * ha)
499 {
500         uint32_t mbox_cmd[MBOX_REG_COUNT];
501         uint32_t mbox_sts[MBOX_REG_COUNT];
502
503         /* Get firmware version */
504         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
505         memset(&mbox_sts, 0, sizeof(mbox_sts));
506
507         mbox_cmd[0] = MBOX_CMD_GET_FW_STATE;
508
509         if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 4, &mbox_cmd[0], &mbox_sts[0]) !=
510             QLA_SUCCESS) {
511                 DEBUG2(printk("scsi%ld: %s: MBOX_CMD_GET_FW_STATE failed w/ "
512                               "status %04X\n", ha->host_no, __func__,
513                               mbox_sts[0]));
514                 return QLA_ERROR;
515         }
516         ha->firmware_state = mbox_sts[1];
517         ha->board_id = mbox_sts[2];
518         ha->addl_fw_state = mbox_sts[3];
519         DEBUG2(printk("scsi%ld: %s firmware_state=0x%x\n",
520                       ha->host_no, __func__, ha->firmware_state);)
521
522         return QLA_SUCCESS;
523 }
524
525 /**
526  * qla4xxx_get_firmware_status - retrieves firmware status
527  * @ha: Pointer to host adapter structure.
528  **/
529 int qla4xxx_get_firmware_status(struct scsi_qla_host * ha)
530 {
531         uint32_t mbox_cmd[MBOX_REG_COUNT];
532         uint32_t mbox_sts[MBOX_REG_COUNT];
533
534         /* Get firmware version */
535         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
536         memset(&mbox_sts, 0, sizeof(mbox_sts));
537
538         mbox_cmd[0] = MBOX_CMD_GET_FW_STATUS;
539
540         if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 3, &mbox_cmd[0], &mbox_sts[0]) !=
541             QLA_SUCCESS) {
542                 DEBUG2(printk("scsi%ld: %s: MBOX_CMD_GET_FW_STATUS failed w/ "
543                               "status %04X\n", ha->host_no, __func__,
544                               mbox_sts[0]));
545                 return QLA_ERROR;
546         }
547
548         ql4_printk(KERN_INFO, ha, "%ld firmare IOCBs available (%d).\n",
549             ha->host_no, mbox_cmd[2]);
550
551         return QLA_SUCCESS;
552 }
553
554 /**
555  * qla4xxx_get_fwddb_entry - retrieves firmware ddb entry
556  * @ha: Pointer to host adapter structure.
557  * @fw_ddb_index: Firmware's device database index
558  * @fw_ddb_entry: Pointer to firmware's device database entry structure
559  * @num_valid_ddb_entries: Pointer to number of valid ddb entries
560  * @next_ddb_index: Pointer to next valid device database index
561  * @fw_ddb_device_state: Pointer to device state
562  **/
563 int qla4xxx_get_fwddb_entry(struct scsi_qla_host *ha,
564                             uint16_t fw_ddb_index,
565                             struct dev_db_entry *fw_ddb_entry,
566                             dma_addr_t fw_ddb_entry_dma,
567                             uint32_t *num_valid_ddb_entries,
568                             uint32_t *next_ddb_index,
569                             uint32_t *fw_ddb_device_state,
570                             uint32_t *conn_err_detail,
571                             uint16_t *tcp_source_port_num,
572                             uint16_t *connection_id)
573 {
574         int status = QLA_ERROR;
575         uint16_t options;
576         uint32_t mbox_cmd[MBOX_REG_COUNT];
577         uint32_t mbox_sts[MBOX_REG_COUNT];
578
579         /* Make sure the device index is valid */
580         if (fw_ddb_index >= MAX_DDB_ENTRIES) {
581                 DEBUG2(printk("scsi%ld: %s: ddb [%d] out of range.\n",
582                               ha->host_no, __func__, fw_ddb_index));
583                 goto exit_get_fwddb;
584         }
585         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
586         memset(&mbox_sts, 0, sizeof(mbox_sts));
587
588         mbox_cmd[0] = MBOX_CMD_GET_DATABASE_ENTRY;
589         mbox_cmd[1] = (uint32_t) fw_ddb_index;
590         mbox_cmd[2] = LSDW(fw_ddb_entry_dma);
591         mbox_cmd[3] = MSDW(fw_ddb_entry_dma);
592         mbox_cmd[4] = sizeof(struct dev_db_entry);
593
594         if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 7, &mbox_cmd[0], &mbox_sts[0]) ==
595             QLA_ERROR) {
596                 DEBUG2(printk("scsi%ld: %s: MBOX_CMD_GET_DATABASE_ENTRY failed"
597                               " with status 0x%04X\n", ha->host_no, __func__,
598                               mbox_sts[0]));
599                 goto exit_get_fwddb;
600         }
601         if (fw_ddb_index != mbox_sts[1]) {
602                 DEBUG2(printk("scsi%ld: %s: ddb mismatch [%d] != [%d].\n",
603                               ha->host_no, __func__, fw_ddb_index,
604                               mbox_sts[1]));
605                 goto exit_get_fwddb;
606         }
607         if (fw_ddb_entry) {
608                 options = le16_to_cpu(fw_ddb_entry->options);
609                 if (options & DDB_OPT_IPV6_DEVICE) {
610                         ql4_printk(KERN_INFO, ha, "%s: DDB[%d] MB0 %04x Tot %d "
611                                 "Next %d State %04x ConnErr %08x %pI6 "
612                                 ":%04d \"%s\"\n", __func__, fw_ddb_index,
613                                 mbox_sts[0], mbox_sts[2], mbox_sts[3],
614                                 mbox_sts[4], mbox_sts[5],
615                                 fw_ddb_entry->ip_addr,
616                                 le16_to_cpu(fw_ddb_entry->port),
617                                 fw_ddb_entry->iscsi_name);
618                 } else {
619                         ql4_printk(KERN_INFO, ha, "%s: DDB[%d] MB0 %04x Tot %d "
620                                 "Next %d State %04x ConnErr %08x %pI4 "
621                                 ":%04d \"%s\"\n", __func__, fw_ddb_index,
622                                 mbox_sts[0], mbox_sts[2], mbox_sts[3],
623                                 mbox_sts[4], mbox_sts[5],
624                                 fw_ddb_entry->ip_addr,
625                                 le16_to_cpu(fw_ddb_entry->port),
626                                 fw_ddb_entry->iscsi_name);
627                 }
628         }
629         if (num_valid_ddb_entries)
630                 *num_valid_ddb_entries = mbox_sts[2];
631         if (next_ddb_index)
632                 *next_ddb_index = mbox_sts[3];
633         if (fw_ddb_device_state)
634                 *fw_ddb_device_state = mbox_sts[4];
635
636         /*
637          * RA: This mailbox has been changed to pass connection error and
638          * details.  Its true for ISP4010 as per Version E - Not sure when it
639          * was changed.  Get the time2wait from the fw_dd_entry field :
640          * default_time2wait which we call it as minTime2Wait DEV_DB_ENTRY
641          * struct.
642          */
643         if (conn_err_detail)
644                 *conn_err_detail = mbox_sts[5];
645         if (tcp_source_port_num)
646                 *tcp_source_port_num = (uint16_t) (mbox_sts[6] >> 16);
647         if (connection_id)
648                 *connection_id = (uint16_t) mbox_sts[6] & 0x00FF;
649         status = QLA_SUCCESS;
650
651 exit_get_fwddb:
652         return status;
653 }
654
655 /**
656  * qla4xxx_set_fwddb_entry - sets a ddb entry.
657  * @ha: Pointer to host adapter structure.
658  * @fw_ddb_index: Firmware's device database index
659  * @fw_ddb_entry: Pointer to firmware's ddb entry structure, or NULL.
660  *
661  * This routine initializes or updates the adapter's device database
662  * entry for the specified device. It also triggers a login for the
663  * specified device. Therefore, it may also be used as a secondary
664  * login routine when a NULL pointer is specified for the fw_ddb_entry.
665  **/
666 int qla4xxx_set_ddb_entry(struct scsi_qla_host * ha, uint16_t fw_ddb_index,
667                           dma_addr_t fw_ddb_entry_dma)
668 {
669         uint32_t mbox_cmd[MBOX_REG_COUNT];
670         uint32_t mbox_sts[MBOX_REG_COUNT];
671         int status;
672
673         /* Do not wait for completion. The firmware will send us an
674          * ASTS_DATABASE_CHANGED (0x8014) to notify us of the login status.
675          */
676         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
677         memset(&mbox_sts, 0, sizeof(mbox_sts));
678
679         mbox_cmd[0] = MBOX_CMD_SET_DATABASE_ENTRY;
680         mbox_cmd[1] = (uint32_t) fw_ddb_index;
681         mbox_cmd[2] = LSDW(fw_ddb_entry_dma);
682         mbox_cmd[3] = MSDW(fw_ddb_entry_dma);
683         mbox_cmd[4] = sizeof(struct dev_db_entry);
684
685         status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 5, &mbox_cmd[0],
686             &mbox_sts[0]);
687         DEBUG2(printk("scsi%ld: %s: status=%d mbx0=0x%x mbx4=0x%x\n",
688             ha->host_no, __func__, status, mbox_sts[0], mbox_sts[4]);)
689
690         return status;
691 }
692
693 /**
694  * qla4xxx_get_crash_record - retrieves crash record.
695  * @ha: Pointer to host adapter structure.
696  *
697  * This routine retrieves a crash record from the QLA4010 after an 8002h aen.
698  **/
699 void qla4xxx_get_crash_record(struct scsi_qla_host * ha)
700 {
701         uint32_t mbox_cmd[MBOX_REG_COUNT];
702         uint32_t mbox_sts[MBOX_REG_COUNT];
703         struct crash_record *crash_record = NULL;
704         dma_addr_t crash_record_dma = 0;
705         uint32_t crash_record_size = 0;
706
707         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
708         memset(&mbox_sts, 0, sizeof(mbox_cmd));
709
710         /* Get size of crash record. */
711         mbox_cmd[0] = MBOX_CMD_GET_CRASH_RECORD;
712
713         if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 5, &mbox_cmd[0], &mbox_sts[0]) !=
714             QLA_SUCCESS) {
715                 DEBUG2(printk("scsi%ld: %s: ERROR: Unable to retrieve size!\n",
716                               ha->host_no, __func__));
717                 goto exit_get_crash_record;
718         }
719         crash_record_size = mbox_sts[4];
720         if (crash_record_size == 0) {
721                 DEBUG2(printk("scsi%ld: %s: ERROR: Crash record size is 0!\n",
722                               ha->host_no, __func__));
723                 goto exit_get_crash_record;
724         }
725
726         /* Alloc Memory for Crash Record. */
727         crash_record = dma_alloc_coherent(&ha->pdev->dev, crash_record_size,
728                                           &crash_record_dma, GFP_KERNEL);
729         if (crash_record == NULL)
730                 goto exit_get_crash_record;
731
732         /* Get Crash Record. */
733         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
734         memset(&mbox_sts, 0, sizeof(mbox_cmd));
735
736         mbox_cmd[0] = MBOX_CMD_GET_CRASH_RECORD;
737         mbox_cmd[2] = LSDW(crash_record_dma);
738         mbox_cmd[3] = MSDW(crash_record_dma);
739         mbox_cmd[4] = crash_record_size;
740
741         if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 5, &mbox_cmd[0], &mbox_sts[0]) !=
742             QLA_SUCCESS)
743                 goto exit_get_crash_record;
744
745         /* Dump Crash Record. */
746
747 exit_get_crash_record:
748         if (crash_record)
749                 dma_free_coherent(&ha->pdev->dev, crash_record_size,
750                                   crash_record, crash_record_dma);
751 }
752
753 /**
754  * qla4xxx_get_conn_event_log - retrieves connection event log
755  * @ha: Pointer to host adapter structure.
756  **/
757 void qla4xxx_get_conn_event_log(struct scsi_qla_host * ha)
758 {
759         uint32_t mbox_cmd[MBOX_REG_COUNT];
760         uint32_t mbox_sts[MBOX_REG_COUNT];
761         struct conn_event_log_entry *event_log = NULL;
762         dma_addr_t event_log_dma = 0;
763         uint32_t event_log_size = 0;
764         uint32_t num_valid_entries;
765         uint32_t      oldest_entry = 0;
766         uint32_t        max_event_log_entries;
767         uint8_t         i;
768
769
770         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
771         memset(&mbox_sts, 0, sizeof(mbox_cmd));
772
773         /* Get size of crash record. */
774         mbox_cmd[0] = MBOX_CMD_GET_CONN_EVENT_LOG;
775
776         if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 5, &mbox_cmd[0], &mbox_sts[0]) !=
777             QLA_SUCCESS)
778                 goto exit_get_event_log;
779
780         event_log_size = mbox_sts[4];
781         if (event_log_size == 0)
782                 goto exit_get_event_log;
783
784         /* Alloc Memory for Crash Record. */
785         event_log = dma_alloc_coherent(&ha->pdev->dev, event_log_size,
786                                        &event_log_dma, GFP_KERNEL);
787         if (event_log == NULL)
788                 goto exit_get_event_log;
789
790         /* Get Crash Record. */
791         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
792         memset(&mbox_sts, 0, sizeof(mbox_cmd));
793
794         mbox_cmd[0] = MBOX_CMD_GET_CONN_EVENT_LOG;
795         mbox_cmd[2] = LSDW(event_log_dma);
796         mbox_cmd[3] = MSDW(event_log_dma);
797
798         if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 5, &mbox_cmd[0], &mbox_sts[0]) !=
799             QLA_SUCCESS) {
800                 DEBUG2(printk("scsi%ld: %s: ERROR: Unable to retrieve event "
801                               "log!\n", ha->host_no, __func__));
802                 goto exit_get_event_log;
803         }
804
805         /* Dump Event Log. */
806         num_valid_entries = mbox_sts[1];
807
808         max_event_log_entries = event_log_size /
809                 sizeof(struct conn_event_log_entry);
810
811         if (num_valid_entries > max_event_log_entries)
812                 oldest_entry = num_valid_entries % max_event_log_entries;
813
814         DEBUG3(printk("scsi%ld: Connection Event Log Dump (%d entries):\n",
815                       ha->host_no, num_valid_entries));
816
817         if (ql4xextended_error_logging == 3) {
818                 if (oldest_entry == 0) {
819                         /* Circular Buffer has not wrapped around */
820                         for (i=0; i < num_valid_entries; i++) {
821                                 qla4xxx_dump_buffer((uint8_t *)event_log+
822                                                     (i*sizeof(*event_log)),
823                                                     sizeof(*event_log));
824                         }
825                 }
826                 else {
827                         /* Circular Buffer has wrapped around -
828                          * display accordingly*/
829                         for (i=oldest_entry; i < max_event_log_entries; i++) {
830                                 qla4xxx_dump_buffer((uint8_t *)event_log+
831                                                     (i*sizeof(*event_log)),
832                                                     sizeof(*event_log));
833                         }
834                         for (i=0; i < oldest_entry; i++) {
835                                 qla4xxx_dump_buffer((uint8_t *)event_log+
836                                                     (i*sizeof(*event_log)),
837                                                     sizeof(*event_log));
838                         }
839                 }
840         }
841
842 exit_get_event_log:
843         if (event_log)
844                 dma_free_coherent(&ha->pdev->dev, event_log_size, event_log,
845                                   event_log_dma);
846 }
847
848 /**
849  * qla4xxx_abort_task - issues Abort Task
850  * @ha: Pointer to host adapter structure.
851  * @srb: Pointer to srb entry
852  *
853  * This routine performs a LUN RESET on the specified target/lun.
854  * The caller must ensure that the ddb_entry and lun_entry pointers
855  * are valid before calling this routine.
856  **/
857 int qla4xxx_abort_task(struct scsi_qla_host *ha, struct srb *srb)
858 {
859         uint32_t mbox_cmd[MBOX_REG_COUNT];
860         uint32_t mbox_sts[MBOX_REG_COUNT];
861         struct scsi_cmnd *cmd = srb->cmd;
862         int status = QLA_SUCCESS;
863         unsigned long flags = 0;
864         uint32_t index;
865
866         /*
867          * Send abort task command to ISP, so that the ISP will return
868          * request with ABORT status
869          */
870         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
871         memset(&mbox_sts, 0, sizeof(mbox_sts));
872
873         spin_lock_irqsave(&ha->hardware_lock, flags);
874         index = (unsigned long)(unsigned char *)cmd->host_scribble;
875         spin_unlock_irqrestore(&ha->hardware_lock, flags);
876
877         /* Firmware already posted completion on response queue */
878         if (index == MAX_SRBS)
879                 return status;
880
881         mbox_cmd[0] = MBOX_CMD_ABORT_TASK;
882         mbox_cmd[1] = srb->fw_ddb_index;
883         mbox_cmd[2] = index;
884         /* Immediate Command Enable */
885         mbox_cmd[5] = 0x01;
886
887         qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 5, &mbox_cmd[0],
888             &mbox_sts[0]);
889         if (mbox_sts[0] != MBOX_STS_COMMAND_COMPLETE) {
890                 status = QLA_ERROR;
891
892                 DEBUG2(printk(KERN_WARNING "scsi%ld:%d:%d: abort task FAILED: "
893                     "mbx0=%04X, mb1=%04X, mb2=%04X, mb3=%04X, mb4=%04X\n",
894                     ha->host_no, cmd->device->id, cmd->device->lun, mbox_sts[0],
895                     mbox_sts[1], mbox_sts[2], mbox_sts[3], mbox_sts[4]));
896         }
897
898         return status;
899 }
900
901 /**
902  * qla4xxx_reset_lun - issues LUN Reset
903  * @ha: Pointer to host adapter structure.
904  * @ddb_entry: Pointer to device database entry
905  * @lun: lun number
906  *
907  * This routine performs a LUN RESET on the specified target/lun.
908  * The caller must ensure that the ddb_entry and lun_entry pointers
909  * are valid before calling this routine.
910  **/
911 int qla4xxx_reset_lun(struct scsi_qla_host * ha, struct ddb_entry * ddb_entry,
912                       int lun)
913 {
914         uint32_t mbox_cmd[MBOX_REG_COUNT];
915         uint32_t mbox_sts[MBOX_REG_COUNT];
916         int status = QLA_SUCCESS;
917
918         DEBUG2(printk("scsi%ld:%d:%d: lun reset issued\n", ha->host_no,
919                       ddb_entry->fw_ddb_index, lun));
920
921         /*
922          * Send lun reset command to ISP, so that the ISP will return all
923          * outstanding requests with RESET status
924          */
925         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
926         memset(&mbox_sts, 0, sizeof(mbox_sts));
927
928         mbox_cmd[0] = MBOX_CMD_LUN_RESET;
929         mbox_cmd[1] = ddb_entry->fw_ddb_index;
930         mbox_cmd[2] = lun << 8;
931         mbox_cmd[5] = 0x01;     /* Immediate Command Enable */
932
933         qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0], &mbox_sts[0]);
934         if (mbox_sts[0] != MBOX_STS_COMMAND_COMPLETE &&
935             mbox_sts[0] != MBOX_STS_COMMAND_ERROR)
936                 status = QLA_ERROR;
937
938         return status;
939 }
940
941 /**
942  * qla4xxx_reset_target - issues target Reset
943  * @ha: Pointer to host adapter structure.
944  * @db_entry: Pointer to device database entry
945  * @un_entry: Pointer to lun entry structure
946  *
947  * This routine performs a TARGET RESET on the specified target.
948  * The caller must ensure that the ddb_entry pointers
949  * are valid before calling this routine.
950  **/
951 int qla4xxx_reset_target(struct scsi_qla_host *ha,
952                          struct ddb_entry *ddb_entry)
953 {
954         uint32_t mbox_cmd[MBOX_REG_COUNT];
955         uint32_t mbox_sts[MBOX_REG_COUNT];
956         int status = QLA_SUCCESS;
957
958         DEBUG2(printk("scsi%ld:%d: target reset issued\n", ha->host_no,
959                       ddb_entry->fw_ddb_index));
960
961         /*
962          * Send target reset command to ISP, so that the ISP will return all
963          * outstanding requests with RESET status
964          */
965         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
966         memset(&mbox_sts, 0, sizeof(mbox_sts));
967
968         mbox_cmd[0] = MBOX_CMD_TARGET_WARM_RESET;
969         mbox_cmd[1] = ddb_entry->fw_ddb_index;
970         mbox_cmd[5] = 0x01;     /* Immediate Command Enable */
971
972         qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0],
973                                 &mbox_sts[0]);
974         if (mbox_sts[0] != MBOX_STS_COMMAND_COMPLETE &&
975             mbox_sts[0] != MBOX_STS_COMMAND_ERROR)
976                 status = QLA_ERROR;
977
978         return status;
979 }
980
981 int qla4xxx_get_flash(struct scsi_qla_host * ha, dma_addr_t dma_addr,
982                       uint32_t offset, uint32_t len)
983 {
984         uint32_t mbox_cmd[MBOX_REG_COUNT];
985         uint32_t mbox_sts[MBOX_REG_COUNT];
986
987         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
988         memset(&mbox_sts, 0, sizeof(mbox_sts));
989
990         mbox_cmd[0] = MBOX_CMD_READ_FLASH;
991         mbox_cmd[1] = LSDW(dma_addr);
992         mbox_cmd[2] = MSDW(dma_addr);
993         mbox_cmd[3] = offset;
994         mbox_cmd[4] = len;
995
996         if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 2, &mbox_cmd[0], &mbox_sts[0]) !=
997             QLA_SUCCESS) {
998                 DEBUG2(printk("scsi%ld: %s: MBOX_CMD_READ_FLASH, failed w/ "
999                     "status %04X %04X, offset %08x, len %08x\n", ha->host_no,
1000                     __func__, mbox_sts[0], mbox_sts[1], offset, len));
1001                 return QLA_ERROR;
1002         }
1003         return QLA_SUCCESS;
1004 }
1005
1006 /**
1007  * qla4xxx_get_fw_version - gets firmware version
1008  * @ha: Pointer to host adapter structure.
1009  *
1010  * Retrieves the firmware version on HBA. In QLA4010, mailboxes 2 & 3 may
1011  * hold an address for data.  Make sure that we write 0 to those mailboxes,
1012  * if unused.
1013  **/
1014 int qla4xxx_get_fw_version(struct scsi_qla_host * ha)
1015 {
1016         uint32_t mbox_cmd[MBOX_REG_COUNT];
1017         uint32_t mbox_sts[MBOX_REG_COUNT];
1018
1019         /* Get firmware version. */
1020         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
1021         memset(&mbox_sts, 0, sizeof(mbox_sts));
1022
1023         mbox_cmd[0] = MBOX_CMD_ABOUT_FW;
1024
1025         if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 5, &mbox_cmd[0], &mbox_sts[0]) !=
1026             QLA_SUCCESS) {
1027                 DEBUG2(printk("scsi%ld: %s: MBOX_CMD_ABOUT_FW failed w/ "
1028                     "status %04X\n", ha->host_no, __func__, mbox_sts[0]));
1029                 return QLA_ERROR;
1030         }
1031
1032         /* Save firmware version information. */
1033         ha->firmware_version[0] = mbox_sts[1];
1034         ha->firmware_version[1] = mbox_sts[2];
1035         ha->patch_number = mbox_sts[3];
1036         ha->build_number = mbox_sts[4];
1037
1038         return QLA_SUCCESS;
1039 }
1040
1041 static int qla4xxx_get_default_ddb(struct scsi_qla_host *ha,
1042                                    dma_addr_t dma_addr)
1043 {
1044         uint32_t mbox_cmd[MBOX_REG_COUNT];
1045         uint32_t mbox_sts[MBOX_REG_COUNT];
1046
1047         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
1048         memset(&mbox_sts, 0, sizeof(mbox_sts));
1049
1050         mbox_cmd[0] = MBOX_CMD_GET_DATABASE_ENTRY_DEFAULTS;
1051         mbox_cmd[2] = LSDW(dma_addr);
1052         mbox_cmd[3] = MSDW(dma_addr);
1053
1054         if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0], &mbox_sts[0]) !=
1055             QLA_SUCCESS) {
1056                 DEBUG2(printk("scsi%ld: %s: failed status %04X\n",
1057                      ha->host_no, __func__, mbox_sts[0]));
1058                 return QLA_ERROR;
1059         }
1060         return QLA_SUCCESS;
1061 }
1062
1063 static int qla4xxx_req_ddb_entry(struct scsi_qla_host *ha, uint32_t *ddb_index)
1064 {
1065         uint32_t mbox_cmd[MBOX_REG_COUNT];
1066         uint32_t mbox_sts[MBOX_REG_COUNT];
1067
1068         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
1069         memset(&mbox_sts, 0, sizeof(mbox_sts));
1070
1071         mbox_cmd[0] = MBOX_CMD_REQUEST_DATABASE_ENTRY;
1072         mbox_cmd[1] = MAX_PRST_DEV_DB_ENTRIES;
1073
1074         if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 3, &mbox_cmd[0], &mbox_sts[0]) !=
1075             QLA_SUCCESS) {
1076                 if (mbox_sts[0] == MBOX_STS_COMMAND_ERROR) {
1077                         *ddb_index = mbox_sts[2];
1078                 } else {
1079                         DEBUG2(printk("scsi%ld: %s: failed status %04X\n",
1080                              ha->host_no, __func__, mbox_sts[0]));
1081                         return QLA_ERROR;
1082                 }
1083         } else {
1084                 *ddb_index = MAX_PRST_DEV_DB_ENTRIES;
1085         }
1086
1087         return QLA_SUCCESS;
1088 }
1089
1090
1091 int qla4xxx_send_tgts(struct scsi_qla_host *ha, char *ip, uint16_t port)
1092 {
1093         struct dev_db_entry *fw_ddb_entry;
1094         dma_addr_t fw_ddb_entry_dma;
1095         uint32_t ddb_index;
1096         int ret_val = QLA_SUCCESS;
1097
1098
1099         fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev,
1100                                           sizeof(*fw_ddb_entry),
1101                                           &fw_ddb_entry_dma, GFP_KERNEL);
1102         if (!fw_ddb_entry) {
1103                 DEBUG2(printk("scsi%ld: %s: Unable to allocate dma buffer.\n",
1104                               ha->host_no, __func__));
1105                 ret_val = QLA_ERROR;
1106                 goto exit_send_tgts_no_free;
1107         }
1108
1109         ret_val = qla4xxx_get_default_ddb(ha, fw_ddb_entry_dma);
1110         if (ret_val != QLA_SUCCESS)
1111                 goto exit_send_tgts;
1112
1113         ret_val = qla4xxx_req_ddb_entry(ha, &ddb_index);
1114         if (ret_val != QLA_SUCCESS)
1115                 goto exit_send_tgts;
1116
1117         memset(fw_ddb_entry->iscsi_alias, 0,
1118                sizeof(fw_ddb_entry->iscsi_alias));
1119
1120         memset(fw_ddb_entry->iscsi_name, 0,
1121                sizeof(fw_ddb_entry->iscsi_name));
1122
1123         memset(fw_ddb_entry->ip_addr, 0, sizeof(fw_ddb_entry->ip_addr));
1124         memset(fw_ddb_entry->tgt_addr, 0,
1125                sizeof(fw_ddb_entry->tgt_addr));
1126
1127         fw_ddb_entry->options = (DDB_OPT_DISC_SESSION | DDB_OPT_TARGET);
1128         fw_ddb_entry->port = cpu_to_le16(ntohs(port));
1129
1130         fw_ddb_entry->ip_addr[0] = *ip;
1131         fw_ddb_entry->ip_addr[1] = *(ip + 1);
1132         fw_ddb_entry->ip_addr[2] = *(ip + 2);
1133         fw_ddb_entry->ip_addr[3] = *(ip + 3);
1134
1135         ret_val = qla4xxx_set_ddb_entry(ha, ddb_index, fw_ddb_entry_dma);
1136
1137 exit_send_tgts:
1138         dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),
1139                           fw_ddb_entry, fw_ddb_entry_dma);
1140 exit_send_tgts_no_free:
1141         return ret_val;
1142 }
1143