diff options
Diffstat (limited to 'drivers/scsi/be2iscsi/be_cmds.c')
-rw-r--r-- | drivers/scsi/be2iscsi/be_cmds.c | 116 |
1 files changed, 98 insertions, 18 deletions
diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c index cda6642c7368..7c7537335c88 100644 --- a/drivers/scsi/be2iscsi/be_cmds.c +++ b/drivers/scsi/be2iscsi/be_cmds.c | |||
@@ -19,6 +19,86 @@ | |||
19 | #include "be_mgmt.h" | 19 | #include "be_mgmt.h" |
20 | #include "be_main.h" | 20 | #include "be_main.h" |
21 | 21 | ||
22 | int beiscsi_pci_soft_reset(struct beiscsi_hba *phba) | ||
23 | { | ||
24 | u32 sreset; | ||
25 | u8 *pci_reset_offset = 0; | ||
26 | u8 *pci_online0_offset = 0; | ||
27 | u8 *pci_online1_offset = 0; | ||
28 | u32 pconline0 = 0; | ||
29 | u32 pconline1 = 0; | ||
30 | u32 i; | ||
31 | |||
32 | pci_reset_offset = (u8 *)phba->pci_va + BE2_SOFT_RESET; | ||
33 | pci_online0_offset = (u8 *)phba->pci_va + BE2_PCI_ONLINE0; | ||
34 | pci_online1_offset = (u8 *)phba->pci_va + BE2_PCI_ONLINE1; | ||
35 | sreset = readl((void *)pci_reset_offset); | ||
36 | sreset |= BE2_SET_RESET; | ||
37 | writel(sreset, (void *)pci_reset_offset); | ||
38 | |||
39 | i = 0; | ||
40 | while (sreset & BE2_SET_RESET) { | ||
41 | if (i > 64) | ||
42 | break; | ||
43 | msleep(100); | ||
44 | sreset = readl((void *)pci_reset_offset); | ||
45 | i++; | ||
46 | } | ||
47 | |||
48 | if (sreset & BE2_SET_RESET) { | ||
49 | printk(KERN_ERR "Soft Reset did not deassert\n"); | ||
50 | return -EIO; | ||
51 | } | ||
52 | pconline1 = BE2_MPU_IRAM_ONLINE; | ||
53 | writel(pconline0, (void *)pci_online0_offset); | ||
54 | writel(pconline1, (void *)pci_online1_offset); | ||
55 | |||
56 | sreset = BE2_SET_RESET; | ||
57 | writel(sreset, (void *)pci_reset_offset); | ||
58 | |||
59 | i = 0; | ||
60 | while (sreset & BE2_SET_RESET) { | ||
61 | if (i > 64) | ||
62 | break; | ||
63 | msleep(1); | ||
64 | sreset = readl((void *)pci_reset_offset); | ||
65 | i++; | ||
66 | } | ||
67 | if (sreset & BE2_SET_RESET) { | ||
68 | printk(KERN_ERR "MPU Online Soft Reset did not deassert\n"); | ||
69 | return -EIO; | ||
70 | } | ||
71 | return 0; | ||
72 | } | ||
73 | |||
74 | int be_chk_reset_complete(struct beiscsi_hba *phba) | ||
75 | { | ||
76 | unsigned int num_loop; | ||
77 | u8 *mpu_sem = 0; | ||
78 | u32 status; | ||
79 | |||
80 | num_loop = 1000; | ||
81 | mpu_sem = (u8 *)phba->csr_va + MPU_EP_SEMAPHORE; | ||
82 | msleep(5000); | ||
83 | |||
84 | while (num_loop) { | ||
85 | status = readl((void *)mpu_sem); | ||
86 | |||
87 | if ((status & 0x80000000) || (status & 0x0000FFFF) == 0xC000) | ||
88 | break; | ||
89 | msleep(60); | ||
90 | num_loop--; | ||
91 | } | ||
92 | |||
93 | if ((status & 0x80000000) || (!num_loop)) { | ||
94 | printk(KERN_ERR "Failed in be_chk_reset_complete" | ||
95 | "status = 0x%x\n", status); | ||
96 | return -EIO; | ||
97 | } | ||
98 | |||
99 | return 0; | ||
100 | } | ||
101 | |||
22 | void be_mcc_notify(struct beiscsi_hba *phba) | 102 | void be_mcc_notify(struct beiscsi_hba *phba) |
23 | { | 103 | { |
24 | struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q; | 104 | struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q; |
@@ -98,7 +178,7 @@ static int be_mcc_compl_process(struct be_ctrl_info *ctrl, | |||
98 | dev_err(&ctrl->pdev->dev, | 178 | dev_err(&ctrl->pdev->dev, |
99 | "error in cmd completion: status(compl/extd)=%d/%d\n", | 179 | "error in cmd completion: status(compl/extd)=%d/%d\n", |
100 | compl_status, extd_status); | 180 | compl_status, extd_status); |
101 | return -1; | 181 | return -EBUSY; |
102 | } | 182 | } |
103 | return 0; | 183 | return 0; |
104 | } | 184 | } |
@@ -151,20 +231,20 @@ void beiscsi_async_link_state_process(struct beiscsi_hba *phba, | |||
151 | { | 231 | { |
152 | switch (evt->port_link_status) { | 232 | switch (evt->port_link_status) { |
153 | case ASYNC_EVENT_LINK_DOWN: | 233 | case ASYNC_EVENT_LINK_DOWN: |
154 | SE_DEBUG(DBG_LVL_1, "Link Down on Physical Port %d \n", | 234 | SE_DEBUG(DBG_LVL_1, "Link Down on Physical Port %d\n", |
155 | evt->physical_port); | 235 | evt->physical_port); |
156 | phba->state |= BE_ADAPTER_LINK_DOWN; | 236 | phba->state |= BE_ADAPTER_LINK_DOWN; |
157 | iscsi_host_for_each_session(phba->shost, | 237 | iscsi_host_for_each_session(phba->shost, |
158 | be2iscsi_fail_session); | 238 | be2iscsi_fail_session); |
159 | break; | 239 | break; |
160 | case ASYNC_EVENT_LINK_UP: | 240 | case ASYNC_EVENT_LINK_UP: |
161 | phba->state = BE_ADAPTER_UP; | 241 | phba->state = BE_ADAPTER_UP; |
162 | SE_DEBUG(DBG_LVL_1, "Link UP on Physical Port %d \n", | 242 | SE_DEBUG(DBG_LVL_1, "Link UP on Physical Port %d\n", |
163 | evt->physical_port); | 243 | evt->physical_port); |
164 | break; | 244 | break; |
165 | default: | 245 | default: |
166 | SE_DEBUG(DBG_LVL_1, "Unexpected Async Notification %d on" | 246 | SE_DEBUG(DBG_LVL_1, "Unexpected Async Notification %d on" |
167 | "Physical Port %d \n", | 247 | "Physical Port %d\n", |
168 | evt->port_link_status, | 248 | evt->port_link_status, |
169 | evt->physical_port); | 249 | evt->physical_port); |
170 | } | 250 | } |
@@ -199,7 +279,7 @@ int beiscsi_process_mcc(struct beiscsi_hba *phba) | |||
199 | else | 279 | else |
200 | SE_DEBUG(DBG_LVL_1, | 280 | SE_DEBUG(DBG_LVL_1, |
201 | " Unsupported Async Event, flags" | 281 | " Unsupported Async Event, flags" |
202 | " = 0x%08x \n", compl->flags); | 282 | " = 0x%08x\n", compl->flags); |
203 | 283 | ||
204 | } else if (compl->flags & CQE_FLAGS_COMPLETED_MASK) { | 284 | } else if (compl->flags & CQE_FLAGS_COMPLETED_MASK) { |
205 | status = be_mcc_compl_process(ctrl, compl); | 285 | status = be_mcc_compl_process(ctrl, compl); |
@@ -231,7 +311,7 @@ static int be_mcc_wait_compl(struct beiscsi_hba *phba) | |||
231 | } | 311 | } |
232 | if (i == mcc_timeout) { | 312 | if (i == mcc_timeout) { |
233 | dev_err(&phba->pcidev->dev, "mccq poll timed out\n"); | 313 | dev_err(&phba->pcidev->dev, "mccq poll timed out\n"); |
234 | return -1; | 314 | return -EBUSY; |
235 | } | 315 | } |
236 | return 0; | 316 | return 0; |
237 | } | 317 | } |
@@ -257,7 +337,7 @@ static int be_mbox_db_ready_wait(struct be_ctrl_info *ctrl) | |||
257 | 337 | ||
258 | if (cnt > 6000000) { | 338 | if (cnt > 6000000) { |
259 | dev_err(&ctrl->pdev->dev, "mbox_db poll timed out\n"); | 339 | dev_err(&ctrl->pdev->dev, "mbox_db poll timed out\n"); |
260 | return -1; | 340 | return -EBUSY; |
261 | } | 341 | } |
262 | 342 | ||
263 | if (cnt > 50) { | 343 | if (cnt > 50) { |
@@ -286,7 +366,7 @@ int be_mbox_notify(struct be_ctrl_info *ctrl) | |||
286 | 366 | ||
287 | status = be_mbox_db_ready_wait(ctrl); | 367 | status = be_mbox_db_ready_wait(ctrl); |
288 | if (status != 0) { | 368 | if (status != 0) { |
289 | SE_DEBUG(DBG_LVL_1, " be_mbox_db_ready_wait failed 1\n"); | 369 | SE_DEBUG(DBG_LVL_1, " be_mbox_db_ready_wait failed\n"); |
290 | return status; | 370 | return status; |
291 | } | 371 | } |
292 | val = 0; | 372 | val = 0; |
@@ -297,19 +377,19 @@ int be_mbox_notify(struct be_ctrl_info *ctrl) | |||
297 | 377 | ||
298 | status = be_mbox_db_ready_wait(ctrl); | 378 | status = be_mbox_db_ready_wait(ctrl); |
299 | if (status != 0) { | 379 | if (status != 0) { |
300 | SE_DEBUG(DBG_LVL_1, " be_mbox_db_ready_wait failed 2\n"); | 380 | SE_DEBUG(DBG_LVL_1, " be_mbox_db_ready_wait failed\n"); |
301 | return status; | 381 | return status; |
302 | } | 382 | } |
303 | if (be_mcc_compl_is_new(compl)) { | 383 | if (be_mcc_compl_is_new(compl)) { |
304 | status = be_mcc_compl_process(ctrl, &mbox->compl); | 384 | status = be_mcc_compl_process(ctrl, &mbox->compl); |
305 | be_mcc_compl_use(compl); | 385 | be_mcc_compl_use(compl); |
306 | if (status) { | 386 | if (status) { |
307 | SE_DEBUG(DBG_LVL_1, "After be_mcc_compl_process \n"); | 387 | SE_DEBUG(DBG_LVL_1, "After be_mcc_compl_process\n"); |
308 | return status; | 388 | return status; |
309 | } | 389 | } |
310 | } else { | 390 | } else { |
311 | dev_err(&ctrl->pdev->dev, "invalid mailbox completion\n"); | 391 | dev_err(&ctrl->pdev->dev, "invalid mailbox completion\n"); |
312 | return -1; | 392 | return -EBUSY; |
313 | } | 393 | } |
314 | return 0; | 394 | return 0; |
315 | } | 395 | } |
@@ -355,7 +435,7 @@ static int be_mbox_notify_wait(struct beiscsi_hba *phba) | |||
355 | return status; | 435 | return status; |
356 | } else { | 436 | } else { |
357 | dev_err(&phba->pcidev->dev, "invalid mailbox completion\n"); | 437 | dev_err(&phba->pcidev->dev, "invalid mailbox completion\n"); |
358 | return -1; | 438 | return -EBUSY; |
359 | } | 439 | } |
360 | return 0; | 440 | return 0; |
361 | } | 441 | } |
@@ -500,7 +580,7 @@ int be_cmd_fw_initialize(struct be_ctrl_info *ctrl) | |||
500 | 580 | ||
501 | status = be_mbox_notify(ctrl); | 581 | status = be_mbox_notify(ctrl); |
502 | if (status) | 582 | if (status) |
503 | SE_DEBUG(DBG_LVL_1, "be_cmd_fw_initialize Failed \n"); | 583 | SE_DEBUG(DBG_LVL_1, "be_cmd_fw_initialize Failed\n"); |
504 | 584 | ||
505 | spin_unlock(&ctrl->mbox_lock); | 585 | spin_unlock(&ctrl->mbox_lock); |
506 | return status; | 586 | return status; |
@@ -517,7 +597,7 @@ int beiscsi_cmd_cq_create(struct be_ctrl_info *ctrl, | |||
517 | void *ctxt = &req->context; | 597 | void *ctxt = &req->context; |
518 | int status; | 598 | int status; |
519 | 599 | ||
520 | SE_DEBUG(DBG_LVL_8, "In beiscsi_cmd_cq_create \n"); | 600 | SE_DEBUG(DBG_LVL_8, "In beiscsi_cmd_cq_create\n"); |
521 | spin_lock(&ctrl->mbox_lock); | 601 | spin_lock(&ctrl->mbox_lock); |
522 | memset(wrb, 0, sizeof(*wrb)); | 602 | memset(wrb, 0, sizeof(*wrb)); |
523 | 603 | ||
@@ -550,7 +630,7 @@ int beiscsi_cmd_cq_create(struct be_ctrl_info *ctrl, | |||
550 | cq->id = le16_to_cpu(resp->cq_id); | 630 | cq->id = le16_to_cpu(resp->cq_id); |
551 | cq->created = true; | 631 | cq->created = true; |
552 | } else | 632 | } else |
553 | SE_DEBUG(DBG_LVL_1, "In be_cmd_cq_create, status=ox%08x \n", | 633 | SE_DEBUG(DBG_LVL_1, "In be_cmd_cq_create, status=ox%08x\n", |
554 | status); | 634 | status); |
555 | spin_unlock(&ctrl->mbox_lock); | 635 | spin_unlock(&ctrl->mbox_lock); |
556 | 636 | ||
@@ -619,7 +699,7 @@ int beiscsi_cmd_q_destroy(struct be_ctrl_info *ctrl, struct be_queue_info *q, | |||
619 | u8 subsys = 0, opcode = 0; | 699 | u8 subsys = 0, opcode = 0; |
620 | int status; | 700 | int status; |
621 | 701 | ||
622 | SE_DEBUG(DBG_LVL_8, "In beiscsi_cmd_q_destroy \n"); | 702 | SE_DEBUG(DBG_LVL_8, "In beiscsi_cmd_q_destroy\n"); |
623 | spin_lock(&ctrl->mbox_lock); | 703 | spin_lock(&ctrl->mbox_lock); |
624 | memset(wrb, 0, sizeof(*wrb)); | 704 | memset(wrb, 0, sizeof(*wrb)); |
625 | be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); | 705 | be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); |
@@ -652,7 +732,7 @@ int beiscsi_cmd_q_destroy(struct be_ctrl_info *ctrl, struct be_queue_info *q, | |||
652 | default: | 732 | default: |
653 | spin_unlock(&ctrl->mbox_lock); | 733 | spin_unlock(&ctrl->mbox_lock); |
654 | BUG(); | 734 | BUG(); |
655 | return -1; | 735 | return -ENXIO; |
656 | } | 736 | } |
657 | be_cmd_hdr_prepare(&req->hdr, subsys, opcode, sizeof(*req)); | 737 | be_cmd_hdr_prepare(&req->hdr, subsys, opcode, sizeof(*req)); |
658 | if (queue_type != QTYPE_SGL) | 738 | if (queue_type != QTYPE_SGL) |