diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-04 15:15:15 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-04 15:15:15 -0700 |
commit | 03da30986793385af57eeca3296253c887b742e6 (patch) | |
tree | 9c46dbe51c9d0856990649dd917ab45474b7be87 /drivers/scsi/be2iscsi/be_cmds.c | |
parent | 6ba74014c1ab0e37af7de6f64b4eccbbae3cb9e7 (diff) | |
parent | 339f4f4eab80caa6cf0d39fb057ad6ddb84ba91e (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (276 commits)
[SCSI] zfcp: Trigger logging in the FCP channel on qdio error conditions
[SCSI] zfcp: Introduce experimental support for DIF/DIX
[SCSI] zfcp: Enable data division support for FCP devices
[SCSI] zfcp: Prevent access on uninitialized memory.
[SCSI] zfcp: Post events through FC transport class
[SCSI] zfcp: Cleanup QDIO attachment and improve processing.
[SCSI] zfcp: Cleanup function parameters for sbal value.
[SCSI] zfcp: Use correct width for timer_interval field
[SCSI] zfcp: Remove SCSI device when removing unit
[SCSI] zfcp: Use memdup_user and kstrdup
[SCSI] zfcp: Fix retry after failed "open port" erp action
[SCSI] zfcp: Fail erp after timeout
[SCSI] zfcp: Use forced_reopen in terminate_rport_io callback
[SCSI] zfcp: Register SCSI devices after successful fc_remote_port_add
[SCSI] zfcp: Do not try "forced close" when port is already closed
[SCSI] zfcp: Do not unblock rport from REOPEN_PORT_FORCED
[SCSI] sd: add support for runtime PM
[SCSI] implement runtime Power Management
[SCSI] convert to the new PM framework
[SCSI] Unify SAM_ and SAM_STAT_ macros
...
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 cda6642c736..7c7537335c8 100644 --- a/drivers/scsi/be2iscsi/be_cmds.c +++ b/drivers/scsi/be2iscsi/be_cmds.c @@ -19,6 +19,86 @@ #include "be_mgmt.h" #include "be_main.h" +int beiscsi_pci_soft_reset(struct beiscsi_hba *phba) +{ + u32 sreset; + u8 *pci_reset_offset = 0; + u8 *pci_online0_offset = 0; + u8 *pci_online1_offset = 0; + u32 pconline0 = 0; + u32 pconline1 = 0; + u32 i; + + pci_reset_offset = (u8 *)phba->pci_va + BE2_SOFT_RESET; + pci_online0_offset = (u8 *)phba->pci_va + BE2_PCI_ONLINE0; + pci_online1_offset = (u8 *)phba->pci_va + BE2_PCI_ONLINE1; + sreset = readl((void *)pci_reset_offset); + sreset |= BE2_SET_RESET; + writel(sreset, (void *)pci_reset_offset); + + i = 0; + while (sreset & BE2_SET_RESET) { + if (i > 64) + break; + msleep(100); + sreset = readl((void *)pci_reset_offset); + i++; + } + + if (sreset & BE2_SET_RESET) { + printk(KERN_ERR "Soft Reset did not deassert\n"); + return -EIO; + } + pconline1 = BE2_MPU_IRAM_ONLINE; + writel(pconline0, (void *)pci_online0_offset); + writel(pconline1, (void *)pci_online1_offset); + + sreset = BE2_SET_RESET; + writel(sreset, (void *)pci_reset_offset); + + i = 0; + while (sreset & BE2_SET_RESET) { + if (i > 64) + break; + msleep(1); + sreset = readl((void *)pci_reset_offset); + i++; + } + if (sreset & BE2_SET_RESET) { + printk(KERN_ERR "MPU Online Soft Reset did not deassert\n"); + return -EIO; + } + return 0; +} + +int be_chk_reset_complete(struct beiscsi_hba *phba) +{ + unsigned int num_loop; + u8 *mpu_sem = 0; + u32 status; + + num_loop = 1000; + mpu_sem = (u8 *)phba->csr_va + MPU_EP_SEMAPHORE; + msleep(5000); + + while (num_loop) { + status = readl((void *)mpu_sem); + + if ((status & 0x80000000) || (status & 0x0000FFFF) == 0xC000) + break; + msleep(60); + num_loop--; + } + + if ((status & 0x80000000) || (!num_loop)) { + printk(KERN_ERR "Failed in be_chk_reset_complete" + "status = 0x%x\n", status); + return -EIO; + } + + return 0; +} + void be_mcc_notify(struct beiscsi_hba *phba) { 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, dev_err(&ctrl->pdev->dev, "error in cmd completion: status(compl/extd)=%d/%d\n", compl_status, extd_status); - return -1; + return -EBUSY; } return 0; } @@ -151,20 +231,20 @@ void beiscsi_async_link_state_process(struct beiscsi_hba *phba, { switch (evt->port_link_status) { case ASYNC_EVENT_LINK_DOWN: - SE_DEBUG(DBG_LVL_1, "Link Down on Physical Port %d \n", - evt->physical_port); + SE_DEBUG(DBG_LVL_1, "Link Down on Physical Port %d\n", + evt->physical_port); phba->state |= BE_ADAPTER_LINK_DOWN; iscsi_host_for_each_session(phba->shost, be2iscsi_fail_session); break; case ASYNC_EVENT_LINK_UP: phba->state = BE_ADAPTER_UP; - SE_DEBUG(DBG_LVL_1, "Link UP on Physical Port %d \n", + SE_DEBUG(DBG_LVL_1, "Link UP on Physical Port %d\n", evt->physical_port); break; default: SE_DEBUG(DBG_LVL_1, "Unexpected Async Notification %d on" - "Physical Port %d \n", + "Physical Port %d\n", evt->port_link_status, evt->physical_port); } @@ -199,7 +279,7 @@ int beiscsi_process_mcc(struct beiscsi_hba *phba) else SE_DEBUG(DBG_LVL_1, " Unsupported Async Event, flags" - " = 0x%08x \n", compl->flags); + " = 0x%08x\n", compl->flags); } else if (compl->flags & CQE_FLAGS_COMPLETED_MASK) { status = be_mcc_compl_process(ctrl, compl); @@ -231,7 +311,7 @@ static int be_mcc_wait_compl(struct beiscsi_hba *phba) } if (i == mcc_timeout) { dev_err(&phba->pcidev->dev, "mccq poll timed out\n"); - return -1; + return -EBUSY; } return 0; } @@ -257,7 +337,7 @@ static int be_mbox_db_ready_wait(struct be_ctrl_info *ctrl) if (cnt > 6000000) { dev_err(&ctrl->pdev->dev, "mbox_db poll timed out\n"); - return -1; + return -EBUSY; } if (cnt > 50) { @@ -286,7 +366,7 @@ int be_mbox_notify(struct be_ctrl_info *ctrl) status = be_mbox_db_ready_wait(ctrl); if (status != 0) { - SE_DEBUG(DBG_LVL_1, " be_mbox_db_ready_wait failed 1\n"); + SE_DEBUG(DBG_LVL_1, " be_mbox_db_ready_wait failed\n"); return status; } val = 0; @@ -297,19 +377,19 @@ int be_mbox_notify(struct be_ctrl_info *ctrl) status = be_mbox_db_ready_wait(ctrl); if (status != 0) { - SE_DEBUG(DBG_LVL_1, " be_mbox_db_ready_wait failed 2\n"); + SE_DEBUG(DBG_LVL_1, " be_mbox_db_ready_wait failed\n"); return status; } if (be_mcc_compl_is_new(compl)) { status = be_mcc_compl_process(ctrl, &mbox->compl); be_mcc_compl_use(compl); if (status) { - SE_DEBUG(DBG_LVL_1, "After be_mcc_compl_process \n"); + SE_DEBUG(DBG_LVL_1, "After be_mcc_compl_process\n"); return status; } } else { dev_err(&ctrl->pdev->dev, "invalid mailbox completion\n"); - return -1; + return -EBUSY; } return 0; } @@ -355,7 +435,7 @@ static int be_mbox_notify_wait(struct beiscsi_hba *phba) return status; } else { dev_err(&phba->pcidev->dev, "invalid mailbox completion\n"); - return -1; + return -EBUSY; } return 0; } @@ -500,7 +580,7 @@ int be_cmd_fw_initialize(struct be_ctrl_info *ctrl) status = be_mbox_notify(ctrl); if (status) - SE_DEBUG(DBG_LVL_1, "be_cmd_fw_initialize Failed \n"); + SE_DEBUG(DBG_LVL_1, "be_cmd_fw_initialize Failed\n"); spin_unlock(&ctrl->mbox_lock); return status; @@ -517,7 +597,7 @@ int beiscsi_cmd_cq_create(struct be_ctrl_info *ctrl, void *ctxt = &req->context; int status; - SE_DEBUG(DBG_LVL_8, "In beiscsi_cmd_cq_create \n"); + SE_DEBUG(DBG_LVL_8, "In beiscsi_cmd_cq_create\n"); spin_lock(&ctrl->mbox_lock); memset(wrb, 0, sizeof(*wrb)); @@ -550,7 +630,7 @@ int beiscsi_cmd_cq_create(struct be_ctrl_info *ctrl, cq->id = le16_to_cpu(resp->cq_id); cq->created = true; } else - SE_DEBUG(DBG_LVL_1, "In be_cmd_cq_create, status=ox%08x \n", + SE_DEBUG(DBG_LVL_1, "In be_cmd_cq_create, status=ox%08x\n", status); spin_unlock(&ctrl->mbox_lock); @@ -619,7 +699,7 @@ int beiscsi_cmd_q_destroy(struct be_ctrl_info *ctrl, struct be_queue_info *q, u8 subsys = 0, opcode = 0; int status; - SE_DEBUG(DBG_LVL_8, "In beiscsi_cmd_q_destroy \n"); + SE_DEBUG(DBG_LVL_8, "In beiscsi_cmd_q_destroy\n"); spin_lock(&ctrl->mbox_lock); memset(wrb, 0, sizeof(*wrb)); 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, default: spin_unlock(&ctrl->mbox_lock); BUG(); - return -1; + return -ENXIO; } be_cmd_hdr_prepare(&req->hdr, subsys, opcode, sizeof(*req)); if (queue_type != QTYPE_SGL) |