Merge master.kernel.org:/pub/scm/linux/kernel/git/lethal/sh-2.6
[linux-2.6] / 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
10
11 /**
12  * qla4xxx_mailbox_command - issues mailbox commands
13  * @ha: Pointer to host adapter structure.
14  * @inCount: number of mailbox registers to load.
15  * @outCount: number of mailbox registers to return.
16  * @mbx_cmd: data pointer for mailbox in registers.
17  * @mbx_sts: data pointer for mailbox out registers.
18  *
19  * This routine sssue mailbox commands and waits for completion.
20  * If outCount is 0, this routine completes successfully WITHOUT waiting
21  * for the mailbox command to complete.
22  **/
23 int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount,
24                             uint8_t outCount, uint32_t *mbx_cmd,
25                             uint32_t *mbx_sts)
26 {
27         int status = QLA_ERROR;
28         uint8_t i;
29         u_long wait_count;
30         uint32_t intr_status;
31         unsigned long flags = 0;
32         DECLARE_WAITQUEUE(wait, current);
33
34         mutex_lock(&ha->mbox_sem);
35
36         /* Mailbox code active */
37         set_bit(AF_MBOX_COMMAND, &ha->flags);
38
39         /* Make sure that pointers are valid */
40         if (!mbx_cmd || !mbx_sts) {
41                 DEBUG2(printk("scsi%ld: %s: Invalid mbx_cmd or mbx_sts "
42                               "pointer\n", ha->host_no, __func__));
43                 goto mbox_exit;
44         }
45
46         /* To prevent overwriting mailbox registers for a command that has
47          * not yet been serviced, check to see if a previously issued
48          * mailbox command is interrupting.
49          * -----------------------------------------------------------------
50          */
51         spin_lock_irqsave(&ha->hardware_lock, flags);
52         intr_status = readl(&ha->reg->ctrl_status);
53         if (intr_status & CSR_SCSI_PROCESSOR_INTR) {
54                 /* Service existing interrupt */
55                 qla4xxx_interrupt_service_routine(ha, intr_status);
56                 clear_bit(AF_MBOX_COMMAND_DONE, &ha->flags);
57         }
58
59         /* Send the mailbox command to the firmware */
60         ha->mbox_status_count = outCount;
61         for (i = 0; i < outCount; i++)
62                 ha->mbox_status[i] = 0;
63
64         /* Load all mailbox registers, except mailbox 0. */
65         for (i = 1; i < inCount; i++)
66                 writel(mbx_cmd[i], &ha->reg->mailbox[i]);
67
68         /* Wakeup firmware  */
69         writel(mbx_cmd[0], &ha->reg->mailbox[0]);
70         readl(&ha->reg->mailbox[0]);
71         writel(set_rmask(CSR_INTR_RISC), &ha->reg->ctrl_status);
72         readl(&ha->reg->ctrl_status);
73         spin_unlock_irqrestore(&ha->hardware_lock, flags);
74
75         /* Wait for completion */
76         set_current_state(TASK_UNINTERRUPTIBLE);
77         add_wait_queue(&ha->mailbox_wait_queue, &wait);
78
79         /*
80          * If we don't want status, don't wait for the mailbox command to
81          * complete.  For example, MBOX_CMD_RESET_FW doesn't return status,
82          * you must poll the inbound Interrupt Mask for completion.
83          */
84         if (outCount == 0) {
85                 status = QLA_SUCCESS;
86                 set_current_state(TASK_RUNNING);
87                 remove_wait_queue(&ha->mailbox_wait_queue, &wait);
88                 goto mbox_exit;
89         }
90         /* Wait for command to complete */
91         wait_count = jiffies + MBOX_TOV * HZ;
92         while (test_bit(AF_MBOX_COMMAND_DONE, &ha->flags) == 0) {
93                 if (time_after_eq(jiffies, wait_count))
94                         break;
95
96                 spin_lock_irqsave(&ha->hardware_lock, flags);
97                 intr_status = readl(&ha->reg->ctrl_status);
98                 if (intr_status & INTR_PENDING) {
99                         /*
100                          * Service the interrupt.
101                          * The ISR will save the mailbox status registers
102                          * to a temporary storage location in the adapter
103                          * structure.
104                          */
105                         ha->mbox_status_count = outCount;
106                         qla4xxx_interrupt_service_routine(ha, intr_status);
107                 }
108                 spin_unlock_irqrestore(&ha->hardware_lock, flags);
109                 msleep(10);
110         }
111         set_current_state(TASK_RUNNING);
112         remove_wait_queue(&ha->mailbox_wait_queue, &wait);
113
114         /* Check for mailbox timeout. */
115         if (!test_bit(AF_MBOX_COMMAND_DONE, &ha->flags)) {
116                 DEBUG2(printk("scsi%ld: Mailbox Cmd 0x%08X timed out ...,"
117                               " Scheduling Adapter Reset\n", ha->host_no,
118                               mbx_cmd[0]));
119                 ha->mailbox_timeout_count++;
120                 mbx_sts[0] = (-1);
121                 set_bit(DPC_RESET_HA, &ha->dpc_flags);
122                 goto mbox_exit;
123         }
124
125         /*
126          * Copy the mailbox out registers to the caller's mailbox in/out
127          * structure.
128          */
129         spin_lock_irqsave(&ha->hardware_lock, flags);
130         for (i = 0; i < outCount; i++)
131                 mbx_sts[i] = ha->mbox_status[i];
132
133         /* Set return status and error flags (if applicable). */
134         switch (ha->mbox_status[0]) {
135         case MBOX_STS_COMMAND_COMPLETE:
136                 status = QLA_SUCCESS;
137                 break;
138
139         case MBOX_STS_INTERMEDIATE_COMPLETION:
140                 status = QLA_SUCCESS;
141                 break;
142
143         case MBOX_STS_BUSY:
144                 DEBUG2( printk("scsi%ld: %s: Cmd = %08X, ISP BUSY\n",
145                                ha->host_no, __func__, mbx_cmd[0]));
146                 ha->mailbox_timeout_count++;
147                 break;
148
149         default:
150                 DEBUG2(printk("scsi%ld: %s: **** FAILED, cmd = %08X, "
151                               "sts = %08X ****\n", ha->host_no, __func__,
152                               mbx_cmd[0], mbx_sts[0]));
153                 break;
154         }
155         spin_unlock_irqrestore(&ha->hardware_lock, flags);
156
157 mbox_exit:
158         clear_bit(AF_MBOX_COMMAND, &ha->flags);
159         clear_bit(AF_MBOX_COMMAND_DONE, &ha->flags);
160         mutex_unlock(&ha->mbox_sem);
161
162         return status;
163 }
164
165
166 /**
167  * qla4xxx_issue_iocb - issue mailbox iocb command
168  * @ha: adapter state pointer.
169  * @buffer: buffer pointer.
170  * @phys_addr: physical address of buffer.
171  * @size: size of buffer.
172  *
173  * Issues iocbs via mailbox commands.
174  * TARGET_QUEUE_LOCK must be released.
175  * ADAPTER_STATE_LOCK must be released.
176  **/
177 int
178 qla4xxx_issue_iocb(struct scsi_qla_host * ha, void *buffer,
179                    dma_addr_t phys_addr, size_t size)
180 {
181         uint32_t mbox_cmd[MBOX_REG_COUNT];
182         uint32_t mbox_sts[MBOX_REG_COUNT];
183         int status;
184
185         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
186         memset(&mbox_sts, 0, sizeof(mbox_sts));
187         mbox_cmd[0] = MBOX_CMD_EXECUTE_IOCB_A64;
188         mbox_cmd[1] = 0;
189         mbox_cmd[2] = LSDW(phys_addr);
190         mbox_cmd[3] = MSDW(phys_addr);
191         status = qla4xxx_mailbox_command(ha, 4, 1, &mbox_cmd[0], &mbox_sts[0]);
192         return status;
193 }
194
195 int qla4xxx_conn_close_sess_logout(struct scsi_qla_host * ha,
196                                    uint16_t fw_ddb_index,
197                                    uint16_t connection_id,
198                                    uint16_t option)
199 {
200         uint32_t mbox_cmd[MBOX_REG_COUNT];
201         uint32_t mbox_sts[MBOX_REG_COUNT];
202
203         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
204         memset(&mbox_sts, 0, sizeof(mbox_sts));
205         mbox_cmd[0] = MBOX_CMD_CONN_CLOSE_SESS_LOGOUT;
206         mbox_cmd[1] = fw_ddb_index;
207         mbox_cmd[2] = connection_id;
208         mbox_cmd[3] = LOGOUT_OPTION_RELOGIN;
209         if (qla4xxx_mailbox_command(ha, 4, 2, &mbox_cmd[0], &mbox_sts[0]) !=
210             QLA_SUCCESS) {
211                 DEBUG2(printk("scsi%ld: %s: MBOX_CMD_CONN_CLOSE_SESS_LOGOUT "
212                               "option %04x failed sts %04X %04X",
213                               ha->host_no, __func__,
214                               option, mbox_sts[0], mbox_sts[1]));
215                 if (mbox_sts[0] == 0x4005)
216                         DEBUG2(printk("%s reason %04X\n", __func__,
217                                       mbox_sts[1]));
218         }
219         return QLA_SUCCESS;
220 }
221
222 int qla4xxx_clear_database_entry(struct scsi_qla_host * ha,
223                                  uint16_t fw_ddb_index)
224 {
225         uint32_t mbox_cmd[MBOX_REG_COUNT];
226         uint32_t mbox_sts[MBOX_REG_COUNT];
227
228         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
229         memset(&mbox_sts, 0, sizeof(mbox_sts));
230         mbox_cmd[0] = MBOX_CMD_CLEAR_DATABASE_ENTRY;
231         mbox_cmd[1] = fw_ddb_index;
232         if (qla4xxx_mailbox_command(ha, 2, 5, &mbox_cmd[0], &mbox_sts[0]) !=
233             QLA_SUCCESS)
234                 return QLA_ERROR;
235
236         return QLA_SUCCESS;
237 }
238
239 /**
240  * qla4xxx_initialize_fw_cb - initializes firmware control block.
241  * @ha: Pointer to host adapter structure.
242  **/
243 int qla4xxx_initialize_fw_cb(struct scsi_qla_host * ha)
244 {
245         struct init_fw_ctrl_blk *init_fw_cb;
246         dma_addr_t init_fw_cb_dma;
247         uint32_t mbox_cmd[MBOX_REG_COUNT];
248         uint32_t mbox_sts[MBOX_REG_COUNT];
249         int status = QLA_ERROR;
250
251         init_fw_cb = dma_alloc_coherent(&ha->pdev->dev,
252                                         sizeof(struct init_fw_ctrl_blk),
253                                         &init_fw_cb_dma, GFP_KERNEL);
254         if (init_fw_cb == NULL) {
255                 DEBUG2(printk("scsi%ld: %s: Unable to alloc init_cb\n",
256                               ha->host_no, __func__));
257                 return 10;
258         }
259         memset(init_fw_cb, 0, sizeof(struct init_fw_ctrl_blk));
260
261         /* Get Initialize Firmware Control Block. */
262         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
263         memset(&mbox_sts, 0, sizeof(mbox_sts));
264         mbox_cmd[0] = MBOX_CMD_GET_INIT_FW_CTRL_BLOCK;
265         mbox_cmd[2] = LSDW(init_fw_cb_dma);
266         mbox_cmd[3] = MSDW(init_fw_cb_dma);
267         if (qla4xxx_mailbox_command(ha, 4, 1, &mbox_cmd[0], &mbox_sts[0]) !=
268             QLA_SUCCESS) {
269                 dma_free_coherent(&ha->pdev->dev,
270                                   sizeof(struct init_fw_ctrl_blk),
271                                   init_fw_cb, init_fw_cb_dma);
272                 return status;
273         }
274
275         /* Initialize request and response queues. */
276         qla4xxx_init_rings(ha);
277
278         /* Fill in the request and response queue information. */
279         init_fw_cb->ReqQConsumerIndex = cpu_to_le16(ha->request_out);
280         init_fw_cb->ComplQProducerIndex = cpu_to_le16(ha->response_in);
281         init_fw_cb->ReqQLen = __constant_cpu_to_le16(REQUEST_QUEUE_DEPTH);
282         init_fw_cb->ComplQLen = __constant_cpu_to_le16(RESPONSE_QUEUE_DEPTH);
283         init_fw_cb->ReqQAddrLo = cpu_to_le32(LSDW(ha->request_dma));
284         init_fw_cb->ReqQAddrHi = cpu_to_le32(MSDW(ha->request_dma));
285         init_fw_cb->ComplQAddrLo = cpu_to_le32(LSDW(ha->response_dma));
286         init_fw_cb->ComplQAddrHi = cpu_to_le32(MSDW(ha->response_dma));
287         init_fw_cb->ShadowRegBufAddrLo =
288                 cpu_to_le32(LSDW(ha->shadow_regs_dma));
289         init_fw_cb->ShadowRegBufAddrHi =
290                 cpu_to_le32(MSDW(ha->shadow_regs_dma));
291
292         /* Set up required options. */
293         init_fw_cb->FwOptions |=
294                 __constant_cpu_to_le16(FWOPT_SESSION_MODE |
295                                        FWOPT_INITIATOR_MODE);
296         init_fw_cb->FwOptions &= __constant_cpu_to_le16(~FWOPT_TARGET_MODE);
297
298         /* Save some info in adapter structure. */
299         ha->firmware_options = le16_to_cpu(init_fw_cb->FwOptions);
300         ha->tcp_options = le16_to_cpu(init_fw_cb->TCPOptions);
301         ha->heartbeat_interval = init_fw_cb->HeartbeatInterval;
302         memcpy(ha->ip_address, init_fw_cb->IPAddr,
303                min(sizeof(ha->ip_address), sizeof(init_fw_cb->IPAddr)));
304         memcpy(ha->subnet_mask, init_fw_cb->SubnetMask,
305                min(sizeof(ha->subnet_mask), sizeof(init_fw_cb->SubnetMask)));
306         memcpy(ha->gateway, init_fw_cb->GatewayIPAddr,
307                min(sizeof(ha->gateway), sizeof(init_fw_cb->GatewayIPAddr)));
308         memcpy(ha->name_string, init_fw_cb->iSCSINameString,
309                min(sizeof(ha->name_string),
310                    sizeof(init_fw_cb->iSCSINameString)));
311         memcpy(ha->alias, init_fw_cb->Alias,
312                min(sizeof(ha->alias), sizeof(init_fw_cb->Alias)));
313
314         /* Save Command Line Paramater info */
315         ha->port_down_retry_count = le16_to_cpu(init_fw_cb->KeepAliveTimeout);
316         ha->discovery_wait = ql4xdiscoverywait;
317
318         /* Send Initialize Firmware Control Block. */
319         mbox_cmd[0] = MBOX_CMD_INITIALIZE_FIRMWARE;
320         mbox_cmd[1] = 0;
321         mbox_cmd[2] = LSDW(init_fw_cb_dma);
322         mbox_cmd[3] = MSDW(init_fw_cb_dma);
323         if (qla4xxx_mailbox_command(ha, 4, 1, &mbox_cmd[0], &mbox_sts[0]) ==
324             QLA_SUCCESS)
325                 status = QLA_SUCCESS;
326          else {
327                 DEBUG2(printk("scsi%ld: %s: MBOX_CMD_INITIALIZE_FIRMWARE "
328                               "failed w/ status %04X\n", ha->host_no, __func__,
329                               mbox_sts[0]));
330         }
331         dma_free_coherent(&ha->pdev->dev, sizeof(struct init_fw_ctrl_blk),
332                           init_fw_cb, init_fw_cb_dma);
333
334         return status;
335 }
336
337 /**
338  * qla4xxx_get_dhcp_ip_address - gets HBA ip address via DHCP
339  * @ha: Pointer to host adapter structure.
340  **/
341 int qla4xxx_get_dhcp_ip_address(struct scsi_qla_host * ha)
342 {
343         struct init_fw_ctrl_blk *init_fw_cb;
344         dma_addr_t init_fw_cb_dma;
345         uint32_t mbox_cmd[MBOX_REG_COUNT];
346         uint32_t mbox_sts[MBOX_REG_COUNT];
347
348         init_fw_cb = dma_alloc_coherent(&ha->pdev->dev,
349                                         sizeof(struct init_fw_ctrl_blk),
350                                         &init_fw_cb_dma, GFP_KERNEL);
351         if (init_fw_cb == NULL) {
352                 printk("scsi%ld: %s: Unable to alloc init_cb\n", ha->host_no,
353                        __func__);
354                 return 10;
355         }
356
357         /* Get Initialize Firmware Control Block. */
358         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
359         memset(&mbox_sts, 0, sizeof(mbox_sts));
360         memset(init_fw_cb, 0, sizeof(struct init_fw_ctrl_blk));
361         mbox_cmd[0] = MBOX_CMD_GET_INIT_FW_CTRL_BLOCK;
362         mbox_cmd[2] = LSDW(init_fw_cb_dma);
363         mbox_cmd[3] = MSDW(init_fw_cb_dma);
364
365         if (qla4xxx_mailbox_command(ha, 4, 1, &mbox_cmd[0], &mbox_sts[0]) !=
366             QLA_SUCCESS) {
367                 DEBUG2(printk("scsi%ld: %s: Failed to get init_fw_ctrl_blk\n",
368                               ha->host_no, __func__));
369                 dma_free_coherent(&ha->pdev->dev,
370                                   sizeof(struct init_fw_ctrl_blk),
371                                   init_fw_cb, init_fw_cb_dma);
372                 return QLA_ERROR;
373         }
374
375         /* Save IP Address. */
376         memcpy(ha->ip_address, init_fw_cb->IPAddr,
377                min(sizeof(ha->ip_address), sizeof(init_fw_cb->IPAddr)));
378         memcpy(ha->subnet_mask, init_fw_cb->SubnetMask,
379                min(sizeof(ha->subnet_mask), sizeof(init_fw_cb->SubnetMask)));
380         memcpy(ha->gateway, init_fw_cb->GatewayIPAddr,
381                min(sizeof(ha->gateway), sizeof(init_fw_cb->GatewayIPAddr)));
382
383         dma_free_coherent(&ha->pdev->dev, sizeof(struct init_fw_ctrl_blk),
384                           init_fw_cb, init_fw_cb_dma);
385
386         return QLA_SUCCESS;
387 }
388
389 /**
390  * qla4xxx_get_firmware_state - gets firmware state of HBA
391  * @ha: Pointer to host adapter structure.
392  **/
393 int qla4xxx_get_firmware_state(struct scsi_qla_host * ha)
394 {
395         uint32_t mbox_cmd[MBOX_REG_COUNT];
396         uint32_t mbox_sts[MBOX_REG_COUNT];
397
398         /* Get firmware version */
399         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
400         memset(&mbox_sts, 0, sizeof(mbox_sts));
401         mbox_cmd[0] = MBOX_CMD_GET_FW_STATE;
402         if (qla4xxx_mailbox_command(ha, 1, 4, &mbox_cmd[0], &mbox_sts[0]) !=
403             QLA_SUCCESS) {
404                 DEBUG2(printk("scsi%ld: %s: MBOX_CMD_GET_FW_STATE failed w/ "
405                               "status %04X\n", ha->host_no, __func__,
406                               mbox_sts[0]));
407                 return QLA_ERROR;
408         }
409         ha->firmware_state = mbox_sts[1];
410         ha->board_id = mbox_sts[2];
411         ha->addl_fw_state = mbox_sts[3];
412         DEBUG2(printk("scsi%ld: %s firmware_state=0x%x\n",
413                       ha->host_no, __func__, ha->firmware_state);)
414
415                 return QLA_SUCCESS;
416 }
417
418 /**
419  * qla4xxx_get_firmware_status - retrieves firmware status
420  * @ha: Pointer to host adapter structure.
421  **/
422 int qla4xxx_get_firmware_status(struct scsi_qla_host * ha)
423 {
424         uint32_t mbox_cmd[MBOX_REG_COUNT];
425         uint32_t mbox_sts[MBOX_REG_COUNT];
426
427         /* Get firmware version */
428         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
429         memset(&mbox_sts, 0, sizeof(mbox_sts));
430         mbox_cmd[0] = MBOX_CMD_GET_FW_STATUS;
431         if (qla4xxx_mailbox_command(ha, 1, 3, &mbox_cmd[0], &mbox_sts[0]) !=
432             QLA_SUCCESS) {
433                 DEBUG2(printk("scsi%ld: %s: MBOX_CMD_GET_FW_STATUS failed w/ "
434                               "status %04X\n", ha->host_no, __func__,
435                               mbox_sts[0]));
436                 return QLA_ERROR;
437         }
438
439         /* High-water mark of IOCBs */
440         ha->iocb_hiwat = mbox_sts[2];
441         if (ha->iocb_hiwat > IOCB_HIWAT_CUSHION)
442                 ha->iocb_hiwat -= IOCB_HIWAT_CUSHION;
443         else
444                 dev_info(&ha->pdev->dev, "WARNING!!!  You have less than %d "
445                            "firmare IOCBs available (%d).\n",
446                            IOCB_HIWAT_CUSHION, ha->iocb_hiwat);
447
448         return QLA_SUCCESS;
449 }
450
451 /**
452  * qla4xxx_get_fwddb_entry - retrieves firmware ddb entry
453  * @ha: Pointer to host adapter structure.
454  * @fw_ddb_index: Firmware's device database index
455  * @fw_ddb_entry: Pointer to firmware's device database entry structure
456  * @num_valid_ddb_entries: Pointer to number of valid ddb entries
457  * @next_ddb_index: Pointer to next valid device database index
458  * @fw_ddb_device_state: Pointer to device state
459  **/
460 int qla4xxx_get_fwddb_entry(struct scsi_qla_host *ha,
461                             uint16_t fw_ddb_index,
462                             struct dev_db_entry *fw_ddb_entry,
463                             dma_addr_t fw_ddb_entry_dma,
464                             uint32_t *num_valid_ddb_entries,
465                             uint32_t *next_ddb_index,
466                             uint32_t *fw_ddb_device_state,
467                             uint32_t *conn_err_detail,
468                             uint16_t *tcp_source_port_num,
469                             uint16_t *connection_id)
470 {
471         int status = QLA_ERROR;
472         uint32_t mbox_cmd[MBOX_REG_COUNT];
473         uint32_t mbox_sts[MBOX_REG_COUNT];
474
475         /* Make sure the device index is valid */
476         if (fw_ddb_index >= MAX_DDB_ENTRIES) {
477                 DEBUG2(printk("scsi%ld: %s: index [%d] out of range.\n",
478                               ha->host_no, __func__, fw_ddb_index));
479                 goto exit_get_fwddb;
480         }
481         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
482         memset(&mbox_sts, 0, sizeof(mbox_sts));
483         mbox_cmd[0] = MBOX_CMD_GET_DATABASE_ENTRY;
484         mbox_cmd[1] = (uint32_t) fw_ddb_index;
485         mbox_cmd[2] = LSDW(fw_ddb_entry_dma);
486         mbox_cmd[3] = MSDW(fw_ddb_entry_dma);
487         if (qla4xxx_mailbox_command(ha, 4, 7, &mbox_cmd[0], &mbox_sts[0]) ==
488             QLA_ERROR) {
489                 DEBUG2(printk("scsi%ld: %s: MBOX_CMD_GET_DATABASE_ENTRY failed"
490                               " with status 0x%04X\n", ha->host_no, __func__,
491                               mbox_sts[0]));
492                 goto exit_get_fwddb;
493         }
494         if (fw_ddb_index != mbox_sts[1]) {
495                 DEBUG2(printk("scsi%ld: %s: index mismatch [%d] != [%d].\n",
496                               ha->host_no, __func__, fw_ddb_index,
497                               mbox_sts[1]));
498                 goto exit_get_fwddb;
499         }
500         if (fw_ddb_entry) {
501                 dev_info(&ha->pdev->dev, "DDB[%d] MB0 %04x Tot %d Next %d "
502                            "State %04x ConnErr %08x %d.%d.%d.%d:%04d \"%s\"\n",
503                            fw_ddb_index, mbox_sts[0], mbox_sts[2], mbox_sts[3],
504                            mbox_sts[4], mbox_sts[5], fw_ddb_entry->ipAddr[0],
505                            fw_ddb_entry->ipAddr[1], fw_ddb_entry->ipAddr[2],
506                            fw_ddb_entry->ipAddr[3],
507                            le16_to_cpu(fw_ddb_entry->portNumber),
508                            fw_ddb_entry->iscsiName);
509         }
510         if (num_valid_ddb_entries)
511                 *num_valid_ddb_entries = mbox_sts[2];
512         if (next_ddb_index)
513                 *next_ddb_index = mbox_sts[3];
514         if (fw_ddb_device_state)
515                 *fw_ddb_device_state = mbox_sts[4];
516
517         /*
518          * RA: This mailbox has been changed to pass connection error and
519          * details.  Its true for ISP4010 as per Version E - Not sure when it
520          * was changed.  Get the time2wait from the fw_dd_entry field :
521          * default_time2wait which we call it as minTime2Wait DEV_DB_ENTRY
522          * struct.
523          */
524         if (conn_err_detail)
525                 *conn_err_detail = mbox_sts[5];
526         if (tcp_source_port_num)
527                 *tcp_source_port_num = (uint16_t) mbox_sts[6] >> 16;
528         if (connection_id)
529                 *connection_id = (uint16_t) mbox_sts[6] & 0x00FF;
530         status = QLA_SUCCESS;
531
532 exit_get_fwddb:
533         return status;
534 }
535
536 /**
537  * qla4xxx_set_fwddb_entry - sets a ddb entry.
538  * @ha: Pointer to host adapter structure.
539  * @fw_ddb_index: Firmware's device database index
540  * @fw_ddb_entry: Pointer to firmware's ddb entry structure, or NULL.
541  *
542  * This routine initializes or updates the adapter's device database
543  * entry for the specified device. It also triggers a login for the
544  * specified device. Therefore, it may also be used as a secondary
545  * login routine when a NULL pointer is specified for the fw_ddb_entry.
546  **/
547 int qla4xxx_set_ddb_entry(struct scsi_qla_host * ha, uint16_t fw_ddb_index,
548                           dma_addr_t fw_ddb_entry_dma)
549 {
550         uint32_t mbox_cmd[MBOX_REG_COUNT];
551         uint32_t mbox_sts[MBOX_REG_COUNT];
552
553         /* Do not wait for completion. The firmware will send us an
554          * ASTS_DATABASE_CHANGED (0x8014) to notify us of the login status.
555          */
556         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
557         memset(&mbox_sts, 0, sizeof(mbox_sts));
558
559         mbox_cmd[0] = MBOX_CMD_SET_DATABASE_ENTRY;
560         mbox_cmd[1] = (uint32_t) fw_ddb_index;
561         mbox_cmd[2] = LSDW(fw_ddb_entry_dma);
562         mbox_cmd[3] = MSDW(fw_ddb_entry_dma);
563         return qla4xxx_mailbox_command(ha, 4, 1, &mbox_cmd[0], &mbox_sts[0]);
564 }
565
566 int qla4xxx_conn_open_session_login(struct scsi_qla_host * ha,
567                                     uint16_t fw_ddb_index)
568 {
569         int status = QLA_ERROR;
570         uint32_t mbox_cmd[MBOX_REG_COUNT];
571         uint32_t mbox_sts[MBOX_REG_COUNT];
572
573         /* Do not wait for completion. The firmware will send us an
574          * ASTS_DATABASE_CHANGED (0x8014) to notify us of the login status.
575          */
576         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
577         memset(&mbox_sts, 0, sizeof(mbox_sts));
578         mbox_cmd[0] = MBOX_CMD_CONN_OPEN_SESS_LOGIN;
579         mbox_cmd[1] = (uint32_t) fw_ddb_index;
580         mbox_cmd[2] = 0;
581         mbox_cmd[3] = 0;
582         mbox_cmd[4] = 0;
583         status = qla4xxx_mailbox_command(ha, 4, 0, &mbox_cmd[0], &mbox_sts[0]);
584         DEBUG2(printk("%s fw_ddb_index=%d status=%d mbx0_1=0x%x :0x%x\n",
585                       __func__, fw_ddb_index, status, mbox_sts[0],
586                       mbox_sts[1]);)
587
588                 return status;
589 }
590
591 /**
592  * qla4xxx_get_crash_record - retrieves crash record.
593  * @ha: Pointer to host adapter structure.
594  *
595  * This routine retrieves a crash record from the QLA4010 after an 8002h aen.
596  **/
597 void qla4xxx_get_crash_record(struct scsi_qla_host * ha)
598 {
599         uint32_t mbox_cmd[MBOX_REG_COUNT];
600         uint32_t mbox_sts[MBOX_REG_COUNT];
601         struct crash_record *crash_record = NULL;
602         dma_addr_t crash_record_dma = 0;
603         uint32_t crash_record_size = 0;
604         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
605         memset(&mbox_sts, 0, sizeof(mbox_cmd));
606
607         /* Get size of crash record. */
608         mbox_cmd[0] = MBOX_CMD_GET_CRASH_RECORD;
609         if (qla4xxx_mailbox_command(ha, 5, 5, &mbox_cmd[0], &mbox_sts[0]) !=
610             QLA_SUCCESS) {
611                 DEBUG2(printk("scsi%ld: %s: ERROR: Unable to retrieve size!\n",
612                               ha->host_no, __func__));
613                 goto exit_get_crash_record;
614         }
615         crash_record_size = mbox_sts[4];
616         if (crash_record_size == 0) {
617                 DEBUG2(printk("scsi%ld: %s: ERROR: Crash record size is 0!\n",
618                               ha->host_no, __func__));
619                 goto exit_get_crash_record;
620         }
621
622         /* Alloc Memory for Crash Record. */
623         crash_record = dma_alloc_coherent(&ha->pdev->dev, crash_record_size,
624                                           &crash_record_dma, GFP_KERNEL);
625         if (crash_record == NULL)
626                 goto exit_get_crash_record;
627
628         /* Get Crash Record. */
629         mbox_cmd[0] = MBOX_CMD_GET_CRASH_RECORD;
630         mbox_cmd[2] = LSDW(crash_record_dma);
631         mbox_cmd[3] = MSDW(crash_record_dma);
632         mbox_cmd[4] = crash_record_size;
633         if (qla4xxx_mailbox_command(ha, 5, 5, &mbox_cmd[0], &mbox_sts[0]) !=
634             QLA_SUCCESS)
635                 goto exit_get_crash_record;
636
637         /* Dump Crash Record. */
638
639 exit_get_crash_record:
640         if (crash_record)
641                 dma_free_coherent(&ha->pdev->dev, crash_record_size,
642                                   crash_record, crash_record_dma);
643 }
644
645 /**
646  * qla4xxx_get_conn_event_log - retrieves connection event log
647  * @ha: Pointer to host adapter structure.
648  **/
649 void qla4xxx_get_conn_event_log(struct scsi_qla_host * ha)
650 {
651         uint32_t mbox_cmd[MBOX_REG_COUNT];
652         uint32_t mbox_sts[MBOX_REG_COUNT];
653         struct conn_event_log_entry *event_log = NULL;
654         dma_addr_t event_log_dma = 0;
655         uint32_t event_log_size = 0;
656         uint32_t num_valid_entries;
657         uint32_t      oldest_entry = 0;
658         uint32_t        max_event_log_entries;
659         uint8_t         i;
660
661
662         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
663         memset(&mbox_sts, 0, sizeof(mbox_cmd));
664
665         /* Get size of crash record. */
666         mbox_cmd[0] = MBOX_CMD_GET_CONN_EVENT_LOG;
667         if (qla4xxx_mailbox_command(ha, 4, 5, &mbox_cmd[0], &mbox_sts[0]) !=
668             QLA_SUCCESS)
669                 goto exit_get_event_log;
670
671         event_log_size = mbox_sts[4];
672         if (event_log_size == 0)
673                 goto exit_get_event_log;
674
675         /* Alloc Memory for Crash Record. */
676         event_log = dma_alloc_coherent(&ha->pdev->dev, event_log_size,
677                                        &event_log_dma, GFP_KERNEL);
678         if (event_log == NULL)
679                 goto exit_get_event_log;
680
681         /* Get Crash Record. */
682         mbox_cmd[0] = MBOX_CMD_GET_CONN_EVENT_LOG;
683         mbox_cmd[2] = LSDW(event_log_dma);
684         mbox_cmd[3] = MSDW(event_log_dma);
685         if (qla4xxx_mailbox_command(ha, 4, 5, &mbox_cmd[0], &mbox_sts[0]) !=
686             QLA_SUCCESS) {
687                 DEBUG2(printk("scsi%ld: %s: ERROR: Unable to retrieve event "
688                               "log!\n", ha->host_no, __func__));
689                 goto exit_get_event_log;
690         }
691
692         /* Dump Event Log. */
693         num_valid_entries = mbox_sts[1];
694
695         max_event_log_entries = event_log_size /
696                 sizeof(struct conn_event_log_entry);
697
698         if (num_valid_entries > max_event_log_entries)
699                 oldest_entry = num_valid_entries % max_event_log_entries;
700
701         DEBUG3(printk("scsi%ld: Connection Event Log Dump (%d entries):\n",
702                       ha->host_no, num_valid_entries));
703
704         if (ql4xextended_error_logging == 3) {
705                 if (oldest_entry == 0) {
706                         /* Circular Buffer has not wrapped around */
707                         for (i=0; i < num_valid_entries; i++) {
708                                 qla4xxx_dump_buffer((uint8_t *)event_log+
709                                                     (i*sizeof(*event_log)),
710                                                     sizeof(*event_log));
711                         }
712                 }
713                 else {
714                         /* Circular Buffer has wrapped around -
715                          * display accordingly*/
716                         for (i=oldest_entry; i < max_event_log_entries; i++) {
717                                 qla4xxx_dump_buffer((uint8_t *)event_log+
718                                                     (i*sizeof(*event_log)),
719                                                     sizeof(*event_log));
720                         }
721                         for (i=0; i < oldest_entry; i++) {
722                                 qla4xxx_dump_buffer((uint8_t *)event_log+
723                                                     (i*sizeof(*event_log)),
724                                                     sizeof(*event_log));
725                         }
726                 }
727         }
728
729 exit_get_event_log:
730         if (event_log)
731                 dma_free_coherent(&ha->pdev->dev, event_log_size, event_log,
732                                   event_log_dma);
733 }
734
735 /**
736  * qla4xxx_reset_lun - issues LUN Reset
737  * @ha: Pointer to host adapter structure.
738  * @db_entry: Pointer to device database entry
739  * @un_entry: Pointer to lun entry structure
740  *
741  * This routine performs a LUN RESET on the specified target/lun.
742  * The caller must ensure that the ddb_entry and lun_entry pointers
743  * are valid before calling this routine.
744  **/
745 int qla4xxx_reset_lun(struct scsi_qla_host * ha, struct ddb_entry * ddb_entry,
746                       int lun)
747 {
748         uint32_t mbox_cmd[MBOX_REG_COUNT];
749         uint32_t mbox_sts[MBOX_REG_COUNT];
750         int status = QLA_SUCCESS;
751
752         DEBUG2(printk("scsi%ld:%d:%d: lun reset issued\n", ha->host_no,
753                       ddb_entry->os_target_id, lun));
754
755         /*
756          * Send lun reset command to ISP, so that the ISP will return all
757          * outstanding requests with RESET status
758          */
759         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
760         memset(&mbox_sts, 0, sizeof(mbox_sts));
761         mbox_cmd[0] = MBOX_CMD_LUN_RESET;
762         mbox_cmd[1] = ddb_entry->fw_ddb_index;
763         mbox_cmd[2] = lun << 8;
764         mbox_cmd[5] = 0x01;     /* Immediate Command Enable */
765         qla4xxx_mailbox_command(ha, 6, 1, &mbox_cmd[0], &mbox_sts[0]);
766         if (mbox_sts[0] != MBOX_STS_COMMAND_COMPLETE &&
767             mbox_sts[0] != MBOX_STS_COMMAND_ERROR)
768                 status = QLA_ERROR;
769
770         return status;
771 }
772
773
774 int qla4xxx_get_flash(struct scsi_qla_host * ha, dma_addr_t dma_addr,
775                       uint32_t offset, uint32_t len)
776 {
777         uint32_t mbox_cmd[MBOX_REG_COUNT];
778         uint32_t mbox_sts[MBOX_REG_COUNT];
779
780         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
781         memset(&mbox_sts, 0, sizeof(mbox_sts));
782         mbox_cmd[0] = MBOX_CMD_READ_FLASH;
783         mbox_cmd[1] = LSDW(dma_addr);
784         mbox_cmd[2] = MSDW(dma_addr);
785         mbox_cmd[3] = offset;
786         mbox_cmd[4] = len;
787         if (qla4xxx_mailbox_command(ha, 5, 2, &mbox_cmd[0], &mbox_sts[0]) !=
788             QLA_SUCCESS) {
789                 DEBUG2(printk("scsi%ld: %s: MBOX_CMD_READ_FLASH, failed w/ "
790                     "status %04X %04X, offset %08x, len %08x\n", ha->host_no,
791                     __func__, mbox_sts[0], mbox_sts[1], offset, len));
792                 return QLA_ERROR;
793         }
794         return QLA_SUCCESS;
795 }
796
797 /**
798  * qla4xxx_get_fw_version - gets firmware version
799  * @ha: Pointer to host adapter structure.
800  *
801  * Retrieves the firmware version on HBA. In QLA4010, mailboxes 2 & 3 may
802  * hold an address for data.  Make sure that we write 0 to those mailboxes,
803  * if unused.
804  **/
805 int qla4xxx_get_fw_version(struct scsi_qla_host * ha)
806 {
807         uint32_t mbox_cmd[MBOX_REG_COUNT];
808         uint32_t mbox_sts[MBOX_REG_COUNT];
809
810         /* Get firmware version. */
811         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
812         memset(&mbox_sts, 0, sizeof(mbox_sts));
813         mbox_cmd[0] = MBOX_CMD_ABOUT_FW;
814         if (qla4xxx_mailbox_command(ha, 4, 5, &mbox_cmd[0], &mbox_sts[0]) !=
815             QLA_SUCCESS) {
816                 DEBUG2(printk("scsi%ld: %s: MBOX_CMD_ABOUT_FW failed w/ "
817                     "status %04X\n", ha->host_no, __func__, mbox_sts[0]));
818                 return QLA_ERROR;
819         }
820
821         /* Save firmware version information. */
822         ha->firmware_version[0] = mbox_sts[1];
823         ha->firmware_version[1] = mbox_sts[2];
824         ha->patch_number = mbox_sts[3];
825         ha->build_number = mbox_sts[4];
826
827         return QLA_SUCCESS;
828 }
829
830 int qla4xxx_get_default_ddb(struct scsi_qla_host *ha, dma_addr_t dma_addr)
831 {
832         uint32_t mbox_cmd[MBOX_REG_COUNT];
833         uint32_t mbox_sts[MBOX_REG_COUNT];
834
835         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
836         memset(&mbox_sts, 0, sizeof(mbox_sts));
837
838         mbox_cmd[0] = MBOX_CMD_GET_DATABASE_ENTRY_DEFAULTS;
839         mbox_cmd[2] = LSDW(dma_addr);
840         mbox_cmd[3] = MSDW(dma_addr);
841
842         if (qla4xxx_mailbox_command(ha, 4, 1, &mbox_cmd[0], &mbox_sts[0]) !=
843             QLA_SUCCESS) {
844                 DEBUG2(printk("scsi%ld: %s: failed status %04X\n",
845                      ha->host_no, __func__, mbox_sts[0]));
846                 return QLA_ERROR;
847         }
848         return QLA_SUCCESS;
849 }
850
851 int qla4xxx_req_ddb_entry(struct scsi_qla_host *ha, uint32_t *ddb_index)
852 {
853         uint32_t mbox_cmd[MBOX_REG_COUNT];
854         uint32_t mbox_sts[MBOX_REG_COUNT];
855
856         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
857         memset(&mbox_sts, 0, sizeof(mbox_sts));
858
859         mbox_cmd[0] = MBOX_CMD_REQUEST_DATABASE_ENTRY;
860         mbox_cmd[1] = MAX_PRST_DEV_DB_ENTRIES;
861
862         if (qla4xxx_mailbox_command(ha, 2, 3, &mbox_cmd[0], &mbox_sts[0]) !=
863             QLA_SUCCESS) {
864                 if (mbox_sts[0] == MBOX_STS_COMMAND_ERROR) {
865                         *ddb_index = mbox_sts[2];
866                 } else {
867                         DEBUG2(printk("scsi%ld: %s: failed status %04X\n",
868                              ha->host_no, __func__, mbox_sts[0]));
869                         return QLA_ERROR;
870                 }
871         } else {
872                 *ddb_index = MAX_PRST_DEV_DB_ENTRIES;
873         }
874
875         return QLA_SUCCESS;
876 }
877
878
879 int qla4xxx_send_tgts(struct scsi_qla_host *ha, char *ip, uint16_t port)
880 {
881         struct dev_db_entry *fw_ddb_entry;
882         dma_addr_t fw_ddb_entry_dma;
883         uint32_t ddb_index;
884         int ret_val = QLA_SUCCESS;
885
886
887         fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev,
888                                           sizeof(*fw_ddb_entry),
889                                           &fw_ddb_entry_dma, GFP_KERNEL);
890         if (!fw_ddb_entry) {
891                 DEBUG2(printk("scsi%ld: %s: Unable to allocate dma buffer.\n",
892                               ha->host_no, __func__));
893                 ret_val = QLA_ERROR;
894                 goto qla4xxx_send_tgts_exit;
895         }
896
897         ret_val = qla4xxx_get_default_ddb(ha, fw_ddb_entry_dma);
898         if (ret_val != QLA_SUCCESS)
899                 goto qla4xxx_send_tgts_exit;
900
901         ret_val = qla4xxx_req_ddb_entry(ha, &ddb_index);
902         if (ret_val != QLA_SUCCESS)
903                 goto qla4xxx_send_tgts_exit;
904
905         memset((void *)fw_ddb_entry->iSCSIAlias, 0,
906                sizeof(fw_ddb_entry->iSCSIAlias));
907
908         memset((void *)fw_ddb_entry->iscsiName, 0,
909                sizeof(fw_ddb_entry->iscsiName));
910
911         memset((void *)fw_ddb_entry->ipAddr, 0, sizeof(fw_ddb_entry->ipAddr));
912         memset((void *)fw_ddb_entry->targetAddr, 0,
913                sizeof(fw_ddb_entry->targetAddr));
914
915         fw_ddb_entry->options = (DDB_OPT_DISC_SESSION | DDB_OPT_TARGET);
916         fw_ddb_entry->portNumber = cpu_to_le16(ntohs(port));
917
918         fw_ddb_entry->ipAddr[0] = *ip;
919         fw_ddb_entry->ipAddr[1] = *(ip + 1);
920         fw_ddb_entry->ipAddr[2] = *(ip + 2);
921         fw_ddb_entry->ipAddr[3] = *(ip + 3);
922
923         ret_val = qla4xxx_set_ddb_entry(ha, ddb_index, fw_ddb_entry_dma);
924
925 qla4xxx_send_tgts_exit:
926         dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),
927                           fw_ddb_entry, fw_ddb_entry_dma);
928         return ret_val;
929 }
930