diff options
Diffstat (limited to 'drivers/scsi/be2iscsi')
-rw-r--r-- | drivers/scsi/be2iscsi/be.h | 21 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_cmds.c | 88 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_cmds.h | 14 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_iscsi.c | 136 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_iscsi.h | 2 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_main.c | 488 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_main.h | 27 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_mgmt.c | 139 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_mgmt.h | 6 |
9 files changed, 547 insertions, 374 deletions
diff --git a/drivers/scsi/be2iscsi/be.h b/drivers/scsi/be2iscsi/be.h index a93a5040f087..136b49cea791 100644 --- a/drivers/scsi/be2iscsi/be.h +++ b/drivers/scsi/be2iscsi/be.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /** | 1 | /** |
2 | * Copyright (C) 2005 - 2009 ServerEngines | 2 | * Copyright (C) 2005 - 2010 ServerEngines |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or | 5 | * This program is free software; you can redistribute it and/or |
@@ -24,6 +24,10 @@ | |||
24 | #define FW_VER_LEN 32 | 24 | #define FW_VER_LEN 32 |
25 | #define MCC_Q_LEN 128 | 25 | #define MCC_Q_LEN 128 |
26 | #define MCC_CQ_LEN 256 | 26 | #define MCC_CQ_LEN 256 |
27 | #define MAX_MCC_CMD 16 | ||
28 | /* BladeEngine Generation numbers */ | ||
29 | #define BE_GEN2 2 | ||
30 | #define BE_GEN3 3 | ||
27 | 31 | ||
28 | struct be_dma_mem { | 32 | struct be_dma_mem { |
29 | void *va; | 33 | void *va; |
@@ -57,6 +61,11 @@ static inline void *queue_head_node(struct be_queue_info *q) | |||
57 | return q->dma_mem.va + q->head * q->entry_size; | 61 | return q->dma_mem.va + q->head * q->entry_size; |
58 | } | 62 | } |
59 | 63 | ||
64 | static inline void *queue_get_wrb(struct be_queue_info *q, unsigned int wrb_num) | ||
65 | { | ||
66 | return q->dma_mem.va + wrb_num * q->entry_size; | ||
67 | } | ||
68 | |||
60 | static inline void *queue_tail_node(struct be_queue_info *q) | 69 | static inline void *queue_tail_node(struct be_queue_info *q) |
61 | { | 70 | { |
62 | return q->dma_mem.va + q->tail * q->entry_size; | 71 | return q->dma_mem.va + q->tail * q->entry_size; |
@@ -104,15 +113,19 @@ struct be_ctrl_info { | |||
104 | spinlock_t mcc_lock; /* For serializing mcc cmds to BE card */ | 113 | spinlock_t mcc_lock; /* For serializing mcc cmds to BE card */ |
105 | spinlock_t mcc_cq_lock; | 114 | spinlock_t mcc_cq_lock; |
106 | 115 | ||
107 | /* MCC Async callback */ | 116 | wait_queue_head_t mcc_wait[MAX_MCC_CMD + 1]; |
108 | void (*async_cb) (void *adapter, bool link_up); | 117 | unsigned int mcc_tag[MAX_MCC_CMD]; |
109 | void *adapter_ctxt; | 118 | unsigned int mcc_numtag[MAX_MCC_CMD + 1]; |
119 | unsigned short mcc_alloc_index; | ||
120 | unsigned short mcc_free_index; | ||
121 | unsigned int mcc_tag_available; | ||
110 | }; | 122 | }; |
111 | 123 | ||
112 | #include "be_cmds.h" | 124 | #include "be_cmds.h" |
113 | 125 | ||
114 | #define PAGE_SHIFT_4K 12 | 126 | #define PAGE_SHIFT_4K 12 |
115 | #define PAGE_SIZE_4K (1 << PAGE_SHIFT_4K) | 127 | #define PAGE_SIZE_4K (1 << PAGE_SHIFT_4K) |
128 | #define mcc_timeout 120000 /* 5s timeout */ | ||
116 | 129 | ||
117 | /* Returns number of pages spanned by the data starting at the given addr */ | 130 | /* Returns number of pages spanned by the data starting at the given addr */ |
118 | #define PAGES_4K_SPANNED(_address, size) \ | 131 | #define PAGES_4K_SPANNED(_address, size) \ |
diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c index f008708f1b08..67098578fba4 100644 --- a/drivers/scsi/be2iscsi/be_cmds.c +++ b/drivers/scsi/be2iscsi/be_cmds.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /** | 1 | /** |
2 | * Copyright (C) 2005 - 2009 ServerEngines | 2 | * Copyright (C) 2005 - 2010 ServerEngines |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or | 5 | * This program is free software; you can redistribute it and/or |
@@ -19,7 +19,7 @@ | |||
19 | #include "be_mgmt.h" | 19 | #include "be_mgmt.h" |
20 | #include "be_main.h" | 20 | #include "be_main.h" |
21 | 21 | ||
22 | static void be_mcc_notify(struct beiscsi_hba *phba) | 22 | void be_mcc_notify(struct beiscsi_hba *phba) |
23 | { | 23 | { |
24 | struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q; | 24 | struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q; |
25 | u32 val = 0; | 25 | u32 val = 0; |
@@ -29,6 +29,52 @@ static void be_mcc_notify(struct beiscsi_hba *phba) | |||
29 | iowrite32(val, phba->db_va + DB_MCCQ_OFFSET); | 29 | iowrite32(val, phba->db_va + DB_MCCQ_OFFSET); |
30 | } | 30 | } |
31 | 31 | ||
32 | unsigned int alloc_mcc_tag(struct beiscsi_hba *phba) | ||
33 | { | ||
34 | unsigned int tag = 0; | ||
35 | unsigned int num = 0; | ||
36 | |||
37 | mcc_tag_rdy: | ||
38 | if (phba->ctrl.mcc_tag_available) { | ||
39 | tag = phba->ctrl.mcc_tag[phba->ctrl.mcc_alloc_index]; | ||
40 | phba->ctrl.mcc_tag[phba->ctrl.mcc_alloc_index] = 0; | ||
41 | phba->ctrl.mcc_numtag[tag] = 0; | ||
42 | } else { | ||
43 | udelay(100); | ||
44 | num++; | ||
45 | if (num < mcc_timeout) | ||
46 | goto mcc_tag_rdy; | ||
47 | } | ||
48 | if (tag) { | ||
49 | phba->ctrl.mcc_tag_available--; | ||
50 | if (phba->ctrl.mcc_alloc_index == (MAX_MCC_CMD - 1)) | ||
51 | phba->ctrl.mcc_alloc_index = 0; | ||
52 | else | ||
53 | phba->ctrl.mcc_alloc_index++; | ||
54 | } | ||
55 | return tag; | ||
56 | } | ||
57 | |||
58 | void free_mcc_tag(struct be_ctrl_info *ctrl, unsigned int tag) | ||
59 | { | ||
60 | spin_lock(&ctrl->mbox_lock); | ||
61 | tag = tag & 0x000000FF; | ||
62 | ctrl->mcc_tag[ctrl->mcc_free_index] = tag; | ||
63 | if (ctrl->mcc_free_index == (MAX_MCC_CMD - 1)) | ||
64 | ctrl->mcc_free_index = 0; | ||
65 | else | ||
66 | ctrl->mcc_free_index++; | ||
67 | ctrl->mcc_tag_available++; | ||
68 | spin_unlock(&ctrl->mbox_lock); | ||
69 | } | ||
70 | |||
71 | bool is_link_state_evt(u32 trailer) | ||
72 | { | ||
73 | return (((trailer >> ASYNC_TRAILER_EVENT_CODE_SHIFT) & | ||
74 | ASYNC_TRAILER_EVENT_CODE_MASK) == | ||
75 | ASYNC_EVENT_CODE_LINK_STATE); | ||
76 | } | ||
77 | |||
32 | static inline bool be_mcc_compl_is_new(struct be_mcc_compl *compl) | 78 | static inline bool be_mcc_compl_is_new(struct be_mcc_compl *compl) |
33 | { | 79 | { |
34 | if (compl->flags != 0) { | 80 | if (compl->flags != 0) { |
@@ -64,12 +110,30 @@ static int be_mcc_compl_process(struct be_ctrl_info *ctrl, | |||
64 | return 0; | 110 | return 0; |
65 | } | 111 | } |
66 | 112 | ||
67 | 113 | int be_mcc_compl_process_isr(struct be_ctrl_info *ctrl, | |
68 | static inline bool is_link_state_evt(u32 trailer) | 114 | struct be_mcc_compl *compl) |
69 | { | 115 | { |
70 | return (((trailer >> ASYNC_TRAILER_EVENT_CODE_SHIFT) & | 116 | u16 compl_status, extd_status; |
71 | ASYNC_TRAILER_EVENT_CODE_MASK) == | 117 | unsigned short tag; |
72 | ASYNC_EVENT_CODE_LINK_STATE); | 118 | |
119 | be_dws_le_to_cpu(compl, 4); | ||
120 | |||
121 | compl_status = (compl->status >> CQE_STATUS_COMPL_SHIFT) & | ||
122 | CQE_STATUS_COMPL_MASK; | ||
123 | /* The ctrl.mcc_numtag[tag] is filled with | ||
124 | * [31] = valid, [30:24] = Rsvd, [23:16] = wrb, [15:8] = extd_status, | ||
125 | * [7:0] = compl_status | ||
126 | */ | ||
127 | tag = (compl->tag0 & 0x000000FF); | ||
128 | extd_status = (compl->status >> CQE_STATUS_EXTD_SHIFT) & | ||
129 | CQE_STATUS_EXTD_MASK; | ||
130 | |||
131 | ctrl->mcc_numtag[tag] = 0x80000000; | ||
132 | ctrl->mcc_numtag[tag] |= (compl->tag0 & 0x00FF0000); | ||
133 | ctrl->mcc_numtag[tag] |= (extd_status & 0x000000FF) << 8; | ||
134 | ctrl->mcc_numtag[tag] |= (compl_status & 0x000000FF); | ||
135 | wake_up_interruptible(&ctrl->mcc_wait[tag]); | ||
136 | return 0; | ||
73 | } | 137 | } |
74 | 138 | ||
75 | static struct be_mcc_compl *be_mcc_compl_get(struct beiscsi_hba *phba) | 139 | static struct be_mcc_compl *be_mcc_compl_get(struct beiscsi_hba *phba) |
@@ -89,7 +153,7 @@ static void be2iscsi_fail_session(struct iscsi_cls_session *cls_session) | |||
89 | iscsi_session_failure(cls_session->dd_data, ISCSI_ERR_CONN_FAILED); | 153 | iscsi_session_failure(cls_session->dd_data, ISCSI_ERR_CONN_FAILED); |
90 | } | 154 | } |
91 | 155 | ||
92 | static void beiscsi_async_link_state_process(struct beiscsi_hba *phba, | 156 | void beiscsi_async_link_state_process(struct beiscsi_hba *phba, |
93 | struct be_async_event_link_state *evt) | 157 | struct be_async_event_link_state *evt) |
94 | { | 158 | { |
95 | switch (evt->port_link_status) { | 159 | switch (evt->port_link_status) { |
@@ -97,13 +161,13 @@ static void beiscsi_async_link_state_process(struct beiscsi_hba *phba, | |||
97 | SE_DEBUG(DBG_LVL_1, "Link Down on Physical Port %d \n", | 161 | SE_DEBUG(DBG_LVL_1, "Link Down on Physical Port %d \n", |
98 | evt->physical_port); | 162 | evt->physical_port); |
99 | phba->state |= BE_ADAPTER_LINK_DOWN; | 163 | phba->state |= BE_ADAPTER_LINK_DOWN; |
164 | iscsi_host_for_each_session(phba->shost, | ||
165 | be2iscsi_fail_session); | ||
100 | break; | 166 | break; |
101 | case ASYNC_EVENT_LINK_UP: | 167 | case ASYNC_EVENT_LINK_UP: |
102 | phba->state = BE_ADAPTER_UP; | 168 | phba->state = BE_ADAPTER_UP; |
103 | SE_DEBUG(DBG_LVL_1, "Link UP on Physical Port %d \n", | 169 | SE_DEBUG(DBG_LVL_1, "Link UP on Physical Port %d \n", |
104 | evt->physical_port); | 170 | evt->physical_port); |
105 | iscsi_host_for_each_session(phba->shost, | ||
106 | be2iscsi_fail_session); | ||
107 | break; | 171 | break; |
108 | default: | 172 | default: |
109 | SE_DEBUG(DBG_LVL_1, "Unexpected Async Notification %d on" | 173 | SE_DEBUG(DBG_LVL_1, "Unexpected Async Notification %d on" |
@@ -162,7 +226,6 @@ int beiscsi_process_mcc(struct beiscsi_hba *phba) | |||
162 | /* Wait till no more pending mcc requests are present */ | 226 | /* Wait till no more pending mcc requests are present */ |
163 | static int be_mcc_wait_compl(struct beiscsi_hba *phba) | 227 | static int be_mcc_wait_compl(struct beiscsi_hba *phba) |
164 | { | 228 | { |
165 | #define mcc_timeout 120000 /* 5s timeout */ | ||
166 | int i, status; | 229 | int i, status; |
167 | for (i = 0; i < mcc_timeout; i++) { | 230 | for (i = 0; i < mcc_timeout; i++) { |
168 | status = beiscsi_process_mcc(phba); | 231 | status = beiscsi_process_mcc(phba); |
@@ -372,9 +435,10 @@ struct be_mcc_wrb *wrb_from_mccq(struct beiscsi_hba *phba) | |||
372 | 435 | ||
373 | BUG_ON(atomic_read(&mccq->used) >= mccq->len); | 436 | BUG_ON(atomic_read(&mccq->used) >= mccq->len); |
374 | wrb = queue_head_node(mccq); | 437 | wrb = queue_head_node(mccq); |
438 | memset(wrb, 0, sizeof(*wrb)); | ||
439 | wrb->tag0 = (mccq->head & 0x000000FF) << 16; | ||
375 | queue_head_inc(mccq); | 440 | queue_head_inc(mccq); |
376 | atomic_inc(&mccq->used); | 441 | atomic_inc(&mccq->used); |
377 | memset(wrb, 0, sizeof(*wrb)); | ||
378 | return wrb; | 442 | return wrb; |
379 | } | 443 | } |
380 | 444 | ||
diff --git a/drivers/scsi/be2iscsi/be_cmds.h b/drivers/scsi/be2iscsi/be_cmds.h index 5de8acb924cb..49fcc787ee8b 100644 --- a/drivers/scsi/be2iscsi/be_cmds.h +++ b/drivers/scsi/be2iscsi/be_cmds.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /** | 1 | /** |
2 | * Copyright (C) 2005 - 2009 ServerEngines | 2 | * Copyright (C) 2005 - 2010 ServerEngines |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or | 5 | * This program is free software; you can redistribute it and/or |
@@ -425,14 +425,20 @@ int beiscsi_cmd_mccq_create(struct beiscsi_hba *phba, | |||
425 | int be_poll_mcc(struct be_ctrl_info *ctrl); | 425 | int be_poll_mcc(struct be_ctrl_info *ctrl); |
426 | unsigned char mgmt_check_supported_fw(struct be_ctrl_info *ctrl, | 426 | unsigned char mgmt_check_supported_fw(struct be_ctrl_info *ctrl, |
427 | struct beiscsi_hba *phba); | 427 | struct beiscsi_hba *phba); |
428 | int be_cmd_get_mac_addr(struct beiscsi_hba *phba, u8 *mac_addr); | 428 | unsigned int be_cmd_get_mac_addr(struct beiscsi_hba *phba); |
429 | 429 | void free_mcc_tag(struct be_ctrl_info *ctrl, unsigned int tag); | |
430 | /*ISCSI Functuions */ | 430 | /*ISCSI Functuions */ |
431 | int be_cmd_fw_initialize(struct be_ctrl_info *ctrl); | 431 | int be_cmd_fw_initialize(struct be_ctrl_info *ctrl); |
432 | 432 | ||
433 | struct be_mcc_wrb *wrb_from_mbox(struct be_dma_mem *mbox_mem); | 433 | struct be_mcc_wrb *wrb_from_mbox(struct be_dma_mem *mbox_mem); |
434 | struct be_mcc_wrb *wrb_from_mccq(struct beiscsi_hba *phba); | 434 | struct be_mcc_wrb *wrb_from_mccq(struct beiscsi_hba *phba); |
435 | int be_mcc_notify_wait(struct beiscsi_hba *phba); | 435 | int be_mcc_notify_wait(struct beiscsi_hba *phba); |
436 | void be_mcc_notify(struct beiscsi_hba *phba); | ||
437 | unsigned int alloc_mcc_tag(struct beiscsi_hba *phba); | ||
438 | void beiscsi_async_link_state_process(struct beiscsi_hba *phba, | ||
439 | struct be_async_event_link_state *evt); | ||
440 | int be_mcc_compl_process_isr(struct be_ctrl_info *ctrl, | ||
441 | struct be_mcc_compl *compl); | ||
436 | 442 | ||
437 | int be_mbox_notify(struct be_ctrl_info *ctrl); | 443 | int be_mbox_notify(struct be_ctrl_info *ctrl); |
438 | 444 | ||
@@ -448,6 +454,8 @@ int be_cmd_iscsi_post_sgl_pages(struct be_ctrl_info *ctrl, | |||
448 | int be_cmd_wrbq_create(struct be_ctrl_info *ctrl, struct be_dma_mem *q_mem, | 454 | int be_cmd_wrbq_create(struct be_ctrl_info *ctrl, struct be_dma_mem *q_mem, |
449 | struct be_queue_info *wrbq); | 455 | struct be_queue_info *wrbq); |
450 | 456 | ||
457 | bool is_link_state_evt(u32 trailer); | ||
458 | |||
451 | struct be_default_pdu_context { | 459 | struct be_default_pdu_context { |
452 | u32 dw[4]; | 460 | u32 dw[4]; |
453 | } __packed; | 461 | } __packed; |
diff --git a/drivers/scsi/be2iscsi/be_iscsi.c b/drivers/scsi/be2iscsi/be_iscsi.c index d587b0362f18..29a3aaf35f9f 100644 --- a/drivers/scsi/be2iscsi/be_iscsi.c +++ b/drivers/scsi/be2iscsi/be_iscsi.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /** | 1 | /** |
2 | * Copyright (C) 2005 - 2009 ServerEngines | 2 | * Copyright (C) 2005 - 2010 ServerEngines |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or | 5 | * This program is free software; you can redistribute it and/or |
@@ -101,6 +101,7 @@ void beiscsi_session_destroy(struct iscsi_cls_session *cls_session) | |||
101 | struct iscsi_session *sess = cls_session->dd_data; | 101 | struct iscsi_session *sess = cls_session->dd_data; |
102 | struct beiscsi_session *beiscsi_sess = sess->dd_data; | 102 | struct beiscsi_session *beiscsi_sess = sess->dd_data; |
103 | 103 | ||
104 | SE_DEBUG(DBG_LVL_8, "In beiscsi_session_destroy\n"); | ||
104 | pci_pool_destroy(beiscsi_sess->bhs_pool); | 105 | pci_pool_destroy(beiscsi_sess->bhs_pool); |
105 | iscsi_session_teardown(cls_session); | 106 | iscsi_session_teardown(cls_session); |
106 | } | 107 | } |
@@ -224,6 +225,7 @@ int beiscsi_conn_get_param(struct iscsi_cls_conn *cls_conn, | |||
224 | struct beiscsi_conn *beiscsi_conn = conn->dd_data; | 225 | struct beiscsi_conn *beiscsi_conn = conn->dd_data; |
225 | int len = 0; | 226 | int len = 0; |
226 | 227 | ||
228 | SE_DEBUG(DBG_LVL_8, "In beiscsi_conn_get_param, param= %d\n", param); | ||
227 | beiscsi_ep = beiscsi_conn->ep; | 229 | beiscsi_ep = beiscsi_conn->ep; |
228 | if (!beiscsi_ep) { | 230 | if (!beiscsi_ep) { |
229 | SE_DEBUG(DBG_LVL_1, | 231 | SE_DEBUG(DBG_LVL_1, |
@@ -254,6 +256,7 @@ int beiscsi_set_param(struct iscsi_cls_conn *cls_conn, | |||
254 | struct iscsi_session *session = conn->session; | 256 | struct iscsi_session *session = conn->session; |
255 | int ret; | 257 | int ret; |
256 | 258 | ||
259 | SE_DEBUG(DBG_LVL_8, "In beiscsi_conn_set_param, param= %d\n", param); | ||
257 | ret = iscsi_set_param(cls_conn, param, buf, buflen); | 260 | ret = iscsi_set_param(cls_conn, param, buf, buflen); |
258 | if (ret) | 261 | if (ret) |
259 | return ret; | 262 | return ret; |
@@ -271,8 +274,8 @@ int beiscsi_set_param(struct iscsi_cls_conn *cls_conn, | |||
271 | conn->max_recv_dlength = 65536; | 274 | conn->max_recv_dlength = 65536; |
272 | break; | 275 | break; |
273 | case ISCSI_PARAM_MAX_BURST: | 276 | case ISCSI_PARAM_MAX_BURST: |
274 | if (session->first_burst > 262144) | 277 | if (session->max_burst > 262144) |
275 | session->first_burst = 262144; | 278 | session->max_burst = 262144; |
276 | break; | 279 | break; |
277 | default: | 280 | default: |
278 | return 0; | 281 | return 0; |
@@ -293,12 +296,41 @@ int beiscsi_get_host_param(struct Scsi_Host *shost, | |||
293 | enum iscsi_host_param param, char *buf) | 296 | enum iscsi_host_param param, char *buf) |
294 | { | 297 | { |
295 | struct beiscsi_hba *phba = (struct beiscsi_hba *)iscsi_host_priv(shost); | 298 | struct beiscsi_hba *phba = (struct beiscsi_hba *)iscsi_host_priv(shost); |
299 | struct be_cmd_resp_get_mac_addr *resp; | ||
300 | struct be_mcc_wrb *wrb; | ||
301 | unsigned int tag, wrb_num; | ||
296 | int len = 0; | 302 | int len = 0; |
303 | unsigned short status, extd_status; | ||
304 | struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q; | ||
297 | 305 | ||
306 | SE_DEBUG(DBG_LVL_8, "In beiscsi_get_host_param, param= %d\n", param); | ||
298 | switch (param) { | 307 | switch (param) { |
299 | case ISCSI_HOST_PARAM_HWADDRESS: | 308 | case ISCSI_HOST_PARAM_HWADDRESS: |
300 | be_cmd_get_mac_addr(phba, phba->mac_address); | 309 | tag = be_cmd_get_mac_addr(phba); |
301 | len = sysfs_format_mac(buf, phba->mac_address, ETH_ALEN); | 310 | if (!tag) { |
311 | SE_DEBUG(DBG_LVL_1, "be_cmd_get_mac_addr Failed \n"); | ||
312 | return -1; | ||
313 | } else | ||
314 | wait_event_interruptible(phba->ctrl.mcc_wait[tag], | ||
315 | phba->ctrl.mcc_numtag[tag]); | ||
316 | |||
317 | wrb_num = (phba->ctrl.mcc_numtag[tag] & 0x00FF0000) >> 16; | ||
318 | extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8; | ||
319 | status = phba->ctrl.mcc_numtag[tag] & 0x000000FF; | ||
320 | if (status || extd_status) { | ||
321 | SE_DEBUG(DBG_LVL_1, "be_cmd_get_mac_addr Failed" | ||
322 | " status = %d extd_status = %d \n", | ||
323 | status, extd_status); | ||
324 | free_mcc_tag(&phba->ctrl, tag); | ||
325 | return -1; | ||
326 | } else { | ||
327 | wrb = queue_get_wrb(mccq, wrb_num); | ||
328 | free_mcc_tag(&phba->ctrl, tag); | ||
329 | resp = embedded_payload(wrb); | ||
330 | memcpy(phba->mac_address, resp->mac_address, ETH_ALEN); | ||
331 | len = sysfs_format_mac(buf, phba->mac_address, | ||
332 | ETH_ALEN); | ||
333 | } | ||
302 | break; | 334 | break; |
303 | default: | 335 | default: |
304 | return iscsi_host_get_param(shost, param, buf); | 336 | return iscsi_host_get_param(shost, param, buf); |
@@ -378,6 +410,7 @@ int beiscsi_conn_start(struct iscsi_cls_conn *cls_conn) | |||
378 | struct beiscsi_endpoint *beiscsi_ep; | 410 | struct beiscsi_endpoint *beiscsi_ep; |
379 | struct beiscsi_offload_params params; | 411 | struct beiscsi_offload_params params; |
380 | 412 | ||
413 | SE_DEBUG(DBG_LVL_8, "In beiscsi_conn_start\n"); | ||
381 | memset(¶ms, 0, sizeof(struct beiscsi_offload_params)); | 414 | memset(¶ms, 0, sizeof(struct beiscsi_offload_params)); |
382 | beiscsi_ep = beiscsi_conn->ep; | 415 | beiscsi_ep = beiscsi_conn->ep; |
383 | if (!beiscsi_ep) | 416 | if (!beiscsi_ep) |
@@ -422,8 +455,14 @@ static int beiscsi_open_conn(struct iscsi_endpoint *ep, | |||
422 | { | 455 | { |
423 | struct beiscsi_endpoint *beiscsi_ep = ep->dd_data; | 456 | struct beiscsi_endpoint *beiscsi_ep = ep->dd_data; |
424 | struct beiscsi_hba *phba = beiscsi_ep->phba; | 457 | struct beiscsi_hba *phba = beiscsi_ep->phba; |
458 | struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q; | ||
459 | struct be_mcc_wrb *wrb; | ||
460 | struct tcp_connect_and_offload_out *ptcpcnct_out; | ||
461 | unsigned short status, extd_status; | ||
462 | unsigned int tag, wrb_num; | ||
425 | int ret = -1; | 463 | int ret = -1; |
426 | 464 | ||
465 | SE_DEBUG(DBG_LVL_8, "In beiscsi_open_conn\n"); | ||
427 | beiscsi_ep->ep_cid = beiscsi_get_cid(phba); | 466 | beiscsi_ep->ep_cid = beiscsi_get_cid(phba); |
428 | if (beiscsi_ep->ep_cid == 0xFFFF) { | 467 | if (beiscsi_ep->ep_cid == 0xFFFF) { |
429 | SE_DEBUG(DBG_LVL_1, "No free cid available\n"); | 468 | SE_DEBUG(DBG_LVL_1, "No free cid available\n"); |
@@ -431,15 +470,44 @@ static int beiscsi_open_conn(struct iscsi_endpoint *ep, | |||
431 | } | 470 | } |
432 | SE_DEBUG(DBG_LVL_8, "In beiscsi_open_conn, ep_cid=%d ", | 471 | SE_DEBUG(DBG_LVL_8, "In beiscsi_open_conn, ep_cid=%d ", |
433 | beiscsi_ep->ep_cid); | 472 | beiscsi_ep->ep_cid); |
434 | phba->ep_array[beiscsi_ep->ep_cid] = ep; | 473 | phba->ep_array[beiscsi_ep->ep_cid - |
435 | if (beiscsi_ep->ep_cid > | 474 | phba->fw_config.iscsi_cid_start] = ep; |
436 | (phba->fw_config.iscsi_cid_start + phba->params.cxns_per_ctrl)) { | 475 | if (beiscsi_ep->ep_cid > (phba->fw_config.iscsi_cid_start + |
476 | phba->params.cxns_per_ctrl * 2)) { | ||
437 | SE_DEBUG(DBG_LVL_1, "Failed in allocate iscsi cid\n"); | 477 | SE_DEBUG(DBG_LVL_1, "Failed in allocate iscsi cid\n"); |
438 | return ret; | 478 | return ret; |
439 | } | 479 | } |
440 | 480 | ||
441 | beiscsi_ep->cid_vld = 0; | 481 | beiscsi_ep->cid_vld = 0; |
442 | return mgmt_open_connection(phba, dst_addr, beiscsi_ep); | 482 | tag = mgmt_open_connection(phba, dst_addr, beiscsi_ep); |
483 | if (!tag) { | ||
484 | SE_DEBUG(DBG_LVL_1, | ||
485 | "mgmt_invalidate_connection Failed for cid=%d \n", | ||
486 | beiscsi_ep->ep_cid); | ||
487 | } else { | ||
488 | wait_event_interruptible(phba->ctrl.mcc_wait[tag], | ||
489 | phba->ctrl.mcc_numtag[tag]); | ||
490 | } | ||
491 | wrb_num = (phba->ctrl.mcc_numtag[tag] & 0x00FF0000) >> 16; | ||
492 | extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8; | ||
493 | status = phba->ctrl.mcc_numtag[tag] & 0x000000FF; | ||
494 | if (status || extd_status) { | ||
495 | SE_DEBUG(DBG_LVL_1, "mgmt_open_connection Failed" | ||
496 | " status = %d extd_status = %d \n", | ||
497 | status, extd_status); | ||
498 | free_mcc_tag(&phba->ctrl, tag); | ||
499 | return -1; | ||
500 | } else { | ||
501 | wrb = queue_get_wrb(mccq, wrb_num); | ||
502 | free_mcc_tag(&phba->ctrl, tag); | ||
503 | |||
504 | ptcpcnct_out = embedded_payload(wrb); | ||
505 | beiscsi_ep = ep->dd_data; | ||
506 | beiscsi_ep->fw_handle = ptcpcnct_out->connection_handle; | ||
507 | beiscsi_ep->cid_vld = 1; | ||
508 | SE_DEBUG(DBG_LVL_8, "mgmt_open_connection Success\n"); | ||
509 | } | ||
510 | return 0; | ||
443 | } | 511 | } |
444 | 512 | ||
445 | /** | 513 | /** |
@@ -459,14 +527,12 @@ static void beiscsi_put_cid(struct beiscsi_hba *phba, unsigned short cid) | |||
459 | * beiscsi_free_ep - free endpoint | 527 | * beiscsi_free_ep - free endpoint |
460 | * @ep: pointer to iscsi endpoint structure | 528 | * @ep: pointer to iscsi endpoint structure |
461 | */ | 529 | */ |
462 | static void beiscsi_free_ep(struct iscsi_endpoint *ep) | 530 | static void beiscsi_free_ep(struct beiscsi_endpoint *beiscsi_ep) |
463 | { | 531 | { |
464 | struct beiscsi_endpoint *beiscsi_ep = ep->dd_data; | ||
465 | struct beiscsi_hba *phba = beiscsi_ep->phba; | 532 | struct beiscsi_hba *phba = beiscsi_ep->phba; |
466 | 533 | ||
467 | beiscsi_put_cid(phba, beiscsi_ep->ep_cid); | 534 | beiscsi_put_cid(phba, beiscsi_ep->ep_cid); |
468 | beiscsi_ep->phba = NULL; | 535 | beiscsi_ep->phba = NULL; |
469 | iscsi_destroy_endpoint(ep); | ||
470 | } | 536 | } |
471 | 537 | ||
472 | /** | 538 | /** |
@@ -495,9 +561,9 @@ beiscsi_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr, | |||
495 | return ERR_PTR(ret); | 561 | return ERR_PTR(ret); |
496 | } | 562 | } |
497 | 563 | ||
498 | if (phba->state) { | 564 | if (phba->state != BE_ADAPTER_UP) { |
499 | ret = -EBUSY; | 565 | ret = -EBUSY; |
500 | SE_DEBUG(DBG_LVL_1, "The Adapet state is Not UP \n"); | 566 | SE_DEBUG(DBG_LVL_1, "The Adapter state is Not UP \n"); |
501 | return ERR_PTR(ret); | 567 | return ERR_PTR(ret); |
502 | } | 568 | } |
503 | 569 | ||
@@ -509,9 +575,9 @@ beiscsi_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr, | |||
509 | 575 | ||
510 | beiscsi_ep = ep->dd_data; | 576 | beiscsi_ep = ep->dd_data; |
511 | beiscsi_ep->phba = phba; | 577 | beiscsi_ep->phba = phba; |
512 | 578 | beiscsi_ep->openiscsi_ep = ep; | |
513 | if (beiscsi_open_conn(ep, NULL, dst_addr, non_blocking)) { | 579 | if (beiscsi_open_conn(ep, NULL, dst_addr, non_blocking)) { |
514 | SE_DEBUG(DBG_LVL_1, "Failed in allocate iscsi cid\n"); | 580 | SE_DEBUG(DBG_LVL_1, "Failed in beiscsi_open_conn \n"); |
515 | ret = -ENOMEM; | 581 | ret = -ENOMEM; |
516 | goto free_ep; | 582 | goto free_ep; |
517 | } | 583 | } |
@@ -519,7 +585,7 @@ beiscsi_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr, | |||
519 | return ep; | 585 | return ep; |
520 | 586 | ||
521 | free_ep: | 587 | free_ep: |
522 | beiscsi_free_ep(ep); | 588 | beiscsi_free_ep(beiscsi_ep); |
523 | return ERR_PTR(ret); | 589 | return ERR_PTR(ret); |
524 | } | 590 | } |
525 | 591 | ||
@@ -546,20 +612,22 @@ int beiscsi_ep_poll(struct iscsi_endpoint *ep, int timeout_ms) | |||
546 | * @ep: The iscsi endpoint | 612 | * @ep: The iscsi endpoint |
547 | * @flag: The type of connection closure | 613 | * @flag: The type of connection closure |
548 | */ | 614 | */ |
549 | static int beiscsi_close_conn(struct iscsi_endpoint *ep, int flag) | 615 | static int beiscsi_close_conn(struct beiscsi_endpoint *beiscsi_ep, int flag) |
550 | { | 616 | { |
551 | int ret = 0; | 617 | int ret = 0; |
552 | struct beiscsi_endpoint *beiscsi_ep = ep->dd_data; | 618 | unsigned int tag; |
553 | struct beiscsi_hba *phba = beiscsi_ep->phba; | 619 | struct beiscsi_hba *phba = beiscsi_ep->phba; |
554 | 620 | ||
555 | if (MGMT_STATUS_SUCCESS != | 621 | tag = mgmt_upload_connection(phba, beiscsi_ep->ep_cid, flag); |
556 | mgmt_upload_connection(phba, beiscsi_ep->ep_cid, | 622 | if (!tag) { |
557 | CONNECTION_UPLOAD_GRACEFUL)) { | ||
558 | SE_DEBUG(DBG_LVL_8, "upload failed for cid 0x%x", | 623 | SE_DEBUG(DBG_LVL_8, "upload failed for cid 0x%x", |
559 | beiscsi_ep->ep_cid); | 624 | beiscsi_ep->ep_cid); |
560 | ret = -1; | 625 | ret = -1; |
626 | } else { | ||
627 | wait_event_interruptible(phba->ctrl.mcc_wait[tag], | ||
628 | phba->ctrl.mcc_numtag[tag]); | ||
629 | free_mcc_tag(&phba->ctrl, tag); | ||
561 | } | 630 | } |
562 | |||
563 | return ret; | 631 | return ret; |
564 | } | 632 | } |
565 | 633 | ||
@@ -574,19 +642,17 @@ void beiscsi_ep_disconnect(struct iscsi_endpoint *ep) | |||
574 | struct beiscsi_conn *beiscsi_conn; | 642 | struct beiscsi_conn *beiscsi_conn; |
575 | struct beiscsi_endpoint *beiscsi_ep; | 643 | struct beiscsi_endpoint *beiscsi_ep; |
576 | struct beiscsi_hba *phba; | 644 | struct beiscsi_hba *phba; |
577 | int flag = 0; | ||
578 | 645 | ||
579 | beiscsi_ep = ep->dd_data; | 646 | beiscsi_ep = ep->dd_data; |
580 | phba = beiscsi_ep->phba; | 647 | phba = beiscsi_ep->phba; |
581 | SE_DEBUG(DBG_LVL_8, "In beiscsi_ep_disconnect\n"); | 648 | SE_DEBUG(DBG_LVL_8, "In beiscsi_ep_disconnect for ep_cid = %d\n", |
649 | beiscsi_ep->ep_cid); | ||
582 | 650 | ||
583 | if (beiscsi_ep->conn) { | 651 | if (beiscsi_ep->conn) { |
584 | beiscsi_conn = beiscsi_ep->conn; | 652 | beiscsi_conn = beiscsi_ep->conn; |
585 | iscsi_suspend_queue(beiscsi_conn->conn); | 653 | iscsi_suspend_queue(beiscsi_conn->conn); |
586 | beiscsi_close_conn(ep, flag); | ||
587 | } | 654 | } |
588 | 655 | ||
589 | beiscsi_free_ep(ep); | ||
590 | } | 656 | } |
591 | 657 | ||
592 | /** | 658 | /** |
@@ -619,23 +685,31 @@ void beiscsi_conn_stop(struct iscsi_cls_conn *cls_conn, int flag) | |||
619 | struct iscsi_session *session = conn->session; | 685 | struct iscsi_session *session = conn->session; |
620 | struct Scsi_Host *shost = iscsi_session_to_shost(session->cls_session); | 686 | struct Scsi_Host *shost = iscsi_session_to_shost(session->cls_session); |
621 | struct beiscsi_hba *phba = iscsi_host_priv(shost); | 687 | struct beiscsi_hba *phba = iscsi_host_priv(shost); |
622 | unsigned int status; | 688 | unsigned int tag; |
623 | unsigned short savecfg_flag = CMD_ISCSI_SESSION_SAVE_CFG_ON_FLASH; | 689 | unsigned short savecfg_flag = CMD_ISCSI_SESSION_SAVE_CFG_ON_FLASH; |
624 | 690 | ||
625 | SE_DEBUG(DBG_LVL_8, "In beiscsi_conn_stop\n"); | ||
626 | beiscsi_ep = beiscsi_conn->ep; | 691 | beiscsi_ep = beiscsi_conn->ep; |
627 | if (!beiscsi_ep) { | 692 | if (!beiscsi_ep) { |
628 | SE_DEBUG(DBG_LVL_8, "In beiscsi_conn_stop , no beiscsi_ep\n"); | 693 | SE_DEBUG(DBG_LVL_8, "In beiscsi_conn_stop , no beiscsi_ep\n"); |
629 | return; | 694 | return; |
630 | } | 695 | } |
631 | status = mgmt_invalidate_connection(phba, beiscsi_ep, | 696 | SE_DEBUG(DBG_LVL_8, "In beiscsi_conn_stop ep_cid = %d\n", |
697 | beiscsi_ep->ep_cid); | ||
698 | tag = mgmt_invalidate_connection(phba, beiscsi_ep, | ||
632 | beiscsi_ep->ep_cid, 1, | 699 | beiscsi_ep->ep_cid, 1, |
633 | savecfg_flag); | 700 | savecfg_flag); |
634 | if (status != MGMT_STATUS_SUCCESS) { | 701 | if (!tag) { |
635 | SE_DEBUG(DBG_LVL_1, | 702 | SE_DEBUG(DBG_LVL_1, |
636 | "mgmt_invalidate_connection Failed for cid=%d \n", | 703 | "mgmt_invalidate_connection Failed for cid=%d \n", |
637 | beiscsi_ep->ep_cid); | 704 | beiscsi_ep->ep_cid); |
705 | } else { | ||
706 | wait_event_interruptible(phba->ctrl.mcc_wait[tag], | ||
707 | phba->ctrl.mcc_numtag[tag]); | ||
708 | free_mcc_tag(&phba->ctrl, tag); | ||
638 | } | 709 | } |
710 | beiscsi_close_conn(beiscsi_ep, CONNECTION_UPLOAD_GRACEFUL); | ||
711 | beiscsi_free_ep(beiscsi_ep); | ||
712 | iscsi_destroy_endpoint(beiscsi_ep->openiscsi_ep); | ||
639 | beiscsi_unbind_conn_to_cid(phba, beiscsi_ep->ep_cid); | 713 | beiscsi_unbind_conn_to_cid(phba, beiscsi_ep->ep_cid); |
640 | iscsi_conn_stop(cls_conn, flag); | 714 | iscsi_conn_stop(cls_conn, flag); |
641 | } | 715 | } |
diff --git a/drivers/scsi/be2iscsi/be_iscsi.h b/drivers/scsi/be2iscsi/be_iscsi.h index f92ffc5349fb..1f512c28cbf9 100644 --- a/drivers/scsi/be2iscsi/be_iscsi.h +++ b/drivers/scsi/be2iscsi/be_iscsi.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /** | 1 | /** |
2 | * Copyright (C) 2005 - 2009 ServerEngines | 2 | * Copyright (C) 2005 - 2010 ServerEngines |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or | 5 | * This program is free software; you can redistribute it and/or |
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c index 1a557fa77888..7c22616ab141 100644 --- a/drivers/scsi/be2iscsi/be_main.c +++ b/drivers/scsi/be2iscsi/be_main.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /** | 1 | /** |
2 | * Copyright (C) 2005 - 2009 ServerEngines | 2 | * Copyright (C) 2005 - 2010 ServerEngines |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or | 5 | * This program is free software; you can redistribute it and/or |
@@ -40,7 +40,6 @@ | |||
40 | static unsigned int be_iopoll_budget = 10; | 40 | static unsigned int be_iopoll_budget = 10; |
41 | static unsigned int be_max_phys_size = 64; | 41 | static unsigned int be_max_phys_size = 64; |
42 | static unsigned int enable_msix = 1; | 42 | static unsigned int enable_msix = 1; |
43 | static unsigned int ring_mode; | ||
44 | 43 | ||
45 | MODULE_DEVICE_TABLE(pci, beiscsi_pci_id_table); | 44 | MODULE_DEVICE_TABLE(pci, beiscsi_pci_id_table); |
46 | MODULE_DESCRIPTION(DRV_DESC " " BUILD_STR); | 45 | MODULE_DESCRIPTION(DRV_DESC " " BUILD_STR); |
@@ -62,10 +61,10 @@ static int beiscsi_slave_configure(struct scsi_device *sdev) | |||
62 | /*------------------- PCI Driver operations and data ----------------- */ | 61 | /*------------------- PCI Driver operations and data ----------------- */ |
63 | static DEFINE_PCI_DEVICE_TABLE(beiscsi_pci_id_table) = { | 62 | static DEFINE_PCI_DEVICE_TABLE(beiscsi_pci_id_table) = { |
64 | { PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID1) }, | 63 | { PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID1) }, |
64 | { PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID2) }, | ||
65 | { PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID1) }, | 65 | { PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID1) }, |
66 | { PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID2) }, | 66 | { PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID2) }, |
67 | { PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID3) }, | 67 | { PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID3) }, |
68 | { PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID4) }, | ||
69 | { 0 } | 68 | { 0 } |
70 | }; | 69 | }; |
71 | MODULE_DEVICE_TABLE(pci, beiscsi_pci_id_table); | 70 | MODULE_DEVICE_TABLE(pci, beiscsi_pci_id_table); |
@@ -112,6 +111,7 @@ static struct beiscsi_hba *beiscsi_hba_alloc(struct pci_dev *pcidev) | |||
112 | memset(phba, 0, sizeof(*phba)); | 111 | memset(phba, 0, sizeof(*phba)); |
113 | phba->shost = shost; | 112 | phba->shost = shost; |
114 | phba->pcidev = pci_dev_get(pcidev); | 113 | phba->pcidev = pci_dev_get(pcidev); |
114 | pci_set_drvdata(pcidev, phba); | ||
115 | 115 | ||
116 | if (iscsi_host_add(shost, &phba->pcidev->dev)) | 116 | if (iscsi_host_add(shost, &phba->pcidev->dev)) |
117 | goto free_devices; | 117 | goto free_devices; |
@@ -143,6 +143,7 @@ static int beiscsi_map_pci_bars(struct beiscsi_hba *phba, | |||
143 | struct pci_dev *pcidev) | 143 | struct pci_dev *pcidev) |
144 | { | 144 | { |
145 | u8 __iomem *addr; | 145 | u8 __iomem *addr; |
146 | int pcicfg_reg; | ||
146 | 147 | ||
147 | addr = ioremap_nocache(pci_resource_start(pcidev, 2), | 148 | addr = ioremap_nocache(pci_resource_start(pcidev, 2), |
148 | pci_resource_len(pcidev, 2)); | 149 | pci_resource_len(pcidev, 2)); |
@@ -159,13 +160,19 @@ static int beiscsi_map_pci_bars(struct beiscsi_hba *phba, | |||
159 | phba->db_va = addr; | 160 | phba->db_va = addr; |
160 | phba->db_pa.u.a64.address = pci_resource_start(pcidev, 4); | 161 | phba->db_pa.u.a64.address = pci_resource_start(pcidev, 4); |
161 | 162 | ||
162 | addr = ioremap_nocache(pci_resource_start(pcidev, 1), | 163 | if (phba->generation == BE_GEN2) |
163 | pci_resource_len(pcidev, 1)); | 164 | pcicfg_reg = 1; |
165 | else | ||
166 | pcicfg_reg = 0; | ||
167 | |||
168 | addr = ioremap_nocache(pci_resource_start(pcidev, pcicfg_reg), | ||
169 | pci_resource_len(pcidev, pcicfg_reg)); | ||
170 | |||
164 | if (addr == NULL) | 171 | if (addr == NULL) |
165 | goto pci_map_err; | 172 | goto pci_map_err; |
166 | phba->ctrl.pcicfg = addr; | 173 | phba->ctrl.pcicfg = addr; |
167 | phba->pci_va = addr; | 174 | phba->pci_va = addr; |
168 | phba->pci_pa.u.a64.address = pci_resource_start(pcidev, 1); | 175 | phba->pci_pa.u.a64.address = pci_resource_start(pcidev, pcicfg_reg); |
169 | return 0; | 176 | return 0; |
170 | 177 | ||
171 | pci_map_err: | 178 | pci_map_err: |
@@ -230,29 +237,27 @@ static int be_ctrl_init(struct beiscsi_hba *phba, struct pci_dev *pdev) | |||
230 | 237 | ||
231 | static void beiscsi_get_params(struct beiscsi_hba *phba) | 238 | static void beiscsi_get_params(struct beiscsi_hba *phba) |
232 | { | 239 | { |
233 | phba->params.ios_per_ctrl = BE2_IO_DEPTH; | 240 | phba->params.ios_per_ctrl = (phba->fw_config.iscsi_icd_count |
234 | phba->params.cxns_per_ctrl = BE2_MAX_SESSIONS; | 241 | - (phba->fw_config.iscsi_cid_count |
235 | phba->params.asyncpdus_per_ctrl = BE2_ASYNCPDUS; | 242 | + BE2_TMFS |
236 | phba->params.icds_per_ctrl = BE2_MAX_ICDS / 2; | 243 | + BE2_NOPOUT_REQ)); |
244 | phba->params.cxns_per_ctrl = phba->fw_config.iscsi_cid_count; | ||
245 | phba->params.asyncpdus_per_ctrl = phba->fw_config.iscsi_cid_count;; | ||
246 | phba->params.icds_per_ctrl = phba->fw_config.iscsi_icd_count;; | ||
237 | phba->params.num_sge_per_io = BE2_SGE; | 247 | phba->params.num_sge_per_io = BE2_SGE; |
238 | phba->params.defpdu_hdr_sz = BE2_DEFPDU_HDR_SZ; | 248 | phba->params.defpdu_hdr_sz = BE2_DEFPDU_HDR_SZ; |
239 | phba->params.defpdu_data_sz = BE2_DEFPDU_DATA_SZ; | 249 | phba->params.defpdu_data_sz = BE2_DEFPDU_DATA_SZ; |
240 | phba->params.eq_timer = 64; | 250 | phba->params.eq_timer = 64; |
241 | phba->params.num_eq_entries = | 251 | phba->params.num_eq_entries = |
242 | (((BE2_CMDS_PER_CXN * 2 + BE2_LOGOUTS + BE2_TMFS + BE2_ASYNCPDUS) / | 252 | (((BE2_CMDS_PER_CXN * 2 + phba->fw_config.iscsi_cid_count * 2 |
243 | 512) + 1) * 512; | 253 | + BE2_TMFS) / 512) + 1) * 512; |
244 | phba->params.num_eq_entries = (phba->params.num_eq_entries < 1024) | 254 | phba->params.num_eq_entries = (phba->params.num_eq_entries < 1024) |
245 | ? 1024 : phba->params.num_eq_entries; | 255 | ? 1024 : phba->params.num_eq_entries; |
246 | SE_DEBUG(DBG_LVL_8, "phba->params.num_eq_entries=%d \n", | 256 | SE_DEBUG(DBG_LVL_8, "phba->params.num_eq_entries=%d \n", |
247 | phba->params.num_eq_entries); | 257 | phba->params.num_eq_entries); |
248 | phba->params.num_cq_entries = | 258 | phba->params.num_cq_entries = |
249 | (((BE2_CMDS_PER_CXN * 2 + BE2_LOGOUTS + BE2_TMFS + BE2_ASYNCPDUS) / | 259 | (((BE2_CMDS_PER_CXN * 2 + phba->fw_config.iscsi_cid_count * 2 |
250 | 512) + 1) * 512; | 260 | + BE2_TMFS) / 512) + 1) * 512; |
251 | SE_DEBUG(DBG_LVL_8, | ||
252 | "phba->params.num_cq_entries=%d BE2_CMDS_PER_CXN=%d" | ||
253 | "BE2_LOGOUTS=%d BE2_TMFS=%d BE2_ASYNCPDUS=%d \n", | ||
254 | phba->params.num_cq_entries, BE2_CMDS_PER_CXN, | ||
255 | BE2_LOGOUTS, BE2_TMFS, BE2_ASYNCPDUS); | ||
256 | phba->params.wrbs_per_cxn = 256; | 261 | phba->params.wrbs_per_cxn = 256; |
257 | } | 262 | } |
258 | 263 | ||
@@ -443,7 +448,7 @@ static irqreturn_t be_isr(int irq, void *dev_id) | |||
443 | if (phba->todo_mcc_cq) | 448 | if (phba->todo_mcc_cq) |
444 | queue_work(phba->wq, &phba->work_cqs); | 449 | queue_work(phba->wq, &phba->work_cqs); |
445 | 450 | ||
446 | if ((num_mcceq_processed) && (!num_ioeq_processed)) | 451 | if ((num_mcceq_processed) && (!num_ioeq_processed)) |
447 | hwi_ring_eq_db(phba, eq->id, 0, | 452 | hwi_ring_eq_db(phba, eq->id, 0, |
448 | (num_ioeq_processed + | 453 | (num_ioeq_processed + |
449 | num_mcceq_processed) , 1, 1); | 454 | num_mcceq_processed) , 1, 1); |
@@ -561,6 +566,7 @@ beiscsi_process_async_pdu(struct beiscsi_conn *beiscsi_conn, | |||
561 | SE_DEBUG(DBG_LVL_1, "In ISCSI_OP_REJECT\n"); | 566 | SE_DEBUG(DBG_LVL_1, "In ISCSI_OP_REJECT\n"); |
562 | break; | 567 | break; |
563 | case ISCSI_OP_LOGIN_RSP: | 568 | case ISCSI_OP_LOGIN_RSP: |
569 | case ISCSI_OP_TEXT_RSP: | ||
564 | task = conn->login_task; | 570 | task = conn->login_task; |
565 | io_task = task->dd_data; | 571 | io_task = task->dd_data; |
566 | login_hdr = (struct iscsi_hdr *)ppdu; | 572 | login_hdr = (struct iscsi_hdr *)ppdu; |
@@ -631,29 +637,29 @@ free_io_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle) | |||
631 | * alloc_wrb_handle - To allocate a wrb handle | 637 | * alloc_wrb_handle - To allocate a wrb handle |
632 | * @phba: The hba pointer | 638 | * @phba: The hba pointer |
633 | * @cid: The cid to use for allocation | 639 | * @cid: The cid to use for allocation |
634 | * @index: index allocation and wrb index | ||
635 | * | 640 | * |
636 | * This happens under session_lock until submission to chip | 641 | * This happens under session_lock until submission to chip |
637 | */ | 642 | */ |
638 | struct wrb_handle *alloc_wrb_handle(struct beiscsi_hba *phba, unsigned int cid, | 643 | struct wrb_handle *alloc_wrb_handle(struct beiscsi_hba *phba, unsigned int cid) |
639 | int index) | ||
640 | { | 644 | { |
641 | struct hwi_wrb_context *pwrb_context; | 645 | struct hwi_wrb_context *pwrb_context; |
642 | struct hwi_controller *phwi_ctrlr; | 646 | struct hwi_controller *phwi_ctrlr; |
643 | struct wrb_handle *pwrb_handle; | 647 | struct wrb_handle *pwrb_handle, *pwrb_handle_tmp; |
644 | 648 | ||
645 | phwi_ctrlr = phba->phwi_ctrlr; | 649 | phwi_ctrlr = phba->phwi_ctrlr; |
646 | pwrb_context = &phwi_ctrlr->wrb_context[cid]; | 650 | pwrb_context = &phwi_ctrlr->wrb_context[cid]; |
647 | if (pwrb_context->wrb_handles_available) { | 651 | if (pwrb_context->wrb_handles_available >= 2) { |
648 | pwrb_handle = pwrb_context->pwrb_handle_base[ | 652 | pwrb_handle = pwrb_context->pwrb_handle_base[ |
649 | pwrb_context->alloc_index]; | 653 | pwrb_context->alloc_index]; |
650 | pwrb_context->wrb_handles_available--; | 654 | pwrb_context->wrb_handles_available--; |
651 | pwrb_handle->nxt_wrb_index = pwrb_handle->wrb_index; | ||
652 | if (pwrb_context->alloc_index == | 655 | if (pwrb_context->alloc_index == |
653 | (phba->params.wrbs_per_cxn - 1)) | 656 | (phba->params.wrbs_per_cxn - 1)) |
654 | pwrb_context->alloc_index = 0; | 657 | pwrb_context->alloc_index = 0; |
655 | else | 658 | else |
656 | pwrb_context->alloc_index++; | 659 | pwrb_context->alloc_index++; |
660 | pwrb_handle_tmp = pwrb_context->pwrb_handle_base[ | ||
661 | pwrb_context->alloc_index]; | ||
662 | pwrb_handle->nxt_wrb_index = pwrb_handle_tmp->wrb_index; | ||
657 | } else | 663 | } else |
658 | pwrb_handle = NULL; | 664 | pwrb_handle = NULL; |
659 | return pwrb_handle; | 665 | return pwrb_handle; |
@@ -671,9 +677,7 @@ static void | |||
671 | free_wrb_handle(struct beiscsi_hba *phba, struct hwi_wrb_context *pwrb_context, | 677 | free_wrb_handle(struct beiscsi_hba *phba, struct hwi_wrb_context *pwrb_context, |
672 | struct wrb_handle *pwrb_handle) | 678 | struct wrb_handle *pwrb_handle) |
673 | { | 679 | { |
674 | if (!ring_mode) | 680 | pwrb_context->pwrb_handle_base[pwrb_context->free_index] = pwrb_handle; |
675 | pwrb_context->pwrb_handle_base[pwrb_context->free_index] = | ||
676 | pwrb_handle; | ||
677 | pwrb_context->wrb_handles_available++; | 681 | pwrb_context->wrb_handles_available++; |
678 | if (pwrb_context->free_index == (phba->params.wrbs_per_cxn - 1)) | 682 | if (pwrb_context->free_index == (phba->params.wrbs_per_cxn - 1)) |
679 | pwrb_context->free_index = 0; | 683 | pwrb_context->free_index = 0; |
@@ -790,6 +794,7 @@ be_complete_io(struct beiscsi_conn *beiscsi_conn, | |||
790 | memcpy(task->sc->sense_buffer, sense, | 794 | memcpy(task->sc->sense_buffer, sense, |
791 | min_t(u16, sense_len, SCSI_SENSE_BUFFERSIZE)); | 795 | min_t(u16, sense_len, SCSI_SENSE_BUFFERSIZE)); |
792 | } | 796 | } |
797 | |||
793 | if (io_task->cmd_bhs->iscsi_hdr.flags & ISCSI_FLAG_CMD_READ) { | 798 | if (io_task->cmd_bhs->iscsi_hdr.flags & ISCSI_FLAG_CMD_READ) { |
794 | if (psol->dw[offsetof(struct amap_sol_cqe, i_res_cnt) / 32] | 799 | if (psol->dw[offsetof(struct amap_sol_cqe, i_res_cnt) / 32] |
795 | & SOL_RES_CNT_MASK) | 800 | & SOL_RES_CNT_MASK) |
@@ -811,6 +816,7 @@ be_complete_logout(struct beiscsi_conn *beiscsi_conn, | |||
811 | struct iscsi_conn *conn = beiscsi_conn->conn; | 816 | struct iscsi_conn *conn = beiscsi_conn->conn; |
812 | 817 | ||
813 | hdr = (struct iscsi_logout_rsp *)task->hdr; | 818 | hdr = (struct iscsi_logout_rsp *)task->hdr; |
819 | hdr->opcode = ISCSI_OP_LOGOUT_RSP; | ||
814 | hdr->t2wait = 5; | 820 | hdr->t2wait = 5; |
815 | hdr->t2retain = 0; | 821 | hdr->t2retain = 0; |
816 | hdr->flags = ((psol->dw[offsetof(struct amap_sol_cqe, i_flags) / 32] | 822 | hdr->flags = ((psol->dw[offsetof(struct amap_sol_cqe, i_flags) / 32] |
@@ -825,6 +831,9 @@ be_complete_logout(struct beiscsi_conn *beiscsi_conn, | |||
825 | & SOL_EXP_CMD_SN_MASK) + | 831 | & SOL_EXP_CMD_SN_MASK) + |
826 | ((psol->dw[offsetof(struct amap_sol_cqe, i_cmd_wnd) | 832 | ((psol->dw[offsetof(struct amap_sol_cqe, i_cmd_wnd) |
827 | / 32] & SOL_CMD_WND_MASK) >> 24) - 1); | 833 | / 32] & SOL_CMD_WND_MASK) >> 24) - 1); |
834 | hdr->dlength[0] = 0; | ||
835 | hdr->dlength[1] = 0; | ||
836 | hdr->dlength[2] = 0; | ||
828 | hdr->hlength = 0; | 837 | hdr->hlength = 0; |
829 | hdr->itt = io_task->libiscsi_itt; | 838 | hdr->itt = io_task->libiscsi_itt; |
830 | __iscsi_complete_pdu(conn, (struct iscsi_hdr *)hdr, NULL, 0); | 839 | __iscsi_complete_pdu(conn, (struct iscsi_hdr *)hdr, NULL, 0); |
@@ -839,6 +848,7 @@ be_complete_tmf(struct beiscsi_conn *beiscsi_conn, | |||
839 | struct beiscsi_io_task *io_task = task->dd_data; | 848 | struct beiscsi_io_task *io_task = task->dd_data; |
840 | 849 | ||
841 | hdr = (struct iscsi_tm_rsp *)task->hdr; | 850 | hdr = (struct iscsi_tm_rsp *)task->hdr; |
851 | hdr->opcode = ISCSI_OP_SCSI_TMFUNC_RSP; | ||
842 | hdr->flags = ((psol->dw[offsetof(struct amap_sol_cqe, i_flags) / 32] | 852 | hdr->flags = ((psol->dw[offsetof(struct amap_sol_cqe, i_flags) / 32] |
843 | & SOL_FLAGS_MASK) >> 24) | 0x80; | 853 | & SOL_FLAGS_MASK) >> 24) | 0x80; |
844 | hdr->response = (psol->dw[offsetof(struct amap_sol_cqe, i_resp) / | 854 | hdr->response = (psol->dw[offsetof(struct amap_sol_cqe, i_resp) / |
@@ -859,7 +869,6 @@ hwi_complete_drvr_msgs(struct beiscsi_conn *beiscsi_conn, | |||
859 | { | 869 | { |
860 | struct hwi_wrb_context *pwrb_context; | 870 | struct hwi_wrb_context *pwrb_context; |
861 | struct wrb_handle *pwrb_handle = NULL; | 871 | struct wrb_handle *pwrb_handle = NULL; |
862 | struct sgl_handle *psgl_handle = NULL; | ||
863 | struct hwi_controller *phwi_ctrlr; | 872 | struct hwi_controller *phwi_ctrlr; |
864 | struct iscsi_task *task; | 873 | struct iscsi_task *task; |
865 | struct beiscsi_io_task *io_task; | 874 | struct beiscsi_io_task *io_task; |
@@ -867,22 +876,14 @@ hwi_complete_drvr_msgs(struct beiscsi_conn *beiscsi_conn, | |||
867 | struct iscsi_session *session = conn->session; | 876 | struct iscsi_session *session = conn->session; |
868 | 877 | ||
869 | phwi_ctrlr = phba->phwi_ctrlr; | 878 | phwi_ctrlr = phba->phwi_ctrlr; |
870 | if (ring_mode) { | 879 | pwrb_context = &phwi_ctrlr->wrb_context[((psol-> |
871 | psgl_handle = phba->sgl_hndl_array[((psol-> | ||
872 | dw[offsetof(struct amap_sol_cqe_ring, icd_index) / | ||
873 | 32] & SOL_ICD_INDEX_MASK) >> 6)]; | ||
874 | pwrb_context = &phwi_ctrlr->wrb_context[psgl_handle->cid]; | ||
875 | task = psgl_handle->task; | ||
876 | pwrb_handle = NULL; | ||
877 | } else { | ||
878 | pwrb_context = &phwi_ctrlr->wrb_context[((psol-> | ||
879 | dw[offsetof(struct amap_sol_cqe, cid) / 32] & | 880 | dw[offsetof(struct amap_sol_cqe, cid) / 32] & |
880 | SOL_CID_MASK) >> 6)]; | 881 | SOL_CID_MASK) >> 6) - |
881 | pwrb_handle = pwrb_context->pwrb_handle_basestd[((psol-> | 882 | phba->fw_config.iscsi_cid_start]; |
883 | pwrb_handle = pwrb_context->pwrb_handle_basestd[((psol-> | ||
882 | dw[offsetof(struct amap_sol_cqe, wrb_index) / | 884 | dw[offsetof(struct amap_sol_cqe, wrb_index) / |
883 | 32] & SOL_WRB_INDEX_MASK) >> 16)]; | 885 | 32] & SOL_WRB_INDEX_MASK) >> 16)]; |
884 | task = pwrb_handle->pio_handle; | 886 | task = pwrb_handle->pio_handle; |
885 | } | ||
886 | 887 | ||
887 | io_task = task->dd_data; | 888 | io_task = task->dd_data; |
888 | spin_lock(&phba->mgmt_sgl_lock); | 889 | spin_lock(&phba->mgmt_sgl_lock); |
@@ -923,31 +924,23 @@ static void hwi_complete_cmd(struct beiscsi_conn *beiscsi_conn, | |||
923 | struct iscsi_wrb *pwrb = NULL; | 924 | struct iscsi_wrb *pwrb = NULL; |
924 | struct hwi_controller *phwi_ctrlr; | 925 | struct hwi_controller *phwi_ctrlr; |
925 | struct iscsi_task *task; | 926 | struct iscsi_task *task; |
926 | struct sgl_handle *psgl_handle = NULL; | ||
927 | unsigned int type; | 927 | unsigned int type; |
928 | struct iscsi_conn *conn = beiscsi_conn->conn; | 928 | struct iscsi_conn *conn = beiscsi_conn->conn; |
929 | struct iscsi_session *session = conn->session; | 929 | struct iscsi_session *session = conn->session; |
930 | 930 | ||
931 | phwi_ctrlr = phba->phwi_ctrlr; | 931 | phwi_ctrlr = phba->phwi_ctrlr; |
932 | if (ring_mode) { | 932 | pwrb_context = &phwi_ctrlr->wrb_context[((psol->dw[offsetof |
933 | psgl_handle = phba->sgl_hndl_array[((psol-> | ||
934 | dw[offsetof(struct amap_sol_cqe_ring, icd_index) / | ||
935 | 32] & SOL_ICD_INDEX_MASK) >> 6)]; | ||
936 | task = psgl_handle->task; | ||
937 | type = psgl_handle->type; | ||
938 | } else { | ||
939 | pwrb_context = &phwi_ctrlr-> | ||
940 | wrb_context[((psol->dw[offsetof | ||
941 | (struct amap_sol_cqe, cid) / 32] | 933 | (struct amap_sol_cqe, cid) / 32] |
942 | & SOL_CID_MASK) >> 6)]; | 934 | & SOL_CID_MASK) >> 6) - |
943 | pwrb_handle = pwrb_context->pwrb_handle_basestd[((psol-> | 935 | phba->fw_config.iscsi_cid_start]; |
936 | pwrb_handle = pwrb_context->pwrb_handle_basestd[((psol-> | ||
944 | dw[offsetof(struct amap_sol_cqe, wrb_index) / | 937 | dw[offsetof(struct amap_sol_cqe, wrb_index) / |
945 | 32] & SOL_WRB_INDEX_MASK) >> 16)]; | 938 | 32] & SOL_WRB_INDEX_MASK) >> 16)]; |
946 | task = pwrb_handle->pio_handle; | 939 | task = pwrb_handle->pio_handle; |
947 | pwrb = pwrb_handle->pwrb; | 940 | pwrb = pwrb_handle->pwrb; |
948 | type = (pwrb->dw[offsetof(struct amap_iscsi_wrb, type) / 32] & | 941 | type = (pwrb->dw[offsetof(struct amap_iscsi_wrb, type) / 32] & |
949 | WRB_TYPE_MASK) >> 28; | 942 | WRB_TYPE_MASK) >> 28; |
950 | } | 943 | |
951 | spin_lock_bh(&session->lock); | 944 | spin_lock_bh(&session->lock); |
952 | switch (type) { | 945 | switch (type) { |
953 | case HWH_TYPE_IO: | 946 | case HWH_TYPE_IO: |
@@ -978,15 +971,7 @@ static void hwi_complete_cmd(struct beiscsi_conn *beiscsi_conn, | |||
978 | break; | 971 | break; |
979 | 972 | ||
980 | default: | 973 | default: |
981 | if (ring_mode) | 974 | shost_printk(KERN_WARNING, phba->shost, |
982 | shost_printk(KERN_WARNING, phba->shost, | ||
983 | "In hwi_complete_cmd, unknown type = %d" | ||
984 | "icd_index 0x%x CID 0x%x\n", type, | ||
985 | ((psol->dw[offsetof(struct amap_sol_cqe_ring, | ||
986 | icd_index) / 32] & SOL_ICD_INDEX_MASK) >> 6), | ||
987 | psgl_handle->cid); | ||
988 | else | ||
989 | shost_printk(KERN_WARNING, phba->shost, | ||
990 | "In hwi_complete_cmd, unknown type = %d" | 975 | "In hwi_complete_cmd, unknown type = %d" |
991 | "wrb_index 0x%x CID 0x%x\n", type, | 976 | "wrb_index 0x%x CID 0x%x\n", type, |
992 | ((psol->dw[offsetof(struct amap_iscsi_wrb, | 977 | ((psol->dw[offsetof(struct amap_iscsi_wrb, |
@@ -1077,7 +1062,8 @@ hwi_get_async_handle(struct beiscsi_hba *phba, | |||
1077 | 1062 | ||
1078 | WARN_ON(!pasync_handle); | 1063 | WARN_ON(!pasync_handle); |
1079 | 1064 | ||
1080 | pasync_handle->cri = (unsigned short)beiscsi_conn->beiscsi_conn_cid; | 1065 | pasync_handle->cri = (unsigned short)beiscsi_conn->beiscsi_conn_cid - |
1066 | phba->fw_config.iscsi_cid_start; | ||
1081 | pasync_handle->is_header = is_header; | 1067 | pasync_handle->is_header = is_header; |
1082 | pasync_handle->buffer_len = ((pdpdu_cqe-> | 1068 | pasync_handle->buffer_len = ((pdpdu_cqe-> |
1083 | dw[offsetof(struct amap_i_t_dpdu_cqe, dpl) / 32] | 1069 | dw[offsetof(struct amap_i_t_dpdu_cqe, dpl) / 32] |
@@ -1327,9 +1313,10 @@ hwi_fwd_async_msg(struct beiscsi_conn *beiscsi_conn, | |||
1327 | } | 1313 | } |
1328 | 1314 | ||
1329 | status = beiscsi_process_async_pdu(beiscsi_conn, phba, | 1315 | status = beiscsi_process_async_pdu(beiscsi_conn, phba, |
1330 | beiscsi_conn->beiscsi_conn_cid, | 1316 | (beiscsi_conn->beiscsi_conn_cid - |
1331 | phdr, hdr_len, pfirst_buffer, | 1317 | phba->fw_config.iscsi_cid_start), |
1332 | buf_len); | 1318 | phdr, hdr_len, pfirst_buffer, |
1319 | buf_len); | ||
1333 | 1320 | ||
1334 | if (status == 0) | 1321 | if (status == 0) |
1335 | hwi_free_async_msg(phba, cri); | 1322 | hwi_free_async_msg(phba, cri); |
@@ -1422,6 +1409,48 @@ static void hwi_process_default_pdu_ring(struct beiscsi_conn *beiscsi_conn, | |||
1422 | hwi_post_async_buffers(phba, pasync_handle->is_header); | 1409 | hwi_post_async_buffers(phba, pasync_handle->is_header); |
1423 | } | 1410 | } |
1424 | 1411 | ||
1412 | static void beiscsi_process_mcc_isr(struct beiscsi_hba *phba) | ||
1413 | { | ||
1414 | struct be_queue_info *mcc_cq; | ||
1415 | struct be_mcc_compl *mcc_compl; | ||
1416 | unsigned int num_processed = 0; | ||
1417 | |||
1418 | mcc_cq = &phba->ctrl.mcc_obj.cq; | ||
1419 | mcc_compl = queue_tail_node(mcc_cq); | ||
1420 | mcc_compl->flags = le32_to_cpu(mcc_compl->flags); | ||
1421 | while (mcc_compl->flags & CQE_FLAGS_VALID_MASK) { | ||
1422 | |||
1423 | if (num_processed >= 32) { | ||
1424 | hwi_ring_cq_db(phba, mcc_cq->id, | ||
1425 | num_processed, 0, 0); | ||
1426 | num_processed = 0; | ||
1427 | } | ||
1428 | if (mcc_compl->flags & CQE_FLAGS_ASYNC_MASK) { | ||
1429 | /* Interpret flags as an async trailer */ | ||
1430 | if (is_link_state_evt(mcc_compl->flags)) | ||
1431 | /* Interpret compl as a async link evt */ | ||
1432 | beiscsi_async_link_state_process(phba, | ||
1433 | (struct be_async_event_link_state *) mcc_compl); | ||
1434 | else | ||
1435 | SE_DEBUG(DBG_LVL_1, | ||
1436 | " Unsupported Async Event, flags" | ||
1437 | " = 0x%08x \n", mcc_compl->flags); | ||
1438 | } else if (mcc_compl->flags & CQE_FLAGS_COMPLETED_MASK) { | ||
1439 | be_mcc_compl_process_isr(&phba->ctrl, mcc_compl); | ||
1440 | atomic_dec(&phba->ctrl.mcc_obj.q.used); | ||
1441 | } | ||
1442 | |||
1443 | mcc_compl->flags = 0; | ||
1444 | queue_tail_inc(mcc_cq); | ||
1445 | mcc_compl = queue_tail_node(mcc_cq); | ||
1446 | mcc_compl->flags = le32_to_cpu(mcc_compl->flags); | ||
1447 | num_processed++; | ||
1448 | } | ||
1449 | |||
1450 | if (num_processed > 0) | ||
1451 | hwi_ring_cq_db(phba, mcc_cq->id, num_processed, 1, 0); | ||
1452 | |||
1453 | } | ||
1425 | 1454 | ||
1426 | static unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq) | 1455 | static unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq) |
1427 | { | 1456 | { |
@@ -1431,7 +1460,8 @@ static unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq) | |||
1431 | unsigned int num_processed = 0; | 1460 | unsigned int num_processed = 0; |
1432 | unsigned int tot_nump = 0; | 1461 | unsigned int tot_nump = 0; |
1433 | struct beiscsi_conn *beiscsi_conn; | 1462 | struct beiscsi_conn *beiscsi_conn; |
1434 | struct sgl_handle *psgl_handle = NULL; | 1463 | struct beiscsi_endpoint *beiscsi_ep; |
1464 | struct iscsi_endpoint *ep; | ||
1435 | struct beiscsi_hba *phba; | 1465 | struct beiscsi_hba *phba; |
1436 | 1466 | ||
1437 | cq = pbe_eq->cq; | 1467 | cq = pbe_eq->cq; |
@@ -1442,32 +1472,13 @@ static unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq) | |||
1442 | CQE_VALID_MASK) { | 1472 | CQE_VALID_MASK) { |
1443 | be_dws_le_to_cpu(sol, sizeof(struct sol_cqe)); | 1473 | be_dws_le_to_cpu(sol, sizeof(struct sol_cqe)); |
1444 | 1474 | ||
1445 | if (ring_mode) { | 1475 | ep = phba->ep_array[(u32) ((sol-> |
1446 | psgl_handle = phba->sgl_hndl_array[((sol-> | 1476 | dw[offsetof(struct amap_sol_cqe, cid) / 32] & |
1447 | dw[offsetof(struct amap_sol_cqe_ring, | 1477 | SOL_CID_MASK) >> 6) - |
1448 | icd_index) / 32] & SOL_ICD_INDEX_MASK) | 1478 | phba->fw_config.iscsi_cid_start]; |
1449 | >> 6)]; | ||
1450 | beiscsi_conn = phba->conn_table[psgl_handle->cid]; | ||
1451 | if (!beiscsi_conn || !beiscsi_conn->ep) { | ||
1452 | shost_printk(KERN_WARNING, phba->shost, | ||
1453 | "Connection table empty for cid = %d\n", | ||
1454 | psgl_handle->cid); | ||
1455 | return 0; | ||
1456 | } | ||
1457 | 1479 | ||
1458 | } else { | 1480 | beiscsi_ep = ep->dd_data; |
1459 | beiscsi_conn = phba->conn_table[(u32) (sol-> | 1481 | beiscsi_conn = beiscsi_ep->conn; |
1460 | dw[offsetof(struct amap_sol_cqe, cid) / 32] & | ||
1461 | SOL_CID_MASK) >> 6]; | ||
1462 | |||
1463 | if (!beiscsi_conn || !beiscsi_conn->ep) { | ||
1464 | shost_printk(KERN_WARNING, phba->shost, | ||
1465 | "Connection table empty for cid = %d\n", | ||
1466 | (u32)(sol->dw[offsetof(struct amap_sol_cqe, | ||
1467 | cid) / 32] & SOL_CID_MASK) >> 6); | ||
1468 | return 0; | ||
1469 | } | ||
1470 | } | ||
1471 | 1482 | ||
1472 | if (num_processed >= 32) { | 1483 | if (num_processed >= 32) { |
1473 | hwi_ring_cq_db(phba, cq->id, | 1484 | hwi_ring_cq_db(phba, cq->id, |
@@ -1511,21 +1522,13 @@ static unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq) | |||
1511 | case CMD_CXN_KILLED_ITT_INVALID: | 1522 | case CMD_CXN_KILLED_ITT_INVALID: |
1512 | case CMD_CXN_KILLED_SEQ_OUTOFORDER: | 1523 | case CMD_CXN_KILLED_SEQ_OUTOFORDER: |
1513 | case CMD_CXN_KILLED_INVALID_DATASN_RCVD: | 1524 | case CMD_CXN_KILLED_INVALID_DATASN_RCVD: |
1514 | if (ring_mode) { | 1525 | SE_DEBUG(DBG_LVL_1, |
1515 | SE_DEBUG(DBG_LVL_1, | ||
1516 | "CQ Error notification for cmd.. " | ||
1517 | "code %d cid 0x%x\n", | ||
1518 | sol->dw[offsetof(struct amap_sol_cqe, code) / | ||
1519 | 32] & CQE_CODE_MASK, psgl_handle->cid); | ||
1520 | } else { | ||
1521 | SE_DEBUG(DBG_LVL_1, | ||
1522 | "CQ Error notification for cmd.. " | 1526 | "CQ Error notification for cmd.. " |
1523 | "code %d cid 0x%x\n", | 1527 | "code %d cid 0x%x\n", |
1524 | sol->dw[offsetof(struct amap_sol_cqe, code) / | 1528 | sol->dw[offsetof(struct amap_sol_cqe, code) / |
1525 | 32] & CQE_CODE_MASK, | 1529 | 32] & CQE_CODE_MASK, |
1526 | (sol->dw[offsetof(struct amap_sol_cqe, cid) / | 1530 | (sol->dw[offsetof(struct amap_sol_cqe, cid) / |
1527 | 32] & SOL_CID_MASK)); | 1531 | 32] & SOL_CID_MASK)); |
1528 | } | ||
1529 | break; | 1532 | break; |
1530 | case UNSOL_DATA_DIGEST_ERROR_NOTIFY: | 1533 | case UNSOL_DATA_DIGEST_ERROR_NOTIFY: |
1531 | SE_DEBUG(DBG_LVL_1, | 1534 | SE_DEBUG(DBG_LVL_1, |
@@ -1547,37 +1550,23 @@ static unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq) | |||
1547 | case CXN_KILLED_OVER_RUN_RESIDUAL: | 1550 | case CXN_KILLED_OVER_RUN_RESIDUAL: |
1548 | case CXN_KILLED_UNDER_RUN_RESIDUAL: | 1551 | case CXN_KILLED_UNDER_RUN_RESIDUAL: |
1549 | case CXN_KILLED_CMND_DATA_NOT_ON_SAME_CONN: | 1552 | case CXN_KILLED_CMND_DATA_NOT_ON_SAME_CONN: |
1550 | if (ring_mode) { | 1553 | SE_DEBUG(DBG_LVL_1, "CQ Error %d, reset CID " |
1551 | SE_DEBUG(DBG_LVL_1, "CQ Error %d, reset CID " | ||
1552 | "0x%x...\n", | ||
1553 | sol->dw[offsetof(struct amap_sol_cqe, code) / | ||
1554 | 32] & CQE_CODE_MASK, psgl_handle->cid); | ||
1555 | } else { | ||
1556 | SE_DEBUG(DBG_LVL_1, "CQ Error %d, reset CID " | ||
1557 | "0x%x...\n", | 1554 | "0x%x...\n", |
1558 | sol->dw[offsetof(struct amap_sol_cqe, code) / | 1555 | sol->dw[offsetof(struct amap_sol_cqe, code) / |
1559 | 32] & CQE_CODE_MASK, | 1556 | 32] & CQE_CODE_MASK, |
1560 | sol->dw[offsetof(struct amap_sol_cqe, cid) / | 1557 | (sol->dw[offsetof(struct amap_sol_cqe, cid) / |
1561 | 32] & CQE_CID_MASK); | 1558 | 32] & CQE_CID_MASK)); |
1562 | } | ||
1563 | iscsi_conn_failure(beiscsi_conn->conn, | 1559 | iscsi_conn_failure(beiscsi_conn->conn, |
1564 | ISCSI_ERR_CONN_FAILED); | 1560 | ISCSI_ERR_CONN_FAILED); |
1565 | break; | 1561 | break; |
1566 | case CXN_KILLED_RST_SENT: | 1562 | case CXN_KILLED_RST_SENT: |
1567 | case CXN_KILLED_RST_RCVD: | 1563 | case CXN_KILLED_RST_RCVD: |
1568 | if (ring_mode) { | 1564 | SE_DEBUG(DBG_LVL_1, "CQ Error %d, reset" |
1569 | SE_DEBUG(DBG_LVL_1, "CQ Error %d, reset" | ||
1570 | "received/sent on CID 0x%x...\n", | ||
1571 | sol->dw[offsetof(struct amap_sol_cqe, code) / | ||
1572 | 32] & CQE_CODE_MASK, psgl_handle->cid); | ||
1573 | } else { | ||
1574 | SE_DEBUG(DBG_LVL_1, "CQ Error %d, reset" | ||
1575 | "received/sent on CID 0x%x...\n", | 1565 | "received/sent on CID 0x%x...\n", |
1576 | sol->dw[offsetof(struct amap_sol_cqe, code) / | 1566 | sol->dw[offsetof(struct amap_sol_cqe, code) / |
1577 | 32] & CQE_CODE_MASK, | 1567 | 32] & CQE_CODE_MASK, |
1578 | sol->dw[offsetof(struct amap_sol_cqe, cid) / | 1568 | (sol->dw[offsetof(struct amap_sol_cqe, cid) / |
1579 | 32] & CQE_CID_MASK); | 1569 | 32] & CQE_CID_MASK)); |
1580 | } | ||
1581 | iscsi_conn_failure(beiscsi_conn->conn, | 1570 | iscsi_conn_failure(beiscsi_conn->conn, |
1582 | ISCSI_ERR_CONN_FAILED); | 1571 | ISCSI_ERR_CONN_FAILED); |
1583 | break; | 1572 | break; |
@@ -1586,8 +1575,8 @@ static unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq) | |||
1586 | "received on CID 0x%x...\n", | 1575 | "received on CID 0x%x...\n", |
1587 | sol->dw[offsetof(struct amap_sol_cqe, code) / | 1576 | sol->dw[offsetof(struct amap_sol_cqe, code) / |
1588 | 32] & CQE_CODE_MASK, | 1577 | 32] & CQE_CODE_MASK, |
1589 | sol->dw[offsetof(struct amap_sol_cqe, cid) / | 1578 | (sol->dw[offsetof(struct amap_sol_cqe, cid) / |
1590 | 32] & CQE_CID_MASK); | 1579 | 32] & CQE_CID_MASK)); |
1591 | break; | 1580 | break; |
1592 | } | 1581 | } |
1593 | 1582 | ||
@@ -1604,7 +1593,7 @@ static unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq) | |||
1604 | return tot_nump; | 1593 | return tot_nump; |
1605 | } | 1594 | } |
1606 | 1595 | ||
1607 | static void beiscsi_process_all_cqs(struct work_struct *work) | 1596 | void beiscsi_process_all_cqs(struct work_struct *work) |
1608 | { | 1597 | { |
1609 | unsigned long flags; | 1598 | unsigned long flags; |
1610 | struct hwi_controller *phwi_ctrlr; | 1599 | struct hwi_controller *phwi_ctrlr; |
@@ -1624,6 +1613,7 @@ static void beiscsi_process_all_cqs(struct work_struct *work) | |||
1624 | spin_lock_irqsave(&phba->isr_lock, flags); | 1613 | spin_lock_irqsave(&phba->isr_lock, flags); |
1625 | phba->todo_mcc_cq = 0; | 1614 | phba->todo_mcc_cq = 0; |
1626 | spin_unlock_irqrestore(&phba->isr_lock, flags); | 1615 | spin_unlock_irqrestore(&phba->isr_lock, flags); |
1616 | beiscsi_process_mcc_isr(phba); | ||
1627 | } | 1617 | } |
1628 | 1618 | ||
1629 | if (phba->todo_cq) { | 1619 | if (phba->todo_cq) { |
@@ -1668,7 +1658,8 @@ hwi_write_sgl(struct iscsi_wrb *pwrb, struct scatterlist *sg, | |||
1668 | io_task->bhs_pa.u.a32.address_hi); | 1658 | io_task->bhs_pa.u.a32.address_hi); |
1669 | 1659 | ||
1670 | l_sg = sg; | 1660 | l_sg = sg; |
1671 | for (index = 0; (index < num_sg) && (index < 2); index++, sg_next(sg)) { | 1661 | for (index = 0; (index < num_sg) && (index < 2); index++, |
1662 | sg = sg_next(sg)) { | ||
1672 | if (index == 0) { | 1663 | if (index == 0) { |
1673 | sg_len = sg_dma_len(sg); | 1664 | sg_len = sg_dma_len(sg); |
1674 | addr = (u64) sg_dma_address(sg); | 1665 | addr = (u64) sg_dma_address(sg); |
@@ -1679,11 +1670,7 @@ hwi_write_sgl(struct iscsi_wrb *pwrb, struct scatterlist *sg, | |||
1679 | AMAP_SET_BITS(struct amap_iscsi_wrb, sge0_len, pwrb, | 1670 | AMAP_SET_BITS(struct amap_iscsi_wrb, sge0_len, pwrb, |
1680 | sg_len); | 1671 | sg_len); |
1681 | sge_len = sg_len; | 1672 | sge_len = sg_len; |
1682 | AMAP_SET_BITS(struct amap_iscsi_wrb, sge0_last, pwrb, | ||
1683 | 1); | ||
1684 | } else { | 1673 | } else { |
1685 | AMAP_SET_BITS(struct amap_iscsi_wrb, sge0_last, pwrb, | ||
1686 | 0); | ||
1687 | AMAP_SET_BITS(struct amap_iscsi_wrb, sge1_r2t_offset, | 1674 | AMAP_SET_BITS(struct amap_iscsi_wrb, sge1_r2t_offset, |
1688 | pwrb, sge_len); | 1675 | pwrb, sge_len); |
1689 | sg_len = sg_dma_len(sg); | 1676 | sg_len = sg_dma_len(sg); |
@@ -1706,13 +1693,27 @@ hwi_write_sgl(struct iscsi_wrb *pwrb, struct scatterlist *sg, | |||
1706 | AMAP_SET_BITS(struct amap_iscsi_sge, addr_lo, psgl, | 1693 | AMAP_SET_BITS(struct amap_iscsi_sge, addr_lo, psgl, |
1707 | io_task->bhs_pa.u.a32.address_lo); | 1694 | io_task->bhs_pa.u.a32.address_lo); |
1708 | 1695 | ||
1709 | if (num_sg == 2) | 1696 | if (num_sg == 1) { |
1710 | AMAP_SET_BITS(struct amap_iscsi_wrb, sge1_last, pwrb, 1); | 1697 | AMAP_SET_BITS(struct amap_iscsi_wrb, sge0_last, pwrb, |
1698 | 1); | ||
1699 | AMAP_SET_BITS(struct amap_iscsi_wrb, sge1_last, pwrb, | ||
1700 | 0); | ||
1701 | } else if (num_sg == 2) { | ||
1702 | AMAP_SET_BITS(struct amap_iscsi_wrb, sge0_last, pwrb, | ||
1703 | 0); | ||
1704 | AMAP_SET_BITS(struct amap_iscsi_wrb, sge1_last, pwrb, | ||
1705 | 1); | ||
1706 | } else { | ||
1707 | AMAP_SET_BITS(struct amap_iscsi_wrb, sge0_last, pwrb, | ||
1708 | 0); | ||
1709 | AMAP_SET_BITS(struct amap_iscsi_wrb, sge1_last, pwrb, | ||
1710 | 0); | ||
1711 | } | ||
1711 | sg = l_sg; | 1712 | sg = l_sg; |
1712 | psgl++; | 1713 | psgl++; |
1713 | psgl++; | 1714 | psgl++; |
1714 | offset = 0; | 1715 | offset = 0; |
1715 | for (index = 0; index < num_sg; index++, sg_next(sg), psgl++) { | 1716 | for (index = 0; index < num_sg; index++, sg = sg_next(sg), psgl++) { |
1716 | sg_len = sg_dma_len(sg); | 1717 | sg_len = sg_dma_len(sg); |
1717 | addr = (u64) sg_dma_address(sg); | 1718 | addr = (u64) sg_dma_address(sg); |
1718 | AMAP_SET_BITS(struct amap_iscsi_sge, addr_lo, psgl, | 1719 | AMAP_SET_BITS(struct amap_iscsi_sge, addr_lo, psgl, |
@@ -2048,10 +2049,9 @@ static void beiscsi_init_wrb_handle(struct beiscsi_hba *phba) | |||
2048 | } | 2049 | } |
2049 | idx = 0; | 2050 | idx = 0; |
2050 | pwrb = mem_descr_wrb->mem_array[idx].virtual_address; | 2051 | pwrb = mem_descr_wrb->mem_array[idx].virtual_address; |
2051 | num_cxn_wrb = | 2052 | num_cxn_wrb = (mem_descr_wrb->mem_array[idx].size) / |
2052 | ((mem_descr_wrb->mem_array[idx].size) / (sizeof(struct iscsi_wrb)) * | 2053 | ((sizeof(struct iscsi_wrb) * |
2053 | phba->params.wrbs_per_cxn); | 2054 | phba->params.wrbs_per_cxn)); |
2054 | |||
2055 | for (index = 0; index < phba->params.cxns_per_ctrl; index += 2) { | 2055 | for (index = 0; index < phba->params.cxns_per_ctrl; index += 2) { |
2056 | pwrb_context = &phwi_ctrlr->wrb_context[index]; | 2056 | pwrb_context = &phwi_ctrlr->wrb_context[index]; |
2057 | if (num_cxn_wrb) { | 2057 | if (num_cxn_wrb) { |
@@ -2064,9 +2064,9 @@ static void beiscsi_init_wrb_handle(struct beiscsi_hba *phba) | |||
2064 | } else { | 2064 | } else { |
2065 | idx++; | 2065 | idx++; |
2066 | pwrb = mem_descr_wrb->mem_array[idx].virtual_address; | 2066 | pwrb = mem_descr_wrb->mem_array[idx].virtual_address; |
2067 | num_cxn_wrb = ((mem_descr_wrb->mem_array[idx].size) / | 2067 | num_cxn_wrb = (mem_descr_wrb->mem_array[idx].size) / |
2068 | (sizeof(struct iscsi_wrb)) * | 2068 | ((sizeof(struct iscsi_wrb) * |
2069 | phba->params.wrbs_per_cxn); | 2069 | phba->params.wrbs_per_cxn)); |
2070 | for (j = 0; j < phba->params.wrbs_per_cxn; j++) { | 2070 | for (j = 0; j < phba->params.wrbs_per_cxn; j++) { |
2071 | pwrb_handle = pwrb_context->pwrb_handle_base[j]; | 2071 | pwrb_handle = pwrb_context->pwrb_handle_base[j]; |
2072 | pwrb_handle->pwrb = pwrb; | 2072 | pwrb_handle->pwrb = pwrb; |
@@ -2383,7 +2383,7 @@ static int beiscsi_create_cqs(struct beiscsi_hba *phba, | |||
2383 | &paddr); | 2383 | &paddr); |
2384 | if (!cq_vaddress) | 2384 | if (!cq_vaddress) |
2385 | goto create_cq_error; | 2385 | goto create_cq_error; |
2386 | ret = be_fill_queue(cq, phba->params.icds_per_ctrl / 2, | 2386 | ret = be_fill_queue(cq, phba->params.num_cq_entries, |
2387 | sizeof(struct sol_cqe), cq_vaddress); | 2387 | sizeof(struct sol_cqe), cq_vaddress); |
2388 | if (ret) { | 2388 | if (ret) { |
2389 | shost_printk(KERN_ERR, phba->shost, | 2389 | shost_printk(KERN_ERR, phba->shost, |
@@ -2634,7 +2634,8 @@ beiscsi_create_wrb_rings(struct beiscsi_hba *phba, | |||
2634 | "wrbq create failed."); | 2634 | "wrbq create failed."); |
2635 | return status; | 2635 | return status; |
2636 | } | 2636 | } |
2637 | phwi_ctrlr->wrb_context[i].cid = phwi_context->be_wrbq[i].id; | 2637 | phwi_ctrlr->wrb_context[i * 2].cid = phwi_context->be_wrbq[i]. |
2638 | id; | ||
2638 | } | 2639 | } |
2639 | kfree(pwrb_arr); | 2640 | kfree(pwrb_arr); |
2640 | return 0; | 2641 | return 0; |
@@ -2803,17 +2804,6 @@ static int hwi_init_port(struct beiscsi_hba *phba) | |||
2803 | goto error; | 2804 | goto error; |
2804 | } | 2805 | } |
2805 | 2806 | ||
2806 | if (phba->fw_config.iscsi_features == 0x1) | ||
2807 | ring_mode = 1; | ||
2808 | else | ||
2809 | ring_mode = 0; | ||
2810 | status = mgmt_get_fw_config(ctrl, phba); | ||
2811 | if (status != 0) { | ||
2812 | shost_printk(KERN_ERR, phba->shost, | ||
2813 | "Error getting fw config\n"); | ||
2814 | goto error; | ||
2815 | } | ||
2816 | |||
2817 | status = beiscsi_create_cqs(phba, phwi_context); | 2807 | status = beiscsi_create_cqs(phba, phwi_context); |
2818 | if (status != 0) { | 2808 | if (status != 0) { |
2819 | shost_printk(KERN_ERR, phba->shost, "CQ not created\n"); | 2809 | shost_printk(KERN_ERR, phba->shost, "CQ not created\n"); |
@@ -2941,17 +2931,6 @@ static int beiscsi_init_sgl_handle(struct beiscsi_hba *phba) | |||
2941 | phba->io_sgl_hndl_avbl = 0; | 2931 | phba->io_sgl_hndl_avbl = 0; |
2942 | phba->eh_sgl_hndl_avbl = 0; | 2932 | phba->eh_sgl_hndl_avbl = 0; |
2943 | 2933 | ||
2944 | if (ring_mode) { | ||
2945 | phba->sgl_hndl_array = kzalloc(sizeof(struct sgl_handle *) * | ||
2946 | phba->params.icds_per_ctrl, | ||
2947 | GFP_KERNEL); | ||
2948 | if (!phba->sgl_hndl_array) { | ||
2949 | shost_printk(KERN_ERR, phba->shost, | ||
2950 | "Mem Alloc Failed. Failing to load\n"); | ||
2951 | return -ENOMEM; | ||
2952 | } | ||
2953 | } | ||
2954 | |||
2955 | mem_descr_sglh = phba->init_mem; | 2934 | mem_descr_sglh = phba->init_mem; |
2956 | mem_descr_sglh += HWI_MEM_SGLH; | 2935 | mem_descr_sglh += HWI_MEM_SGLH; |
2957 | if (1 == mem_descr_sglh->num_elements) { | 2936 | if (1 == mem_descr_sglh->num_elements) { |
@@ -2959,8 +2938,6 @@ static int beiscsi_init_sgl_handle(struct beiscsi_hba *phba) | |||
2959 | phba->params.ios_per_ctrl, | 2938 | phba->params.ios_per_ctrl, |
2960 | GFP_KERNEL); | 2939 | GFP_KERNEL); |
2961 | if (!phba->io_sgl_hndl_base) { | 2940 | if (!phba->io_sgl_hndl_base) { |
2962 | if (ring_mode) | ||
2963 | kfree(phba->sgl_hndl_array); | ||
2964 | shost_printk(KERN_ERR, phba->shost, | 2941 | shost_printk(KERN_ERR, phba->shost, |
2965 | "Mem Alloc Failed. Failing to load\n"); | 2942 | "Mem Alloc Failed. Failing to load\n"); |
2966 | return -ENOMEM; | 2943 | return -ENOMEM; |
@@ -3032,7 +3009,7 @@ static int beiscsi_init_sgl_handle(struct beiscsi_hba *phba) | |||
3032 | AMAP_SET_BITS(struct amap_iscsi_sge, addr_lo, pfrag, 0); | 3009 | AMAP_SET_BITS(struct amap_iscsi_sge, addr_lo, pfrag, 0); |
3033 | pfrag += phba->params.num_sge_per_io; | 3010 | pfrag += phba->params.num_sge_per_io; |
3034 | psgl_handle->sgl_index = | 3011 | psgl_handle->sgl_index = |
3035 | phba->fw_config.iscsi_cid_start + arr_index++; | 3012 | phba->fw_config.iscsi_icd_start + arr_index++; |
3036 | } | 3013 | } |
3037 | idx++; | 3014 | idx++; |
3038 | } | 3015 | } |
@@ -3047,7 +3024,7 @@ static int hba_setup_cid_tbls(struct beiscsi_hba *phba) | |||
3047 | { | 3024 | { |
3048 | int i, new_cid; | 3025 | int i, new_cid; |
3049 | 3026 | ||
3050 | phba->cid_array = kmalloc(sizeof(void *) * phba->params.cxns_per_ctrl, | 3027 | phba->cid_array = kzalloc(sizeof(void *) * phba->params.cxns_per_ctrl, |
3051 | GFP_KERNEL); | 3028 | GFP_KERNEL); |
3052 | if (!phba->cid_array) { | 3029 | if (!phba->cid_array) { |
3053 | shost_printk(KERN_ERR, phba->shost, | 3030 | shost_printk(KERN_ERR, phba->shost, |
@@ -3055,7 +3032,7 @@ static int hba_setup_cid_tbls(struct beiscsi_hba *phba) | |||
3055 | "hba_setup_cid_tbls\n"); | 3032 | "hba_setup_cid_tbls\n"); |
3056 | return -ENOMEM; | 3033 | return -ENOMEM; |
3057 | } | 3034 | } |
3058 | phba->ep_array = kmalloc(sizeof(struct iscsi_endpoint *) * | 3035 | phba->ep_array = kzalloc(sizeof(struct iscsi_endpoint *) * |
3059 | phba->params.cxns_per_ctrl * 2, GFP_KERNEL); | 3036 | phba->params.cxns_per_ctrl * 2, GFP_KERNEL); |
3060 | if (!phba->ep_array) { | 3037 | if (!phba->ep_array) { |
3061 | shost_printk(KERN_ERR, phba->shost, | 3038 | shost_printk(KERN_ERR, phba->shost, |
@@ -3064,7 +3041,7 @@ static int hba_setup_cid_tbls(struct beiscsi_hba *phba) | |||
3064 | kfree(phba->cid_array); | 3041 | kfree(phba->cid_array); |
3065 | return -ENOMEM; | 3042 | return -ENOMEM; |
3066 | } | 3043 | } |
3067 | new_cid = phba->fw_config.iscsi_icd_start; | 3044 | new_cid = phba->fw_config.iscsi_cid_start; |
3068 | for (i = 0; i < phba->params.cxns_per_ctrl; i++) { | 3045 | for (i = 0; i < phba->params.cxns_per_ctrl; i++) { |
3069 | phba->cid_array[i] = new_cid; | 3046 | phba->cid_array[i] = new_cid; |
3070 | new_cid += 2; | 3047 | new_cid += 2; |
@@ -3145,8 +3122,6 @@ static int beiscsi_init_port(struct beiscsi_hba *phba) | |||
3145 | if (hba_setup_cid_tbls(phba)) { | 3122 | if (hba_setup_cid_tbls(phba)) { |
3146 | shost_printk(KERN_ERR, phba->shost, | 3123 | shost_printk(KERN_ERR, phba->shost, |
3147 | "Failed in hba_setup_cid_tbls\n"); | 3124 | "Failed in hba_setup_cid_tbls\n"); |
3148 | if (ring_mode) | ||
3149 | kfree(phba->sgl_hndl_array); | ||
3150 | kfree(phba->io_sgl_hndl_base); | 3125 | kfree(phba->io_sgl_hndl_base); |
3151 | kfree(phba->eh_sgl_hndl_base); | 3126 | kfree(phba->eh_sgl_hndl_base); |
3152 | goto do_cleanup_ctrlr; | 3127 | goto do_cleanup_ctrlr; |
@@ -3166,6 +3141,7 @@ static void hwi_purge_eq(struct beiscsi_hba *phba) | |||
3166 | struct be_queue_info *eq; | 3141 | struct be_queue_info *eq; |
3167 | struct be_eq_entry *eqe = NULL; | 3142 | struct be_eq_entry *eqe = NULL; |
3168 | int i, eq_msix; | 3143 | int i, eq_msix; |
3144 | unsigned int num_processed; | ||
3169 | 3145 | ||
3170 | phwi_ctrlr = phba->phwi_ctrlr; | 3146 | phwi_ctrlr = phba->phwi_ctrlr; |
3171 | phwi_context = phwi_ctrlr->phwi_ctxt; | 3147 | phwi_context = phwi_ctrlr->phwi_ctxt; |
@@ -3177,13 +3153,17 @@ static void hwi_purge_eq(struct beiscsi_hba *phba) | |||
3177 | for (i = 0; i < (phba->num_cpus + eq_msix); i++) { | 3153 | for (i = 0; i < (phba->num_cpus + eq_msix); i++) { |
3178 | eq = &phwi_context->be_eq[i].q; | 3154 | eq = &phwi_context->be_eq[i].q; |
3179 | eqe = queue_tail_node(eq); | 3155 | eqe = queue_tail_node(eq); |
3180 | 3156 | num_processed = 0; | |
3181 | while (eqe->dw[offsetof(struct amap_eq_entry, valid) / 32] | 3157 | while (eqe->dw[offsetof(struct amap_eq_entry, valid) / 32] |
3182 | & EQE_VALID_MASK) { | 3158 | & EQE_VALID_MASK) { |
3183 | AMAP_SET_BITS(struct amap_eq_entry, valid, eqe, 0); | 3159 | AMAP_SET_BITS(struct amap_eq_entry, valid, eqe, 0); |
3184 | queue_tail_inc(eq); | 3160 | queue_tail_inc(eq); |
3185 | eqe = queue_tail_node(eq); | 3161 | eqe = queue_tail_node(eq); |
3162 | num_processed++; | ||
3186 | } | 3163 | } |
3164 | |||
3165 | if (num_processed) | ||
3166 | hwi_ring_eq_db(phba, eq->id, 1, num_processed, 1, 1); | ||
3187 | } | 3167 | } |
3188 | } | 3168 | } |
3189 | 3169 | ||
@@ -3195,10 +3175,9 @@ static void beiscsi_clean_port(struct beiscsi_hba *phba) | |||
3195 | if (mgmt_status) | 3175 | if (mgmt_status) |
3196 | shost_printk(KERN_WARNING, phba->shost, | 3176 | shost_printk(KERN_WARNING, phba->shost, |
3197 | "mgmt_epfw_cleanup FAILED \n"); | 3177 | "mgmt_epfw_cleanup FAILED \n"); |
3198 | hwi_cleanup(phba); | 3178 | |
3199 | hwi_purge_eq(phba); | 3179 | hwi_purge_eq(phba); |
3200 | if (ring_mode) | 3180 | hwi_cleanup(phba); |
3201 | kfree(phba->sgl_hndl_array); | ||
3202 | kfree(phba->io_sgl_hndl_base); | 3181 | kfree(phba->io_sgl_hndl_base); |
3203 | kfree(phba->eh_sgl_hndl_base); | 3182 | kfree(phba->eh_sgl_hndl_base); |
3204 | kfree(phba->cid_array); | 3183 | kfree(phba->cid_array); |
@@ -3219,7 +3198,8 @@ beiscsi_offload_connection(struct beiscsi_conn *beiscsi_conn, | |||
3219 | * We can always use 0 here because it is reserved by libiscsi for | 3198 | * We can always use 0 here because it is reserved by libiscsi for |
3220 | * login/startup related tasks. | 3199 | * login/startup related tasks. |
3221 | */ | 3200 | */ |
3222 | pwrb_handle = alloc_wrb_handle(phba, beiscsi_conn->beiscsi_conn_cid, 0); | 3201 | pwrb_handle = alloc_wrb_handle(phba, (beiscsi_conn->beiscsi_conn_cid - |
3202 | phba->fw_config.iscsi_cid_start)); | ||
3223 | pwrb = (struct iscsi_target_context_update_wrb *)pwrb_handle->pwrb; | 3203 | pwrb = (struct iscsi_target_context_update_wrb *)pwrb_handle->pwrb; |
3224 | memset(pwrb, 0, sizeof(*pwrb)); | 3204 | memset(pwrb, 0, sizeof(*pwrb)); |
3225 | AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, | 3205 | AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, |
@@ -3283,8 +3263,7 @@ beiscsi_offload_connection(struct beiscsi_conn *beiscsi_conn, | |||
3283 | be_dws_le_to_cpu(pwrb, sizeof(struct iscsi_target_context_update_wrb)); | 3263 | be_dws_le_to_cpu(pwrb, sizeof(struct iscsi_target_context_update_wrb)); |
3284 | 3264 | ||
3285 | doorbell |= beiscsi_conn->beiscsi_conn_cid & DB_WRB_POST_CID_MASK; | 3265 | doorbell |= beiscsi_conn->beiscsi_conn_cid & DB_WRB_POST_CID_MASK; |
3286 | if (!ring_mode) | 3266 | doorbell |= (pwrb_handle->wrb_index & DB_DEF_PDU_WRB_INDEX_MASK) |
3287 | doorbell |= (pwrb_handle->wrb_index & DB_DEF_PDU_WRB_INDEX_MASK) | ||
3288 | << DB_DEF_PDU_WRB_INDEX_SHIFT; | 3267 | << DB_DEF_PDU_WRB_INDEX_SHIFT; |
3289 | doorbell |= 1 << DB_DEF_PDU_NUM_POSTED_SHIFT; | 3268 | doorbell |= 1 << DB_DEF_PDU_NUM_POSTED_SHIFT; |
3290 | 3269 | ||
@@ -3328,8 +3307,9 @@ static int beiscsi_alloc_pdu(struct iscsi_task *task, uint8_t opcode) | |||
3328 | io_task->bhs_pa.u.a64.address = paddr; | 3307 | io_task->bhs_pa.u.a64.address = paddr; |
3329 | io_task->libiscsi_itt = (itt_t)task->itt; | 3308 | io_task->libiscsi_itt = (itt_t)task->itt; |
3330 | io_task->pwrb_handle = alloc_wrb_handle(phba, | 3309 | io_task->pwrb_handle = alloc_wrb_handle(phba, |
3331 | beiscsi_conn->beiscsi_conn_cid, | 3310 | beiscsi_conn->beiscsi_conn_cid - |
3332 | task->itt); | 3311 | phba->fw_config.iscsi_cid_start |
3312 | ); | ||
3333 | io_task->conn = beiscsi_conn; | 3313 | io_task->conn = beiscsi_conn; |
3334 | 3314 | ||
3335 | task->hdr = (struct iscsi_hdr *)&io_task->cmd_bhs->iscsi_hdr; | 3315 | task->hdr = (struct iscsi_hdr *)&io_task->cmd_bhs->iscsi_hdr; |
@@ -3343,7 +3323,7 @@ static int beiscsi_alloc_pdu(struct iscsi_task *task, uint8_t opcode) | |||
3343 | goto free_hndls; | 3323 | goto free_hndls; |
3344 | } else { | 3324 | } else { |
3345 | io_task->scsi_cmnd = NULL; | 3325 | io_task->scsi_cmnd = NULL; |
3346 | if ((task->hdr->opcode & ISCSI_OPCODE_MASK) == ISCSI_OP_LOGIN) { | 3326 | if ((opcode & ISCSI_OPCODE_MASK) == ISCSI_OP_LOGIN) { |
3347 | if (!beiscsi_conn->login_in_progress) { | 3327 | if (!beiscsi_conn->login_in_progress) { |
3348 | spin_lock(&phba->mgmt_sgl_lock); | 3328 | spin_lock(&phba->mgmt_sgl_lock); |
3349 | io_task->psgl_handle = (struct sgl_handle *) | 3329 | io_task->psgl_handle = (struct sgl_handle *) |
@@ -3370,21 +3350,16 @@ static int beiscsi_alloc_pdu(struct iscsi_task *task, uint8_t opcode) | |||
3370 | itt = (itt_t) cpu_to_be32(((unsigned int)io_task->pwrb_handle-> | 3350 | itt = (itt_t) cpu_to_be32(((unsigned int)io_task->pwrb_handle-> |
3371 | wrb_index << 16) | (unsigned int) | 3351 | wrb_index << 16) | (unsigned int) |
3372 | (io_task->psgl_handle->sgl_index)); | 3352 | (io_task->psgl_handle->sgl_index)); |
3373 | if (ring_mode) { | 3353 | io_task->pwrb_handle->pio_handle = task; |
3374 | phba->sgl_hndl_array[io_task->psgl_handle->sgl_index - | ||
3375 | phba->fw_config.iscsi_cid_start] = | ||
3376 | io_task->psgl_handle; | ||
3377 | io_task->psgl_handle->task = task; | ||
3378 | io_task->psgl_handle->cid = beiscsi_conn->beiscsi_conn_cid; | ||
3379 | } else | ||
3380 | io_task->pwrb_handle->pio_handle = task; | ||
3381 | 3354 | ||
3382 | io_task->cmd_bhs->iscsi_hdr.itt = itt; | 3355 | io_task->cmd_bhs->iscsi_hdr.itt = itt; |
3383 | return 0; | 3356 | return 0; |
3384 | 3357 | ||
3385 | free_hndls: | 3358 | free_hndls: |
3386 | phwi_ctrlr = phba->phwi_ctrlr; | 3359 | phwi_ctrlr = phba->phwi_ctrlr; |
3387 | pwrb_context = &phwi_ctrlr->wrb_context[beiscsi_conn->beiscsi_conn_cid]; | 3360 | pwrb_context = &phwi_ctrlr->wrb_context[ |
3361 | beiscsi_conn->beiscsi_conn_cid - | ||
3362 | phba->fw_config.iscsi_cid_start]; | ||
3388 | free_wrb_handle(phba, pwrb_context, io_task->pwrb_handle); | 3363 | free_wrb_handle(phba, pwrb_context, io_task->pwrb_handle); |
3389 | io_task->pwrb_handle = NULL; | 3364 | io_task->pwrb_handle = NULL; |
3390 | pci_pool_free(beiscsi_sess->bhs_pool, io_task->cmd_bhs, | 3365 | pci_pool_free(beiscsi_sess->bhs_pool, io_task->cmd_bhs, |
@@ -3404,7 +3379,8 @@ static void beiscsi_cleanup_task(struct iscsi_task *task) | |||
3404 | struct hwi_controller *phwi_ctrlr; | 3379 | struct hwi_controller *phwi_ctrlr; |
3405 | 3380 | ||
3406 | phwi_ctrlr = phba->phwi_ctrlr; | 3381 | phwi_ctrlr = phba->phwi_ctrlr; |
3407 | pwrb_context = &phwi_ctrlr->wrb_context[beiscsi_conn->beiscsi_conn_cid]; | 3382 | pwrb_context = &phwi_ctrlr->wrb_context[beiscsi_conn->beiscsi_conn_cid |
3383 | - phba->fw_config.iscsi_cid_start]; | ||
3408 | if (io_task->pwrb_handle) { | 3384 | if (io_task->pwrb_handle) { |
3409 | free_wrb_handle(phba, pwrb_context, io_task->pwrb_handle); | 3385 | free_wrb_handle(phba, pwrb_context, io_task->pwrb_handle); |
3410 | io_task->pwrb_handle = NULL; | 3386 | io_task->pwrb_handle = NULL; |
@@ -3460,18 +3436,12 @@ static int beiscsi_iotask(struct iscsi_task *task, struct scatterlist *sg, | |||
3460 | ISCSI_OPCODE_SCSI_DATA_OUT); | 3436 | ISCSI_OPCODE_SCSI_DATA_OUT); |
3461 | AMAP_SET_BITS(struct amap_pdu_data_out, final_bit, | 3437 | AMAP_SET_BITS(struct amap_pdu_data_out, final_bit, |
3462 | &io_task->cmd_bhs->iscsi_data_pdu, 1); | 3438 | &io_task->cmd_bhs->iscsi_data_pdu, 1); |
3463 | if (ring_mode) | 3439 | AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, |
3464 | io_task->psgl_handle->type = INI_WR_CMD; | 3440 | INI_WR_CMD); |
3465 | else | ||
3466 | AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, | ||
3467 | INI_WR_CMD); | ||
3468 | AMAP_SET_BITS(struct amap_iscsi_wrb, dsp, pwrb, 1); | 3441 | AMAP_SET_BITS(struct amap_iscsi_wrb, dsp, pwrb, 1); |
3469 | } else { | 3442 | } else { |
3470 | if (ring_mode) | 3443 | AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, |
3471 | io_task->psgl_handle->type = INI_RD_CMD; | 3444 | INI_RD_CMD); |
3472 | else | ||
3473 | AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, | ||
3474 | INI_RD_CMD); | ||
3475 | AMAP_SET_BITS(struct amap_iscsi_wrb, dsp, pwrb, 0); | 3445 | AMAP_SET_BITS(struct amap_iscsi_wrb, dsp, pwrb, 0); |
3476 | } | 3446 | } |
3477 | memcpy(&io_task->cmd_bhs->iscsi_data_pdu. | 3447 | memcpy(&io_task->cmd_bhs->iscsi_data_pdu. |
@@ -3496,8 +3466,7 @@ static int beiscsi_iotask(struct iscsi_task *task, struct scatterlist *sg, | |||
3496 | be_dws_le_to_cpu(pwrb, sizeof(struct iscsi_wrb)); | 3466 | be_dws_le_to_cpu(pwrb, sizeof(struct iscsi_wrb)); |
3497 | 3467 | ||
3498 | doorbell |= beiscsi_conn->beiscsi_conn_cid & DB_WRB_POST_CID_MASK; | 3468 | doorbell |= beiscsi_conn->beiscsi_conn_cid & DB_WRB_POST_CID_MASK; |
3499 | if (!ring_mode) | 3469 | doorbell |= (io_task->pwrb_handle->wrb_index & |
3500 | doorbell |= (io_task->pwrb_handle->wrb_index & | ||
3501 | DB_DEF_PDU_WRB_INDEX_MASK) << DB_DEF_PDU_WRB_INDEX_SHIFT; | 3470 | DB_DEF_PDU_WRB_INDEX_MASK) << DB_DEF_PDU_WRB_INDEX_SHIFT; |
3502 | doorbell |= 1 << DB_DEF_PDU_NUM_POSTED_SHIFT; | 3471 | doorbell |= 1 << DB_DEF_PDU_NUM_POSTED_SHIFT; |
3503 | 3472 | ||
@@ -3519,49 +3488,46 @@ static int beiscsi_mtask(struct iscsi_task *task) | |||
3519 | unsigned int doorbell = 0; | 3488 | unsigned int doorbell = 0; |
3520 | unsigned int i, cid; | 3489 | unsigned int i, cid; |
3521 | struct iscsi_task *aborted_task; | 3490 | struct iscsi_task *aborted_task; |
3491 | unsigned int tag; | ||
3522 | 3492 | ||
3523 | cid = beiscsi_conn->beiscsi_conn_cid; | 3493 | cid = beiscsi_conn->beiscsi_conn_cid; |
3524 | pwrb = io_task->pwrb_handle->pwrb; | 3494 | pwrb = io_task->pwrb_handle->pwrb; |
3495 | memset(pwrb, 0, sizeof(*pwrb)); | ||
3525 | AMAP_SET_BITS(struct amap_iscsi_wrb, cmdsn_itt, pwrb, | 3496 | AMAP_SET_BITS(struct amap_iscsi_wrb, cmdsn_itt, pwrb, |
3526 | be32_to_cpu(task->cmdsn)); | 3497 | be32_to_cpu(task->cmdsn)); |
3527 | AMAP_SET_BITS(struct amap_iscsi_wrb, wrb_idx, pwrb, | 3498 | AMAP_SET_BITS(struct amap_iscsi_wrb, wrb_idx, pwrb, |
3528 | io_task->pwrb_handle->wrb_index); | 3499 | io_task->pwrb_handle->wrb_index); |
3529 | AMAP_SET_BITS(struct amap_iscsi_wrb, sgl_icd_idx, pwrb, | 3500 | AMAP_SET_BITS(struct amap_iscsi_wrb, sgl_icd_idx, pwrb, |
3530 | io_task->psgl_handle->sgl_index); | 3501 | io_task->psgl_handle->sgl_index); |
3531 | |||
3532 | switch (task->hdr->opcode & ISCSI_OPCODE_MASK) { | 3502 | switch (task->hdr->opcode & ISCSI_OPCODE_MASK) { |
3533 | case ISCSI_OP_LOGIN: | 3503 | case ISCSI_OP_LOGIN: |
3534 | if (ring_mode) | 3504 | AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, |
3535 | io_task->psgl_handle->type = TGT_DM_CMD; | 3505 | TGT_DM_CMD); |
3536 | else | ||
3537 | AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, | ||
3538 | TGT_DM_CMD); | ||
3539 | AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0); | 3506 | AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0); |
3540 | AMAP_SET_BITS(struct amap_iscsi_wrb, cmdsn_itt, pwrb, 1); | 3507 | AMAP_SET_BITS(struct amap_iscsi_wrb, cmdsn_itt, pwrb, 1); |
3541 | hwi_write_buffer(pwrb, task); | 3508 | hwi_write_buffer(pwrb, task); |
3542 | break; | 3509 | break; |
3543 | case ISCSI_OP_NOOP_OUT: | 3510 | case ISCSI_OP_NOOP_OUT: |
3544 | if (ring_mode) | 3511 | AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, |
3545 | io_task->psgl_handle->type = INI_RD_CMD; | 3512 | INI_RD_CMD); |
3513 | if (task->hdr->ttt == ISCSI_RESERVED_TAG) | ||
3514 | AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0); | ||
3546 | else | 3515 | else |
3547 | AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, | 3516 | AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 1); |
3548 | INI_RD_CMD); | ||
3549 | hwi_write_buffer(pwrb, task); | 3517 | hwi_write_buffer(pwrb, task); |
3550 | break; | 3518 | break; |
3551 | case ISCSI_OP_TEXT: | 3519 | case ISCSI_OP_TEXT: |
3552 | if (ring_mode) | 3520 | AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, |
3553 | io_task->psgl_handle->type = INI_WR_CMD; | 3521 | TGT_DM_CMD); |
3554 | else | 3522 | AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0); |
3555 | AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, | ||
3556 | INI_WR_CMD); | ||
3557 | AMAP_SET_BITS(struct amap_iscsi_wrb, dsp, pwrb, 1); | ||
3558 | hwi_write_buffer(pwrb, task); | 3523 | hwi_write_buffer(pwrb, task); |
3559 | break; | 3524 | break; |
3560 | case ISCSI_OP_SCSI_TMFUNC: | 3525 | case ISCSI_OP_SCSI_TMFUNC: |
3561 | session = conn->session; | 3526 | session = conn->session; |
3562 | i = ((struct iscsi_tm *)task->hdr)->rtt; | 3527 | i = ((struct iscsi_tm *)task->hdr)->rtt; |
3563 | phwi_ctrlr = phba->phwi_ctrlr; | 3528 | phwi_ctrlr = phba->phwi_ctrlr; |
3564 | pwrb_context = &phwi_ctrlr->wrb_context[cid]; | 3529 | pwrb_context = &phwi_ctrlr->wrb_context[cid - |
3530 | phba->fw_config.iscsi_cid_start]; | ||
3565 | pwrb_handle = pwrb_context->pwrb_handle_basestd[be32_to_cpu(i) | 3531 | pwrb_handle = pwrb_context->pwrb_handle_basestd[be32_to_cpu(i) |
3566 | >> 16]; | 3532 | >> 16]; |
3567 | aborted_task = pwrb_handle->pio_handle; | 3533 | aborted_task = pwrb_handle->pio_handle; |
@@ -3572,22 +3538,25 @@ static int beiscsi_mtask(struct iscsi_task *task) | |||
3572 | if (!aborted_io_task->scsi_cmnd) | 3538 | if (!aborted_io_task->scsi_cmnd) |
3573 | return 0; | 3539 | return 0; |
3574 | 3540 | ||
3575 | mgmt_invalidate_icds(phba, | 3541 | tag = mgmt_invalidate_icds(phba, |
3576 | aborted_io_task->psgl_handle->sgl_index, | 3542 | aborted_io_task->psgl_handle->sgl_index, |
3577 | cid); | 3543 | cid); |
3578 | if (ring_mode) | 3544 | if (!tag) { |
3579 | io_task->psgl_handle->type = INI_TMF_CMD; | 3545 | shost_printk(KERN_WARNING, phba->shost, |
3580 | else | 3546 | "mgmt_invalidate_icds could not be" |
3581 | AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, | 3547 | " submitted\n"); |
3582 | INI_TMF_CMD); | 3548 | } else { |
3549 | wait_event_interruptible(phba->ctrl.mcc_wait[tag], | ||
3550 | phba->ctrl.mcc_numtag[tag]); | ||
3551 | free_mcc_tag(&phba->ctrl, tag); | ||
3552 | } | ||
3553 | AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, | ||
3554 | INI_TMF_CMD); | ||
3583 | AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0); | 3555 | AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0); |
3584 | hwi_write_buffer(pwrb, task); | 3556 | hwi_write_buffer(pwrb, task); |
3585 | break; | 3557 | break; |
3586 | case ISCSI_OP_LOGOUT: | 3558 | case ISCSI_OP_LOGOUT: |
3587 | AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0); | 3559 | AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0); |
3588 | if (ring_mode) | ||
3589 | io_task->psgl_handle->type = HWH_TYPE_LOGOUT; | ||
3590 | else | ||
3591 | AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, | 3560 | AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, |
3592 | HWH_TYPE_LOGOUT); | 3561 | HWH_TYPE_LOGOUT); |
3593 | hwi_write_buffer(pwrb, task); | 3562 | hwi_write_buffer(pwrb, task); |
@@ -3600,14 +3569,13 @@ static int beiscsi_mtask(struct iscsi_task *task) | |||
3600 | } | 3569 | } |
3601 | 3570 | ||
3602 | AMAP_SET_BITS(struct amap_iscsi_wrb, r2t_exp_dtl, pwrb, | 3571 | AMAP_SET_BITS(struct amap_iscsi_wrb, r2t_exp_dtl, pwrb, |
3603 | be32_to_cpu(task->data_count)); | 3572 | task->data_count); |
3604 | AMAP_SET_BITS(struct amap_iscsi_wrb, ptr2nextwrb, pwrb, | 3573 | AMAP_SET_BITS(struct amap_iscsi_wrb, ptr2nextwrb, pwrb, |
3605 | io_task->pwrb_handle->nxt_wrb_index); | 3574 | io_task->pwrb_handle->nxt_wrb_index); |
3606 | be_dws_le_to_cpu(pwrb, sizeof(struct iscsi_wrb)); | 3575 | be_dws_le_to_cpu(pwrb, sizeof(struct iscsi_wrb)); |
3607 | 3576 | ||
3608 | doorbell |= cid & DB_WRB_POST_CID_MASK; | 3577 | doorbell |= cid & DB_WRB_POST_CID_MASK; |
3609 | if (!ring_mode) | 3578 | doorbell |= (io_task->pwrb_handle->wrb_index & |
3610 | doorbell |= (io_task->pwrb_handle->wrb_index & | ||
3611 | DB_DEF_PDU_WRB_INDEX_MASK) << DB_DEF_PDU_WRB_INDEX_SHIFT; | 3579 | DB_DEF_PDU_WRB_INDEX_MASK) << DB_DEF_PDU_WRB_INDEX_SHIFT; |
3612 | doorbell |= 1 << DB_DEF_PDU_NUM_POSTED_SHIFT; | 3580 | doorbell |= 1 << DB_DEF_PDU_NUM_POSTED_SHIFT; |
3613 | iowrite32(doorbell, phba->db_va + DB_TXULP0_OFFSET); | 3581 | iowrite32(doorbell, phba->db_va + DB_TXULP0_OFFSET); |
@@ -3649,7 +3617,6 @@ static int beiscsi_task_xmit(struct iscsi_task *task) | |||
3649 | return beiscsi_iotask(task, sg, num_sg, xferlen, writedir); | 3617 | return beiscsi_iotask(task, sg, num_sg, xferlen, writedir); |
3650 | } | 3618 | } |
3651 | 3619 | ||
3652 | |||
3653 | static void beiscsi_remove(struct pci_dev *pcidev) | 3620 | static void beiscsi_remove(struct pci_dev *pcidev) |
3654 | { | 3621 | { |
3655 | struct beiscsi_hba *phba = NULL; | 3622 | struct beiscsi_hba *phba = NULL; |
@@ -3734,7 +3701,20 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev, | |||
3734 | } | 3701 | } |
3735 | SE_DEBUG(DBG_LVL_8, " phba = %p \n", phba); | 3702 | SE_DEBUG(DBG_LVL_8, " phba = %p \n", phba); |
3736 | 3703 | ||
3737 | pci_set_drvdata(pcidev, phba); | 3704 | switch (pcidev->device) { |
3705 | case BE_DEVICE_ID1: | ||
3706 | case OC_DEVICE_ID1: | ||
3707 | case OC_DEVICE_ID2: | ||
3708 | phba->generation = BE_GEN2; | ||
3709 | break; | ||
3710 | case BE_DEVICE_ID2: | ||
3711 | case OC_DEVICE_ID3: | ||
3712 | phba->generation = BE_GEN3; | ||
3713 | break; | ||
3714 | default: | ||
3715 | phba->generation = 0; | ||
3716 | } | ||
3717 | |||
3738 | if (enable_msix) | 3718 | if (enable_msix) |
3739 | num_cpus = find_num_cpus(); | 3719 | num_cpus = find_num_cpus(); |
3740 | else | 3720 | else |
@@ -3754,7 +3734,15 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev, | |||
3754 | spin_lock_init(&phba->io_sgl_lock); | 3734 | spin_lock_init(&phba->io_sgl_lock); |
3755 | spin_lock_init(&phba->mgmt_sgl_lock); | 3735 | spin_lock_init(&phba->mgmt_sgl_lock); |
3756 | spin_lock_init(&phba->isr_lock); | 3736 | spin_lock_init(&phba->isr_lock); |
3737 | ret = mgmt_get_fw_config(&phba->ctrl, phba); | ||
3738 | if (ret != 0) { | ||
3739 | shost_printk(KERN_ERR, phba->shost, | ||
3740 | "Error getting fw config\n"); | ||
3741 | goto free_port; | ||
3742 | } | ||
3743 | phba->shost->max_id = phba->fw_config.iscsi_cid_count; | ||
3757 | beiscsi_get_params(phba); | 3744 | beiscsi_get_params(phba); |
3745 | phba->shost->can_queue = phba->params.ios_per_ctrl; | ||
3758 | ret = beiscsi_init_port(phba); | 3746 | ret = beiscsi_init_port(phba); |
3759 | if (ret < 0) { | 3747 | if (ret < 0) { |
3760 | shost_printk(KERN_ERR, phba->shost, "beiscsi_dev_probe-" | 3748 | shost_printk(KERN_ERR, phba->shost, "beiscsi_dev_probe-" |
@@ -3762,6 +3750,15 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev, | |||
3762 | goto free_port; | 3750 | goto free_port; |
3763 | } | 3751 | } |
3764 | 3752 | ||
3753 | for (i = 0; i < MAX_MCC_CMD ; i++) { | ||
3754 | init_waitqueue_head(&phba->ctrl.mcc_wait[i + 1]); | ||
3755 | phba->ctrl.mcc_tag[i] = i + 1; | ||
3756 | phba->ctrl.mcc_numtag[i + 1] = 0; | ||
3757 | phba->ctrl.mcc_tag_available++; | ||
3758 | } | ||
3759 | |||
3760 | phba->ctrl.mcc_alloc_index = phba->ctrl.mcc_free_index = 0; | ||
3761 | |||
3765 | snprintf(phba->wq_name, sizeof(phba->wq_name), "beiscsi_q_irq%u", | 3762 | snprintf(phba->wq_name, sizeof(phba->wq_name), "beiscsi_q_irq%u", |
3766 | phba->shost->host_no); | 3763 | phba->shost->host_no); |
3767 | phba->wq = create_workqueue(phba->wq_name); | 3764 | phba->wq = create_workqueue(phba->wq_name); |
@@ -3836,7 +3833,7 @@ disable_pci: | |||
3836 | struct iscsi_transport beiscsi_iscsi_transport = { | 3833 | struct iscsi_transport beiscsi_iscsi_transport = { |
3837 | .owner = THIS_MODULE, | 3834 | .owner = THIS_MODULE, |
3838 | .name = DRV_NAME, | 3835 | .name = DRV_NAME, |
3839 | .caps = CAP_RECOVERY_L0 | CAP_HDRDGST | | 3836 | .caps = CAP_RECOVERY_L0 | CAP_HDRDGST | CAP_TEXT_NEGO | |
3840 | CAP_MULTI_R2T | CAP_DATADGST | CAP_DATA_PATH_OFFLOAD, | 3837 | CAP_MULTI_R2T | CAP_DATADGST | CAP_DATA_PATH_OFFLOAD, |
3841 | .param_mask = ISCSI_MAX_RECV_DLENGTH | | 3838 | .param_mask = ISCSI_MAX_RECV_DLENGTH | |
3842 | ISCSI_MAX_XMIT_DLENGTH | | 3839 | ISCSI_MAX_XMIT_DLENGTH | |
@@ -3859,7 +3856,7 @@ struct iscsi_transport beiscsi_iscsi_transport = { | |||
3859 | ISCSI_USERNAME | ISCSI_PASSWORD | | 3856 | ISCSI_USERNAME | ISCSI_PASSWORD | |
3860 | ISCSI_USERNAME_IN | ISCSI_PASSWORD_IN | | 3857 | ISCSI_USERNAME_IN | ISCSI_PASSWORD_IN | |
3861 | ISCSI_FAST_ABORT | ISCSI_ABORT_TMO | | 3858 | ISCSI_FAST_ABORT | ISCSI_ABORT_TMO | |
3862 | ISCSI_LU_RESET_TMO | ISCSI_TGT_RESET_TMO | | 3859 | ISCSI_LU_RESET_TMO | |
3863 | ISCSI_PING_TMO | ISCSI_RECV_TMO | | 3860 | ISCSI_PING_TMO | ISCSI_RECV_TMO | |
3864 | ISCSI_IFACE_NAME | ISCSI_INITIATOR_NAME, | 3861 | ISCSI_IFACE_NAME | ISCSI_INITIATOR_NAME, |
3865 | .host_param_mask = ISCSI_HOST_HWADDRESS | ISCSI_HOST_IPADDRESS | | 3862 | .host_param_mask = ISCSI_HOST_HWADDRESS | ISCSI_HOST_IPADDRESS | |
@@ -3905,7 +3902,7 @@ static int __init beiscsi_module_init(void) | |||
3905 | SE_DEBUG(DBG_LVL_1, | 3902 | SE_DEBUG(DBG_LVL_1, |
3906 | "beiscsi_module_init - Unable to register beiscsi" | 3903 | "beiscsi_module_init - Unable to register beiscsi" |
3907 | "transport.\n"); | 3904 | "transport.\n"); |
3908 | ret = -ENOMEM; | 3905 | return -ENOMEM; |
3909 | } | 3906 | } |
3910 | SE_DEBUG(DBG_LVL_8, "In beiscsi_module_init, tt=%p \n", | 3907 | SE_DEBUG(DBG_LVL_8, "In beiscsi_module_init, tt=%p \n", |
3911 | &beiscsi_iscsi_transport); | 3908 | &beiscsi_iscsi_transport); |
@@ -3917,7 +3914,6 @@ static int __init beiscsi_module_init(void) | |||
3917 | "beiscsi pci driver.\n"); | 3914 | "beiscsi pci driver.\n"); |
3918 | goto unregister_iscsi_transport; | 3915 | goto unregister_iscsi_transport; |
3919 | } | 3916 | } |
3920 | ring_mode = 0; | ||
3921 | return 0; | 3917 | return 0; |
3922 | 3918 | ||
3923 | unregister_iscsi_transport: | 3919 | unregister_iscsi_transport: |
diff --git a/drivers/scsi/be2iscsi/be_main.h b/drivers/scsi/be2iscsi/be_main.h index 25e6b208b771..c53a80ab796c 100644 --- a/drivers/scsi/be2iscsi/be_main.h +++ b/drivers/scsi/be2iscsi/be_main.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /** | 1 | /** |
2 | * Copyright (C) 2005 - 2009 ServerEngines | 2 | * Copyright (C) 2005 - 2010 ServerEngines |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or | 5 | * This program is free software; you can redistribute it and/or |
@@ -40,31 +40,29 @@ | |||
40 | #define DRV_DESC BE_NAME " " "Driver" | 40 | #define DRV_DESC BE_NAME " " "Driver" |
41 | 41 | ||
42 | #define BE_VENDOR_ID 0x19A2 | 42 | #define BE_VENDOR_ID 0x19A2 |
43 | /* DEVICE ID's for BE2 */ | ||
43 | #define BE_DEVICE_ID1 0x212 | 44 | #define BE_DEVICE_ID1 0x212 |
44 | #define OC_DEVICE_ID1 0x702 | 45 | #define OC_DEVICE_ID1 0x702 |
45 | #define OC_DEVICE_ID2 0x703 | 46 | #define OC_DEVICE_ID2 0x703 |
47 | |||
48 | /* DEVICE ID's for BE3 */ | ||
49 | #define BE_DEVICE_ID2 0x222 | ||
46 | #define OC_DEVICE_ID3 0x712 | 50 | #define OC_DEVICE_ID3 0x712 |
47 | #define OC_DEVICE_ID4 0x222 | ||
48 | 51 | ||
49 | #define BE2_MAX_SESSIONS 64 | 52 | #define BE2_IO_DEPTH 1024 |
53 | #define BE2_MAX_SESSIONS 256 | ||
50 | #define BE2_CMDS_PER_CXN 128 | 54 | #define BE2_CMDS_PER_CXN 128 |
51 | #define BE2_LOGOUTS BE2_MAX_SESSIONS | ||
52 | #define BE2_TMFS 16 | 55 | #define BE2_TMFS 16 |
53 | #define BE2_NOPOUT_REQ 16 | 56 | #define BE2_NOPOUT_REQ 16 |
54 | #define BE2_ASYNCPDUS BE2_MAX_SESSIONS | ||
55 | #define BE2_MAX_ICDS 2048 | ||
56 | #define BE2_SGE 32 | 57 | #define BE2_SGE 32 |
57 | #define BE2_DEFPDU_HDR_SZ 64 | 58 | #define BE2_DEFPDU_HDR_SZ 64 |
58 | #define BE2_DEFPDU_DATA_SZ 8192 | 59 | #define BE2_DEFPDU_DATA_SZ 8192 |
59 | #define BE2_IO_DEPTH \ | ||
60 | (BE2_MAX_ICDS / 2 - (BE2_LOGOUTS + BE2_TMFS + BE2_NOPOUT_REQ)) | ||
61 | 60 | ||
62 | #define MAX_CPUS 31 | 61 | #define MAX_CPUS 31 |
63 | #define BEISCSI_SGLIST_ELEMENTS BE2_SGE | 62 | #define BEISCSI_SGLIST_ELEMENTS 30 |
64 | 63 | ||
65 | #define BEISCSI_MAX_CMNDS 1024 /* Max IO's per Ctrlr sht->can_queue */ | ||
66 | #define BEISCSI_CMD_PER_LUN 128 /* scsi_host->cmd_per_lun */ | 64 | #define BEISCSI_CMD_PER_LUN 128 /* scsi_host->cmd_per_lun */ |
67 | #define BEISCSI_MAX_SECTORS 2048 /* scsi_host->max_sectors */ | 65 | #define BEISCSI_MAX_SECTORS 256 /* scsi_host->max_sectors */ |
68 | 66 | ||
69 | #define BEISCSI_MAX_CMD_LEN 16 /* scsi_host->max_cmd_len */ | 67 | #define BEISCSI_MAX_CMD_LEN 16 /* scsi_host->max_cmd_len */ |
70 | #define BEISCSI_NUM_MAX_LUN 256 /* scsi_host->max_lun */ | 68 | #define BEISCSI_NUM_MAX_LUN 256 /* scsi_host->max_lun */ |
@@ -330,6 +328,7 @@ struct beiscsi_hba { | |||
330 | struct workqueue_struct *wq; /* The actuak work queue */ | 328 | struct workqueue_struct *wq; /* The actuak work queue */ |
331 | struct work_struct work_cqs; /* The work being queued */ | 329 | struct work_struct work_cqs; /* The work being queued */ |
332 | struct be_ctrl_info ctrl; | 330 | struct be_ctrl_info ctrl; |
331 | unsigned int generation; | ||
333 | }; | 332 | }; |
334 | 333 | ||
335 | struct beiscsi_session { | 334 | struct beiscsi_session { |
@@ -656,11 +655,12 @@ struct amap_iscsi_wrb { | |||
656 | 655 | ||
657 | } __packed; | 656 | } __packed; |
658 | 657 | ||
659 | struct wrb_handle *alloc_wrb_handle(struct beiscsi_hba *phba, unsigned int cid, | 658 | struct wrb_handle *alloc_wrb_handle(struct beiscsi_hba *phba, unsigned int cid); |
660 | int index); | ||
661 | void | 659 | void |
662 | free_mgmt_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle); | 660 | free_mgmt_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle); |
663 | 661 | ||
662 | void beiscsi_process_all_cqs(struct work_struct *work); | ||
663 | |||
664 | struct pdu_nop_out { | 664 | struct pdu_nop_out { |
665 | u32 dw[12]; | 665 | u32 dw[12]; |
666 | }; | 666 | }; |
@@ -802,7 +802,6 @@ struct hwi_controller { | |||
802 | struct be_ring default_pdu_hdr; | 802 | struct be_ring default_pdu_hdr; |
803 | struct be_ring default_pdu_data; | 803 | struct be_ring default_pdu_data; |
804 | struct hwi_context_memory *phwi_ctxt; | 804 | struct hwi_context_memory *phwi_ctxt; |
805 | unsigned short cq_errors[CXN_KILLED_CMND_DATA_NOT_ON_SAME_CONN]; | ||
806 | }; | 805 | }; |
807 | 806 | ||
808 | enum hwh_type_enum { | 807 | enum hwh_type_enum { |
diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c index 79c2bd525a84..317bcd042ced 100644 --- a/drivers/scsi/be2iscsi/be_mgmt.c +++ b/drivers/scsi/be2iscsi/be_mgmt.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /** | 1 | /** |
2 | * Copyright (C) 2005 - 2009 ServerEngines | 2 | * Copyright (C) 2005 - 2010 ServerEngines |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or | 5 | * This program is free software; you can redistribute it and/or |
@@ -48,6 +48,14 @@ unsigned char mgmt_get_fw_config(struct be_ctrl_info *ctrl, | |||
48 | pfw_cfg->ulp[0].sq_base; | 48 | pfw_cfg->ulp[0].sq_base; |
49 | phba->fw_config.iscsi_cid_count = | 49 | phba->fw_config.iscsi_cid_count = |
50 | pfw_cfg->ulp[0].sq_count; | 50 | pfw_cfg->ulp[0].sq_count; |
51 | if (phba->fw_config.iscsi_cid_count > (BE2_MAX_SESSIONS / 2)) { | ||
52 | SE_DEBUG(DBG_LVL_8, | ||
53 | "FW reported MAX CXNS as %d \t" | ||
54 | "Max Supported = %d.\n", | ||
55 | phba->fw_config.iscsi_cid_count, | ||
56 | BE2_MAX_SESSIONS); | ||
57 | phba->fw_config.iscsi_cid_count = BE2_MAX_SESSIONS / 2; | ||
58 | } | ||
51 | } else { | 59 | } else { |
52 | shost_printk(KERN_WARNING, phba->shost, | 60 | shost_printk(KERN_WARNING, phba->shost, |
53 | "Failed in mgmt_get_fw_config \n"); | 61 | "Failed in mgmt_get_fw_config \n"); |
@@ -77,6 +85,7 @@ unsigned char mgmt_check_supported_fw(struct be_ctrl_info *ctrl, | |||
77 | } | 85 | } |
78 | nonemb_cmd.size = sizeof(struct be_mgmt_controller_attributes); | 86 | nonemb_cmd.size = sizeof(struct be_mgmt_controller_attributes); |
79 | req = nonemb_cmd.va; | 87 | req = nonemb_cmd.va; |
88 | memset(req, 0, sizeof(*req)); | ||
80 | spin_lock(&ctrl->mbox_lock); | 89 | spin_lock(&ctrl->mbox_lock); |
81 | memset(wrb, 0, sizeof(*wrb)); | 90 | memset(wrb, 0, sizeof(*wrb)); |
82 | be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1); | 91 | be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1); |
@@ -140,10 +149,17 @@ unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba, | |||
140 | { | 149 | { |
141 | struct be_dma_mem nonemb_cmd; | 150 | struct be_dma_mem nonemb_cmd; |
142 | struct be_ctrl_info *ctrl = &phba->ctrl; | 151 | struct be_ctrl_info *ctrl = &phba->ctrl; |
143 | struct be_mcc_wrb *wrb = wrb_from_mccq(phba); | 152 | struct be_mcc_wrb *wrb; |
144 | struct be_sge *sge = nonembedded_sgl(wrb); | 153 | struct be_sge *sge; |
145 | struct invalidate_commands_params_in *req; | 154 | struct invalidate_commands_params_in *req; |
146 | int status = 0; | 155 | unsigned int tag = 0; |
156 | |||
157 | spin_lock(&ctrl->mbox_lock); | ||
158 | tag = alloc_mcc_tag(phba); | ||
159 | if (!tag) { | ||
160 | spin_unlock(&ctrl->mbox_lock); | ||
161 | return tag; | ||
162 | } | ||
147 | 163 | ||
148 | nonemb_cmd.va = pci_alloc_consistent(ctrl->pdev, | 164 | nonemb_cmd.va = pci_alloc_consistent(ctrl->pdev, |
149 | sizeof(struct invalidate_commands_params_in), | 165 | sizeof(struct invalidate_commands_params_in), |
@@ -156,8 +172,10 @@ unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba, | |||
156 | } | 172 | } |
157 | nonemb_cmd.size = sizeof(struct invalidate_commands_params_in); | 173 | nonemb_cmd.size = sizeof(struct invalidate_commands_params_in); |
158 | req = nonemb_cmd.va; | 174 | req = nonemb_cmd.va; |
159 | spin_lock(&ctrl->mbox_lock); | 175 | memset(req, 0, sizeof(*req)); |
160 | memset(wrb, 0, sizeof(*wrb)); | 176 | wrb = wrb_from_mccq(phba); |
177 | sge = nonembedded_sgl(wrb); | ||
178 | wrb->tag0 |= tag; | ||
161 | 179 | ||
162 | be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1); | 180 | be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1); |
163 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI, | 181 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI, |
@@ -172,14 +190,12 @@ unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba, | |||
172 | sge->pa_lo = cpu_to_le32(nonemb_cmd.dma & 0xFFFFFFFF); | 190 | sge->pa_lo = cpu_to_le32(nonemb_cmd.dma & 0xFFFFFFFF); |
173 | sge->len = cpu_to_le32(nonemb_cmd.size); | 191 | sge->len = cpu_to_le32(nonemb_cmd.size); |
174 | 192 | ||
175 | status = be_mcc_notify_wait(phba); | 193 | be_mcc_notify(phba); |
176 | if (status) | ||
177 | SE_DEBUG(DBG_LVL_1, "ICDS Invalidation Failed\n"); | ||
178 | spin_unlock(&ctrl->mbox_lock); | 194 | spin_unlock(&ctrl->mbox_lock); |
179 | if (nonemb_cmd.va) | 195 | if (nonemb_cmd.va) |
180 | pci_free_consistent(ctrl->pdev, nonemb_cmd.size, | 196 | pci_free_consistent(ctrl->pdev, nonemb_cmd.size, |
181 | nonemb_cmd.va, nonemb_cmd.dma); | 197 | nonemb_cmd.va, nonemb_cmd.dma); |
182 | return status; | 198 | return tag; |
183 | } | 199 | } |
184 | 200 | ||
185 | unsigned char mgmt_invalidate_connection(struct beiscsi_hba *phba, | 201 | unsigned char mgmt_invalidate_connection(struct beiscsi_hba *phba, |
@@ -189,13 +205,19 @@ unsigned char mgmt_invalidate_connection(struct beiscsi_hba *phba, | |||
189 | unsigned short savecfg_flag) | 205 | unsigned short savecfg_flag) |
190 | { | 206 | { |
191 | struct be_ctrl_info *ctrl = &phba->ctrl; | 207 | struct be_ctrl_info *ctrl = &phba->ctrl; |
192 | struct be_mcc_wrb *wrb = wrb_from_mccq(phba); | 208 | struct be_mcc_wrb *wrb; |
193 | struct iscsi_invalidate_connection_params_in *req = | 209 | struct iscsi_invalidate_connection_params_in *req; |
194 | embedded_payload(wrb); | 210 | unsigned int tag = 0; |
195 | int status = 0; | ||
196 | 211 | ||
197 | spin_lock(&ctrl->mbox_lock); | 212 | spin_lock(&ctrl->mbox_lock); |
198 | memset(wrb, 0, sizeof(*wrb)); | 213 | tag = alloc_mcc_tag(phba); |
214 | if (!tag) { | ||
215 | spin_unlock(&ctrl->mbox_lock); | ||
216 | return tag; | ||
217 | } | ||
218 | wrb = wrb_from_mccq(phba); | ||
219 | wrb->tag0 |= tag; | ||
220 | req = embedded_payload(wrb); | ||
199 | 221 | ||
200 | be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); | 222 | be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); |
201 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI, | 223 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI, |
@@ -208,35 +230,37 @@ unsigned char mgmt_invalidate_connection(struct beiscsi_hba *phba, | |||
208 | else | 230 | else |
209 | req->cleanup_type = CMD_ISCSI_CONNECTION_INVALIDATE; | 231 | req->cleanup_type = CMD_ISCSI_CONNECTION_INVALIDATE; |
210 | req->save_cfg = savecfg_flag; | 232 | req->save_cfg = savecfg_flag; |
211 | status = be_mcc_notify_wait(phba); | 233 | be_mcc_notify(phba); |
212 | if (status) | ||
213 | SE_DEBUG(DBG_LVL_1, "Invalidation Failed\n"); | ||
214 | |||
215 | spin_unlock(&ctrl->mbox_lock); | 234 | spin_unlock(&ctrl->mbox_lock); |
216 | return status; | 235 | return tag; |
217 | } | 236 | } |
218 | 237 | ||
219 | unsigned char mgmt_upload_connection(struct beiscsi_hba *phba, | 238 | unsigned char mgmt_upload_connection(struct beiscsi_hba *phba, |
220 | unsigned short cid, unsigned int upload_flag) | 239 | unsigned short cid, unsigned int upload_flag) |
221 | { | 240 | { |
222 | struct be_ctrl_info *ctrl = &phba->ctrl; | 241 | struct be_ctrl_info *ctrl = &phba->ctrl; |
223 | struct be_mcc_wrb *wrb = wrb_from_mccq(phba); | 242 | struct be_mcc_wrb *wrb; |
224 | struct tcp_upload_params_in *req = embedded_payload(wrb); | 243 | struct tcp_upload_params_in *req; |
225 | int status = 0; | 244 | unsigned int tag = 0; |
226 | 245 | ||
227 | spin_lock(&ctrl->mbox_lock); | 246 | spin_lock(&ctrl->mbox_lock); |
228 | memset(wrb, 0, sizeof(*wrb)); | 247 | tag = alloc_mcc_tag(phba); |
248 | if (!tag) { | ||
249 | spin_unlock(&ctrl->mbox_lock); | ||
250 | return tag; | ||
251 | } | ||
252 | wrb = wrb_from_mccq(phba); | ||
253 | req = embedded_payload(wrb); | ||
254 | wrb->tag0 |= tag; | ||
229 | 255 | ||
230 | be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); | 256 | be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); |
231 | be_cmd_hdr_prepare(&req->hdr, CMD_COMMON_TCP_UPLOAD, | 257 | be_cmd_hdr_prepare(&req->hdr, CMD_COMMON_TCP_UPLOAD, |
232 | OPCODE_COMMON_TCP_UPLOAD, sizeof(*req)); | 258 | OPCODE_COMMON_TCP_UPLOAD, sizeof(*req)); |
233 | req->id = (unsigned short)cid; | 259 | req->id = (unsigned short)cid; |
234 | req->upload_type = (unsigned char)upload_flag; | 260 | req->upload_type = (unsigned char)upload_flag; |
235 | status = be_mcc_notify_wait(phba); | 261 | be_mcc_notify(phba); |
236 | if (status) | ||
237 | SE_DEBUG(DBG_LVL_1, "mgmt_upload_connection Failed\n"); | ||
238 | spin_unlock(&ctrl->mbox_lock); | 262 | spin_unlock(&ctrl->mbox_lock); |
239 | return status; | 263 | return tag; |
240 | } | 264 | } |
241 | 265 | ||
242 | int mgmt_open_connection(struct beiscsi_hba *phba, | 266 | int mgmt_open_connection(struct beiscsi_hba *phba, |
@@ -248,13 +272,13 @@ int mgmt_open_connection(struct beiscsi_hba *phba, | |||
248 | struct sockaddr_in *daddr_in = (struct sockaddr_in *)dst_addr; | 272 | struct sockaddr_in *daddr_in = (struct sockaddr_in *)dst_addr; |
249 | struct sockaddr_in6 *daddr_in6 = (struct sockaddr_in6 *)dst_addr; | 273 | struct sockaddr_in6 *daddr_in6 = (struct sockaddr_in6 *)dst_addr; |
250 | struct be_ctrl_info *ctrl = &phba->ctrl; | 274 | struct be_ctrl_info *ctrl = &phba->ctrl; |
251 | struct be_mcc_wrb *wrb = wrb_from_mccq(phba); | 275 | struct be_mcc_wrb *wrb; |
252 | struct tcp_connect_and_offload_in *req = embedded_payload(wrb); | 276 | struct tcp_connect_and_offload_in *req; |
253 | unsigned short def_hdr_id; | 277 | unsigned short def_hdr_id; |
254 | unsigned short def_data_id; | 278 | unsigned short def_data_id; |
255 | struct phys_addr template_address = { 0, 0 }; | 279 | struct phys_addr template_address = { 0, 0 }; |
256 | struct phys_addr *ptemplate_address; | 280 | struct phys_addr *ptemplate_address; |
257 | int status = 0; | 281 | unsigned int tag = 0; |
258 | unsigned int i; | 282 | unsigned int i; |
259 | unsigned short cid = beiscsi_ep->ep_cid; | 283 | unsigned short cid = beiscsi_ep->ep_cid; |
260 | 284 | ||
@@ -266,7 +290,14 @@ int mgmt_open_connection(struct beiscsi_hba *phba, | |||
266 | ptemplate_address = &template_address; | 290 | ptemplate_address = &template_address; |
267 | ISCSI_GET_PDU_TEMPLATE_ADDRESS(phba, ptemplate_address); | 291 | ISCSI_GET_PDU_TEMPLATE_ADDRESS(phba, ptemplate_address); |
268 | spin_lock(&ctrl->mbox_lock); | 292 | spin_lock(&ctrl->mbox_lock); |
269 | memset(wrb, 0, sizeof(*wrb)); | 293 | tag = alloc_mcc_tag(phba); |
294 | if (!tag) { | ||
295 | spin_unlock(&ctrl->mbox_lock); | ||
296 | return tag; | ||
297 | } | ||
298 | wrb = wrb_from_mccq(phba); | ||
299 | req = embedded_payload(wrb); | ||
300 | wrb->tag0 |= tag; | ||
270 | 301 | ||
271 | be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); | 302 | be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); |
272 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI, | 303 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI, |
@@ -311,46 +342,36 @@ int mgmt_open_connection(struct beiscsi_hba *phba, | |||
311 | req->do_offload = 1; | 342 | req->do_offload = 1; |
312 | req->dataout_template_pa.lo = ptemplate_address->lo; | 343 | req->dataout_template_pa.lo = ptemplate_address->lo; |
313 | req->dataout_template_pa.hi = ptemplate_address->hi; | 344 | req->dataout_template_pa.hi = ptemplate_address->hi; |
314 | status = be_mcc_notify_wait(phba); | 345 | be_mcc_notify(phba); |
315 | if (!status) { | ||
316 | struct iscsi_endpoint *ep; | ||
317 | struct tcp_connect_and_offload_out *ptcpcnct_out = | ||
318 | embedded_payload(wrb); | ||
319 | |||
320 | ep = phba->ep_array[ptcpcnct_out->cid]; | ||
321 | beiscsi_ep = ep->dd_data; | ||
322 | beiscsi_ep->fw_handle = ptcpcnct_out->connection_handle; | ||
323 | beiscsi_ep->cid_vld = 1; | ||
324 | SE_DEBUG(DBG_LVL_8, "mgmt_open_connection Success\n"); | ||
325 | } else | ||
326 | SE_DEBUG(DBG_LVL_1, "mgmt_open_connection Failed\n"); | ||
327 | spin_unlock(&ctrl->mbox_lock); | 346 | spin_unlock(&ctrl->mbox_lock); |
328 | return status; | 347 | return tag; |
329 | } | 348 | } |
330 | 349 | ||
331 | int be_cmd_get_mac_addr(struct beiscsi_hba *phba, u8 *mac_addr) | 350 | unsigned int be_cmd_get_mac_addr(struct beiscsi_hba *phba) |
332 | { | 351 | { |
333 | struct be_ctrl_info *ctrl = &phba->ctrl; | 352 | struct be_ctrl_info *ctrl = &phba->ctrl; |
334 | struct be_mcc_wrb *wrb = wrb_from_mccq(phba); | 353 | struct be_mcc_wrb *wrb; |
335 | struct be_cmd_req_get_mac_addr *req = embedded_payload(wrb); | 354 | struct be_cmd_req_get_mac_addr *req; |
336 | int status; | 355 | unsigned int tag = 0; |
337 | 356 | ||
338 | SE_DEBUG(DBG_LVL_8, "In be_cmd_get_mac_addr\n"); | 357 | SE_DEBUG(DBG_LVL_8, "In be_cmd_get_mac_addr\n"); |
339 | spin_lock(&ctrl->mbox_lock); | 358 | spin_lock(&ctrl->mbox_lock); |
340 | memset(wrb, 0, sizeof(*wrb)); | 359 | tag = alloc_mcc_tag(phba); |
360 | if (!tag) { | ||
361 | spin_unlock(&ctrl->mbox_lock); | ||
362 | return tag; | ||
363 | } | ||
364 | |||
365 | wrb = wrb_from_mccq(phba); | ||
366 | req = embedded_payload(wrb); | ||
367 | wrb->tag0 |= tag; | ||
341 | be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); | 368 | be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); |
342 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI, | 369 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI, |
343 | OPCODE_COMMON_ISCSI_NTWK_GET_NIC_CONFIG, | 370 | OPCODE_COMMON_ISCSI_NTWK_GET_NIC_CONFIG, |
344 | sizeof(*req)); | 371 | sizeof(*req)); |
345 | 372 | ||
346 | status = be_mcc_notify_wait(phba); | 373 | be_mcc_notify(phba); |
347 | if (!status) { | ||
348 | struct be_cmd_resp_get_mac_addr *resp = embedded_payload(wrb); | ||
349 | |||
350 | memcpy(mac_addr, resp->mac_address, ETH_ALEN); | ||
351 | } | ||
352 | |||
353 | spin_unlock(&ctrl->mbox_lock); | 374 | spin_unlock(&ctrl->mbox_lock); |
354 | return status; | 375 | return tag; |
355 | } | 376 | } |
356 | 377 | ||
diff --git a/drivers/scsi/be2iscsi/be_mgmt.h b/drivers/scsi/be2iscsi/be_mgmt.h index 24eaff923f85..ecead6a5aa56 100644 --- a/drivers/scsi/be2iscsi/be_mgmt.h +++ b/drivers/scsi/be2iscsi/be_mgmt.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /** | 1 | /** |
2 | * Copyright (C) 2005 - 2009 ServerEngines | 2 | * Copyright (C) 2005 - 2010 ServerEngines |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or | 5 | * This program is free software; you can redistribute it and/or |
@@ -231,6 +231,7 @@ struct beiscsi_endpoint { | |||
231 | struct beiscsi_hba *phba; | 231 | struct beiscsi_hba *phba; |
232 | struct beiscsi_sess *sess; | 232 | struct beiscsi_sess *sess; |
233 | struct beiscsi_conn *conn; | 233 | struct beiscsi_conn *conn; |
234 | struct iscsi_endpoint *openiscsi_ep; | ||
234 | unsigned short ip_type; | 235 | unsigned short ip_type; |
235 | char dst6_addr[ISCSI_ADDRESS_BUF_LEN]; | 236 | char dst6_addr[ISCSI_ADDRESS_BUF_LEN]; |
236 | unsigned long dst_addr; | 237 | unsigned long dst_addr; |
@@ -249,7 +250,4 @@ unsigned char mgmt_invalidate_connection(struct beiscsi_hba *phba, | |||
249 | unsigned short issue_reset, | 250 | unsigned short issue_reset, |
250 | unsigned short savecfg_flag); | 251 | unsigned short savecfg_flag); |
251 | 252 | ||
252 | unsigned char mgmt_fw_cmd(struct be_ctrl_info *ctrl, | ||
253 | struct beiscsi_hba *phba, | ||
254 | char *buf, unsigned int len); | ||
255 | #endif | 253 | #endif |