diff options
author | Jayamohan Kallickal <jayamohank@serverengines.com> | 2010-01-04 18:40:46 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2010-01-18 11:48:23 -0500 |
commit | 756d29c8c7ed8887ed7d752371ce2f6d12399267 (patch) | |
tree | eb70b756dc22a798538b306010647b72709a6206 /drivers/scsi/be2iscsi | |
parent | 51a462500fbed4a1e8110dc60a421a3f12b9580b (diff) |
[SCSI] be2iscsi: Enable async mode for mcc rings
This patches enables async mode for mcc rings so that
multiple requests can be queued.
Signed-off-by: Jayamohan Kallickal <jayamohank@serverengines.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/be2iscsi')
-rw-r--r-- | drivers/scsi/be2iscsi/be.h | 16 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_cmds.c | 82 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_cmds.h | 12 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_iscsi.c | 100 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_main.c | 83 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_main.h | 2 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_mgmt.c | 128 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_mgmt.h | 3 |
8 files changed, 330 insertions, 96 deletions
diff --git a/drivers/scsi/be2iscsi/be.h b/drivers/scsi/be2iscsi/be.h index a93a5040f087..3861cf44dc15 100644 --- a/drivers/scsi/be2iscsi/be.h +++ b/drivers/scsi/be2iscsi/be.h | |||
@@ -24,6 +24,7 @@ | |||
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 | ||
27 | 28 | ||
28 | struct be_dma_mem { | 29 | struct be_dma_mem { |
29 | void *va; | 30 | void *va; |
@@ -57,6 +58,11 @@ static inline void *queue_head_node(struct be_queue_info *q) | |||
57 | return q->dma_mem.va + q->head * q->entry_size; | 58 | return q->dma_mem.va + q->head * q->entry_size; |
58 | } | 59 | } |
59 | 60 | ||
61 | static inline void *queue_get_wrb(struct be_queue_info *q, unsigned int wrb_num) | ||
62 | { | ||
63 | return q->dma_mem.va + wrb_num * q->entry_size; | ||
64 | } | ||
65 | |||
60 | static inline void *queue_tail_node(struct be_queue_info *q) | 66 | static inline void *queue_tail_node(struct be_queue_info *q) |
61 | { | 67 | { |
62 | return q->dma_mem.va + q->tail * q->entry_size; | 68 | return q->dma_mem.va + q->tail * q->entry_size; |
@@ -104,15 +110,19 @@ struct be_ctrl_info { | |||
104 | spinlock_t mcc_lock; /* For serializing mcc cmds to BE card */ | 110 | spinlock_t mcc_lock; /* For serializing mcc cmds to BE card */ |
105 | spinlock_t mcc_cq_lock; | 111 | spinlock_t mcc_cq_lock; |
106 | 112 | ||
107 | /* MCC Async callback */ | 113 | wait_queue_head_t mcc_wait[MAX_MCC_CMD + 1]; |
108 | void (*async_cb) (void *adapter, bool link_up); | 114 | unsigned int mcc_tag[MAX_MCC_CMD]; |
109 | void *adapter_ctxt; | 115 | unsigned int mcc_numtag[MAX_MCC_CMD + 1]; |
116 | unsigned short mcc_alloc_index; | ||
117 | unsigned short mcc_free_index; | ||
118 | unsigned int mcc_tag_available; | ||
110 | }; | 119 | }; |
111 | 120 | ||
112 | #include "be_cmds.h" | 121 | #include "be_cmds.h" |
113 | 122 | ||
114 | #define PAGE_SHIFT_4K 12 | 123 | #define PAGE_SHIFT_4K 12 |
115 | #define PAGE_SIZE_4K (1 << PAGE_SHIFT_4K) | 124 | #define PAGE_SIZE_4K (1 << PAGE_SHIFT_4K) |
125 | #define mcc_timeout 120000 /* 5s timeout */ | ||
116 | 126 | ||
117 | /* Returns number of pages spanned by the data starting at the given addr */ | 127 | /* Returns number of pages spanned by the data starting at the given addr */ |
118 | #define PAGES_4K_SPANNED(_address, size) \ | 128 | #define PAGES_4K_SPANNED(_address, size) \ |
diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c index f008708f1b08..d4a0d1da4875 100644 --- a/drivers/scsi/be2iscsi/be_cmds.c +++ b/drivers/scsi/be2iscsi/be_cmds.c | |||
@@ -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) { |
@@ -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..69dddfaebe59 100644 --- a/drivers/scsi/be2iscsi/be_cmds.h +++ b/drivers/scsi/be2iscsi/be_cmds.h | |||
@@ -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 f22918427a2e..95694d3d2089 100644 --- a/drivers/scsi/be2iscsi/be_iscsi.c +++ b/drivers/scsi/be2iscsi/be_iscsi.c | |||
@@ -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; |
@@ -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"); |
@@ -440,7 +479,35 @@ static int beiscsi_open_conn(struct iscsi_endpoint *ep, | |||
440 | } | 479 | } |
441 | 480 | ||
442 | beiscsi_ep->cid_vld = 0; | 481 | beiscsi_ep->cid_vld = 0; |
443 | 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; | ||
444 | } | 511 | } |
445 | 512 | ||
446 | /** | 513 | /** |
@@ -509,7 +576,6 @@ beiscsi_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr, | |||
509 | beiscsi_ep = ep->dd_data; | 576 | beiscsi_ep = ep->dd_data; |
510 | beiscsi_ep->phba = phba; | 577 | beiscsi_ep->phba = phba; |
511 | beiscsi_ep->openiscsi_ep = ep; | 578 | beiscsi_ep->openiscsi_ep = ep; |
512 | |||
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 beiscsi_open_conn \n"); | 580 | SE_DEBUG(DBG_LVL_1, "Failed in beiscsi_open_conn \n"); |
515 | ret = -ENOMEM; | 581 | ret = -ENOMEM; |
@@ -549,16 +615,19 @@ int beiscsi_ep_poll(struct iscsi_endpoint *ep, int timeout_ms) | |||
549 | static int beiscsi_close_conn(struct beiscsi_endpoint *beiscsi_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; |
618 | unsigned int tag; | ||
552 | struct beiscsi_hba *phba = beiscsi_ep->phba; | 619 | struct beiscsi_hba *phba = beiscsi_ep->phba; |
553 | 620 | ||
554 | if (MGMT_STATUS_SUCCESS != | 621 | tag = mgmt_upload_connection(phba, beiscsi_ep->ep_cid, flag); |
555 | mgmt_upload_connection(phba, beiscsi_ep->ep_cid, | 622 | if (!tag) { |
556 | flag)) { | ||
557 | SE_DEBUG(DBG_LVL_8, "upload failed for cid 0x%x", | 623 | SE_DEBUG(DBG_LVL_8, "upload failed for cid 0x%x", |
558 | beiscsi_ep->ep_cid); | 624 | beiscsi_ep->ep_cid); |
559 | 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); | ||
560 | } | 630 | } |
561 | |||
562 | return ret; | 631 | return ret; |
563 | } | 632 | } |
564 | 633 | ||
@@ -576,6 +645,8 @@ void beiscsi_ep_disconnect(struct iscsi_endpoint *ep) | |||
576 | 645 | ||
577 | beiscsi_ep = ep->dd_data; | 646 | beiscsi_ep = ep->dd_data; |
578 | phba = beiscsi_ep->phba; | 647 | phba = beiscsi_ep->phba; |
648 | SE_DEBUG(DBG_LVL_8, "In beiscsi_ep_disconnect for ep_cid = %d\n", | ||
649 | beiscsi_ep->ep_cid); | ||
579 | 650 | ||
580 | if (beiscsi_ep->conn) { | 651 | if (beiscsi_ep->conn) { |
581 | beiscsi_conn = beiscsi_ep->conn; | 652 | beiscsi_conn = beiscsi_ep->conn; |
@@ -614,22 +685,27 @@ void beiscsi_conn_stop(struct iscsi_cls_conn *cls_conn, int flag) | |||
614 | struct iscsi_session *session = conn->session; | 685 | struct iscsi_session *session = conn->session; |
615 | struct Scsi_Host *shost = iscsi_session_to_shost(session->cls_session); | 686 | struct Scsi_Host *shost = iscsi_session_to_shost(session->cls_session); |
616 | struct beiscsi_hba *phba = iscsi_host_priv(shost); | 687 | struct beiscsi_hba *phba = iscsi_host_priv(shost); |
617 | unsigned int status; | 688 | unsigned int tag; |
618 | unsigned short savecfg_flag = CMD_ISCSI_SESSION_SAVE_CFG_ON_FLASH; | 689 | unsigned short savecfg_flag = CMD_ISCSI_SESSION_SAVE_CFG_ON_FLASH; |
619 | 690 | ||
620 | SE_DEBUG(DBG_LVL_8, "In beiscsi_conn_stop\n"); | ||
621 | beiscsi_ep = beiscsi_conn->ep; | 691 | beiscsi_ep = beiscsi_conn->ep; |
622 | if (!beiscsi_ep) { | 692 | if (!beiscsi_ep) { |
623 | 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"); |
624 | return; | 694 | return; |
625 | } | 695 | } |
626 | 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, | ||
627 | beiscsi_ep->ep_cid, 1, | 699 | beiscsi_ep->ep_cid, 1, |
628 | savecfg_flag); | 700 | savecfg_flag); |
629 | if (status != MGMT_STATUS_SUCCESS) { | 701 | if (!tag) { |
630 | SE_DEBUG(DBG_LVL_1, | 702 | SE_DEBUG(DBG_LVL_1, |
631 | "mgmt_invalidate_connection Failed for cid=%d \n", | 703 | "mgmt_invalidate_connection Failed for cid=%d \n", |
632 | 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); | ||
633 | } | 709 | } |
634 | beiscsi_close_conn(beiscsi_ep, CONNECTION_UPLOAD_GRACEFUL); | 710 | beiscsi_close_conn(beiscsi_ep, CONNECTION_UPLOAD_GRACEFUL); |
635 | beiscsi_free_ep(beiscsi_ep); | 711 | beiscsi_free_ep(beiscsi_ep); |
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c index 6170548a5289..a6a2c6469677 100644 --- a/drivers/scsi/be2iscsi/be_main.c +++ b/drivers/scsi/be2iscsi/be_main.c | |||
@@ -442,7 +442,7 @@ static irqreturn_t be_isr(int irq, void *dev_id) | |||
442 | if (phba->todo_mcc_cq) | 442 | if (phba->todo_mcc_cq) |
443 | queue_work(phba->wq, &phba->work_cqs); | 443 | queue_work(phba->wq, &phba->work_cqs); |
444 | 444 | ||
445 | if ((num_mcceq_processed) && (!num_ioeq_processed)) | 445 | if ((num_mcceq_processed) && (!num_ioeq_processed)) |
446 | hwi_ring_eq_db(phba, eq->id, 0, | 446 | hwi_ring_eq_db(phba, eq->id, 0, |
447 | (num_ioeq_processed + | 447 | (num_ioeq_processed + |
448 | num_mcceq_processed) , 1, 1); | 448 | num_mcceq_processed) , 1, 1); |
@@ -651,7 +651,6 @@ struct wrb_handle *alloc_wrb_handle(struct beiscsi_hba *phba, unsigned int cid) | |||
651 | pwrb_context->alloc_index = 0; | 651 | pwrb_context->alloc_index = 0; |
652 | else | 652 | else |
653 | pwrb_context->alloc_index++; | 653 | pwrb_context->alloc_index++; |
654 | |||
655 | pwrb_handle_tmp = pwrb_context->pwrb_handle_base[ | 654 | pwrb_handle_tmp = pwrb_context->pwrb_handle_base[ |
656 | pwrb_context->alloc_index]; | 655 | pwrb_context->alloc_index]; |
657 | pwrb_handle->nxt_wrb_index = pwrb_handle_tmp->wrb_index; | 656 | pwrb_handle->nxt_wrb_index = pwrb_handle_tmp->wrb_index; |
@@ -791,6 +790,7 @@ be_complete_io(struct beiscsi_conn *beiscsi_conn, | |||
791 | memcpy(task->sc->sense_buffer, sense, | 790 | memcpy(task->sc->sense_buffer, sense, |
792 | min_t(u16, sense_len, SCSI_SENSE_BUFFERSIZE)); | 791 | min_t(u16, sense_len, SCSI_SENSE_BUFFERSIZE)); |
793 | } | 792 | } |
793 | |||
794 | if (io_task->cmd_bhs->iscsi_hdr.flags & ISCSI_FLAG_CMD_READ) { | 794 | if (io_task->cmd_bhs->iscsi_hdr.flags & ISCSI_FLAG_CMD_READ) { |
795 | if (psol->dw[offsetof(struct amap_sol_cqe, i_res_cnt) / 32] | 795 | if (psol->dw[offsetof(struct amap_sol_cqe, i_res_cnt) / 32] |
796 | & SOL_RES_CNT_MASK) | 796 | & SOL_RES_CNT_MASK) |
@@ -1432,6 +1432,48 @@ static void hwi_process_default_pdu_ring(struct beiscsi_conn *beiscsi_conn, | |||
1432 | hwi_post_async_buffers(phba, pasync_handle->is_header); | 1432 | hwi_post_async_buffers(phba, pasync_handle->is_header); |
1433 | } | 1433 | } |
1434 | 1434 | ||
1435 | static void beiscsi_process_mcc_isr(struct beiscsi_hba *phba) | ||
1436 | { | ||
1437 | struct be_queue_info *mcc_cq; | ||
1438 | struct be_mcc_compl *mcc_compl; | ||
1439 | unsigned int num_processed = 0; | ||
1440 | |||
1441 | mcc_cq = &phba->ctrl.mcc_obj.cq; | ||
1442 | mcc_compl = queue_tail_node(mcc_cq); | ||
1443 | mcc_compl->flags = le32_to_cpu(mcc_compl->flags); | ||
1444 | while (mcc_compl->flags & CQE_FLAGS_VALID_MASK) { | ||
1445 | |||
1446 | if (num_processed >= 32) { | ||
1447 | hwi_ring_cq_db(phba, mcc_cq->id, | ||
1448 | num_processed, 0, 0); | ||
1449 | num_processed = 0; | ||
1450 | } | ||
1451 | if (mcc_compl->flags & CQE_FLAGS_ASYNC_MASK) { | ||
1452 | /* Interpret flags as an async trailer */ | ||
1453 | if (is_link_state_evt(mcc_compl->flags)) | ||
1454 | /* Interpret compl as a async link evt */ | ||
1455 | beiscsi_async_link_state_process(phba, | ||
1456 | (struct be_async_event_link_state *) mcc_compl); | ||
1457 | else | ||
1458 | SE_DEBUG(DBG_LVL_1, | ||
1459 | " Unsupported Async Event, flags" | ||
1460 | " = 0x%08x \n", mcc_compl->flags); | ||
1461 | } else if (mcc_compl->flags & CQE_FLAGS_COMPLETED_MASK) { | ||
1462 | be_mcc_compl_process_isr(&phba->ctrl, mcc_compl); | ||
1463 | atomic_dec(&phba->ctrl.mcc_obj.q.used); | ||
1464 | } | ||
1465 | |||
1466 | mcc_compl->flags = 0; | ||
1467 | queue_tail_inc(mcc_cq); | ||
1468 | mcc_compl = queue_tail_node(mcc_cq); | ||
1469 | mcc_compl->flags = le32_to_cpu(mcc_compl->flags); | ||
1470 | num_processed++; | ||
1471 | } | ||
1472 | |||
1473 | if (num_processed > 0) | ||
1474 | hwi_ring_cq_db(phba, mcc_cq->id, num_processed, 1, 0); | ||
1475 | |||
1476 | } | ||
1435 | 1477 | ||
1436 | static unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq) | 1478 | static unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq) |
1437 | { | 1479 | { |
@@ -1468,6 +1510,7 @@ static unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq) | |||
1468 | } | 1510 | } |
1469 | beiscsi_ep = ep->dd_data; | 1511 | beiscsi_ep = ep->dd_data; |
1470 | beiscsi_conn = beiscsi_ep->conn; | 1512 | beiscsi_conn = beiscsi_ep->conn; |
1513 | |||
1471 | if (num_processed >= 32) { | 1514 | if (num_processed >= 32) { |
1472 | hwi_ring_cq_db(phba, cq->id, | 1515 | hwi_ring_cq_db(phba, cq->id, |
1473 | num_processed, 0, 0); | 1516 | num_processed, 0, 0); |
@@ -1603,7 +1646,7 @@ static unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq) | |||
1603 | return tot_nump; | 1646 | return tot_nump; |
1604 | } | 1647 | } |
1605 | 1648 | ||
1606 | static void beiscsi_process_all_cqs(struct work_struct *work) | 1649 | void beiscsi_process_all_cqs(struct work_struct *work) |
1607 | { | 1650 | { |
1608 | unsigned long flags; | 1651 | unsigned long flags; |
1609 | struct hwi_controller *phwi_ctrlr; | 1652 | struct hwi_controller *phwi_ctrlr; |
@@ -1623,6 +1666,7 @@ static void beiscsi_process_all_cqs(struct work_struct *work) | |||
1623 | spin_lock_irqsave(&phba->isr_lock, flags); | 1666 | spin_lock_irqsave(&phba->isr_lock, flags); |
1624 | phba->todo_mcc_cq = 0; | 1667 | phba->todo_mcc_cq = 0; |
1625 | spin_unlock_irqrestore(&phba->isr_lock, flags); | 1668 | spin_unlock_irqrestore(&phba->isr_lock, flags); |
1669 | beiscsi_process_mcc_isr(phba); | ||
1626 | } | 1670 | } |
1627 | 1671 | ||
1628 | if (phba->todo_cq) { | 1672 | if (phba->todo_cq) { |
@@ -3160,6 +3204,7 @@ static void hwi_purge_eq(struct beiscsi_hba *phba) | |||
3160 | struct be_queue_info *eq; | 3204 | struct be_queue_info *eq; |
3161 | struct be_eq_entry *eqe = NULL; | 3205 | struct be_eq_entry *eqe = NULL; |
3162 | int i, eq_msix; | 3206 | int i, eq_msix; |
3207 | unsigned int num_processed; | ||
3163 | 3208 | ||
3164 | phwi_ctrlr = phba->phwi_ctrlr; | 3209 | phwi_ctrlr = phba->phwi_ctrlr; |
3165 | phwi_context = phwi_ctrlr->phwi_ctxt; | 3210 | phwi_context = phwi_ctrlr->phwi_ctxt; |
@@ -3171,13 +3216,17 @@ static void hwi_purge_eq(struct beiscsi_hba *phba) | |||
3171 | for (i = 0; i < (phba->num_cpus + eq_msix); i++) { | 3216 | for (i = 0; i < (phba->num_cpus + eq_msix); i++) { |
3172 | eq = &phwi_context->be_eq[i].q; | 3217 | eq = &phwi_context->be_eq[i].q; |
3173 | eqe = queue_tail_node(eq); | 3218 | eqe = queue_tail_node(eq); |
3174 | 3219 | num_processed = 0; | |
3175 | while (eqe->dw[offsetof(struct amap_eq_entry, valid) / 32] | 3220 | while (eqe->dw[offsetof(struct amap_eq_entry, valid) / 32] |
3176 | & EQE_VALID_MASK) { | 3221 | & EQE_VALID_MASK) { |
3177 | AMAP_SET_BITS(struct amap_eq_entry, valid, eqe, 0); | 3222 | AMAP_SET_BITS(struct amap_eq_entry, valid, eqe, 0); |
3178 | queue_tail_inc(eq); | 3223 | queue_tail_inc(eq); |
3179 | eqe = queue_tail_node(eq); | 3224 | eqe = queue_tail_node(eq); |
3225 | num_processed++; | ||
3180 | } | 3226 | } |
3227 | |||
3228 | if (num_processed) | ||
3229 | hwi_ring_eq_db(phba, eq->id, 1, num_processed, 1, 1); | ||
3181 | } | 3230 | } |
3182 | } | 3231 | } |
3183 | 3232 | ||
@@ -3189,8 +3238,9 @@ static void beiscsi_clean_port(struct beiscsi_hba *phba) | |||
3189 | if (mgmt_status) | 3238 | if (mgmt_status) |
3190 | shost_printk(KERN_WARNING, phba->shost, | 3239 | shost_printk(KERN_WARNING, phba->shost, |
3191 | "mgmt_epfw_cleanup FAILED \n"); | 3240 | "mgmt_epfw_cleanup FAILED \n"); |
3192 | hwi_cleanup(phba); | 3241 | |
3193 | hwi_purge_eq(phba); | 3242 | hwi_purge_eq(phba); |
3243 | hwi_cleanup(phba); | ||
3194 | if (ring_mode) | 3244 | if (ring_mode) |
3195 | kfree(phba->sgl_hndl_array); | 3245 | kfree(phba->sgl_hndl_array); |
3196 | kfree(phba->io_sgl_hndl_base); | 3246 | kfree(phba->io_sgl_hndl_base); |
@@ -3519,6 +3569,7 @@ static int beiscsi_mtask(struct iscsi_task *task) | |||
3519 | unsigned int doorbell = 0; | 3569 | unsigned int doorbell = 0; |
3520 | unsigned int i, cid; | 3570 | unsigned int i, cid; |
3521 | struct iscsi_task *aborted_task; | 3571 | struct iscsi_task *aborted_task; |
3572 | unsigned int tag; | ||
3522 | 3573 | ||
3523 | cid = beiscsi_conn->beiscsi_conn_cid; | 3574 | cid = beiscsi_conn->beiscsi_conn_cid; |
3524 | pwrb = io_task->pwrb_handle->pwrb; | 3575 | pwrb = io_task->pwrb_handle->pwrb; |
@@ -3550,7 +3601,6 @@ static int beiscsi_mtask(struct iscsi_task *task) | |||
3550 | AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0); | 3601 | AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0); |
3551 | else | 3602 | else |
3552 | AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 1); | 3603 | AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 1); |
3553 | |||
3554 | hwi_write_buffer(pwrb, task); | 3604 | hwi_write_buffer(pwrb, task); |
3555 | break; | 3605 | break; |
3556 | case ISCSI_OP_TEXT: | 3606 | case ISCSI_OP_TEXT: |
@@ -3579,9 +3629,18 @@ static int beiscsi_mtask(struct iscsi_task *task) | |||
3579 | if (!aborted_io_task->scsi_cmnd) | 3629 | if (!aborted_io_task->scsi_cmnd) |
3580 | return 0; | 3630 | return 0; |
3581 | 3631 | ||
3582 | mgmt_invalidate_icds(phba, | 3632 | tag = mgmt_invalidate_icds(phba, |
3583 | aborted_io_task->psgl_handle->sgl_index, | 3633 | aborted_io_task->psgl_handle->sgl_index, |
3584 | cid); | 3634 | cid); |
3635 | if (!tag) { | ||
3636 | shost_printk(KERN_WARNING, phba->shost, | ||
3637 | "mgmt_invalidate_icds could not be" | ||
3638 | " submitted\n"); | ||
3639 | } else { | ||
3640 | wait_event_interruptible(phba->ctrl.mcc_wait[tag], | ||
3641 | phba->ctrl.mcc_numtag[tag]); | ||
3642 | free_mcc_tag(&phba->ctrl, tag); | ||
3643 | } | ||
3585 | if (ring_mode) | 3644 | if (ring_mode) |
3586 | io_task->psgl_handle->type = INI_TMF_CMD; | 3645 | io_task->psgl_handle->type = INI_TMF_CMD; |
3587 | else | 3646 | else |
@@ -3656,7 +3715,6 @@ static int beiscsi_task_xmit(struct iscsi_task *task) | |||
3656 | return beiscsi_iotask(task, sg, num_sg, xferlen, writedir); | 3715 | return beiscsi_iotask(task, sg, num_sg, xferlen, writedir); |
3657 | } | 3716 | } |
3658 | 3717 | ||
3659 | |||
3660 | static void beiscsi_remove(struct pci_dev *pcidev) | 3718 | static void beiscsi_remove(struct pci_dev *pcidev) |
3661 | { | 3719 | { |
3662 | struct beiscsi_hba *phba = NULL; | 3720 | struct beiscsi_hba *phba = NULL; |
@@ -3776,6 +3834,15 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev, | |||
3776 | goto free_port; | 3834 | goto free_port; |
3777 | } | 3835 | } |
3778 | 3836 | ||
3837 | for (i = 0; i < MAX_MCC_CMD ; i++) { | ||
3838 | init_waitqueue_head(&phba->ctrl.mcc_wait[i + 1]); | ||
3839 | phba->ctrl.mcc_tag[i] = i + 1; | ||
3840 | phba->ctrl.mcc_numtag[i + 1] = 0; | ||
3841 | phba->ctrl.mcc_tag_available++; | ||
3842 | } | ||
3843 | |||
3844 | phba->ctrl.mcc_alloc_index = phba->ctrl.mcc_free_index = 0; | ||
3845 | |||
3779 | snprintf(phba->wq_name, sizeof(phba->wq_name), "beiscsi_q_irq%u", | 3846 | snprintf(phba->wq_name, sizeof(phba->wq_name), "beiscsi_q_irq%u", |
3780 | phba->shost->host_no); | 3847 | phba->shost->host_no); |
3781 | phba->wq = create_workqueue(phba->wq_name); | 3848 | phba->wq = create_workqueue(phba->wq_name); |
diff --git a/drivers/scsi/be2iscsi/be_main.h b/drivers/scsi/be2iscsi/be_main.h index 0553f49db9be..4cde8f6eb5bc 100644 --- a/drivers/scsi/be2iscsi/be_main.h +++ b/drivers/scsi/be2iscsi/be_main.h | |||
@@ -655,6 +655,8 @@ struct wrb_handle *alloc_wrb_handle(struct beiscsi_hba *phba, unsigned int cid); | |||
655 | void | 655 | void |
656 | free_mgmt_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle); | 656 | free_mgmt_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle); |
657 | 657 | ||
658 | void beiscsi_process_all_cqs(struct work_struct *work); | ||
659 | |||
658 | struct pdu_nop_out { | 660 | struct pdu_nop_out { |
659 | u32 dw[12]; | 661 | u32 dw[12]; |
660 | }; | 662 | }; |
diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c index df1b327fe17b..18f80411aef6 100644 --- a/drivers/scsi/be2iscsi/be_mgmt.c +++ b/drivers/scsi/be2iscsi/be_mgmt.c | |||
@@ -148,10 +148,17 @@ unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba, | |||
148 | { | 148 | { |
149 | struct be_dma_mem nonemb_cmd; | 149 | struct be_dma_mem nonemb_cmd; |
150 | struct be_ctrl_info *ctrl = &phba->ctrl; | 150 | struct be_ctrl_info *ctrl = &phba->ctrl; |
151 | struct be_mcc_wrb *wrb = wrb_from_mccq(phba); | 151 | struct be_mcc_wrb *wrb; |
152 | struct be_sge *sge = nonembedded_sgl(wrb); | 152 | struct be_sge *sge; |
153 | struct invalidate_commands_params_in *req; | 153 | struct invalidate_commands_params_in *req; |
154 | int status = 0; | 154 | unsigned int tag = 0; |
155 | |||
156 | spin_lock(&ctrl->mbox_lock); | ||
157 | tag = alloc_mcc_tag(phba); | ||
158 | if (!tag) { | ||
159 | spin_unlock(&ctrl->mbox_lock); | ||
160 | return tag; | ||
161 | } | ||
155 | 162 | ||
156 | nonemb_cmd.va = pci_alloc_consistent(ctrl->pdev, | 163 | nonemb_cmd.va = pci_alloc_consistent(ctrl->pdev, |
157 | sizeof(struct invalidate_commands_params_in), | 164 | sizeof(struct invalidate_commands_params_in), |
@@ -164,8 +171,9 @@ unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba, | |||
164 | } | 171 | } |
165 | nonemb_cmd.size = sizeof(struct invalidate_commands_params_in); | 172 | nonemb_cmd.size = sizeof(struct invalidate_commands_params_in); |
166 | req = nonemb_cmd.va; | 173 | req = nonemb_cmd.va; |
167 | spin_lock(&ctrl->mbox_lock); | 174 | wrb = wrb_from_mccq(phba); |
168 | memset(wrb, 0, sizeof(*wrb)); | 175 | sge = nonembedded_sgl(wrb); |
176 | wrb->tag0 |= tag; | ||
169 | 177 | ||
170 | be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1); | 178 | be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1); |
171 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI, | 179 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI, |
@@ -180,14 +188,12 @@ unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba, | |||
180 | sge->pa_lo = cpu_to_le32(nonemb_cmd.dma & 0xFFFFFFFF); | 188 | sge->pa_lo = cpu_to_le32(nonemb_cmd.dma & 0xFFFFFFFF); |
181 | sge->len = cpu_to_le32(nonemb_cmd.size); | 189 | sge->len = cpu_to_le32(nonemb_cmd.size); |
182 | 190 | ||
183 | status = be_mcc_notify_wait(phba); | 191 | be_mcc_notify(phba); |
184 | if (status) | ||
185 | SE_DEBUG(DBG_LVL_1, "ICDS Invalidation Failed\n"); | ||
186 | spin_unlock(&ctrl->mbox_lock); | 192 | spin_unlock(&ctrl->mbox_lock); |
187 | if (nonemb_cmd.va) | 193 | if (nonemb_cmd.va) |
188 | pci_free_consistent(ctrl->pdev, nonemb_cmd.size, | 194 | pci_free_consistent(ctrl->pdev, nonemb_cmd.size, |
189 | nonemb_cmd.va, nonemb_cmd.dma); | 195 | nonemb_cmd.va, nonemb_cmd.dma); |
190 | return status; | 196 | return tag; |
191 | } | 197 | } |
192 | 198 | ||
193 | unsigned char mgmt_invalidate_connection(struct beiscsi_hba *phba, | 199 | unsigned char mgmt_invalidate_connection(struct beiscsi_hba *phba, |
@@ -197,13 +203,19 @@ unsigned char mgmt_invalidate_connection(struct beiscsi_hba *phba, | |||
197 | unsigned short savecfg_flag) | 203 | unsigned short savecfg_flag) |
198 | { | 204 | { |
199 | struct be_ctrl_info *ctrl = &phba->ctrl; | 205 | struct be_ctrl_info *ctrl = &phba->ctrl; |
200 | struct be_mcc_wrb *wrb = wrb_from_mccq(phba); | 206 | struct be_mcc_wrb *wrb; |
201 | struct iscsi_invalidate_connection_params_in *req = | 207 | struct iscsi_invalidate_connection_params_in *req; |
202 | embedded_payload(wrb); | 208 | unsigned int tag = 0; |
203 | int status = 0; | ||
204 | 209 | ||
205 | spin_lock(&ctrl->mbox_lock); | 210 | spin_lock(&ctrl->mbox_lock); |
206 | memset(wrb, 0, sizeof(*wrb)); | 211 | tag = alloc_mcc_tag(phba); |
212 | if (!tag) { | ||
213 | spin_unlock(&ctrl->mbox_lock); | ||
214 | return tag; | ||
215 | } | ||
216 | wrb = wrb_from_mccq(phba); | ||
217 | wrb->tag0 |= tag; | ||
218 | req = embedded_payload(wrb); | ||
207 | 219 | ||
208 | be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); | 220 | be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); |
209 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI, | 221 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI, |
@@ -216,35 +228,37 @@ unsigned char mgmt_invalidate_connection(struct beiscsi_hba *phba, | |||
216 | else | 228 | else |
217 | req->cleanup_type = CMD_ISCSI_CONNECTION_INVALIDATE; | 229 | req->cleanup_type = CMD_ISCSI_CONNECTION_INVALIDATE; |
218 | req->save_cfg = savecfg_flag; | 230 | req->save_cfg = savecfg_flag; |
219 | status = be_mcc_notify_wait(phba); | 231 | be_mcc_notify(phba); |
220 | if (status) | ||
221 | SE_DEBUG(DBG_LVL_1, "Invalidation Failed\n"); | ||
222 | |||
223 | spin_unlock(&ctrl->mbox_lock); | 232 | spin_unlock(&ctrl->mbox_lock); |
224 | return status; | 233 | return tag; |
225 | } | 234 | } |
226 | 235 | ||
227 | unsigned char mgmt_upload_connection(struct beiscsi_hba *phba, | 236 | unsigned char mgmt_upload_connection(struct beiscsi_hba *phba, |
228 | unsigned short cid, unsigned int upload_flag) | 237 | unsigned short cid, unsigned int upload_flag) |
229 | { | 238 | { |
230 | struct be_ctrl_info *ctrl = &phba->ctrl; | 239 | struct be_ctrl_info *ctrl = &phba->ctrl; |
231 | struct be_mcc_wrb *wrb = wrb_from_mccq(phba); | 240 | struct be_mcc_wrb *wrb; |
232 | struct tcp_upload_params_in *req = embedded_payload(wrb); | 241 | struct tcp_upload_params_in *req; |
233 | int status = 0; | 242 | unsigned int tag = 0; |
234 | 243 | ||
235 | spin_lock(&ctrl->mbox_lock); | 244 | spin_lock(&ctrl->mbox_lock); |
236 | memset(wrb, 0, sizeof(*wrb)); | 245 | tag = alloc_mcc_tag(phba); |
246 | if (!tag) { | ||
247 | spin_unlock(&ctrl->mbox_lock); | ||
248 | return tag; | ||
249 | } | ||
250 | wrb = wrb_from_mccq(phba); | ||
251 | req = embedded_payload(wrb); | ||
252 | wrb->tag0 |= tag; | ||
237 | 253 | ||
238 | be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); | 254 | be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); |
239 | be_cmd_hdr_prepare(&req->hdr, CMD_COMMON_TCP_UPLOAD, | 255 | be_cmd_hdr_prepare(&req->hdr, CMD_COMMON_TCP_UPLOAD, |
240 | OPCODE_COMMON_TCP_UPLOAD, sizeof(*req)); | 256 | OPCODE_COMMON_TCP_UPLOAD, sizeof(*req)); |
241 | req->id = (unsigned short)cid; | 257 | req->id = (unsigned short)cid; |
242 | req->upload_type = (unsigned char)upload_flag; | 258 | req->upload_type = (unsigned char)upload_flag; |
243 | status = be_mcc_notify_wait(phba); | 259 | be_mcc_notify(phba); |
244 | if (status) | ||
245 | SE_DEBUG(DBG_LVL_1, "mgmt_upload_connection Failed\n"); | ||
246 | spin_unlock(&ctrl->mbox_lock); | 260 | spin_unlock(&ctrl->mbox_lock); |
247 | return status; | 261 | return tag; |
248 | } | 262 | } |
249 | 263 | ||
250 | int mgmt_open_connection(struct beiscsi_hba *phba, | 264 | int mgmt_open_connection(struct beiscsi_hba *phba, |
@@ -256,13 +270,13 @@ int mgmt_open_connection(struct beiscsi_hba *phba, | |||
256 | struct sockaddr_in *daddr_in = (struct sockaddr_in *)dst_addr; | 270 | struct sockaddr_in *daddr_in = (struct sockaddr_in *)dst_addr; |
257 | struct sockaddr_in6 *daddr_in6 = (struct sockaddr_in6 *)dst_addr; | 271 | struct sockaddr_in6 *daddr_in6 = (struct sockaddr_in6 *)dst_addr; |
258 | struct be_ctrl_info *ctrl = &phba->ctrl; | 272 | struct be_ctrl_info *ctrl = &phba->ctrl; |
259 | struct be_mcc_wrb *wrb = wrb_from_mccq(phba); | 273 | struct be_mcc_wrb *wrb; |
260 | struct tcp_connect_and_offload_in *req = embedded_payload(wrb); | 274 | struct tcp_connect_and_offload_in *req; |
261 | unsigned short def_hdr_id; | 275 | unsigned short def_hdr_id; |
262 | unsigned short def_data_id; | 276 | unsigned short def_data_id; |
263 | struct phys_addr template_address = { 0, 0 }; | 277 | struct phys_addr template_address = { 0, 0 }; |
264 | struct phys_addr *ptemplate_address; | 278 | struct phys_addr *ptemplate_address; |
265 | int status = 0; | 279 | unsigned int tag = 0; |
266 | unsigned int i; | 280 | unsigned int i; |
267 | unsigned short cid = beiscsi_ep->ep_cid; | 281 | unsigned short cid = beiscsi_ep->ep_cid; |
268 | 282 | ||
@@ -274,7 +288,14 @@ int mgmt_open_connection(struct beiscsi_hba *phba, | |||
274 | ptemplate_address = &template_address; | 288 | ptemplate_address = &template_address; |
275 | ISCSI_GET_PDU_TEMPLATE_ADDRESS(phba, ptemplate_address); | 289 | ISCSI_GET_PDU_TEMPLATE_ADDRESS(phba, ptemplate_address); |
276 | spin_lock(&ctrl->mbox_lock); | 290 | spin_lock(&ctrl->mbox_lock); |
277 | memset(wrb, 0, sizeof(*wrb)); | 291 | tag = alloc_mcc_tag(phba); |
292 | if (!tag) { | ||
293 | spin_unlock(&ctrl->mbox_lock); | ||
294 | return tag; | ||
295 | } | ||
296 | wrb = wrb_from_mccq(phba); | ||
297 | req = embedded_payload(wrb); | ||
298 | wrb->tag0 |= tag; | ||
278 | 299 | ||
279 | be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); | 300 | be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); |
280 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI, | 301 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI, |
@@ -319,47 +340,36 @@ int mgmt_open_connection(struct beiscsi_hba *phba, | |||
319 | req->do_offload = 1; | 340 | req->do_offload = 1; |
320 | req->dataout_template_pa.lo = ptemplate_address->lo; | 341 | req->dataout_template_pa.lo = ptemplate_address->lo; |
321 | req->dataout_template_pa.hi = ptemplate_address->hi; | 342 | req->dataout_template_pa.hi = ptemplate_address->hi; |
322 | status = be_mcc_notify_wait(phba); | 343 | be_mcc_notify(phba); |
323 | if (!status) { | ||
324 | struct iscsi_endpoint *ep; | ||
325 | struct tcp_connect_and_offload_out *ptcpcnct_out = | ||
326 | embedded_payload(wrb); | ||
327 | |||
328 | ep = phba->ep_array[ptcpcnct_out->cid - | ||
329 | phba->fw_config.iscsi_cid_start]; | ||
330 | beiscsi_ep = ep->dd_data; | ||
331 | beiscsi_ep->fw_handle = ptcpcnct_out->connection_handle; | ||
332 | beiscsi_ep->cid_vld = 1; | ||
333 | SE_DEBUG(DBG_LVL_8, "mgmt_open_connection Success\n"); | ||
334 | } else | ||
335 | SE_DEBUG(DBG_LVL_1, "mgmt_open_connection Failed\n"); | ||
336 | spin_unlock(&ctrl->mbox_lock); | 344 | spin_unlock(&ctrl->mbox_lock); |
337 | return status; | 345 | return tag; |
338 | } | 346 | } |
339 | 347 | ||
340 | int be_cmd_get_mac_addr(struct beiscsi_hba *phba, u8 *mac_addr) | 348 | unsigned int be_cmd_get_mac_addr(struct beiscsi_hba *phba) |
341 | { | 349 | { |
342 | struct be_ctrl_info *ctrl = &phba->ctrl; | 350 | struct be_ctrl_info *ctrl = &phba->ctrl; |
343 | struct be_mcc_wrb *wrb = wrb_from_mccq(phba); | 351 | struct be_mcc_wrb *wrb; |
344 | struct be_cmd_req_get_mac_addr *req = embedded_payload(wrb); | 352 | struct be_cmd_req_get_mac_addr *req; |
345 | int status; | 353 | unsigned int tag = 0; |
346 | 354 | ||
347 | SE_DEBUG(DBG_LVL_8, "In be_cmd_get_mac_addr\n"); | 355 | SE_DEBUG(DBG_LVL_8, "In be_cmd_get_mac_addr\n"); |
348 | spin_lock(&ctrl->mbox_lock); | 356 | spin_lock(&ctrl->mbox_lock); |
349 | memset(wrb, 0, sizeof(*wrb)); | 357 | tag = alloc_mcc_tag(phba); |
358 | if (!tag) { | ||
359 | spin_unlock(&ctrl->mbox_lock); | ||
360 | return tag; | ||
361 | } | ||
362 | |||
363 | wrb = wrb_from_mccq(phba); | ||
364 | req = embedded_payload(wrb); | ||
365 | wrb->tag0 |= tag; | ||
350 | be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); | 366 | be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); |
351 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI, | 367 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI, |
352 | OPCODE_COMMON_ISCSI_NTWK_GET_NIC_CONFIG, | 368 | OPCODE_COMMON_ISCSI_NTWK_GET_NIC_CONFIG, |
353 | sizeof(*req)); | 369 | sizeof(*req)); |
354 | 370 | ||
355 | status = be_mcc_notify_wait(phba); | 371 | be_mcc_notify(phba); |
356 | if (!status) { | ||
357 | struct be_cmd_resp_get_mac_addr *resp = embedded_payload(wrb); | ||
358 | |||
359 | memcpy(mac_addr, resp->mac_address, ETH_ALEN); | ||
360 | } | ||
361 | |||
362 | spin_unlock(&ctrl->mbox_lock); | 372 | spin_unlock(&ctrl->mbox_lock); |
363 | return status; | 373 | return tag; |
364 | } | 374 | } |
365 | 375 | ||
diff --git a/drivers/scsi/be2iscsi/be_mgmt.h b/drivers/scsi/be2iscsi/be_mgmt.h index 6bc59e8e1fe5..f873a66cd48f 100644 --- a/drivers/scsi/be2iscsi/be_mgmt.h +++ b/drivers/scsi/be2iscsi/be_mgmt.h | |||
@@ -250,7 +250,4 @@ unsigned char mgmt_invalidate_connection(struct beiscsi_hba *phba, | |||
250 | unsigned short issue_reset, | 250 | unsigned short issue_reset, |
251 | unsigned short savecfg_flag); | 251 | unsigned short savecfg_flag); |
252 | 252 | ||
253 | unsigned char mgmt_fw_cmd(struct be_ctrl_info *ctrl, | ||
254 | struct beiscsi_hba *phba, | ||
255 | char *buf, unsigned int len); | ||
256 | #endif | 253 | #endif |