diff options
-rw-r--r-- | drivers/scsi/qla4xxx/ql4_def.h | 45 | ||||
-rw-r--r-- | drivers/scsi/qla4xxx/ql4_glbl.h | 12 | ||||
-rw-r--r-- | drivers/scsi/qla4xxx/ql4_init.c | 608 | ||||
-rw-r--r-- | drivers/scsi/qla4xxx/ql4_iocb.c | 2 | ||||
-rw-r--r-- | drivers/scsi/qla4xxx/ql4_mbx.c | 55 | ||||
-rw-r--r-- | drivers/scsi/qla4xxx/ql4_os.c | 126 |
6 files changed, 10 insertions, 838 deletions
diff --git a/drivers/scsi/qla4xxx/ql4_def.h b/drivers/scsi/qla4xxx/ql4_def.h index 3e404fe8e36d..6e2be9d963ac 100644 --- a/drivers/scsi/qla4xxx/ql4_def.h +++ b/drivers/scsi/qla4xxx/ql4_def.h | |||
@@ -233,52 +233,12 @@ struct ql4_aen_log { | |||
233 | * Device Database (DDB) structure | 233 | * Device Database (DDB) structure |
234 | */ | 234 | */ |
235 | struct ddb_entry { | 235 | struct ddb_entry { |
236 | struct list_head list; /* ddb list */ | ||
237 | struct scsi_qla_host *ha; | 236 | struct scsi_qla_host *ha; |
238 | struct iscsi_cls_session *sess; | 237 | struct iscsi_cls_session *sess; |
239 | struct iscsi_cls_conn *conn; | 238 | struct iscsi_cls_conn *conn; |
240 | 239 | ||
241 | atomic_t state; /* DDB State */ | ||
242 | |||
243 | unsigned long flags; /* DDB Flags */ | ||
244 | |||
245 | uint16_t fw_ddb_index; /* DDB firmware index */ | 240 | uint16_t fw_ddb_index; /* DDB firmware index */ |
246 | uint16_t options; | ||
247 | uint32_t fw_ddb_device_state; /* F/W Device State -- see ql4_fw.h */ | 241 | uint32_t fw_ddb_device_state; /* F/W Device State -- see ql4_fw.h */ |
248 | |||
249 | uint32_t CmdSn; | ||
250 | uint16_t target_session_id; | ||
251 | uint16_t connection_id; | ||
252 | uint16_t exe_throttle; /* Max mumber of cmds outstanding | ||
253 | * simultaneously */ | ||
254 | uint16_t task_mgmt_timeout; /* Min time for task mgmt cmds to | ||
255 | * complete */ | ||
256 | uint16_t default_relogin_timeout; /* Max time to wait for | ||
257 | * relogin to complete */ | ||
258 | uint16_t tcp_source_port_num; | ||
259 | uint32_t default_time2wait; /* Default Min time between | ||
260 | * relogins (+aens) */ | ||
261 | |||
262 | atomic_t retry_relogin_timer; /* Min Time between relogins | ||
263 | * (4000 only) */ | ||
264 | atomic_t relogin_timer; /* Max Time to wait for relogin to complete */ | ||
265 | atomic_t relogin_retry_count; /* Num of times relogin has been | ||
266 | * retried */ | ||
267 | |||
268 | uint16_t port; | ||
269 | uint32_t tpgt; | ||
270 | uint8_t ip_addr[IP_ADDR_LEN]; | ||
271 | uint8_t iscsi_name[ISCSI_NAME_SIZE]; /* 72 x48 */ | ||
272 | uint8_t iscsi_alias[0x20]; | ||
273 | uint8_t isid[6]; | ||
274 | uint16_t iscsi_max_burst_len; | ||
275 | uint16_t iscsi_max_outsnd_r2t; | ||
276 | uint16_t iscsi_first_burst_len; | ||
277 | uint16_t iscsi_max_rcv_data_seg_len; | ||
278 | uint16_t iscsi_max_snd_data_seg_len; | ||
279 | |||
280 | struct in6_addr remote_ipv6_addr; | ||
281 | struct in6_addr link_local_ipv6_addr; | ||
282 | }; | 242 | }; |
283 | 243 | ||
284 | /* | 244 | /* |
@@ -546,10 +506,7 @@ struct scsi_qla_host { | |||
546 | volatile uint8_t mbox_status_count; | 506 | volatile uint8_t mbox_status_count; |
547 | volatile uint32_t mbox_status[MBOX_REG_COUNT]; | 507 | volatile uint32_t mbox_status[MBOX_REG_COUNT]; |
548 | 508 | ||
549 | /* local device database list (contains internal ddb entries) */ | 509 | /* FW ddb index map */ |
550 | struct list_head ddb_list; | ||
551 | |||
552 | /* Map ddb_list entry by FW ddb index */ | ||
553 | struct ddb_entry *fw_ddb_index_map[MAX_DDB_ENTRIES]; | 510 | struct ddb_entry *fw_ddb_index_map[MAX_DDB_ENTRIES]; |
554 | 511 | ||
555 | /* Saved srb for status continuation entry processing */ | 512 | /* Saved srb for status continuation entry processing */ |
diff --git a/drivers/scsi/qla4xxx/ql4_glbl.h b/drivers/scsi/qla4xxx/ql4_glbl.h index d802340e3541..85b8253b3fc2 100644 --- a/drivers/scsi/qla4xxx/ql4_glbl.h +++ b/drivers/scsi/qla4xxx/ql4_glbl.h | |||
@@ -12,20 +12,15 @@ struct iscsi_cls_conn; | |||
12 | 12 | ||
13 | int qla4xxx_hw_reset(struct scsi_qla_host *ha); | 13 | int qla4xxx_hw_reset(struct scsi_qla_host *ha); |
14 | int ql4xxx_lock_drvr_wait(struct scsi_qla_host *a); | 14 | int ql4xxx_lock_drvr_wait(struct scsi_qla_host *a); |
15 | int qla4xxx_send_tgts(struct scsi_qla_host *ha, char *ip, uint16_t port); | ||
16 | int qla4xxx_send_command_to_isp(struct scsi_qla_host *ha, struct srb *srb); | 15 | int qla4xxx_send_command_to_isp(struct scsi_qla_host *ha, struct srb *srb); |
17 | int qla4xxx_initialize_adapter(struct scsi_qla_host *ha, | 16 | int qla4xxx_initialize_adapter(struct scsi_qla_host *ha); |
18 | uint8_t renew_ddb_list); | ||
19 | int qla4xxx_soft_reset(struct scsi_qla_host *ha); | 17 | int qla4xxx_soft_reset(struct scsi_qla_host *ha); |
20 | irqreturn_t qla4xxx_intr_handler(int irq, void *dev_id); | 18 | irqreturn_t qla4xxx_intr_handler(int irq, void *dev_id); |
21 | 19 | ||
22 | void qla4xxx_free_ddb_list(struct scsi_qla_host *ha); | ||
23 | void qla4xxx_free_ddb(struct scsi_qla_host *ha, struct ddb_entry *ddb_entry); | 20 | void qla4xxx_free_ddb(struct scsi_qla_host *ha, struct ddb_entry *ddb_entry); |
24 | void qla4xxx_process_aen(struct scsi_qla_host *ha, uint8_t process_aen); | 21 | void qla4xxx_process_aen(struct scsi_qla_host *ha, uint8_t process_aen); |
25 | 22 | ||
26 | int qla4xxx_get_dhcp_ip_address(struct scsi_qla_host *ha); | 23 | int qla4xxx_get_dhcp_ip_address(struct scsi_qla_host *ha); |
27 | int qla4xxx_relogin_device(struct scsi_qla_host *ha, | ||
28 | struct ddb_entry *ddb_entry); | ||
29 | int qla4xxx_abort_task(struct scsi_qla_host *ha, struct srb *srb); | 24 | int qla4xxx_abort_task(struct scsi_qla_host *ha, struct srb *srb); |
30 | int qla4xxx_reset_lun(struct scsi_qla_host *ha, struct ddb_entry *ddb_entry, | 25 | int qla4xxx_reset_lun(struct scsi_qla_host *ha, struct ddb_entry *ddb_entry, |
31 | int lun); | 26 | int lun); |
@@ -66,9 +61,6 @@ int qla4xxx_get_acb(struct scsi_qla_host *ha, uint32_t *mbox_cmd, | |||
66 | void qla4xxx_mark_device_missing(struct iscsi_cls_session *cls_session); | 61 | void qla4xxx_mark_device_missing(struct iscsi_cls_session *cls_session); |
67 | u16 rd_nvram_word(struct scsi_qla_host *ha, int offset); | 62 | u16 rd_nvram_word(struct scsi_qla_host *ha, int offset); |
68 | void qla4xxx_get_crash_record(struct scsi_qla_host *ha); | 63 | void qla4xxx_get_crash_record(struct scsi_qla_host *ha); |
69 | struct ddb_entry *qla4xxx_alloc_sess(struct scsi_qla_host *ha); | ||
70 | int qla4xxx_add_sess(struct ddb_entry *); | ||
71 | void qla4xxx_destroy_sess(struct ddb_entry *ddb_entry); | ||
72 | int qla4xxx_is_nvram_configuration_valid(struct scsi_qla_host *ha); | 64 | int qla4xxx_is_nvram_configuration_valid(struct scsi_qla_host *ha); |
73 | int qla4xxx_about_firmware(struct scsi_qla_host *ha); | 65 | int qla4xxx_about_firmware(struct scsi_qla_host *ha); |
74 | void qla4xxx_interrupt_service_routine(struct scsi_qla_host *ha, | 66 | void qla4xxx_interrupt_service_routine(struct scsi_qla_host *ha, |
@@ -77,13 +69,11 @@ int qla4xxx_init_rings(struct scsi_qla_host *ha); | |||
77 | void qla4xxx_srb_compl(struct kref *ref); | 69 | void qla4xxx_srb_compl(struct kref *ref); |
78 | struct srb *qla4xxx_del_from_active_array(struct scsi_qla_host *ha, | 70 | struct srb *qla4xxx_del_from_active_array(struct scsi_qla_host *ha, |
79 | uint32_t index); | 71 | uint32_t index); |
80 | int qla4xxx_reinitialize_ddb_list(struct scsi_qla_host *ha); | ||
81 | int qla4xxx_process_ddb_changed(struct scsi_qla_host *ha, uint32_t fw_ddb_index, | 72 | int qla4xxx_process_ddb_changed(struct scsi_qla_host *ha, uint32_t fw_ddb_index, |
82 | uint32_t state, uint32_t conn_error); | 73 | uint32_t state, uint32_t conn_error); |
83 | void qla4xxx_dump_buffer(void *b, uint32_t size); | 74 | void qla4xxx_dump_buffer(void *b, uint32_t size); |
84 | int qla4xxx_send_marker_iocb(struct scsi_qla_host *ha, | 75 | int qla4xxx_send_marker_iocb(struct scsi_qla_host *ha, |
85 | struct ddb_entry *ddb_entry, int lun, uint16_t mrkr_mod); | 76 | struct ddb_entry *ddb_entry, int lun, uint16_t mrkr_mod); |
86 | int qla4_is_relogin_allowed(struct scsi_qla_host *ha, uint32_t conn_err); | ||
87 | int qla4xxx_set_flash(struct scsi_qla_host *ha, dma_addr_t dma_addr, | 77 | int qla4xxx_set_flash(struct scsi_qla_host *ha, dma_addr_t dma_addr, |
88 | uint32_t offset, uint32_t length, uint32_t options); | 78 | uint32_t offset, uint32_t length, uint32_t options); |
89 | int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount, | 79 | int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount, |
diff --git a/drivers/scsi/qla4xxx/ql4_init.c b/drivers/scsi/qla4xxx/ql4_init.c index ca6b2c5f0fdd..21f6f4bacd9d 100644 --- a/drivers/scsi/qla4xxx/ql4_init.c +++ b/drivers/scsi/qla4xxx/ql4_init.c | |||
@@ -11,9 +11,6 @@ | |||
11 | #include "ql4_dbg.h" | 11 | #include "ql4_dbg.h" |
12 | #include "ql4_inline.h" | 12 | #include "ql4_inline.h" |
13 | 13 | ||
14 | static struct ddb_entry *qla4xxx_alloc_ddb(struct scsi_qla_host *ha, | ||
15 | uint32_t fw_ddb_index); | ||
16 | |||
17 | static void ql4xxx_set_mac_number(struct scsi_qla_host *ha) | 14 | static void ql4xxx_set_mac_number(struct scsi_qla_host *ha) |
18 | { | 15 | { |
19 | uint32_t value; | 16 | uint32_t value; |
@@ -60,25 +57,6 @@ void qla4xxx_free_ddb(struct scsi_qla_host *ha, | |||
60 | } | 57 | } |
61 | 58 | ||
62 | /** | 59 | /** |
63 | * qla4xxx_free_ddb_list - deallocate all ddbs | ||
64 | * @ha: pointer to host adapter structure. | ||
65 | * | ||
66 | * This routine deallocates and removes all devices on the sppecified adapter. | ||
67 | **/ | ||
68 | void qla4xxx_free_ddb_list(struct scsi_qla_host *ha) | ||
69 | { | ||
70 | struct list_head *ptr; | ||
71 | struct ddb_entry *ddb_entry; | ||
72 | |||
73 | while (!list_empty(&ha->ddb_list)) { | ||
74 | ptr = ha->ddb_list.next; | ||
75 | /* Free memory for device entry and remove */ | ||
76 | ddb_entry = list_entry(ptr, struct ddb_entry, list); | ||
77 | qla4xxx_free_ddb(ha, ddb_entry); | ||
78 | } | ||
79 | } | ||
80 | |||
81 | /** | ||
82 | * qla4xxx_init_response_q_entries() - Initializes response queue entries. | 60 | * qla4xxx_init_response_q_entries() - Initializes response queue entries. |
83 | * @ha: HA context | 61 | * @ha: HA context |
84 | * | 62 | * |
@@ -468,489 +446,6 @@ static int qla4xxx_init_firmware(struct scsi_qla_host *ha) | |||
468 | return qla4xxx_get_firmware_status(ha); | 446 | return qla4xxx_get_firmware_status(ha); |
469 | } | 447 | } |
470 | 448 | ||
471 | static struct ddb_entry* qla4xxx_get_ddb_entry(struct scsi_qla_host *ha, | ||
472 | uint32_t fw_ddb_index, | ||
473 | uint32_t *new_tgt) | ||
474 | { | ||
475 | struct dev_db_entry *fw_ddb_entry = NULL; | ||
476 | dma_addr_t fw_ddb_entry_dma; | ||
477 | struct ddb_entry *ddb_entry = NULL; | ||
478 | int found = 0; | ||
479 | uint32_t device_state; | ||
480 | |||
481 | *new_tgt = 0; | ||
482 | /* Make sure the dma buffer is valid */ | ||
483 | fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev, | ||
484 | sizeof(*fw_ddb_entry), | ||
485 | &fw_ddb_entry_dma, GFP_KERNEL); | ||
486 | if (fw_ddb_entry == NULL) { | ||
487 | DEBUG2(printk("scsi%ld: %s: Unable to allocate dma buffer.\n", | ||
488 | ha->host_no, __func__)); | ||
489 | goto exit_get_ddb_entry_no_free; | ||
490 | } | ||
491 | |||
492 | if (qla4xxx_get_fwddb_entry(ha, fw_ddb_index, fw_ddb_entry, | ||
493 | fw_ddb_entry_dma, NULL, NULL, | ||
494 | &device_state, NULL, NULL, NULL) == | ||
495 | QLA_ERROR) { | ||
496 | DEBUG2(printk("scsi%ld: %s: failed get_ddb_entry for " | ||
497 | "fw_ddb_index %d\n", ha->host_no, __func__, | ||
498 | fw_ddb_index)); | ||
499 | goto exit_get_ddb_entry; | ||
500 | } | ||
501 | |||
502 | /* Allocate DDB if not already allocated. */ | ||
503 | DEBUG2(printk("scsi%ld: %s: Looking for ddb[%d]\n", ha->host_no, | ||
504 | __func__, fw_ddb_index)); | ||
505 | list_for_each_entry(ddb_entry, &ha->ddb_list, list) { | ||
506 | if ((memcmp(ddb_entry->iscsi_name, fw_ddb_entry->iscsi_name, | ||
507 | ISCSI_NAME_SIZE) == 0) && | ||
508 | (ddb_entry->tpgt == | ||
509 | le32_to_cpu(fw_ddb_entry->tgt_portal_grp)) && | ||
510 | (memcmp(ddb_entry->isid, fw_ddb_entry->isid, | ||
511 | sizeof(ddb_entry->isid)) == 0)) { | ||
512 | found++; | ||
513 | break; | ||
514 | } | ||
515 | } | ||
516 | |||
517 | /* if not found allocate new ddb */ | ||
518 | if (!found) { | ||
519 | DEBUG2(printk("scsi%ld: %s: ddb[%d] not found - allocating " | ||
520 | "new ddb\n", ha->host_no, __func__, | ||
521 | fw_ddb_index)); | ||
522 | *new_tgt = 1; | ||
523 | ddb_entry = qla4xxx_alloc_ddb(ha, fw_ddb_index); | ||
524 | } | ||
525 | |||
526 | exit_get_ddb_entry: | ||
527 | dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry), fw_ddb_entry, | ||
528 | fw_ddb_entry_dma); | ||
529 | |||
530 | exit_get_ddb_entry_no_free: | ||
531 | return ddb_entry; | ||
532 | } | ||
533 | |||
534 | /** | ||
535 | * qla4xxx_update_ddb_entry - update driver's internal ddb | ||
536 | * @ha: pointer to host adapter structure. | ||
537 | * @ddb_entry: pointer to device database structure to be filled | ||
538 | * @fw_ddb_index: index of the ddb entry in fw ddb table | ||
539 | * | ||
540 | * This routine updates the driver's internal device database entry | ||
541 | * with information retrieved from the firmware's device database | ||
542 | * entry for the specified device. The ddb_entry->fw_ddb_index field | ||
543 | * must be initialized prior to calling this routine | ||
544 | * | ||
545 | **/ | ||
546 | static int qla4xxx_update_ddb_entry(struct scsi_qla_host *ha, | ||
547 | struct ddb_entry *ddb_entry, | ||
548 | uint32_t fw_ddb_index) | ||
549 | { | ||
550 | struct dev_db_entry *fw_ddb_entry = NULL; | ||
551 | dma_addr_t fw_ddb_entry_dma; | ||
552 | int status = QLA_ERROR; | ||
553 | uint32_t conn_err; | ||
554 | |||
555 | if (ddb_entry == NULL) { | ||
556 | DEBUG2(printk("scsi%ld: %s: ddb_entry is NULL\n", ha->host_no, | ||
557 | __func__)); | ||
558 | |||
559 | goto exit_update_ddb_no_free; | ||
560 | } | ||
561 | |||
562 | /* Make sure the dma buffer is valid */ | ||
563 | fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev, | ||
564 | sizeof(*fw_ddb_entry), | ||
565 | &fw_ddb_entry_dma, GFP_KERNEL); | ||
566 | if (fw_ddb_entry == NULL) { | ||
567 | DEBUG2(printk("scsi%ld: %s: Unable to allocate dma buffer.\n", | ||
568 | ha->host_no, __func__)); | ||
569 | |||
570 | goto exit_update_ddb_no_free; | ||
571 | } | ||
572 | |||
573 | if (qla4xxx_get_fwddb_entry(ha, fw_ddb_index, fw_ddb_entry, | ||
574 | fw_ddb_entry_dma, NULL, NULL, | ||
575 | &ddb_entry->fw_ddb_device_state, &conn_err, | ||
576 | &ddb_entry->tcp_source_port_num, | ||
577 | &ddb_entry->connection_id) == | ||
578 | QLA_ERROR) { | ||
579 | DEBUG2(printk("scsi%ld: %s: failed get_ddb_entry for " | ||
580 | "fw_ddb_index %d\n", ha->host_no, __func__, | ||
581 | fw_ddb_index)); | ||
582 | |||
583 | goto exit_update_ddb; | ||
584 | } | ||
585 | |||
586 | status = QLA_SUCCESS; | ||
587 | ddb_entry->options = le16_to_cpu(fw_ddb_entry->options); | ||
588 | ddb_entry->target_session_id = le16_to_cpu(fw_ddb_entry->tsid); | ||
589 | ddb_entry->task_mgmt_timeout = | ||
590 | le16_to_cpu(fw_ddb_entry->def_timeout); | ||
591 | ddb_entry->CmdSn = 0; | ||
592 | ddb_entry->exe_throttle = le16_to_cpu(fw_ddb_entry->exec_throttle); | ||
593 | ddb_entry->default_relogin_timeout = | ||
594 | le16_to_cpu(fw_ddb_entry->def_timeout); | ||
595 | ddb_entry->default_time2wait = le16_to_cpu(fw_ddb_entry->iscsi_def_time2wait); | ||
596 | |||
597 | /* Update index in case it changed */ | ||
598 | ddb_entry->fw_ddb_index = fw_ddb_index; | ||
599 | ha->fw_ddb_index_map[fw_ddb_index] = ddb_entry; | ||
600 | |||
601 | ddb_entry->port = le16_to_cpu(fw_ddb_entry->port); | ||
602 | ddb_entry->tpgt = le32_to_cpu(fw_ddb_entry->tgt_portal_grp); | ||
603 | memcpy(ddb_entry->isid, fw_ddb_entry->isid, sizeof(ddb_entry->isid)); | ||
604 | |||
605 | memcpy(&ddb_entry->iscsi_name[0], &fw_ddb_entry->iscsi_name[0], | ||
606 | min(sizeof(ddb_entry->iscsi_name), | ||
607 | sizeof(fw_ddb_entry->iscsi_name))); | ||
608 | memcpy(&ddb_entry->iscsi_alias[0], &fw_ddb_entry->iscsi_alias[0], | ||
609 | min(sizeof(ddb_entry->iscsi_alias), | ||
610 | sizeof(fw_ddb_entry->iscsi_alias))); | ||
611 | memcpy(&ddb_entry->ip_addr[0], &fw_ddb_entry->ip_addr[0], | ||
612 | min(sizeof(ddb_entry->ip_addr), sizeof(fw_ddb_entry->ip_addr))); | ||
613 | |||
614 | ddb_entry->iscsi_max_burst_len = fw_ddb_entry->iscsi_max_burst_len; | ||
615 | ddb_entry->iscsi_max_outsnd_r2t = fw_ddb_entry->iscsi_max_outsnd_r2t; | ||
616 | ddb_entry->iscsi_first_burst_len = fw_ddb_entry->iscsi_first_burst_len; | ||
617 | ddb_entry->iscsi_max_rcv_data_seg_len = | ||
618 | fw_ddb_entry->iscsi_max_rcv_data_seg_len; | ||
619 | ddb_entry->iscsi_max_snd_data_seg_len = | ||
620 | fw_ddb_entry->iscsi_max_snd_data_seg_len; | ||
621 | |||
622 | if (ddb_entry->options & DDB_OPT_IPV6_DEVICE) { | ||
623 | memcpy(&ddb_entry->remote_ipv6_addr, | ||
624 | fw_ddb_entry->ip_addr, | ||
625 | min(sizeof(ddb_entry->remote_ipv6_addr), | ||
626 | sizeof(fw_ddb_entry->ip_addr))); | ||
627 | memcpy(&ddb_entry->link_local_ipv6_addr, | ||
628 | fw_ddb_entry->link_local_ipv6_addr, | ||
629 | min(sizeof(ddb_entry->link_local_ipv6_addr), | ||
630 | sizeof(fw_ddb_entry->link_local_ipv6_addr))); | ||
631 | |||
632 | DEBUG2(ql4_printk(KERN_INFO, ha, "%s: DDB[%d] State %04x" | ||
633 | " ConnErr %08x IP %pI6 " | ||
634 | ":%04d \"%s\"\n", | ||
635 | __func__, fw_ddb_index, | ||
636 | ddb_entry->fw_ddb_device_state, | ||
637 | conn_err, fw_ddb_entry->ip_addr, | ||
638 | le16_to_cpu(fw_ddb_entry->port), | ||
639 | fw_ddb_entry->iscsi_name)); | ||
640 | } else | ||
641 | DEBUG2(ql4_printk(KERN_INFO, ha, "%s: DDB[%d] State %04x" | ||
642 | " ConnErr %08x IP %pI4 " | ||
643 | ":%04d \"%s\"\n", | ||
644 | __func__, fw_ddb_index, | ||
645 | ddb_entry->fw_ddb_device_state, | ||
646 | conn_err, fw_ddb_entry->ip_addr, | ||
647 | le16_to_cpu(fw_ddb_entry->port), | ||
648 | fw_ddb_entry->iscsi_name)); | ||
649 | exit_update_ddb: | ||
650 | if (fw_ddb_entry) | ||
651 | dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry), | ||
652 | fw_ddb_entry, fw_ddb_entry_dma); | ||
653 | |||
654 | exit_update_ddb_no_free: | ||
655 | return status; | ||
656 | } | ||
657 | |||
658 | /** | ||
659 | * qla4xxx_alloc_ddb - allocate device database entry | ||
660 | * @ha: Pointer to host adapter structure. | ||
661 | * @fw_ddb_index: Firmware's device database index | ||
662 | * | ||
663 | * This routine allocates a ddb_entry, ititializes some values, and | ||
664 | * inserts it into the ddb list. | ||
665 | **/ | ||
666 | static struct ddb_entry * qla4xxx_alloc_ddb(struct scsi_qla_host *ha, | ||
667 | uint32_t fw_ddb_index) | ||
668 | { | ||
669 | struct ddb_entry *ddb_entry; | ||
670 | |||
671 | DEBUG2(printk("scsi%ld: %s: fw_ddb_index [%d]\n", ha->host_no, | ||
672 | __func__, fw_ddb_index)); | ||
673 | |||
674 | ddb_entry = qla4xxx_alloc_sess(ha); | ||
675 | if (ddb_entry == NULL) { | ||
676 | DEBUG2(printk("scsi%ld: %s: Unable to allocate memory " | ||
677 | "to add fw_ddb_index [%d]\n", | ||
678 | ha->host_no, __func__, fw_ddb_index)); | ||
679 | return ddb_entry; | ||
680 | } | ||
681 | |||
682 | ddb_entry->fw_ddb_index = fw_ddb_index; | ||
683 | atomic_set(&ddb_entry->retry_relogin_timer, INVALID_ENTRY); | ||
684 | atomic_set(&ddb_entry->relogin_timer, 0); | ||
685 | atomic_set(&ddb_entry->relogin_retry_count, 0); | ||
686 | atomic_set(&ddb_entry->state, DDB_STATE_ONLINE); | ||
687 | list_add_tail(&ddb_entry->list, &ha->ddb_list); | ||
688 | ha->fw_ddb_index_map[fw_ddb_index] = ddb_entry; | ||
689 | ha->tot_ddbs++; | ||
690 | |||
691 | return ddb_entry; | ||
692 | } | ||
693 | |||
694 | /** | ||
695 | * qla4_is_relogin_allowed - Are we allowed to login? | ||
696 | * @ha: Pointer to host adapter structure. | ||
697 | * @conn_err: Last connection error associated with the ddb | ||
698 | * | ||
699 | * This routine tests the given connection error to determine if | ||
700 | * we are allowed to login. | ||
701 | **/ | ||
702 | int qla4_is_relogin_allowed(struct scsi_qla_host *ha, uint32_t conn_err) | ||
703 | { | ||
704 | uint32_t err_code, login_rsp_sts_class; | ||
705 | int relogin = 1; | ||
706 | |||
707 | err_code = ((conn_err & 0x00ff0000) >> 16); | ||
708 | login_rsp_sts_class = ((conn_err & 0x0000ff00) >> 8); | ||
709 | if (err_code == 0x1c || err_code == 0x06) { | ||
710 | DEBUG2(ql4_printk(KERN_INFO, ha, | ||
711 | ": conn_err=0x%08x, send target completed" | ||
712 | " or access denied failure\n", conn_err)); | ||
713 | relogin = 0; | ||
714 | } | ||
715 | if ((err_code == 0x08) && (login_rsp_sts_class == 0x02)) { | ||
716 | /* Login Response PDU returned an error. | ||
717 | Login Response Status in Error Code Detail | ||
718 | indicates login should not be retried.*/ | ||
719 | DEBUG2(ql4_printk(KERN_INFO, ha, | ||
720 | ": conn_err=0x%08x, do not retry relogin\n", | ||
721 | conn_err)); | ||
722 | relogin = 0; | ||
723 | } | ||
724 | |||
725 | return relogin; | ||
726 | } | ||
727 | |||
728 | static void qla4xxx_flush_AENS(struct scsi_qla_host *ha) | ||
729 | { | ||
730 | unsigned long wtime; | ||
731 | |||
732 | /* Flush the 0x8014 AEN from the firmware as a result of | ||
733 | * Auto connect. We are basically doing get_firmware_ddb() | ||
734 | * to determine whether we need to log back in or not. | ||
735 | * Trying to do a set ddb before we have processed 0x8014 | ||
736 | * will result in another set_ddb() for the same ddb. In other | ||
737 | * words there will be stale entries in the aen_q. | ||
738 | */ | ||
739 | wtime = jiffies + (2 * HZ); | ||
740 | do { | ||
741 | if (qla4xxx_get_firmware_state(ha) == QLA_SUCCESS) | ||
742 | if (ha->firmware_state & (BIT_2 | BIT_0)) | ||
743 | return; | ||
744 | |||
745 | if (test_and_clear_bit(DPC_AEN, &ha->dpc_flags)) | ||
746 | qla4xxx_process_aen(ha, FLUSH_DDB_CHANGED_AENS); | ||
747 | |||
748 | msleep(1000); | ||
749 | } while (!time_after_eq(jiffies, wtime)); | ||
750 | } | ||
751 | |||
752 | /** | ||
753 | * qla4xxx_build_ddb_list - builds driver ddb list | ||
754 | * @ha: Pointer to host adapter structure. | ||
755 | * | ||
756 | * This routine searches for all valid firmware ddb entries and builds | ||
757 | * an internal ddb list. Ddbs that are considered valid are those with | ||
758 | * a device state of SESSION_ACTIVE. | ||
759 | * A relogin (set_ddb) is issued for DDBs that are not online. | ||
760 | **/ | ||
761 | static int qla4xxx_build_ddb_list(struct scsi_qla_host *ha) | ||
762 | { | ||
763 | int status = QLA_ERROR; | ||
764 | uint32_t fw_ddb_index = 0; | ||
765 | uint32_t next_fw_ddb_index = 0; | ||
766 | uint32_t ddb_state; | ||
767 | uint32_t conn_err; | ||
768 | struct ddb_entry *ddb_entry; | ||
769 | struct dev_db_entry *fw_ddb_entry = NULL; | ||
770 | dma_addr_t fw_ddb_entry_dma; | ||
771 | uint32_t ipv6_device; | ||
772 | uint32_t new_tgt; | ||
773 | |||
774 | qla4xxx_flush_AENS(ha); | ||
775 | |||
776 | fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry), | ||
777 | &fw_ddb_entry_dma, GFP_KERNEL); | ||
778 | if (fw_ddb_entry == NULL) { | ||
779 | DEBUG2(ql4_printk(KERN_INFO, ha, "%s: DMA alloc failed\n", | ||
780 | __func__)); | ||
781 | |||
782 | goto exit_build_ddb_list_no_free; | ||
783 | } | ||
784 | |||
785 | ql4_printk(KERN_INFO, ha, "Initializing DDBs ...\n"); | ||
786 | for (fw_ddb_index = 0; fw_ddb_index < MAX_DDB_ENTRIES; | ||
787 | fw_ddb_index = next_fw_ddb_index) { | ||
788 | /* First, let's see if a device exists here */ | ||
789 | if (qla4xxx_get_fwddb_entry(ha, fw_ddb_index, fw_ddb_entry, | ||
790 | 0, NULL, &next_fw_ddb_index, | ||
791 | &ddb_state, &conn_err, | ||
792 | NULL, NULL) == | ||
793 | QLA_ERROR) { | ||
794 | DEBUG2(printk("scsi%ld: %s: get_ddb_entry, " | ||
795 | "fw_ddb_index %d failed", ha->host_no, | ||
796 | __func__, fw_ddb_index)); | ||
797 | goto exit_build_ddb_list; | ||
798 | } | ||
799 | |||
800 | DEBUG2(printk("scsi%ld: %s: Getting DDB[%d] ddbstate=0x%x, " | ||
801 | "next_fw_ddb_index=%d.\n", ha->host_no, __func__, | ||
802 | fw_ddb_index, ddb_state, next_fw_ddb_index)); | ||
803 | |||
804 | /* Issue relogin, if necessary. */ | ||
805 | if (ddb_state == DDB_DS_SESSION_FAILED || | ||
806 | ddb_state == DDB_DS_NO_CONNECTION_ACTIVE) { | ||
807 | /* Try and login to device */ | ||
808 | DEBUG2(printk("scsi%ld: %s: Login to DDB[%d]\n", | ||
809 | ha->host_no, __func__, fw_ddb_index)); | ||
810 | ipv6_device = le16_to_cpu(fw_ddb_entry->options) & | ||
811 | DDB_OPT_IPV6_DEVICE; | ||
812 | if (qla4_is_relogin_allowed(ha, conn_err) && | ||
813 | ((!ipv6_device && | ||
814 | *((uint32_t *)fw_ddb_entry->ip_addr)) | ||
815 | || ipv6_device)) { | ||
816 | qla4xxx_set_ddb_entry(ha, fw_ddb_index, 0, | ||
817 | NULL); | ||
818 | if (qla4xxx_get_fwddb_entry(ha, fw_ddb_index, | ||
819 | NULL, 0, NULL, | ||
820 | &next_fw_ddb_index, | ||
821 | &ddb_state, &conn_err, | ||
822 | NULL, NULL) | ||
823 | == QLA_ERROR) { | ||
824 | DEBUG2(printk("scsi%ld: %s:" | ||
825 | "get_ddb_entry %d failed\n", | ||
826 | ha->host_no, | ||
827 | __func__, fw_ddb_index)); | ||
828 | goto exit_build_ddb_list; | ||
829 | } | ||
830 | } | ||
831 | } | ||
832 | |||
833 | if (ddb_state != DDB_DS_SESSION_ACTIVE) | ||
834 | goto next_one; | ||
835 | /* | ||
836 | * if fw_ddb with session active state found, | ||
837 | * add to ddb_list | ||
838 | */ | ||
839 | DEBUG2(printk("scsi%ld: %s: DDB[%d] added to list\n", | ||
840 | ha->host_no, __func__, fw_ddb_index)); | ||
841 | |||
842 | /* Add DDB to internal our ddb list. */ | ||
843 | ddb_entry = qla4xxx_get_ddb_entry(ha, fw_ddb_index, &new_tgt); | ||
844 | if (ddb_entry == NULL) { | ||
845 | DEBUG2(printk("scsi%ld: %s: Unable to allocate memory " | ||
846 | "for device at fw_ddb_index %d\n", | ||
847 | ha->host_no, __func__, fw_ddb_index)); | ||
848 | goto exit_build_ddb_list; | ||
849 | } | ||
850 | /* Fill in the device structure */ | ||
851 | if (qla4xxx_update_ddb_entry(ha, ddb_entry, fw_ddb_index) == | ||
852 | QLA_ERROR) { | ||
853 | ha->fw_ddb_index_map[fw_ddb_index] = | ||
854 | (struct ddb_entry *)INVALID_ENTRY; | ||
855 | |||
856 | DEBUG2(printk("scsi%ld: %s: update_ddb_entry failed " | ||
857 | "for fw_ddb_index %d.\n", | ||
858 | ha->host_no, __func__, fw_ddb_index)); | ||
859 | goto exit_build_ddb_list; | ||
860 | } | ||
861 | |||
862 | next_one: | ||
863 | /* We know we've reached the last device when | ||
864 | * next_fw_ddb_index is 0 */ | ||
865 | if (next_fw_ddb_index == 0) | ||
866 | break; | ||
867 | } | ||
868 | |||
869 | status = QLA_SUCCESS; | ||
870 | ql4_printk(KERN_INFO, ha, "DDB list done..\n"); | ||
871 | |||
872 | exit_build_ddb_list: | ||
873 | dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry), fw_ddb_entry, | ||
874 | fw_ddb_entry_dma); | ||
875 | |||
876 | exit_build_ddb_list_no_free: | ||
877 | return status; | ||
878 | } | ||
879 | |||
880 | static int qla4xxx_initialize_ddb_list(struct scsi_qla_host *ha) | ||
881 | { | ||
882 | uint16_t fw_ddb_index; | ||
883 | int status = QLA_SUCCESS; | ||
884 | |||
885 | /* free the ddb list if is not empty */ | ||
886 | if (!list_empty(&ha->ddb_list)) | ||
887 | qla4xxx_free_ddb_list(ha); | ||
888 | |||
889 | for (fw_ddb_index = 0; fw_ddb_index < MAX_DDB_ENTRIES; fw_ddb_index++) | ||
890 | ha->fw_ddb_index_map[fw_ddb_index] = | ||
891 | (struct ddb_entry *)INVALID_ENTRY; | ||
892 | |||
893 | ha->tot_ddbs = 0; | ||
894 | |||
895 | /* Perform device discovery and build ddb list. */ | ||
896 | status = qla4xxx_build_ddb_list(ha); | ||
897 | |||
898 | return status; | ||
899 | } | ||
900 | |||
901 | /** | ||
902 | * qla4xxx_reinitialize_ddb_list - update the driver ddb list | ||
903 | * @ha: pointer to host adapter structure. | ||
904 | * | ||
905 | * This routine obtains device information from the F/W database after | ||
906 | * firmware or adapter resets. The device table is preserved. | ||
907 | **/ | ||
908 | int qla4xxx_reinitialize_ddb_list(struct scsi_qla_host *ha) | ||
909 | { | ||
910 | int status = QLA_SUCCESS; | ||
911 | struct ddb_entry *ddb_entry, *detemp; | ||
912 | |||
913 | /* Update the device information for all devices. */ | ||
914 | list_for_each_entry_safe(ddb_entry, detemp, &ha->ddb_list, list) { | ||
915 | qla4xxx_update_ddb_entry(ha, ddb_entry, | ||
916 | ddb_entry->fw_ddb_index); | ||
917 | if (ddb_entry->fw_ddb_device_state == DDB_DS_SESSION_ACTIVE) { | ||
918 | atomic_set(&ddb_entry->state, DDB_STATE_ONLINE); | ||
919 | DEBUG2(printk ("scsi%ld: %s: ddb index [%d] marked " | ||
920 | "ONLINE\n", ha->host_no, __func__, | ||
921 | ddb_entry->fw_ddb_index)); | ||
922 | iscsi_unblock_session(ddb_entry->sess); | ||
923 | } else if (atomic_read(&ddb_entry->state) == DDB_STATE_ONLINE) | ||
924 | qla4xxx_mark_device_missing(ddb_entry->sess); | ||
925 | } | ||
926 | return status; | ||
927 | } | ||
928 | |||
929 | /** | ||
930 | * qla4xxx_relogin_device - re-establish session | ||
931 | * @ha: Pointer to host adapter structure. | ||
932 | * @ddb_entry: Pointer to device database entry | ||
933 | * | ||
934 | * This routine does a session relogin with the specified device. | ||
935 | * The ddb entry must be assigned prior to making this call. | ||
936 | **/ | ||
937 | int qla4xxx_relogin_device(struct scsi_qla_host *ha, | ||
938 | struct ddb_entry * ddb_entry) | ||
939 | { | ||
940 | uint16_t relogin_timer; | ||
941 | |||
942 | relogin_timer = max(ddb_entry->default_relogin_timeout, | ||
943 | (uint16_t)RELOGIN_TOV); | ||
944 | atomic_set(&ddb_entry->relogin_timer, relogin_timer); | ||
945 | |||
946 | DEBUG2(printk("scsi%ld: Relogin ddb [%d]. TOV=%d\n", ha->host_no, | ||
947 | ddb_entry->fw_ddb_index, relogin_timer)); | ||
948 | |||
949 | qla4xxx_set_ddb_entry(ha, ddb_entry->fw_ddb_index, 0, NULL); | ||
950 | |||
951 | return QLA_SUCCESS; | ||
952 | } | ||
953 | |||
954 | static int qla4xxx_config_nvram(struct scsi_qla_host *ha) | 449 | static int qla4xxx_config_nvram(struct scsi_qla_host *ha) |
955 | { | 450 | { |
956 | unsigned long flags; | 451 | unsigned long flags; |
@@ -1254,18 +749,13 @@ int qla4xxx_start_firmware(struct scsi_qla_host *ha) | |||
1254 | /** | 749 | /** |
1255 | * qla4xxx_initialize_adapter - initiailizes hba | 750 | * qla4xxx_initialize_adapter - initiailizes hba |
1256 | * @ha: Pointer to host adapter structure. | 751 | * @ha: Pointer to host adapter structure. |
1257 | * @renew_ddb_list: Indicates what to do with the adapter's ddb list | ||
1258 | * after adapter recovery has completed. | ||
1259 | * 0=preserve ddb list, 1=destroy and rebuild ddb list | ||
1260 | * | 752 | * |
1261 | * This routine parforms all of the steps necessary to initialize the adapter. | 753 | * This routine parforms all of the steps necessary to initialize the adapter. |
1262 | * | 754 | * |
1263 | **/ | 755 | **/ |
1264 | int qla4xxx_initialize_adapter(struct scsi_qla_host *ha, | 756 | int qla4xxx_initialize_adapter(struct scsi_qla_host *ha) |
1265 | uint8_t renew_ddb_list) | ||
1266 | { | 757 | { |
1267 | int status = QLA_ERROR; | 758 | int status = QLA_ERROR; |
1268 | int8_t ip_address[IP_ADDR_LEN] = {0} ; | ||
1269 | 759 | ||
1270 | ha->eeprom_cmd_data = 0; | 760 | ha->eeprom_cmd_data = 0; |
1271 | 761 | ||
@@ -1291,47 +781,6 @@ int qla4xxx_initialize_adapter(struct scsi_qla_host *ha, | |||
1291 | if (status == QLA_ERROR) | 781 | if (status == QLA_ERROR) |
1292 | goto exit_init_hba; | 782 | goto exit_init_hba; |
1293 | 783 | ||
1294 | /* | ||
1295 | * FW is waiting to get an IP address from DHCP server: Skip building | ||
1296 | * the ddb_list and wait for DHCP lease acquired aen to come in | ||
1297 | * followed by 0x8014 aen" to trigger the tgt discovery process. | ||
1298 | */ | ||
1299 | if (ha->firmware_state & FW_STATE_CONFIGURING_IP) | ||
1300 | goto exit_init_online; | ||
1301 | |||
1302 | /* Skip device discovery if ip and subnet is zero */ | ||
1303 | if (memcmp(ha->ip_config.ip_address, ip_address, IP_ADDR_LEN) == 0 || | ||
1304 | memcmp(ha->ip_config.subnet_mask, ip_address, IP_ADDR_LEN) == 0) | ||
1305 | goto exit_init_online; | ||
1306 | |||
1307 | if (renew_ddb_list == PRESERVE_DDB_LIST) { | ||
1308 | /* | ||
1309 | * We want to preserve lun states (i.e. suspended, etc.) | ||
1310 | * for recovery initiated by the driver. So just update | ||
1311 | * the device states for the existing ddb_list. | ||
1312 | */ | ||
1313 | qla4xxx_reinitialize_ddb_list(ha); | ||
1314 | } else if (renew_ddb_list == REBUILD_DDB_LIST) { | ||
1315 | /* | ||
1316 | * We want to build the ddb_list from scratch during | ||
1317 | * driver initialization and recovery initiated by the | ||
1318 | * INT_HBA_RESET IOCTL. | ||
1319 | */ | ||
1320 | status = qla4xxx_initialize_ddb_list(ha); | ||
1321 | if (status == QLA_ERROR) { | ||
1322 | DEBUG2(printk("%s(%ld) Error occurred during build" | ||
1323 | "ddb list\n", __func__, ha->host_no)); | ||
1324 | goto exit_init_hba; | ||
1325 | } | ||
1326 | |||
1327 | } | ||
1328 | if (!ha->tot_ddbs) { | ||
1329 | DEBUG2(printk("scsi%ld: Failed to initialize devices or none " | ||
1330 | "present in Firmware device database\n", | ||
1331 | ha->host_no)); | ||
1332 | } | ||
1333 | |||
1334 | exit_init_online: | ||
1335 | set_bit(AF_ONLINE, &ha->flags); | 784 | set_bit(AF_ONLINE, &ha->flags); |
1336 | exit_init_hba: | 785 | exit_init_hba: |
1337 | if (is_qla8022(ha) && (status == QLA_ERROR)) { | 786 | if (is_qla8022(ha) && (status == QLA_ERROR)) { |
@@ -1346,61 +795,6 @@ exit_init_hba: | |||
1346 | } | 795 | } |
1347 | 796 | ||
1348 | /** | 797 | /** |
1349 | * qla4xxx_add_device_dynamically - ddb addition due to an AEN | ||
1350 | * @ha: Pointer to host adapter structure. | ||
1351 | * @fw_ddb_index: Firmware's device database index | ||
1352 | * | ||
1353 | * This routine processes adds a device as a result of an 8014h AEN. | ||
1354 | **/ | ||
1355 | static void qla4xxx_add_device_dynamically(struct scsi_qla_host *ha, | ||
1356 | uint32_t fw_ddb_index) | ||
1357 | { | ||
1358 | struct ddb_entry * ddb_entry; | ||
1359 | uint32_t new_tgt; | ||
1360 | |||
1361 | /* First allocate a device structure */ | ||
1362 | ddb_entry = qla4xxx_get_ddb_entry(ha, fw_ddb_index, &new_tgt); | ||
1363 | if (ddb_entry == NULL) { | ||
1364 | DEBUG2(printk(KERN_WARNING | ||
1365 | "scsi%ld: Unable to allocate memory to add " | ||
1366 | "fw_ddb_index %d\n", ha->host_no, fw_ddb_index)); | ||
1367 | return; | ||
1368 | } | ||
1369 | |||
1370 | if (!new_tgt && (ddb_entry->fw_ddb_index != fw_ddb_index)) { | ||
1371 | /* Target has been bound to a new fw_ddb_index */ | ||
1372 | qla4xxx_free_ddb(ha, ddb_entry); | ||
1373 | ddb_entry = qla4xxx_alloc_ddb(ha, fw_ddb_index); | ||
1374 | if (ddb_entry == NULL) { | ||
1375 | DEBUG2(printk(KERN_WARNING | ||
1376 | "scsi%ld: Unable to allocate memory" | ||
1377 | " to add fw_ddb_index %d\n", | ||
1378 | ha->host_no, fw_ddb_index)); | ||
1379 | return; | ||
1380 | } | ||
1381 | } | ||
1382 | if (qla4xxx_update_ddb_entry(ha, ddb_entry, fw_ddb_index) == | ||
1383 | QLA_ERROR) { | ||
1384 | ha->fw_ddb_index_map[fw_ddb_index] = | ||
1385 | (struct ddb_entry *)INVALID_ENTRY; | ||
1386 | DEBUG2(printk(KERN_WARNING | ||
1387 | "scsi%ld: failed to add new device at index " | ||
1388 | "[%d]\n Unable to retrieve fw ddb entry\n", | ||
1389 | ha->host_no, fw_ddb_index)); | ||
1390 | qla4xxx_free_ddb(ha, ddb_entry); | ||
1391 | return; | ||
1392 | } | ||
1393 | |||
1394 | if (qla4xxx_add_sess(ddb_entry)) { | ||
1395 | DEBUG2(printk(KERN_WARNING | ||
1396 | "scsi%ld: failed to add new device at index " | ||
1397 | "[%d]\n Unable to add connection and session\n", | ||
1398 | ha->host_no, fw_ddb_index)); | ||
1399 | qla4xxx_free_ddb(ha, ddb_entry); | ||
1400 | } | ||
1401 | } | ||
1402 | |||
1403 | /** | ||
1404 | * qla4xxx_process_ddb_changed - process ddb state change | 798 | * qla4xxx_process_ddb_changed - process ddb state change |
1405 | * @ha - Pointer to host adapter structure. | 799 | * @ha - Pointer to host adapter structure. |
1406 | * @fw_ddb_index - Firmware's device database index | 800 | * @fw_ddb_index - Firmware's device database index |
diff --git a/drivers/scsi/qla4xxx/ql4_iocb.c b/drivers/scsi/qla4xxx/ql4_iocb.c index e9def6260215..ad40a613bcf1 100644 --- a/drivers/scsi/qla4xxx/ql4_iocb.c +++ b/drivers/scsi/qla4xxx/ql4_iocb.c | |||
@@ -313,10 +313,8 @@ int qla4xxx_send_command_to_isp(struct scsi_qla_host *ha, struct srb * srb) | |||
313 | cmd_entry->hdr.entryType = ET_COMMAND; | 313 | cmd_entry->hdr.entryType = ET_COMMAND; |
314 | cmd_entry->handle = cpu_to_le32(index); | 314 | cmd_entry->handle = cpu_to_le32(index); |
315 | cmd_entry->target = cpu_to_le16(ddb_entry->fw_ddb_index); | 315 | cmd_entry->target = cpu_to_le16(ddb_entry->fw_ddb_index); |
316 | cmd_entry->connection_id = cpu_to_le16(ddb_entry->connection_id); | ||
317 | 316 | ||
318 | int_to_scsilun(cmd->device->lun, &cmd_entry->lun); | 317 | int_to_scsilun(cmd->device->lun, &cmd_entry->lun); |
319 | cmd_entry->cmdSeqNum = cpu_to_le32(ddb_entry->CmdSn); | ||
320 | cmd_entry->ttlByteCnt = cpu_to_le32(scsi_bufflen(cmd)); | 318 | cmd_entry->ttlByteCnt = cpu_to_le32(scsi_bufflen(cmd)); |
321 | memcpy(cmd_entry->cdb, cmd->cmnd, cmd->cmd_len); | 319 | memcpy(cmd_entry->cdb, cmd->cmnd, cmd->cmd_len); |
322 | cmd_entry->dataSegCnt = cpu_to_le16(tot_dsds); | 320 | cmd_entry->dataSegCnt = cpu_to_le16(tot_dsds); |
diff --git a/drivers/scsi/qla4xxx/ql4_mbx.c b/drivers/scsi/qla4xxx/ql4_mbx.c index 32e40cb534f4..21884019dab8 100644 --- a/drivers/scsi/qla4xxx/ql4_mbx.c +++ b/drivers/scsi/qla4xxx/ql4_mbx.c | |||
@@ -1214,61 +1214,6 @@ int qla4xxx_req_ddb_entry(struct scsi_qla_host *ha, uint32_t ddb_index, | |||
1214 | return status; | 1214 | return status; |
1215 | } | 1215 | } |
1216 | 1216 | ||
1217 | int qla4xxx_send_tgts(struct scsi_qla_host *ha, char *ip, uint16_t port) | ||
1218 | { | ||
1219 | struct dev_db_entry *fw_ddb_entry; | ||
1220 | dma_addr_t fw_ddb_entry_dma; | ||
1221 | uint32_t ddb_index; | ||
1222 | uint32_t mbx_sts; | ||
1223 | uint32_t options = 0; | ||
1224 | int ret_val = QLA_SUCCESS; | ||
1225 | |||
1226 | |||
1227 | fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev, | ||
1228 | sizeof(*fw_ddb_entry), | ||
1229 | &fw_ddb_entry_dma, GFP_KERNEL); | ||
1230 | if (!fw_ddb_entry) { | ||
1231 | DEBUG2(printk("scsi%ld: %s: Unable to allocate dma buffer.\n", | ||
1232 | ha->host_no, __func__)); | ||
1233 | ret_val = QLA_ERROR; | ||
1234 | goto exit_send_tgts_no_free; | ||
1235 | } | ||
1236 | |||
1237 | ret_val = qla4xxx_get_default_ddb(ha, options, fw_ddb_entry_dma); | ||
1238 | if (ret_val != QLA_SUCCESS) | ||
1239 | goto exit_send_tgts; | ||
1240 | |||
1241 | ret_val = qla4xxx_req_ddb_entry(ha, &ddb_index, &mbx_sts); | ||
1242 | if (ret_val != QLA_SUCCESS) | ||
1243 | goto exit_send_tgts; | ||
1244 | |||
1245 | memset(fw_ddb_entry->iscsi_alias, 0, | ||
1246 | sizeof(fw_ddb_entry->iscsi_alias)); | ||
1247 | |||
1248 | memset(fw_ddb_entry->iscsi_name, 0, | ||
1249 | sizeof(fw_ddb_entry->iscsi_name)); | ||
1250 | |||
1251 | memset(fw_ddb_entry->ip_addr, 0, sizeof(fw_ddb_entry->ip_addr)); | ||
1252 | memset(fw_ddb_entry->tgt_addr, 0, | ||
1253 | sizeof(fw_ddb_entry->tgt_addr)); | ||
1254 | |||
1255 | fw_ddb_entry->options = (DDB_OPT_DISC_SESSION | DDB_OPT_TARGET); | ||
1256 | fw_ddb_entry->port = cpu_to_le16(ntohs(port)); | ||
1257 | |||
1258 | fw_ddb_entry->ip_addr[0] = *ip; | ||
1259 | fw_ddb_entry->ip_addr[1] = *(ip + 1); | ||
1260 | fw_ddb_entry->ip_addr[2] = *(ip + 2); | ||
1261 | fw_ddb_entry->ip_addr[3] = *(ip + 3); | ||
1262 | |||
1263 | ret_val = qla4xxx_set_ddb_entry(ha, ddb_index, fw_ddb_entry_dma, NULL); | ||
1264 | |||
1265 | exit_send_tgts: | ||
1266 | dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry), | ||
1267 | fw_ddb_entry, fw_ddb_entry_dma); | ||
1268 | exit_send_tgts_no_free: | ||
1269 | return ret_val; | ||
1270 | } | ||
1271 | |||
1272 | int qla4xxx_clear_ddb_entry(struct scsi_qla_host *ha, uint32_t ddb_index) | 1217 | int qla4xxx_clear_ddb_entry(struct scsi_qla_host *ha, uint32_t ddb_index) |
1273 | { | 1218 | { |
1274 | int status; | 1219 | int status; |
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c index 2374475080f4..bfb3d37612fc 100644 --- a/drivers/scsi/qla4xxx/ql4_os.c +++ b/drivers/scsi/qla4xxx/ql4_os.c | |||
@@ -72,9 +72,6 @@ static void qla4xxx_config_dma_addressing(struct scsi_qla_host *ha); | |||
72 | /* | 72 | /* |
73 | * iSCSI template entry points | 73 | * iSCSI template entry points |
74 | */ | 74 | */ |
75 | static int qla4xxx_tgt_dscvr(struct Scsi_Host *shost, | ||
76 | enum iscsi_tgt_dscvr type, uint32_t enable, | ||
77 | struct sockaddr *dst_addr); | ||
78 | static int qla4xxx_conn_get_param(struct iscsi_cls_conn *conn, | 75 | static int qla4xxx_conn_get_param(struct iscsi_cls_conn *conn, |
79 | enum iscsi_param param, char *buf); | 76 | enum iscsi_param param, char *buf); |
80 | static int qla4xxx_host_get_param(struct Scsi_Host *shost, | 77 | static int qla4xxx_host_get_param(struct Scsi_Host *shost, |
@@ -121,7 +118,6 @@ static int qla4xxx_eh_host_reset(struct scsi_cmnd *cmd); | |||
121 | static int qla4xxx_slave_alloc(struct scsi_device *device); | 118 | static int qla4xxx_slave_alloc(struct scsi_device *device); |
122 | static int qla4xxx_slave_configure(struct scsi_device *device); | 119 | static int qla4xxx_slave_configure(struct scsi_device *device); |
123 | static void qla4xxx_slave_destroy(struct scsi_device *sdev); | 120 | static void qla4xxx_slave_destroy(struct scsi_device *sdev); |
124 | static void qla4xxx_scan_start(struct Scsi_Host *shost); | ||
125 | static mode_t ql4_attr_is_visible(int param_type, int param); | 121 | static mode_t ql4_attr_is_visible(int param_type, int param); |
126 | 122 | ||
127 | static struct qla4_8xxx_legacy_intr_set legacy_intr[] = | 123 | static struct qla4_8xxx_legacy_intr_set legacy_intr[] = |
@@ -160,7 +156,6 @@ static struct iscsi_transport qla4xxx_iscsi_transport = { | |||
160 | CAP_DATA_PATH_OFFLOAD | CAP_HDRDGST | | 156 | CAP_DATA_PATH_OFFLOAD | CAP_HDRDGST | |
161 | CAP_DATADGST | CAP_LOGIN_OFFLOAD | | 157 | CAP_DATADGST | CAP_LOGIN_OFFLOAD | |
162 | CAP_MULTI_R2T, | 158 | CAP_MULTI_R2T, |
163 | .tgt_dscvr = qla4xxx_tgt_dscvr, | ||
164 | .attr_is_visible = ql4_attr_is_visible, | 159 | .attr_is_visible = ql4_attr_is_visible, |
165 | .create_session = qla4xxx_session_create, | 160 | .create_session = qla4xxx_session_create, |
166 | .destroy_session = qla4xxx_session_destroy, | 161 | .destroy_session = qla4xxx_session_destroy, |
@@ -949,41 +944,6 @@ static int qla4xxx_conn_get_param(struct iscsi_cls_conn *cls_conn, | |||
949 | 944 | ||
950 | } | 945 | } |
951 | 946 | ||
952 | static int qla4xxx_tgt_dscvr(struct Scsi_Host *shost, | ||
953 | enum iscsi_tgt_dscvr type, uint32_t enable, | ||
954 | struct sockaddr *dst_addr) | ||
955 | { | ||
956 | struct scsi_qla_host *ha; | ||
957 | struct sockaddr_in *addr; | ||
958 | struct sockaddr_in6 *addr6; | ||
959 | int ret = 0; | ||
960 | |||
961 | ha = (struct scsi_qla_host *) to_qla_host(shost); | ||
962 | |||
963 | switch (type) { | ||
964 | case ISCSI_TGT_DSCVR_SEND_TARGETS: | ||
965 | if (dst_addr->sa_family == AF_INET) { | ||
966 | addr = (struct sockaddr_in *)dst_addr; | ||
967 | if (qla4xxx_send_tgts(ha, (char *)&addr->sin_addr, | ||
968 | addr->sin_port) != QLA_SUCCESS) | ||
969 | ret = -EIO; | ||
970 | } else if (dst_addr->sa_family == AF_INET6) { | ||
971 | /* | ||
972 | * TODO: fix qla4xxx_send_tgts | ||
973 | */ | ||
974 | addr6 = (struct sockaddr_in6 *)dst_addr; | ||
975 | if (qla4xxx_send_tgts(ha, (char *)&addr6->sin6_addr, | ||
976 | addr6->sin6_port) != QLA_SUCCESS) | ||
977 | ret = -EIO; | ||
978 | } else | ||
979 | ret = -ENOSYS; | ||
980 | break; | ||
981 | default: | ||
982 | ret = -ENOSYS; | ||
983 | } | ||
984 | return ret; | ||
985 | } | ||
986 | |||
987 | static struct iscsi_cls_session * | 947 | static struct iscsi_cls_session * |
988 | qla4xxx_session_create(struct iscsi_endpoint *ep, | 948 | qla4xxx_session_create(struct iscsi_endpoint *ep, |
989 | uint16_t cmds_max, uint16_t qdepth, | 949 | uint16_t cmds_max, uint16_t qdepth, |
@@ -1073,18 +1033,6 @@ static void qla4xxx_session_destroy(struct iscsi_cls_session *cls_sess) | |||
1073 | iscsi_session_teardown(cls_sess); | 1033 | iscsi_session_teardown(cls_sess); |
1074 | } | 1034 | } |
1075 | 1035 | ||
1076 | void qla4xxx_destroy_sess(struct ddb_entry *ddb_entry) | ||
1077 | { | ||
1078 | if (!ddb_entry->sess) | ||
1079 | return; | ||
1080 | |||
1081 | if (ddb_entry->conn) { | ||
1082 | atomic_set(&ddb_entry->state, DDB_STATE_DEAD); | ||
1083 | iscsi_remove_session(ddb_entry->sess); | ||
1084 | } | ||
1085 | iscsi_free_session(ddb_entry->sess); | ||
1086 | } | ||
1087 | |||
1088 | static struct iscsi_cls_conn * | 1036 | static struct iscsi_cls_conn * |
1089 | qla4xxx_conn_create(struct iscsi_cls_session *cls_sess, uint32_t conn_idx) | 1037 | qla4xxx_conn_create(struct iscsi_cls_session *cls_sess, uint32_t conn_idx) |
1090 | { | 1038 | { |
@@ -1129,7 +1077,6 @@ static int qla4xxx_conn_start(struct iscsi_cls_conn *cls_conn) | |||
1129 | struct scsi_qla_host *ha; | 1077 | struct scsi_qla_host *ha; |
1130 | struct dev_db_entry *fw_ddb_entry; | 1078 | struct dev_db_entry *fw_ddb_entry; |
1131 | dma_addr_t fw_ddb_entry_dma; | 1079 | dma_addr_t fw_ddb_entry_dma; |
1132 | uint32_t fw_ddb_device_state; | ||
1133 | uint32_t mbx_sts = 0; | 1080 | uint32_t mbx_sts = 0; |
1134 | int ret = 0; | 1081 | int ret = 0; |
1135 | int status = QLA_SUCCESS; | 1082 | int status = QLA_SUCCESS; |
@@ -1166,9 +1113,8 @@ static int qla4xxx_conn_start(struct iscsi_cls_conn *cls_conn) | |||
1166 | 1113 | ||
1167 | status = qla4xxx_conn_open(ha, ddb_entry->fw_ddb_index); | 1114 | status = qla4xxx_conn_open(ha, ddb_entry->fw_ddb_index); |
1168 | if (status == QLA_ERROR) { | 1115 | if (status == QLA_ERROR) { |
1169 | ql4_printk(KERN_ERR, ha, "%s: Login failed: %s %s:%d\n", | 1116 | ql4_printk(KERN_ERR, ha, "%s: Login failed: %s\n", __func__, |
1170 | __func__, ddb_entry->iscsi_name, | 1117 | sess->targetname); |
1171 | ddb_entry->ip_addr, ddb_entry->port); | ||
1172 | ret = -EINVAL; | 1118 | ret = -EINVAL; |
1173 | goto exit_conn_start; | 1119 | goto exit_conn_start; |
1174 | } | 1120 | } |
@@ -1429,59 +1375,6 @@ void qla4xxx_update_session_conn_param(struct scsi_qla_host *ha, | |||
1429 | min(sizeof(ha->name_string), sizeof(sess->initiatorname))); | 1375 | min(sizeof(ha->name_string), sizeof(sess->initiatorname))); |
1430 | } | 1376 | } |
1431 | 1377 | ||
1432 | int qla4xxx_add_sess(struct ddb_entry *ddb_entry) | ||
1433 | { | ||
1434 | int err; | ||
1435 | |||
1436 | ddb_entry->sess->recovery_tmo = ql4xsess_recovery_tmo; | ||
1437 | |||
1438 | err = iscsi_add_session(ddb_entry->sess, ddb_entry->fw_ddb_index); | ||
1439 | if (err) { | ||
1440 | DEBUG2(printk(KERN_ERR "Could not add session.\n")); | ||
1441 | return err; | ||
1442 | } | ||
1443 | |||
1444 | ddb_entry->conn = iscsi_create_conn(ddb_entry->sess, 0, 0); | ||
1445 | if (!ddb_entry->conn) { | ||
1446 | iscsi_remove_session(ddb_entry->sess); | ||
1447 | DEBUG2(printk(KERN_ERR "Could not add connection.\n")); | ||
1448 | return -ENOMEM; | ||
1449 | } | ||
1450 | |||
1451 | /* finally ready to go */ | ||
1452 | iscsi_unblock_session(ddb_entry->sess); | ||
1453 | return 0; | ||
1454 | } | ||
1455 | |||
1456 | struct ddb_entry *qla4xxx_alloc_sess(struct scsi_qla_host *ha) | ||
1457 | { | ||
1458 | struct ddb_entry *ddb_entry; | ||
1459 | struct iscsi_cls_session *sess; | ||
1460 | |||
1461 | sess = iscsi_alloc_session(ha->host, &qla4xxx_iscsi_transport, | ||
1462 | sizeof(struct ddb_entry)); | ||
1463 | if (!sess) | ||
1464 | return NULL; | ||
1465 | |||
1466 | ddb_entry = sess->dd_data; | ||
1467 | memset(ddb_entry, 0, sizeof(*ddb_entry)); | ||
1468 | ddb_entry->ha = ha; | ||
1469 | ddb_entry->sess = sess; | ||
1470 | return ddb_entry; | ||
1471 | } | ||
1472 | |||
1473 | static void qla4xxx_scan_start(struct Scsi_Host *shost) | ||
1474 | { | ||
1475 | struct scsi_qla_host *ha = to_qla_host(shost); | ||
1476 | struct ddb_entry *ddb_entry, *ddbtemp; | ||
1477 | |||
1478 | /* finish setup of sessions that were already setup in firmware */ | ||
1479 | list_for_each_entry_safe(ddb_entry, ddbtemp, &ha->ddb_list, list) { | ||
1480 | if (ddb_entry->fw_ddb_device_state == DDB_DS_SESSION_ACTIVE) | ||
1481 | qla4xxx_add_sess(ddb_entry); | ||
1482 | } | ||
1483 | } | ||
1484 | |||
1485 | /* | 1378 | /* |
1486 | * Timer routines | 1379 | * Timer routines |
1487 | */ | 1380 | */ |
@@ -2232,7 +2125,7 @@ recover_ha_init_adapter: | |||
2232 | 2125 | ||
2233 | /* NOTE: AF_ONLINE flag set upon successful completion of | 2126 | /* NOTE: AF_ONLINE flag set upon successful completion of |
2234 | * qla4xxx_initialize_adapter */ | 2127 | * qla4xxx_initialize_adapter */ |
2235 | status = qla4xxx_initialize_adapter(ha, PRESERVE_DDB_LIST); | 2128 | status = qla4xxx_initialize_adapter(ha); |
2236 | } | 2129 | } |
2237 | 2130 | ||
2238 | /* Retry failed adapter initialization, if necessary | 2131 | /* Retry failed adapter initialization, if necessary |
@@ -2732,7 +2625,6 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev, | |||
2732 | qla4xxx_config_dma_addressing(ha); | 2625 | qla4xxx_config_dma_addressing(ha); |
2733 | 2626 | ||
2734 | /* Initialize lists and spinlocks. */ | 2627 | /* Initialize lists and spinlocks. */ |
2735 | INIT_LIST_HEAD(&ha->ddb_list); | ||
2736 | INIT_LIST_HEAD(&ha->free_srb_q); | 2628 | INIT_LIST_HEAD(&ha->free_srb_q); |
2737 | 2629 | ||
2738 | mutex_init(&ha->mbox_sem); | 2630 | mutex_init(&ha->mbox_sem); |
@@ -2778,7 +2670,7 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev, | |||
2778 | * firmware | 2670 | * firmware |
2779 | * NOTE: interrupts enabled upon successful completion | 2671 | * NOTE: interrupts enabled upon successful completion |
2780 | */ | 2672 | */ |
2781 | status = qla4xxx_initialize_adapter(ha, REBUILD_DDB_LIST); | 2673 | status = qla4xxx_initialize_adapter(ha); |
2782 | while ((!test_bit(AF_ONLINE, &ha->flags)) && | 2674 | while ((!test_bit(AF_ONLINE, &ha->flags)) && |
2783 | init_retry_count++ < MAX_INIT_RETRIES) { | 2675 | init_retry_count++ < MAX_INIT_RETRIES) { |
2784 | 2676 | ||
@@ -2799,7 +2691,7 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev, | |||
2799 | if (ha->isp_ops->reset_chip(ha) == QLA_ERROR) | 2691 | if (ha->isp_ops->reset_chip(ha) == QLA_ERROR) |
2800 | continue; | 2692 | continue; |
2801 | 2693 | ||
2802 | status = qla4xxx_initialize_adapter(ha, REBUILD_DDB_LIST); | 2694 | status = qla4xxx_initialize_adapter(ha); |
2803 | } | 2695 | } |
2804 | 2696 | ||
2805 | if (!test_bit(AF_ONLINE, &ha->flags)) { | 2697 | if (!test_bit(AF_ONLINE, &ha->flags)) { |
@@ -2936,9 +2828,6 @@ static void __devexit qla4xxx_remove_adapter(struct pci_dev *pdev) | |||
2936 | if (!is_qla8022(ha)) | 2828 | if (!is_qla8022(ha)) |
2937 | qla4xxx_prevent_other_port_reinit(ha); | 2829 | qla4xxx_prevent_other_port_reinit(ha); |
2938 | 2830 | ||
2939 | /* remove devs from iscsi_sessions to scsi_devices */ | ||
2940 | qla4xxx_free_ddb_list(ha); | ||
2941 | |||
2942 | /* destroy iface from sysfs */ | 2831 | /* destroy iface from sysfs */ |
2943 | qla4xxx_destroy_ifaces(ha); | 2832 | qla4xxx_destroy_ifaces(ha); |
2944 | 2833 | ||
@@ -3485,7 +3374,7 @@ static uint32_t qla4_8xxx_error_recovery(struct scsi_qla_host *ha) | |||
3485 | 3374 | ||
3486 | qla4_8xxx_idc_unlock(ha); | 3375 | qla4_8xxx_idc_unlock(ha); |
3487 | clear_bit(AF_FW_RECOVERY, &ha->flags); | 3376 | clear_bit(AF_FW_RECOVERY, &ha->flags); |
3488 | rval = qla4xxx_initialize_adapter(ha, PRESERVE_DDB_LIST); | 3377 | rval = qla4xxx_initialize_adapter(ha); |
3489 | qla4_8xxx_idc_lock(ha); | 3378 | qla4_8xxx_idc_lock(ha); |
3490 | 3379 | ||
3491 | if (rval != QLA_SUCCESS) { | 3380 | if (rval != QLA_SUCCESS) { |
@@ -3521,8 +3410,7 @@ static uint32_t qla4_8xxx_error_recovery(struct scsi_qla_host *ha) | |||
3521 | if ((qla4_8xxx_rd_32(ha, QLA82XX_CRB_DEV_STATE) == | 3410 | if ((qla4_8xxx_rd_32(ha, QLA82XX_CRB_DEV_STATE) == |
3522 | QLA82XX_DEV_READY)) { | 3411 | QLA82XX_DEV_READY)) { |
3523 | clear_bit(AF_FW_RECOVERY, &ha->flags); | 3412 | clear_bit(AF_FW_RECOVERY, &ha->flags); |
3524 | rval = qla4xxx_initialize_adapter(ha, | 3413 | rval = qla4xxx_initialize_adapter(ha); |
3525 | PRESERVE_DDB_LIST); | ||
3526 | if (rval == QLA_SUCCESS) { | 3414 | if (rval == QLA_SUCCESS) { |
3527 | ret = qla4xxx_request_irqs(ha); | 3415 | ret = qla4xxx_request_irqs(ha); |
3528 | if (ret) { | 3416 | if (ret) { |