diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-10-28 16:44:18 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-10-28 16:44:18 -0700 |
commit | ec7ae517537ae5c7b0b2cd7f562dfa3e7a05b954 (patch) | |
tree | e6b0c64a51a7c0aa0efd09d4f7a80872e3b1657a /drivers/scsi/be2iscsi | |
parent | 97d2eb13a019ec09cc1a7ea2d3705c0b117b3c0d (diff) | |
parent | 590134fa78fbdbe5fea78c7ae0b2c3364bc9572f (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: (204 commits)
[SCSI] qla4xxx: export address/port of connection (fix udev disk names)
[SCSI] ipr: Fix BUG on adapter dump timeout
[SCSI] megaraid_sas: Fix instance access in megasas_reset_timer
[SCSI] hpsa: change confusing message to be more clear
[SCSI] iscsi class: fix vlan configuration
[SCSI] qla4xxx: fix data alignment and use nl helpers
[SCSI] iscsi class: fix link local mispelling
[SCSI] iscsi class: Replace iscsi_get_next_target_id with IDA
[SCSI] aacraid: use lower snprintf() limit
[SCSI] lpfc 8.3.27: Change driver version to 8.3.27
[SCSI] lpfc 8.3.27: T10 additions for SLI4
[SCSI] lpfc 8.3.27: Fix queue allocation failure recovery
[SCSI] lpfc 8.3.27: Change algorithm for getting physical port name
[SCSI] lpfc 8.3.27: Changed worst case mailbox timeout
[SCSI] lpfc 8.3.27: Miscellanous logic and interface fixes
[SCSI] megaraid_sas: Changelog and version update
[SCSI] megaraid_sas: Add driver workaround for PERC5/1068 kdump kernel panic
[SCSI] megaraid_sas: Add multiple MSI-X vector/multiple reply queue support
[SCSI] megaraid_sas: Add support for MegaRAID 9360/9380 12GB/s controllers
[SCSI] megaraid_sas: Clear FUSION_IN_RESET before enabling interrupts
...
Diffstat (limited to 'drivers/scsi/be2iscsi')
-rw-r--r-- | drivers/scsi/be2iscsi/be_cmds.c | 20 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_cmds.h | 2 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_iscsi.c | 60 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_iscsi.h | 2 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_main.c | 112 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_main.h | 5 |
6 files changed, 151 insertions, 50 deletions
diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c index b8a82f2c62c..cdb15364bc6 100644 --- a/drivers/scsi/be2iscsi/be_cmds.c +++ b/drivers/scsi/be2iscsi/be_cmds.c @@ -660,6 +660,7 @@ int beiscsi_cmd_mccq_create(struct beiscsi_hba *phba, spin_lock(&phba->ctrl.mbox_lock); ctrl = &phba->ctrl; wrb = wrb_from_mbox(&ctrl->mbox_mem); + memset(wrb, 0, sizeof(*wrb)); req = embedded_payload(wrb); ctxt = &req->context; @@ -868,3 +869,22 @@ error: beiscsi_cmd_q_destroy(ctrl, NULL, QTYPE_SGL); return status; } + +int beiscsi_cmd_reset_function(struct beiscsi_hba *phba) +{ + struct be_ctrl_info *ctrl = &phba->ctrl; + struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); + struct be_post_sgl_pages_req *req = embedded_payload(wrb); + int status; + + spin_lock(&ctrl->mbox_lock); + + req = embedded_payload(wrb); + be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); + be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, + OPCODE_COMMON_FUNCTION_RESET, sizeof(*req)); + status = be_mbox_notify_wait(phba); + + spin_unlock(&ctrl->mbox_lock); + return status; +} diff --git a/drivers/scsi/be2iscsi/be_cmds.h b/drivers/scsi/be2iscsi/be_cmds.h index 497eb29e5c9..8b40a5b4366 100644 --- a/drivers/scsi/be2iscsi/be_cmds.h +++ b/drivers/scsi/be2iscsi/be_cmds.h @@ -561,6 +561,8 @@ int be_cmd_iscsi_post_sgl_pages(struct be_ctrl_info *ctrl, struct be_dma_mem *q_mem, u32 page_offset, u32 num_pages); +int beiscsi_cmd_reset_function(struct beiscsi_hba *phba); + int be_cmd_wrbq_create(struct be_ctrl_info *ctrl, struct be_dma_mem *q_mem, struct be_queue_info *wrbq); diff --git a/drivers/scsi/be2iscsi/be_iscsi.c b/drivers/scsi/be2iscsi/be_iscsi.c index 3cad1060502..8b002f6db6c 100644 --- a/drivers/scsi/be2iscsi/be_iscsi.c +++ b/drivers/scsi/be2iscsi/be_iscsi.c @@ -177,9 +177,8 @@ int beiscsi_conn_bind(struct iscsi_cls_session *cls_session, { struct iscsi_conn *conn = cls_conn->dd_data; struct beiscsi_conn *beiscsi_conn = conn->dd_data; - struct Scsi_Host *shost = - (struct Scsi_Host *)iscsi_session_to_shost(cls_session); - struct beiscsi_hba *phba = (struct beiscsi_hba *)iscsi_host_priv(shost); + struct Scsi_Host *shost = iscsi_session_to_shost(cls_session); + struct beiscsi_hba *phba = iscsi_host_priv(shost); struct beiscsi_endpoint *beiscsi_ep; struct iscsi_endpoint *ep; @@ -290,7 +289,7 @@ int beiscsi_set_param(struct iscsi_cls_conn *cls_conn, int beiscsi_get_host_param(struct Scsi_Host *shost, enum iscsi_host_param param, char *buf) { - struct beiscsi_hba *phba = (struct beiscsi_hba *)iscsi_host_priv(shost); + struct beiscsi_hba *phba = iscsi_host_priv(shost); int status = 0; SE_DEBUG(DBG_LVL_8, "In beiscsi_get_host_param, param= %d\n", param); @@ -733,3 +732,56 @@ void beiscsi_ep_disconnect(struct iscsi_endpoint *ep) beiscsi_unbind_conn_to_cid(phba, beiscsi_ep->ep_cid); iscsi_destroy_endpoint(beiscsi_ep->openiscsi_ep); } + +mode_t be2iscsi_attr_is_visible(int param_type, int param) +{ + switch (param_type) { + case ISCSI_HOST_PARAM: + switch (param) { + case ISCSI_HOST_PARAM_HWADDRESS: + case ISCSI_HOST_PARAM_IPADDRESS: + case ISCSI_HOST_PARAM_INITIATOR_NAME: + return S_IRUGO; + default: + return 0; + } + case ISCSI_PARAM: + switch (param) { + case ISCSI_PARAM_MAX_RECV_DLENGTH: + case ISCSI_PARAM_MAX_XMIT_DLENGTH: + case ISCSI_PARAM_HDRDGST_EN: + case ISCSI_PARAM_DATADGST_EN: + case ISCSI_PARAM_CONN_ADDRESS: + case ISCSI_PARAM_CONN_PORT: + case ISCSI_PARAM_EXP_STATSN: + case ISCSI_PARAM_PERSISTENT_ADDRESS: + case ISCSI_PARAM_PERSISTENT_PORT: + case ISCSI_PARAM_PING_TMO: + case ISCSI_PARAM_RECV_TMO: + case ISCSI_PARAM_INITIAL_R2T_EN: + case ISCSI_PARAM_MAX_R2T: + case ISCSI_PARAM_IMM_DATA_EN: + case ISCSI_PARAM_FIRST_BURST: + case ISCSI_PARAM_MAX_BURST: + case ISCSI_PARAM_PDU_INORDER_EN: + case ISCSI_PARAM_DATASEQ_INORDER_EN: + case ISCSI_PARAM_ERL: + case ISCSI_PARAM_TARGET_NAME: + case ISCSI_PARAM_TPGT: + case ISCSI_PARAM_USERNAME: + case ISCSI_PARAM_PASSWORD: + case ISCSI_PARAM_USERNAME_IN: + case ISCSI_PARAM_PASSWORD_IN: + case ISCSI_PARAM_FAST_ABORT: + case ISCSI_PARAM_ABORT_TMO: + case ISCSI_PARAM_LU_RESET_TMO: + case ISCSI_PARAM_IFACE_NAME: + case ISCSI_PARAM_INITIATOR_NAME: + return S_IRUGO; + default: + return 0; + } + } + + return 0; +} diff --git a/drivers/scsi/be2iscsi/be_iscsi.h b/drivers/scsi/be2iscsi/be_iscsi.h index ff60b7fd92d..4a1f2e393f3 100644 --- a/drivers/scsi/be2iscsi/be_iscsi.h +++ b/drivers/scsi/be2iscsi/be_iscsi.h @@ -26,6 +26,8 @@ #define BE2_IPV4 0x1 #define BE2_IPV6 0x10 +mode_t be2iscsi_attr_is_visible(int param_type, int param); + void beiscsi_offload_connection(struct beiscsi_conn *beiscsi_conn, struct beiscsi_offload_params *params); diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c index 0a9bdfa3d93..7b0a8ab7104 100644 --- a/drivers/scsi/be2iscsi/be_main.c +++ b/drivers/scsi/be2iscsi/be_main.c @@ -822,33 +822,47 @@ static int beiscsi_init_irqs(struct beiscsi_hba *phba) struct hwi_controller *phwi_ctrlr; struct hwi_context_memory *phwi_context; int ret, msix_vec, i, j; - char desc[32]; phwi_ctrlr = phba->phwi_ctrlr; phwi_context = phwi_ctrlr->phwi_ctxt; if (phba->msix_enabled) { for (i = 0; i < phba->num_cpus; i++) { - sprintf(desc, "beiscsi_msix_%04x", i); + phba->msi_name[i] = kzalloc(BEISCSI_MSI_NAME, + GFP_KERNEL); + if (!phba->msi_name[i]) { + ret = -ENOMEM; + goto free_msix_irqs; + } + + sprintf(phba->msi_name[i], "beiscsi_%02x_%02x", + phba->shost->host_no, i); msix_vec = phba->msix_entries[i].vector; - ret = request_irq(msix_vec, be_isr_msix, 0, desc, + ret = request_irq(msix_vec, be_isr_msix, 0, + phba->msi_name[i], &phwi_context->be_eq[i]); if (ret) { shost_printk(KERN_ERR, phba->shost, "beiscsi_init_irqs-Failed to" "register msix for i = %d\n", i); - if (!i) - return ret; + kfree(phba->msi_name[i]); goto free_msix_irqs; } } + phba->msi_name[i] = kzalloc(BEISCSI_MSI_NAME, GFP_KERNEL); + if (!phba->msi_name[i]) { + ret = -ENOMEM; + goto free_msix_irqs; + } + sprintf(phba->msi_name[i], "beiscsi_mcc_%02x", + phba->shost->host_no); msix_vec = phba->msix_entries[i].vector; - ret = request_irq(msix_vec, be_isr_mcc, 0, "beiscsi_msix_mcc", + ret = request_irq(msix_vec, be_isr_mcc, 0, phba->msi_name[i], &phwi_context->be_eq[i]); if (ret) { shost_printk(KERN_ERR, phba->shost, "beiscsi_init_irqs-" "Failed to register beiscsi_msix_mcc\n"); - i++; + kfree(phba->msi_name[i]); goto free_msix_irqs; } @@ -863,8 +877,11 @@ static int beiscsi_init_irqs(struct beiscsi_hba *phba) } return 0; free_msix_irqs: - for (j = i - 1; j == 0; j++) + for (j = i - 1; j >= 0; j--) { + kfree(phba->msi_name[j]); + msix_vec = phba->msix_entries[j].vector; free_irq(msix_vec, &phwi_context->be_eq[j]); + } return ret; } @@ -1106,7 +1123,12 @@ be_complete_io(struct beiscsi_conn *beiscsi_conn, & SOL_STS_MASK) >> 8); flags = ((psol->dw[offsetof(struct amap_sol_cqe, i_flags) / 32] & SOL_FLAGS_MASK) >> 24) | 0x80; + if (!task->sc) { + if (io_task->scsi_cmnd) + scsi_dma_unmap(io_task->scsi_cmnd); + return; + } task->sc->result = (DID_OK << 16) | status; if (rsp != ISCSI_STATUS_CMD_COMPLETED) { task->sc->result = DID_ERROR << 16; @@ -4027,11 +4049,11 @@ static int beiscsi_mtask(struct iscsi_task *task) TGT_DM_CMD); AMAP_SET_BITS(struct amap_iscsi_wrb, cmdsn_itt, pwrb, 0); - AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0); + AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 1); } else { AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, INI_RD_CMD); - AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 1); + AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0); } hwi_write_buffer(pwrb, task); break; @@ -4102,9 +4124,8 @@ static int beiscsi_task_xmit(struct iscsi_task *task) return beiscsi_iotask(task, sg, num_sg, xferlen, writedir); } -static void beiscsi_remove(struct pci_dev *pcidev) +static void beiscsi_quiesce(struct beiscsi_hba *phba) { - struct beiscsi_hba *phba = NULL; struct hwi_controller *phwi_ctrlr; struct hwi_context_memory *phwi_context; struct be_eq_obj *pbe_eq; @@ -4112,12 +4133,6 @@ static void beiscsi_remove(struct pci_dev *pcidev) u8 *real_offset = 0; u32 value = 0; - phba = (struct beiscsi_hba *)pci_get_drvdata(pcidev); - if (!phba) { - dev_err(&pcidev->dev, "beiscsi_remove called with no phba\n"); - return; - } - phwi_ctrlr = phba->phwi_ctrlr; phwi_context = phwi_ctrlr->phwi_ctxt; hwi_disable_intr(phba); @@ -4125,6 +4140,7 @@ static void beiscsi_remove(struct pci_dev *pcidev) for (i = 0; i <= phba->num_cpus; i++) { msix_vec = phba->msix_entries[i].vector; free_irq(msix_vec, &phwi_context->be_eq[i]); + kfree(phba->msi_name[i]); } } else if (phba->pcidev->irq) @@ -4152,10 +4168,40 @@ static void beiscsi_remove(struct pci_dev *pcidev) phba->ctrl.mbox_mem_alloced.size, phba->ctrl.mbox_mem_alloced.va, phba->ctrl.mbox_mem_alloced.dma); +} + +static void beiscsi_remove(struct pci_dev *pcidev) +{ + + struct beiscsi_hba *phba = NULL; + + phba = pci_get_drvdata(pcidev); + if (!phba) { + dev_err(&pcidev->dev, "beiscsi_remove called with no phba\n"); + return; + } + + beiscsi_quiesce(phba); iscsi_boot_destroy_kset(phba->boot_kset); iscsi_host_remove(phba->shost); pci_dev_put(phba->pcidev); iscsi_host_free(phba->shost); + pci_disable_device(pcidev); +} + +static void beiscsi_shutdown(struct pci_dev *pcidev) +{ + + struct beiscsi_hba *phba = NULL; + + phba = (struct beiscsi_hba *)pci_get_drvdata(pcidev); + if (!phba) { + dev_err(&pcidev->dev, "beiscsi_shutdown called with no phba\n"); + return; + } + + beiscsi_quiesce(phba); + pci_disable_device(pcidev); } static void beiscsi_msix_enable(struct beiscsi_hba *phba) @@ -4235,7 +4281,7 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev, gcrashmode++; shost_printk(KERN_ERR, phba->shost, "Loading Driver in crashdump mode\n"); - ret = beiscsi_pci_soft_reset(phba); + ret = beiscsi_cmd_reset_function(phba); if (ret) { shost_printk(KERN_ERR, phba->shost, "Reset Failed. Aborting Crashdump\n"); @@ -4364,37 +4410,12 @@ struct iscsi_transport beiscsi_iscsi_transport = { .name = DRV_NAME, .caps = CAP_RECOVERY_L0 | CAP_HDRDGST | CAP_TEXT_NEGO | CAP_MULTI_R2T | CAP_DATADGST | CAP_DATA_PATH_OFFLOAD, - .param_mask = ISCSI_MAX_RECV_DLENGTH | - ISCSI_MAX_XMIT_DLENGTH | - ISCSI_HDRDGST_EN | - ISCSI_DATADGST_EN | - ISCSI_INITIAL_R2T_EN | - ISCSI_MAX_R2T | - ISCSI_IMM_DATA_EN | - ISCSI_FIRST_BURST | - ISCSI_MAX_BURST | - ISCSI_PDU_INORDER_EN | - ISCSI_DATASEQ_INORDER_EN | - ISCSI_ERL | - ISCSI_CONN_PORT | - ISCSI_CONN_ADDRESS | - ISCSI_EXP_STATSN | - ISCSI_PERSISTENT_PORT | - ISCSI_PERSISTENT_ADDRESS | - ISCSI_TARGET_NAME | ISCSI_TPGT | - ISCSI_USERNAME | ISCSI_PASSWORD | - ISCSI_USERNAME_IN | ISCSI_PASSWORD_IN | - ISCSI_FAST_ABORT | ISCSI_ABORT_TMO | - ISCSI_LU_RESET_TMO | - ISCSI_PING_TMO | ISCSI_RECV_TMO | - ISCSI_IFACE_NAME | ISCSI_INITIATOR_NAME, - .host_param_mask = ISCSI_HOST_HWADDRESS | ISCSI_HOST_IPADDRESS | - ISCSI_HOST_INITIATOR_NAME, .create_session = beiscsi_session_create, .destroy_session = beiscsi_session_destroy, .create_conn = beiscsi_conn_create, .bind_conn = beiscsi_conn_bind, .destroy_conn = iscsi_conn_teardown, + .attr_is_visible = be2iscsi_attr_is_visible, .set_param = beiscsi_set_param, .get_conn_param = iscsi_conn_get_param, .get_session_param = iscsi_session_get_param, @@ -4418,6 +4439,7 @@ static struct pci_driver beiscsi_pci_driver = { .name = DRV_NAME, .probe = beiscsi_dev_probe, .remove = beiscsi_remove, + .shutdown = beiscsi_shutdown, .id_table = beiscsi_pci_id_table }; diff --git a/drivers/scsi/be2iscsi/be_main.h b/drivers/scsi/be2iscsi/be_main.h index 5ce5170254c..b4a06d5e5f9 100644 --- a/drivers/scsi/be2iscsi/be_main.h +++ b/drivers/scsi/be2iscsi/be_main.h @@ -34,7 +34,7 @@ #include "be.h" #define DRV_NAME "be2iscsi" -#define BUILD_STR "2.103.298.0" +#define BUILD_STR "4.1.239.0" #define BE_NAME "ServerEngines BladeEngine2" \ "Linux iSCSI Driver version" BUILD_STR #define DRV_DESC BE_NAME " " "Driver" @@ -162,6 +162,8 @@ do { \ #define PAGES_REQUIRED(x) \ ((x < PAGE_SIZE) ? 1 : ((x + PAGE_SIZE - 1) / PAGE_SIZE)) +#define BEISCSI_MSI_NAME 20 /* size of msi_name string */ + enum be_mem_enum { HWI_MEM_ADDN_CONTEXT, HWI_MEM_WRB, @@ -287,6 +289,7 @@ struct beiscsi_hba { unsigned int num_cpus; unsigned int nxt_cqid; struct msix_entry msix_entries[MAX_CPUS + 1]; + char *msi_name[MAX_CPUS + 1]; bool msix_enabled; struct be_mem_descriptor *init_mem; |