diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-02-26 16:55:27 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-02-26 16:55:27 -0800 |
commit | 654451748b779b28077d9058442d0f354251870d (patch) | |
tree | ff889a2f6226e16b1121789f809927666a9ccf13 /drivers/scsi | |
parent | 64d497f55379b1e320a08ec2426468d96f5642ec (diff) | |
parent | 77c9cfc51b0d732b2524799810fb30018074fd60 (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: (158 commits)
[SCSI] Fix printing of failed 32-byte commands
[SCSI] Fix printing of variable length commands
[SCSI] libsrp: fix bug in ADDITIONAL CDB LENGTH interpretation
[SCSI] scsi_dh_alua: Add IBM Power Virtual SCSI ALUA device to dev list
[SCSI] scsi_dh_alua: add netapp to dev list
[SCSI] qla2xxx: Update version number to 8.03.02-k1.
[SCSI] qla2xxx: EEH: Restore PCI saved state during pci slot reset.
[SCSI] qla2xxx: Add firmware ETS burst support.
[SCSI] qla2xxx: Correct loop-resync issues during SNS scans.
[SCSI] qla2xxx: Correct use-after-free issue in terminate_rport_io callback.
[SCSI] qla2xxx: Correct EH bus-reset handling.
[SCSI] qla2xxx: Proper clean-up of BSG requests when request times out.
[SCSI] qla2xxx: Initialize payload receive length in failure path of vendor commands
[SCSI] fix duplicate removal on error path in scsi_sysfs_add_sdev
[SCSI] fix refcounting bug in scsi_get_host_dev
[SCSI] fix memory leak in scsi_report_lun_scan
[SCSI] lpfc: correct PPC build failure
[SCSI] raid_class: add raid1e
[SCSI] mpt2sas: Do not call sas_is_tlr_enabled for RAID volumes.
[SCSI] zfcp: Introduce header file for qdio structs and inline functions
...
Diffstat (limited to 'drivers/scsi')
96 files changed, 9244 insertions, 2868 deletions
diff --git a/drivers/scsi/FlashPoint.c b/drivers/scsi/FlashPoint.c index b898d382b7b..e40cdfb7541 100644 --- a/drivers/scsi/FlashPoint.c +++ b/drivers/scsi/FlashPoint.c @@ -3924,7 +3924,7 @@ static void FPT_sinits(struct sccb *p_sccb, unsigned char p_card) { struct sccb_mgr_tar_info *currTar_Info; - if ((p_sccb->TargID > MAX_SCSI_TAR) || (p_sccb->Lun > MAX_LUN)) { + if ((p_sccb->TargID >= MAX_SCSI_TAR) || (p_sccb->Lun >= MAX_LUN)) { return; } currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID]; diff --git a/drivers/scsi/be2iscsi/be.h b/drivers/scsi/be2iscsi/be.h index a93a5040f08..136b49cea79 100644 --- a/drivers/scsi/be2iscsi/be.h +++ b/drivers/scsi/be2iscsi/be.h @@ -1,5 +1,5 @@ /** - * Copyright (C) 2005 - 2009 ServerEngines + * Copyright (C) 2005 - 2010 ServerEngines * All rights reserved. * * This program is free software; you can redistribute it and/or @@ -24,6 +24,10 @@ #define FW_VER_LEN 32 #define MCC_Q_LEN 128 #define MCC_CQ_LEN 256 +#define MAX_MCC_CMD 16 +/* BladeEngine Generation numbers */ +#define BE_GEN2 2 +#define BE_GEN3 3 struct be_dma_mem { void *va; @@ -57,6 +61,11 @@ static inline void *queue_head_node(struct be_queue_info *q) return q->dma_mem.va + q->head * q->entry_size; } +static inline void *queue_get_wrb(struct be_queue_info *q, unsigned int wrb_num) +{ + return q->dma_mem.va + wrb_num * q->entry_size; +} + static inline void *queue_tail_node(struct be_queue_info *q) { return q->dma_mem.va + q->tail * q->entry_size; @@ -104,15 +113,19 @@ struct be_ctrl_info { spinlock_t mcc_lock; /* For serializing mcc cmds to BE card */ spinlock_t mcc_cq_lock; - /* MCC Async callback */ - void (*async_cb) (void *adapter, bool link_up); - void *adapter_ctxt; + wait_queue_head_t mcc_wait[MAX_MCC_CMD + 1]; + unsigned int mcc_tag[MAX_MCC_CMD]; + unsigned int mcc_numtag[MAX_MCC_CMD + 1]; + unsigned short mcc_alloc_index; + unsigned short mcc_free_index; + unsigned int mcc_tag_available; }; #include "be_cmds.h" #define PAGE_SHIFT_4K 12 #define PAGE_SIZE_4K (1 << PAGE_SHIFT_4K) +#define mcc_timeout 120000 /* 5s timeout */ /* Returns number of pages spanned by the data starting at the given addr */ #define PAGES_4K_SPANNED(_address, size) \ diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c index f008708f1b0..67098578fba 100644 --- a/drivers/scsi/be2iscsi/be_cmds.c +++ b/drivers/scsi/be2iscsi/be_cmds.c @@ -1,5 +1,5 @@ /** - * Copyright (C) 2005 - 2009 ServerEngines + * Copyright (C) 2005 - 2010 ServerEngines * All rights reserved. * * This program is free software; you can redistribute it and/or @@ -19,7 +19,7 @@ #include "be_mgmt.h" #include "be_main.h" -static void be_mcc_notify(struct beiscsi_hba *phba) +void be_mcc_notify(struct beiscsi_hba *phba) { struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q; u32 val = 0; @@ -29,6 +29,52 @@ static void be_mcc_notify(struct beiscsi_hba *phba) iowrite32(val, phba->db_va + DB_MCCQ_OFFSET); } +unsigned int alloc_mcc_tag(struct beiscsi_hba *phba) +{ + unsigned int tag = 0; + unsigned int num = 0; + +mcc_tag_rdy: + if (phba->ctrl.mcc_tag_available) { + tag = phba->ctrl.mcc_tag[phba->ctrl.mcc_alloc_index]; + phba->ctrl.mcc_tag[phba->ctrl.mcc_alloc_index] = 0; + phba->ctrl.mcc_numtag[tag] = 0; + } else { + udelay(100); + num++; + if (num < mcc_timeout) + goto mcc_tag_rdy; + } + if (tag) { + phba->ctrl.mcc_tag_available--; + if (phba->ctrl.mcc_alloc_index == (MAX_MCC_CMD - 1)) + phba->ctrl.mcc_alloc_index = 0; + else + phba->ctrl.mcc_alloc_index++; + } + return tag; +} + +void free_mcc_tag(struct be_ctrl_info *ctrl, unsigned int tag) +{ + spin_lock(&ctrl->mbox_lock); + tag = tag & 0x000000FF; + ctrl->mcc_tag[ctrl->mcc_free_index] = tag; + if (ctrl->mcc_free_index == (MAX_MCC_CMD - 1)) + ctrl->mcc_free_index = 0; + else + ctrl->mcc_free_index++; + ctrl->mcc_tag_available++; + spin_unlock(&ctrl->mbox_lock); +} + +bool is_link_state_evt(u32 trailer) +{ + return (((trailer >> ASYNC_TRAILER_EVENT_CODE_SHIFT) & + ASYNC_TRAILER_EVENT_CODE_MASK) == + ASYNC_EVENT_CODE_LINK_STATE); +} + static inline bool be_mcc_compl_is_new(struct be_mcc_compl *compl) { if (compl->flags != 0) { @@ -64,12 +110,30 @@ static int be_mcc_compl_process(struct be_ctrl_info *ctrl, return 0; } - -static inline bool is_link_state_evt(u32 trailer) +int be_mcc_compl_process_isr(struct be_ctrl_info *ctrl, + struct be_mcc_compl *compl) { - return (((trailer >> ASYNC_TRAILER_EVENT_CODE_SHIFT) & - ASYNC_TRAILER_EVENT_CODE_MASK) == - ASYNC_EVENT_CODE_LINK_STATE); + u16 compl_status, extd_status; + unsigned short tag; + + be_dws_le_to_cpu(compl, 4); + + compl_status = (compl->status >> CQE_STATUS_COMPL_SHIFT) & + CQE_STATUS_COMPL_MASK; + /* The ctrl.mcc_numtag[tag] is filled with + * [31] = valid, [30:24] = Rsvd, [23:16] = wrb, [15:8] = extd_status, + * [7:0] = compl_status + */ + tag = (compl->tag0 & 0x000000FF); + extd_status = (compl->status >> CQE_STATUS_EXTD_SHIFT) & + CQE_STATUS_EXTD_MASK; + + ctrl->mcc_numtag[tag] = 0x80000000; + ctrl->mcc_numtag[tag] |= (compl->tag0 & 0x00FF0000); + ctrl->mcc_numtag[tag] |= (extd_status & 0x000000FF) << 8; + ctrl->mcc_numtag[tag] |= (compl_status & 0x000000FF); + wake_up_interruptible(&ctrl->mcc_wait[tag]); + return 0; } 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) iscsi_session_failure(cls_session->dd_data, ISCSI_ERR_CONN_FAILED); } -static void beiscsi_async_link_state_process(struct beiscsi_hba *phba, +void beiscsi_async_link_state_process(struct beiscsi_hba *phba, struct be_async_event_link_state *evt) { switch (evt->port_link_status) { @@ -97,13 +161,13 @@ static void beiscsi_async_link_state_process(struct beiscsi_hba *phba, 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", evt->physical_port); - iscsi_host_for_each_session(phba->shost, - be2iscsi_fail_session); break; default: SE_DEBUG(DBG_LVL_1, "Unexpected Async Notification %d on" @@ -162,7 +226,6 @@ int beiscsi_process_mcc(struct beiscsi_hba *phba) /* Wait till no more pending mcc requests are present */ static int be_mcc_wait_compl(struct beiscsi_hba *phba) { -#define mcc_timeout 120000 /* 5s timeout */ int i, status; for (i = 0; i < mcc_timeout; i++) { status = beiscsi_process_mcc(phba); @@ -372,9 +435,10 @@ struct be_mcc_wrb *wrb_from_mccq(struct beiscsi_hba *phba) BUG_ON(atomic_read(&mccq->used) >= mccq->len); wrb = queue_head_node(mccq); + memset(wrb, 0, sizeof(*wrb)); + wrb->tag0 = (mccq->head & 0x000000FF) << 16; queue_head_inc(mccq); atomic_inc(&mccq->used); - memset(wrb, 0, sizeof(*wrb)); return wrb; } diff --git a/drivers/scsi/be2iscsi/be_cmds.h b/drivers/scsi/be2iscsi/be_cmds.h index 5de8acb924c..49fcc787ee8 100644 --- a/drivers/scsi/be2iscsi/be_cmds.h +++ b/drivers/scsi/be2iscsi/be_cmds.h @@ -1,5 +1,5 @@ /** - * Copyright (C) 2005 - 2009 ServerEngines + * Copyright (C) 2005 - 2010 ServerEngines * All rights reserved. * * This program is free software; you can redistribute it and/or @@ -425,14 +425,20 @@ int beiscsi_cmd_mccq_create(struct beiscsi_hba *phba, int be_poll_mcc(struct be_ctrl_info *ctrl); unsigned char mgmt_check_supported_fw(struct be_ctrl_info *ctrl, struct beiscsi_hba *phba); -int be_cmd_get_mac_addr(struct beiscsi_hba *phba, u8 *mac_addr); - +unsigned int be_cmd_get_mac_addr(struct beiscsi_hba *phba); +void free_mcc_tag(struct be_ctrl_info *ctrl, unsigned int tag); /*ISCSI Functuions */ int be_cmd_fw_initialize(struct be_ctrl_info *ctrl); struct be_mcc_wrb *wrb_from_mbox(struct be_dma_mem *mbox_mem); struct be_mcc_wrb *wrb_from_mccq(struct beiscsi_hba *phba); int be_mcc_notify_wait(struct beiscsi_hba *phba); +void be_mcc_notify(struct beiscsi_hba *phba); +unsigned int alloc_mcc_tag(struct beiscsi_hba *phba); +void beiscsi_async_link_state_process(struct beiscsi_hba *phba, + struct be_async_event_link_state *evt); +int be_mcc_compl_process_isr(struct be_ctrl_info *ctrl, + struct be_mcc_compl *compl); int be_mbox_notify(struct be_ctrl_info *ctrl); @@ -448,6 +454,8 @@ int be_cmd_iscsi_post_sgl_pages(struct be_ctrl_info *ctrl, int be_cmd_wrbq_create(struct be_ctrl_info *ctrl, struct be_dma_mem *q_mem, struct be_queue_info *wrbq); +bool is_link_state_evt(u32 trailer); + struct be_default_pdu_context { u32 dw[4]; } __packed; diff --git a/drivers/scsi/be2iscsi/be_iscsi.c b/drivers/scsi/be2iscsi/be_iscsi.c index d587b0362f1..29a3aaf35f9 100644 --- a/drivers/scsi/be2iscsi/be_iscsi.c +++ b/drivers/scsi/be2iscsi/be_iscsi.c @@ -1,5 +1,5 @@ /** - * Copyright (C) 2005 - 2009 ServerEngines + * Copyright (C) 2005 - 2010 ServerEngines * All rights reserved. * * 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)< |