提交 0d522ee7 编写于 作者: L Linus Torvalds

Merge tag 'scsi-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi

Pull first round of SCSI updates from James Bottomley:
 "This patch set is driver updates for qla4xxx, scsi_debug, pm80xx,
  fcoe/libfc, eas2r, lpfc, be2iscsi and megaraid_sas plus some assorted
  bug fixes and cleanups"

* tag 'scsi-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (106 commits)
  [SCSI] scsi_error: Escalate to LUN reset if abort fails
  [SCSI] Add 'eh_deadline' to limit SCSI EH runtime
  [SCSI] remove check for 'resetting'
  [SCSI] dc395: Move 'last_reset' into internal host structure
  [SCSI] tmscsim: Move 'last_reset' into host structure
  [SCSI] advansys: Remove 'last_reset' references
  [SCSI] dpt_i2o: return SCSI_MLQUEUE_HOST_BUSY when in reset
  [SCSI] dpt_i2o: Remove DPTI_STATE_IOCTL
  [SCSI] megaraid_sas: Fix synchronization problem between sysPD IO path and AEN path
  [SCSI] lpfc: Fix typo on NULL assignment
  [SCSI] scsi_dh_alua: ALUA handler attach should succeed while TPG is transitioning
  [SCSI] scsi_dh_alua: ALUA check sense should retry device internal reset unit attention
  [SCSI] esas2r: Cleanup snprinf formatting of firmware version
  [SCSI] esas2r: Remove superfluous mask of pcie_cap_reg
  [SCSI] esas2r: Fixes for big-endian platforms
  [SCSI] esas2r: Directly call kernel functions for atomic bit operations
  [SCSI] lpfc 8.3.43: Update lpfc version to driver version 8.3.43
  [SCSI] lpfc 8.3.43: Fixed not processing task management IOCB response status
  [SCSI] lpfc 8.3.43: Fixed spinlock hang.
  [SCSI] lpfc 8.3.43: Fixed invalid Total_Data_Placed value received for els and ct command responses
  ...
...@@ -1867,7 +1867,7 @@ S: Supported ...@@ -1867,7 +1867,7 @@ S: Supported
F: drivers/net/wireless/brcm80211/ F: drivers/net/wireless/brcm80211/
BROADCOM BNX2FC 10 GIGABIT FCOE DRIVER BROADCOM BNX2FC 10 GIGABIT FCOE DRIVER
M: Bhanu Prakash Gollapudi <bprakash@broadcom.com> M: Eddie Wai <eddie.wai@broadcom.com>
L: linux-scsi@vger.kernel.org L: linux-scsi@vger.kernel.org
S: Supported S: Supported
F: drivers/scsi/bnx2fc/ F: drivers/scsi/bnx2fc/
......
...@@ -26,8 +26,8 @@ ...@@ -26,8 +26,8 @@
*/ */
#define blogic_drvr_version "2.1.16" #define blogic_drvr_version "2.1.17"
#define blogic_drvr_date "18 July 2002" #define blogic_drvr_date "12 September 2013"
#include <linux/module.h> #include <linux/module.h>
#include <linux/init.h> #include <linux/init.h>
...@@ -311,12 +311,14 @@ static struct blogic_ccb *blogic_alloc_ccb(struct blogic_adapter *adapter) ...@@ -311,12 +311,14 @@ static struct blogic_ccb *blogic_alloc_ccb(struct blogic_adapter *adapter)
caller. caller.
*/ */
static void blogic_dealloc_ccb(struct blogic_ccb *ccb) static void blogic_dealloc_ccb(struct blogic_ccb *ccb, int dma_unmap)
{ {
struct blogic_adapter *adapter = ccb->adapter; struct blogic_adapter *adapter = ccb->adapter;
scsi_dma_unmap(ccb->command); if (ccb->command != NULL)
pci_unmap_single(adapter->pci_device, ccb->sensedata, scsi_dma_unmap(ccb->command);
if (dma_unmap)
pci_unmap_single(adapter->pci_device, ccb->sensedata,
ccb->sense_datalen, PCI_DMA_FROMDEVICE); ccb->sense_datalen, PCI_DMA_FROMDEVICE);
ccb->command = NULL; ccb->command = NULL;
...@@ -2762,8 +2764,8 @@ static void blogic_process_ccbs(struct blogic_adapter *adapter) ...@@ -2762,8 +2764,8 @@ static void blogic_process_ccbs(struct blogic_adapter *adapter)
/* /*
Place CCB back on the Host Adapter's free list. Place CCB back on the Host Adapter's free list.
*/ */
blogic_dealloc_ccb(ccb); blogic_dealloc_ccb(ccb, 1);
#if 0 /* this needs to be redone different for new EH */ #if 0 /* this needs to be redone different for new EH */
/* /*
Bus Device Reset CCBs have the command field Bus Device Reset CCBs have the command field
non-NULL only when a Bus Device Reset was requested non-NULL only when a Bus Device Reset was requested
...@@ -2791,7 +2793,7 @@ static void blogic_process_ccbs(struct blogic_adapter *adapter) ...@@ -2791,7 +2793,7 @@ static void blogic_process_ccbs(struct blogic_adapter *adapter)
if (ccb->status == BLOGIC_CCB_RESET && if (ccb->status == BLOGIC_CCB_RESET &&
ccb->tgt_id == tgt_id) { ccb->tgt_id == tgt_id) {
command = ccb->command; command = ccb->command;
blogic_dealloc_ccb(ccb); blogic_dealloc_ccb(ccb, 1);
adapter->active_cmds[tgt_id]--; adapter->active_cmds[tgt_id]--;
command->result = DID_RESET << 16; command->result = DID_RESET << 16;
command->scsi_done(command); command->scsi_done(command);
...@@ -2862,7 +2864,7 @@ static void blogic_process_ccbs(struct blogic_adapter *adapter) ...@@ -2862,7 +2864,7 @@ static void blogic_process_ccbs(struct blogic_adapter *adapter)
/* /*
Place CCB back on the Host Adapter's free list. Place CCB back on the Host Adapter's free list.
*/ */
blogic_dealloc_ccb(ccb); blogic_dealloc_ccb(ccb, 1);
/* /*
Call the SCSI Command Completion Routine. Call the SCSI Command Completion Routine.
*/ */
...@@ -3034,6 +3036,7 @@ static int blogic_qcmd_lck(struct scsi_cmnd *command, ...@@ -3034,6 +3036,7 @@ static int blogic_qcmd_lck(struct scsi_cmnd *command,
int buflen = scsi_bufflen(command); int buflen = scsi_bufflen(command);
int count; int count;
struct blogic_ccb *ccb; struct blogic_ccb *ccb;
dma_addr_t sense_buf;
/* /*
SCSI REQUEST_SENSE commands will be executed automatically by the SCSI REQUEST_SENSE commands will be executed automatically by the
...@@ -3179,10 +3182,17 @@ static int blogic_qcmd_lck(struct scsi_cmnd *command, ...@@ -3179,10 +3182,17 @@ static int blogic_qcmd_lck(struct scsi_cmnd *command,
} }
memcpy(ccb->cdb, cdb, cdblen); memcpy(ccb->cdb, cdb, cdblen);
ccb->sense_datalen = SCSI_SENSE_BUFFERSIZE; ccb->sense_datalen = SCSI_SENSE_BUFFERSIZE;
ccb->sensedata = pci_map_single(adapter->pci_device, ccb->command = command;
sense_buf = pci_map_single(adapter->pci_device,
command->sense_buffer, ccb->sense_datalen, command->sense_buffer, ccb->sense_datalen,
PCI_DMA_FROMDEVICE); PCI_DMA_FROMDEVICE);
ccb->command = command; if (dma_mapping_error(&adapter->pci_device->dev, sense_buf)) {
blogic_err("DMA mapping for sense data buffer failed\n",
adapter);
blogic_dealloc_ccb(ccb, 0);
return SCSI_MLQUEUE_HOST_BUSY;
}
ccb->sensedata = sense_buf;
command->scsi_done = comp_cb; command->scsi_done = comp_cb;
if (blogic_multimaster_type(adapter)) { if (blogic_multimaster_type(adapter)) {
/* /*
...@@ -3203,7 +3213,7 @@ static int blogic_qcmd_lck(struct scsi_cmnd *command, ...@@ -3203,7 +3213,7 @@ static int blogic_qcmd_lck(struct scsi_cmnd *command,
if (!blogic_write_outbox(adapter, BLOGIC_MBOX_START, if (!blogic_write_outbox(adapter, BLOGIC_MBOX_START,
ccb)) { ccb)) {
blogic_warn("Still unable to write Outgoing Mailbox - " "Host Adapter Dead?\n", adapter); blogic_warn("Still unable to write Outgoing Mailbox - " "Host Adapter Dead?\n", adapter);
blogic_dealloc_ccb(ccb); blogic_dealloc_ccb(ccb, 1);
command->result = DID_ERROR << 16; command->result = DID_ERROR << 16;
command->scsi_done(command); command->scsi_done(command);
} }
...@@ -3337,7 +3347,7 @@ static int blogic_resetadapter(struct blogic_adapter *adapter, bool hard_reset) ...@@ -3337,7 +3347,7 @@ static int blogic_resetadapter(struct blogic_adapter *adapter, bool hard_reset)
for (ccb = adapter->all_ccbs; ccb != NULL; ccb = ccb->next_all) for (ccb = adapter->all_ccbs; ccb != NULL; ccb = ccb->next_all)
if (ccb->status == BLOGIC_CCB_ACTIVE) if (ccb->status == BLOGIC_CCB_ACTIVE)
blogic_dealloc_ccb(ccb); blogic_dealloc_ccb(ccb, 1);
/* /*
* Wait a few seconds between the Host Adapter Hard Reset which * Wait a few seconds between the Host Adapter Hard Reset which
* initiates a SCSI Bus Reset and issuing any SCSI Commands. Some * initiates a SCSI Bus Reset and issuing any SCSI Commands. Some
......
...@@ -2511,8 +2511,8 @@ static void asc_prt_scsi_host(struct Scsi_Host *s) ...@@ -2511,8 +2511,8 @@ static void asc_prt_scsi_host(struct Scsi_Host *s)
struct asc_board *boardp = shost_priv(s); struct asc_board *boardp = shost_priv(s);
printk("Scsi_Host at addr 0x%p, device %s\n", s, dev_name(boardp->dev)); printk("Scsi_Host at addr 0x%p, device %s\n", s, dev_name(boardp->dev));
printk(" host_busy %u, host_no %d, last_reset %d,\n", printk(" host_busy %u, host_no %d,\n",
s->host_busy, s->host_no, (unsigned)s->last_reset); s->host_busy, s->host_no);
printk(" base 0x%lx, io_port 0x%lx, irq %d,\n", printk(" base 0x%lx, io_port 0x%lx, irq %d,\n",
(ulong)s->base, (ulong)s->io_port, boardp->irq); (ulong)s->base, (ulong)s->io_port, boardp->irq);
...@@ -3345,8 +3345,8 @@ static void asc_prt_driver_conf(struct seq_file *m, struct Scsi_Host *shost) ...@@ -3345,8 +3345,8 @@ static void asc_prt_driver_conf(struct seq_file *m, struct Scsi_Host *shost)
shost->host_no); shost->host_no);
seq_printf(m, seq_printf(m,
" host_busy %u, last_reset %lu, max_id %u, max_lun %u, max_channel %u\n", " host_busy %u, max_id %u, max_lun %u, max_channel %u\n",
shost->host_busy, shost->last_reset, shost->max_id, shost->host_busy, shost->max_id,
shost->max_lun, shost->max_channel); shost->max_lun, shost->max_channel);
seq_printf(m, seq_printf(m,
......
...@@ -128,7 +128,7 @@ struct be_ctrl_info { ...@@ -128,7 +128,7 @@ struct be_ctrl_info {
#define PAGE_SHIFT_4K 12 #define PAGE_SHIFT_4K 12
#define PAGE_SIZE_4K (1 << PAGE_SHIFT_4K) #define PAGE_SIZE_4K (1 << PAGE_SHIFT_4K)
#define mcc_timeout 120000 /* 5s timeout */ #define mcc_timeout 120000 /* 12s timeout */
/* Returns number of pages spanned by the data starting at the given addr */ /* Returns number of pages spanned by the data starting at the given addr */
#define PAGES_4K_SPANNED(_address, size) \ #define PAGES_4K_SPANNED(_address, size) \
......
...@@ -17,9 +17,9 @@ ...@@ -17,9 +17,9 @@
#include <scsi/iscsi_proto.h> #include <scsi/iscsi_proto.h>
#include "be_main.h"
#include "be.h" #include "be.h"
#include "be_mgmt.h" #include "be_mgmt.h"
#include "be_main.h"
int beiscsi_pci_soft_reset(struct beiscsi_hba *phba) int beiscsi_pci_soft_reset(struct beiscsi_hba *phba)
{ {
...@@ -158,8 +158,10 @@ int beiscsi_mccq_compl(struct beiscsi_hba *phba, ...@@ -158,8 +158,10 @@ int beiscsi_mccq_compl(struct beiscsi_hba *phba,
struct be_cmd_resp_hdr *ioctl_resp_hdr; struct be_cmd_resp_hdr *ioctl_resp_hdr;
struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q; struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
if (beiscsi_error(phba)) if (beiscsi_error(phba)) {
free_mcc_tag(&phba->ctrl, tag);
return -EIO; return -EIO;
}
/* wait for the mccq completion */ /* wait for the mccq completion */
rc = wait_event_interruptible_timeout( rc = wait_event_interruptible_timeout(
...@@ -173,7 +175,11 @@ int beiscsi_mccq_compl(struct beiscsi_hba *phba, ...@@ -173,7 +175,11 @@ int beiscsi_mccq_compl(struct beiscsi_hba *phba,
BEISCSI_LOG_INIT | BEISCSI_LOG_EH | BEISCSI_LOG_INIT | BEISCSI_LOG_EH |
BEISCSI_LOG_CONFIG, BEISCSI_LOG_CONFIG,
"BC_%d : MBX Cmd Completion timed out\n"); "BC_%d : MBX Cmd Completion timed out\n");
rc = -EAGAIN; rc = -EBUSY;
/* decrement the mccq used count */
atomic_dec(&phba->ctrl.mcc_obj.q.used);
goto release_mcc_tag; goto release_mcc_tag;
} else } else
rc = 0; rc = 0;
...@@ -208,10 +214,18 @@ int beiscsi_mccq_compl(struct beiscsi_hba *phba, ...@@ -208,10 +214,18 @@ int beiscsi_mccq_compl(struct beiscsi_hba *phba,
if (status == MCC_STATUS_INSUFFICIENT_BUFFER) { if (status == MCC_STATUS_INSUFFICIENT_BUFFER) {
ioctl_resp_hdr = (struct be_cmd_resp_hdr *) ioctl_hdr; ioctl_resp_hdr = (struct be_cmd_resp_hdr *) ioctl_hdr;
if (ioctl_resp_hdr->response_length) beiscsi_log(phba, KERN_WARNING,
goto release_mcc_tag; BEISCSI_LOG_INIT | BEISCSI_LOG_EH |
BEISCSI_LOG_CONFIG,
"BC_%d : Insufficent Buffer Error "
"Resp_Len : %d Actual_Resp_Len : %d\n",
ioctl_resp_hdr->response_length,
ioctl_resp_hdr->actual_resp_len);
rc = -EAGAIN;
goto release_mcc_tag;
} }
rc = -EAGAIN; rc = -EIO;
} }
release_mcc_tag: release_mcc_tag:
...@@ -363,7 +377,7 @@ void beiscsi_async_link_state_process(struct beiscsi_hba *phba, ...@@ -363,7 +377,7 @@ void beiscsi_async_link_state_process(struct beiscsi_hba *phba,
} else if ((evt->port_link_status & ASYNC_EVENT_LINK_UP) || } else if ((evt->port_link_status & ASYNC_EVENT_LINK_UP) ||
((evt->port_link_status & ASYNC_EVENT_LOGICAL) && ((evt->port_link_status & ASYNC_EVENT_LOGICAL) &&
(evt->port_fault == BEISCSI_PHY_LINK_FAULT_NONE))) { (evt->port_fault == BEISCSI_PHY_LINK_FAULT_NONE))) {
phba->state = BE_ADAPTER_UP; phba->state = BE_ADAPTER_LINK_UP;
beiscsi_log(phba, KERN_ERR, beiscsi_log(phba, KERN_ERR,
BEISCSI_LOG_CONFIG | BEISCSI_LOG_INIT, BEISCSI_LOG_CONFIG | BEISCSI_LOG_INIT,
...@@ -486,33 +500,47 @@ int be_mcc_notify_wait(struct beiscsi_hba *phba) ...@@ -486,33 +500,47 @@ int be_mcc_notify_wait(struct beiscsi_hba *phba)
**/ **/
static int be_mbox_db_ready_wait(struct be_ctrl_info *ctrl) static int be_mbox_db_ready_wait(struct be_ctrl_info *ctrl)
{ {
#define BEISCSI_MBX_RDY_BIT_TIMEOUT 4000 /* 4sec */
void __iomem *db = ctrl->db + MPU_MAILBOX_DB_OFFSET; void __iomem *db = ctrl->db + MPU_MAILBOX_DB_OFFSET;
struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev); struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev);
uint32_t wait = 0; unsigned long timeout;
bool read_flag = false;
int ret = 0, i;
u32 ready; u32 ready;
DECLARE_WAIT_QUEUE_HEAD_ONSTACK(rdybit_check_q);
do { if (beiscsi_error(phba))
return -EIO;
if (beiscsi_error(phba)) timeout = jiffies + (HZ * 110);
return -EIO;
ready = ioread32(db) & MPU_MAILBOX_DB_RDY_MASK; do {
if (ready) for (i = 0; i < BEISCSI_MBX_RDY_BIT_TIMEOUT; i++) {
break; ready = ioread32(db) & MPU_MAILBOX_DB_RDY_MASK;
if (ready) {
read_flag = true;
break;
}
mdelay(1);
}
if (wait > BEISCSI_HOST_MBX_TIMEOUT) { if (!read_flag) {
beiscsi_log(phba, KERN_ERR, wait_event_timeout(rdybit_check_q,
BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX, (read_flag != true),
"BC_%d : FW Timed Out\n"); HZ * 5);
}
} while ((time_before(jiffies, timeout)) && !read_flag);
if (!read_flag) {
beiscsi_log(phba, KERN_ERR,
BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
"BC_%d : FW Timed Out\n");
phba->fw_timeout = true; phba->fw_timeout = true;
beiscsi_ue_detect(phba); beiscsi_ue_detect(phba);
return -EBUSY; ret = -EBUSY;
} }
mdelay(1); return ret;
wait++;
} while (true);
return 0;
} }
/* /*
...@@ -699,7 +727,7 @@ struct be_mcc_wrb *wrb_from_mccq(struct beiscsi_hba *phba) ...@@ -699,7 +727,7 @@ struct be_mcc_wrb *wrb_from_mccq(struct beiscsi_hba *phba)
struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q; struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
struct be_mcc_wrb *wrb; struct be_mcc_wrb *wrb;
BUG_ON(atomic_read(&mccq->used) >= mccq->len); WARN_ON(atomic_read(&mccq->used) >= mccq->len);
wrb = queue_head_node(mccq); wrb = queue_head_node(mccq);
memset(wrb, 0, sizeof(*wrb)); memset(wrb, 0, sizeof(*wrb));
wrb->tag0 = (mccq->head & 0x000000FF) << 16; wrb->tag0 = (mccq->head & 0x000000FF) << 16;
...@@ -1009,10 +1037,29 @@ int beiscsi_cmd_q_destroy(struct be_ctrl_info *ctrl, struct be_queue_info *q, ...@@ -1009,10 +1037,29 @@ int beiscsi_cmd_q_destroy(struct be_ctrl_info *ctrl, struct be_queue_info *q,
return status; return status;
} }
/**
* be_cmd_create_default_pdu_queue()- Create DEFQ for the adapter
* @ctrl: ptr to ctrl_info
* @cq: Completion Queue
* @dq: Default Queue
* @lenght: ring size
* @entry_size: size of each entry in DEFQ
* @is_header: Header or Data DEFQ
* @ulp_num: Bind to which ULP
*
* Create HDR/Data DEFQ for the passed ULP. Unsol PDU are posted
* on this queue by the FW
*
* return
* Success: 0
* Failure: Non-Zero Value
*
**/
int be_cmd_create_default_pdu_queue(struct be_ctrl_info *ctrl, int be_cmd_create_default_pdu_queue(struct be_ctrl_info *ctrl,
struct be_queue_info *cq, struct be_queue_info *cq,
struct be_queue_info *dq, int length, struct be_queue_info *dq, int length,
int entry_size) int entry_size, uint8_t is_header,
uint8_t ulp_num)
{ {
struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
struct be_defq_create_req *req = embedded_payload(wrb); struct be_defq_create_req *req = embedded_payload(wrb);
...@@ -1030,6 +1077,11 @@ int be_cmd_create_default_pdu_queue(struct be_ctrl_info *ctrl, ...@@ -1030,6 +1077,11 @@ int be_cmd_create_default_pdu_queue(struct be_ctrl_info *ctrl,
OPCODE_COMMON_ISCSI_DEFQ_CREATE, sizeof(*req)); OPCODE_COMMON_ISCSI_DEFQ_CREATE, sizeof(*req));
req->num_pages = PAGES_4K_SPANNED(q_mem->va, q_mem->size); req->num_pages = PAGES_4K_SPANNED(q_mem->va, q_mem->size);
if (phba->fw_config.dual_ulp_aware) {
req->ulp_num = ulp_num;
req->dua_feature |= (1 << BEISCSI_DUAL_ULP_AWARE_BIT);
req->dua_feature |= (1 << BEISCSI_BIND_Q_TO_ULP_BIT);
}
if (is_chip_be2_be3r(phba)) { if (is_chip_be2_be3r(phba)) {
AMAP_SET_BITS(struct amap_be_default_pdu_context, AMAP_SET_BITS(struct amap_be_default_pdu_context,
...@@ -1067,22 +1119,53 @@ int be_cmd_create_default_pdu_queue(struct be_ctrl_info *ctrl, ...@@ -1067,22 +1119,53 @@ int be_cmd_create_default_pdu_queue(struct be_ctrl_info *ctrl,
status = be_mbox_notify(ctrl); status = be_mbox_notify(ctrl);
if (!status) { if (!status) {
struct be_ring *defq_ring;
struct be_defq_create_resp *resp = embedded_payload(wrb); struct be_defq_create_resp *resp = embedded_payload(wrb);
dq->id = le16_to_cpu(resp->id); dq->id = le16_to_cpu(resp->id);
dq->created = true; dq->created = true;
if (is_header)
defq_ring = &phba->phwi_ctrlr->default_pdu_hdr[ulp_num];
else
defq_ring = &phba->phwi_ctrlr->
default_pdu_data[ulp_num];
defq_ring->id = dq->id;
if (!phba->fw_config.dual_ulp_aware) {
defq_ring->ulp_num = BEISCSI_ULP0;
defq_ring->doorbell_offset = DB_RXULP0_OFFSET;
} else {
defq_ring->ulp_num = resp->ulp_num;
defq_ring->doorbell_offset = resp->doorbell_offset;
}
} }
spin_unlock(&ctrl->mbox_lock); spin_unlock(&ctrl->mbox_lock);
return status; return status;
} }
int be_cmd_wrbq_create(struct be_ctrl_info *ctrl, struct be_dma_mem *q_mem, /**
struct be_queue_info *wrbq) * be_cmd_wrbq_create()- Create WRBQ
* @ctrl: ptr to ctrl_info
* @q_mem: memory details for the queue
* @wrbq: queue info
* @pwrb_context: ptr to wrb_context
* @ulp_num: ULP on which the WRBQ is to be created
*
* Create WRBQ on the passed ULP_NUM.
*
**/
int be_cmd_wrbq_create(struct be_ctrl_info *ctrl,
struct be_dma_mem *q_mem,
struct be_queue_info *wrbq,
struct hwi_wrb_context *pwrb_context,
uint8_t ulp_num)
{ {
struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
struct be_wrbq_create_req *req = embedded_payload(wrb); struct be_wrbq_create_req *req = embedded_payload(wrb);
struct be_wrbq_create_resp *resp = embedded_payload(wrb); struct be_wrbq_create_resp *resp = embedded_payload(wrb);
struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev);
int status; int status;
spin_lock(&ctrl->mbox_lock); spin_lock(&ctrl->mbox_lock);
...@@ -1093,17 +1176,78 @@ int be_cmd_wrbq_create(struct be_ctrl_info *ctrl, struct be_dma_mem *q_mem, ...@@ -1093,17 +1176,78 @@ int be_cmd_wrbq_create(struct be_ctrl_info *ctrl, struct be_dma_mem *q_mem,
be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI, be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
OPCODE_COMMON_ISCSI_WRBQ_CREATE, sizeof(*req)); OPCODE_COMMON_ISCSI_WRBQ_CREATE, sizeof(*req));
req->num_pages = PAGES_4K_SPANNED(q_mem->va, q_mem->size); req->num_pages = PAGES_4K_SPANNED(q_mem->va, q_mem->size);
if (phba->fw_config.dual_ulp_aware) {
req->ulp_num = ulp_num;
req->dua_feature |= (1 << BEISCSI_DUAL_ULP_AWARE_BIT);
req->dua_feature |= (1 << BEISCSI_BIND_Q_TO_ULP_BIT);
}
be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem); be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
status = be_mbox_notify(ctrl); status = be_mbox_notify(ctrl);
if (!status) { if (!status) {
wrbq->id = le16_to_cpu(resp->cid); wrbq->id = le16_to_cpu(resp->cid);
wrbq->created = true; wrbq->created = true;
pwrb_context->cid = wrbq->id;
if (!phba->fw_config.dual_ulp_aware) {
pwrb_context->doorbell_offset = DB_TXULP0_OFFSET;
pwrb_context->ulp_num = BEISCSI_ULP0;
} else {
pwrb_context->ulp_num = resp->ulp_num;
pwrb_context->doorbell_offset = resp->doorbell_offset;
}
} }
spin_unlock(&ctrl->mbox_lock); spin_unlock(&ctrl->mbox_lock);
return status; return status;
} }
int be_cmd_iscsi_post_template_hdr(struct be_ctrl_info *ctrl,
struct be_dma_mem *q_mem)
{
struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
struct be_post_template_pages_req *req = embedded_payload(wrb);
int status;
spin_lock(&ctrl->mbox_lock);
memset(wrb, 0, sizeof(*wrb));
be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
OPCODE_COMMON_ADD_TEMPLATE_HEADER_BUFFERS,
sizeof(*req));
req->num_pages = PAGES_4K_SPANNED(q_mem->va, q_mem->size);
req->type = BEISCSI_TEMPLATE_HDR_TYPE_ISCSI;
be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
status = be_mbox_notify(ctrl);
spin_unlock(&ctrl->mbox_lock);
return status;
}
int be_cmd_iscsi_remove_template_hdr(struct be_ctrl_info *ctrl)
{
struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
struct be_remove_template_pages_req *req = embedded_payload(wrb);
int status;
spin_lock(&ctrl->mbox_lock);
memset(wrb, 0, sizeof(*wrb));
be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
OPCODE_COMMON_REMOVE_TEMPLATE_HEADER_BUFFERS,
sizeof(*req));
req->type = BEISCSI_TEMPLATE_HDR_TYPE_ISCSI;
status = be_mbox_notify(ctrl);
spin_unlock(&ctrl->mbox_lock);
return status;
}
int be_cmd_iscsi_post_sgl_pages(struct be_ctrl_info *ctrl, int be_cmd_iscsi_post_sgl_pages(struct be_ctrl_info *ctrl,
struct be_dma_mem *q_mem, struct be_dma_mem *q_mem,
u32 page_offset, u32 num_pages) u32 page_offset, u32 num_pages)
......
...@@ -40,6 +40,7 @@ struct be_mcc_wrb { ...@@ -40,6 +40,7 @@ struct be_mcc_wrb {
u32 tag1; /* dword 3 */ u32 tag1; /* dword 3 */
u32 rsvd; /* dword 4 */ u32 rsvd; /* dword 4 */
union { union {
#define EMBED_MBX_MAX_PAYLOAD_SIZE 220
u8 embedded_payload[236]; /* used by embedded cmds */ u8 embedded_payload[236]; /* used by embedded cmds */
struct be_sge sgl[19]; /* used by non-embedded cmds */ struct be_sge sgl[19]; /* used by non-embedded cmds */
} payload; } payload;
...@@ -162,6 +163,8 @@ struct be_mcc_mailbox { ...@@ -162,6 +163,8 @@ struct be_mcc_mailbox {
#define OPCODE_COMMON_CQ_CREATE 12 #define OPCODE_COMMON_CQ_CREATE 12
#define OPCODE_COMMON_EQ_CREATE 13 #define OPCODE_COMMON_EQ_CREATE 13
#define OPCODE_COMMON_MCC_CREATE 21 #define OPCODE_COMMON_MCC_CREATE 21
#define OPCODE_COMMON_ADD_TEMPLATE_HEADER_BUFFERS 24
#define OPCODE_COMMON_REMOVE_TEMPLATE_HEADER_BUFFERS 25
#define OPCODE_COMMON_GET_CNTL_ATTRIBUTES 32 #define OPCODE_COMMON_GET_CNTL_ATTRIBUTES 32
#define OPCODE_COMMON_GET_FW_VERSION 35 #define OPCODE_COMMON_GET_FW_VERSION 35
#define OPCODE_COMMON_MODIFY_EQ_DELAY 41 #define OPCODE_COMMON_MODIFY_EQ_DELAY 41
...@@ -217,6 +220,10 @@ struct phys_addr { ...@@ -217,6 +220,10 @@ struct phys_addr {
u32 hi; u32 hi;
}; };
struct virt_addr {
u32 lo;
u32 hi;
};
/************************** /**************************
* BE Command definitions * * BE Command definitions *
**************************/ **************************/
...@@ -722,7 +729,13 @@ int be_mbox_notify(struct be_ctrl_info *ctrl); ...@@ -722,7 +729,13 @@ int be_mbox_notify(struct be_ctrl_info *ctrl);
int be_cmd_create_default_pdu_queue(struct be_ctrl_info *ctrl, int be_cmd_create_default_pdu_queue(struct be_ctrl_info *ctrl,
struct be_queue_info *cq, struct be_queue_info *cq,
struct be_queue_info *dq, int length, struct be_queue_info *dq, int length,
int entry_size); int entry_size, uint8_t is_header,
uint8_t ulp_num);
int be_cmd_iscsi_post_template_hdr(struct be_ctrl_info *ctrl,
struct be_dma_mem *q_mem);
int be_cmd_iscsi_remove_template_hdr(struct be_ctrl_info *ctrl);
int be_cmd_iscsi_post_sgl_pages(struct be_ctrl_info *ctrl, int be_cmd_iscsi_post_sgl_pages(struct be_ctrl_info *ctrl,
struct be_dma_mem *q_mem, u32 page_offset, struct be_dma_mem *q_mem, u32 page_offset,
...@@ -731,7 +744,9 @@ int be_cmd_iscsi_post_sgl_pages(struct be_ctrl_info *ctrl, ...@@ -731,7 +744,9 @@ int be_cmd_iscsi_post_sgl_pages(struct be_ctrl_info *ctrl,
int beiscsi_cmd_reset_function(struct beiscsi_hba *phba); 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, int be_cmd_wrbq_create(struct be_ctrl_info *ctrl, struct be_dma_mem *q_mem,
struct be_queue_info *wrbq); struct be_queue_info *wrbq,
struct hwi_wrb_context *pwrb_context,
uint8_t ulp_num);
bool is_link_state_evt(u32 trailer); bool is_link_state_evt(u32 trailer);
...@@ -776,7 +791,9 @@ struct be_defq_create_req { ...@@ -776,7 +791,9 @@ struct be_defq_create_req {
struct be_cmd_req_hdr hdr; struct be_cmd_req_hdr hdr;
u16 num_pages; u16 num_pages;
u8 ulp_num; u8 ulp_num;
u8 rsvd0; #define BEISCSI_DUAL_ULP_AWARE_BIT 0 /* Byte 3 - Bit 0 */
#define BEISCSI_BIND_Q_TO_ULP_BIT 1 /* Byte 3 - Bit 1 */
u8 dua_feature;
struct be_default_pdu_context context; struct be_default_pdu_context context;
struct phys_addr pages[8]; struct phys_addr pages[8];
} __packed; } __packed;
...@@ -784,6 +801,27 @@ struct be_defq_create_req { ...@@ -784,6 +801,27 @@ struct be_defq_create_req {
struct be_defq_create_resp { struct be_defq_create_resp {
struct be_cmd_req_hdr hdr; struct be_cmd_req_hdr hdr;
u16 id; u16 id;
u8 rsvd0;
u8 ulp_num;
u32 doorbell_offset;
u16 register_set;
u16 doorbell_format;
} __packed;
struct be_post_template_pages_req {
struct be_cmd_req_hdr hdr;
u16 num_pages;
#define BEISCSI_TEMPLATE_HDR_TYPE_ISCSI 0x1
u16 type;
struct phys_addr scratch_pa;
struct virt_addr scratch_va;
struct virt_addr pages_va;
struct phys_addr pages[16];
} __packed;
struct be_remove_template_pages_req {
struct be_cmd_req_hdr hdr;
u16 type;
u16 rsvd0; u16 rsvd0;
} __packed; } __packed;
...@@ -800,14 +838,18 @@ struct be_wrbq_create_req { ...@@ -800,14 +838,18 @@ struct be_wrbq_create_req {
struct be_cmd_req_hdr hdr; struct be_cmd_req_hdr hdr;
u16 num_pages; u16 num_pages;
u8 ulp_num; u8 ulp_num;
u8 rsvd0; u8 dua_feature;
struct phys_addr pages[8]; struct phys_addr pages[8];
} __packed; } __packed;
struct be_wrbq_create_resp { struct be_wrbq_create_resp {
struct be_cmd_resp_hdr resp_hdr; struct be_cmd_resp_hdr resp_hdr;
u16 cid; u16 cid;
u16 rsvd0; u8 rsvd0;
u8 ulp_num;
u32 doorbell_offset;
u16 register_set;
u16 doorbell_format;
} __packed; } __packed;
#define SOL_CID_MASK 0x0000FFC0 #define SOL_CID_MASK 0x0000FFC0
...@@ -1002,6 +1044,7 @@ union tcp_upload_params { ...@@ -1002,6 +1044,7 @@ union tcp_upload_params {
} __packed; } __packed;
struct be_ulp_fw_cfg { struct be_ulp_fw_cfg {
#define BEISCSI_ULP_ISCSI_INI_MODE 0x10
u32 ulp_mode; u32 ulp_mode;
u32 etx_base; u32 etx_base;
u32 etx_count; u32 etx_count;
...@@ -1017,14 +1060,26 @@ struct be_ulp_fw_cfg { ...@@ -1017,14 +1060,26 @@ struct be_ulp_fw_cfg {
u32 icd_count; u32 icd_count;
}; };
struct be_ulp_chain_icd {
u32 chain_base;
u32 chain_count;
};
struct be_fw_cfg { struct be_fw_cfg {
struct be_cmd_req_hdr hdr; struct be_cmd_req_hdr hdr;
u32 be_config_number; u32 be_config_number;
u32 asic_revision; u32 asic_revision;
u32 phys_port; u32 phys_port;
#define BEISCSI_FUNC_ISCSI_INI_MODE 0x10
#define BEISCSI_FUNC_DUA_MODE 0x800
u32 function_mode; u32 function_mode;
struct be_ulp_fw_cfg ulp[2]; struct be_ulp_fw_cfg ulp[2];
u32 function_caps; u32 function_caps;
u32 cqid_base;
u32 cqid_count;
u32 eqid_base;
u32 eqid_count;
struct be_ulp_chain_icd chain_icd[2];
} __packed; } __packed;
struct be_cmd_get_all_if_id_req { struct be_cmd_get_all_if_id_req {
......
...@@ -58,10 +58,15 @@ struct iscsi_cls_session *beiscsi_session_create(struct iscsi_endpoint *ep, ...@@ -58,10 +58,15 @@ struct iscsi_cls_session *beiscsi_session_create(struct iscsi_endpoint *ep,
} }
beiscsi_ep = ep->dd_data; beiscsi_ep = ep->dd_data;
phba = beiscsi_ep->phba; phba = beiscsi_ep->phba;
shost = phba->shost;
beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, if (phba->state & BE_ADAPTER_PCI_ERR) {
"BS_%d : In beiscsi_session_create\n"); beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
"BS_%d : PCI_ERROR Recovery\n");
return NULL;
} else {
beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
"BS_%d : In beiscsi_session_create\n");
}
if (cmds_max > beiscsi_ep->phba->params.wrbs_per_cxn) { if (cmds_max > beiscsi_ep->phba->params.wrbs_per_cxn) {
beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
...@@ -74,6 +79,7 @@ struct iscsi_cls_session *beiscsi_session_create(struct iscsi_endpoint *ep, ...@@ -74,6 +79,7 @@ struct iscsi_cls_session *beiscsi_session_create(struct iscsi_endpoint *ep,
cmds_max = beiscsi_ep->phba->params.wrbs_per_cxn; cmds_max = beiscsi_ep->phba->params.wrbs_per_cxn;
} }
shost = phba->shost;
cls_session = iscsi_session_setup(&beiscsi_iscsi_transport, cls_session = iscsi_session_setup(&beiscsi_iscsi_transport,
shost, cmds_max, shost, cmds_max,
sizeof(*beiscsi_sess), sizeof(*beiscsi_sess),
...@@ -194,6 +200,8 @@ int beiscsi_conn_bind(struct iscsi_cls_session *cls_session, ...@@ -194,6 +200,8 @@ int beiscsi_conn_bind(struct iscsi_cls_session *cls_session,
struct beiscsi_conn *beiscsi_conn = conn->dd_data; struct beiscsi_conn *beiscsi_conn = conn->dd_data;
struct Scsi_Host *shost = iscsi_session_to_shost(cls_session); struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);
struct beiscsi_hba *phba = iscsi_host_priv(shost); struct beiscsi_hba *phba = iscsi_host_priv(shost);
struct hwi_controller *phwi_ctrlr = phba->phwi_ctrlr;
struct hwi_wrb_context *pwrb_context;
struct beiscsi_endpoint *beiscsi_ep; struct beiscsi_endpoint *beiscsi_ep;
struct iscsi_endpoint *ep; struct iscsi_endpoint *ep;
...@@ -214,9 +222,13 @@ int beiscsi_conn_bind(struct iscsi_cls_session *cls_session, ...@@ -214,9 +222,13 @@ int beiscsi_conn_bind(struct iscsi_cls_session *cls_session,
return -EEXIST; return -EEXIST;
} }
pwrb_context = &phwi_ctrlr->wrb_context[BE_GET_CRI_FROM_CID(
beiscsi_ep->ep_cid)];
beiscsi_conn->beiscsi_conn_cid = beiscsi_ep->ep_cid; beiscsi_conn->beiscsi_conn_cid = beiscsi_ep->ep_cid;
beiscsi_conn->ep = beiscsi_ep; beiscsi_conn->ep = beiscsi_ep;
beiscsi_ep->conn = beiscsi_conn; beiscsi_ep->conn = beiscsi_conn;
beiscsi_conn->doorbell_offset = pwrb_context->doorbell_offset;
beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
"BS_%d : beiscsi_conn=%p conn=%p ep_cid=%d\n", "BS_%d : beiscsi_conn=%p conn=%p ep_cid=%d\n",
...@@ -265,13 +277,17 @@ static int beiscsi_create_ipv6_iface(struct beiscsi_hba *phba) ...@@ -265,13 +277,17 @@ static int beiscsi_create_ipv6_iface(struct beiscsi_hba *phba)
void beiscsi_create_def_ifaces(struct beiscsi_hba *phba) void beiscsi_create_def_ifaces(struct beiscsi_hba *phba)
{ {
struct be_cmd_get_if_info_resp if_info; struct be_cmd_get_if_info_resp *if_info;
if (!mgmt_get_if_info(phba, BE2_IPV4, &if_info)) if (!mgmt_get_if_info(phba, BE2_IPV4, &if_info)) {
beiscsi_create_ipv4_iface(phba); beiscsi_create_ipv4_iface(phba);
kfree(if_info);
}
if (!mgmt_get_if_info(phba, BE2_IPV6, &if_info)) if (!mgmt_get_if_info(phba, BE2_IPV6, &if_info)) {
beiscsi_create_ipv6_iface(phba); beiscsi_create_ipv6_iface(phba);
kfree(if_info);
}
} }
void beiscsi_destroy_def_ifaces(struct beiscsi_hba *phba) void beiscsi_destroy_def_ifaces(struct beiscsi_hba *phba)
...@@ -467,6 +483,12 @@ int be2iscsi_iface_set_param(struct Scsi_Host *shost, ...@@ -467,6 +483,12 @@ int be2iscsi_iface_set_param(struct Scsi_Host *shost,
uint32_t rm_len = dt_len; uint32_t rm_len = dt_len;
int ret = 0 ; int ret = 0 ;
if (phba->state & BE_ADAPTER_PCI_ERR) {
beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
"BS_%d : In PCI_ERROR Recovery\n");
return -EBUSY;
}
nla_for_each_attr(attrib, data, dt_len, rm_len) { nla_for_each_attr(attrib, data, dt_len, rm_len) {
iface_param = nla_data(attrib); iface_param = nla_data(attrib);
...@@ -512,59 +534,60 @@ static int be2iscsi_get_if_param(struct beiscsi_hba *phba, ...@@ -512,59 +534,60 @@ static int be2iscsi_get_if_param(struct beiscsi_hba *phba,
struct iscsi_iface *iface, int param, struct iscsi_iface *iface, int param,
char *buf) char *buf)
{ {
struct be_cmd_get_if_info_resp if_info; struct be_cmd_get_if_info_resp *if_info;
int len, ip_type = BE2_IPV4; int len, ip_type = BE2_IPV4;
memset(&if_info, 0, sizeof(if_info));
if (iface->iface_type == ISCSI_IFACE_TYPE_IPV6) if (iface->iface_type == ISCSI_IFACE_TYPE_IPV6)
ip_type = BE2_IPV6; ip_type = BE2_IPV6;
len = mgmt_get_if_info(phba, ip_type, &if_info); len = mgmt_get_if_info(phba, ip_type, &if_info);
if (len) if (len) {
kfree(if_info);
return len; return len;
}
switch (param) { switch (param) {
case ISCSI_NET_PARAM_IPV4_ADDR: case ISCSI_NET_PARAM_IPV4_ADDR:
len = sprintf(buf, "%pI4\n", &if_info.ip_addr.addr); len = sprintf(buf, "%pI4\n", if_info->ip_addr.addr);
break; break;
case ISCSI_NET_PARAM_IPV6_ADDR: case ISCSI_NET_PARAM_IPV6_ADDR:
len = sprintf(buf, "%pI6\n", &if_info.ip_addr.addr); len = sprintf(buf, "%pI6\n", if_info->ip_addr.addr);
break; break;
case ISCSI_NET_PARAM_IPV4_BOOTPROTO: case ISCSI_NET_PARAM_IPV4_BOOTPROTO:
if (!if_info.dhcp_state) if (!if_info->dhcp_state)
len = sprintf(buf, "static\n"); len = sprintf(buf, "static\n");
else else
len = sprintf(buf, "dhcp\n"); len = sprintf(buf, "dhcp\n");
break; break;
case ISCSI_NET_PARAM_IPV4_SUBNET: case ISCSI_NET_PARAM_IPV4_SUBNET:
len = sprintf(buf, "%pI4\n", &if_info.ip_addr.subnet_mask); len = sprintf(buf, "%pI4\n", if_info->ip_addr.subnet_mask);
break; break;
case ISCSI_NET_PARAM_VLAN_ENABLED: case ISCSI_NET_PARAM_VLAN_ENABLED:
len = sprintf(buf, "%s\n", len = sprintf(buf, "%s\n",
(if_info.vlan_priority == BEISCSI_VLAN_DISABLE) (if_info->vlan_priority == BEISCSI_VLAN_DISABLE)
? "Disabled\n" : "Enabled\n"); ? "Disabled\n" : "Enabled\n");
break; break;
case ISCSI_NET_PARAM_VLAN_ID: case ISCSI_NET_PARAM_VLAN_ID:
if (if_info.vlan_priority == BEISCSI_VLAN_DISABLE) if (if_info->vlan_priority == BEISCSI_VLAN_DISABLE)
return -EINVAL; return -EINVAL;
else else
len = sprintf(buf, "%d\n", len = sprintf(buf, "%d\n",
(if_info.vlan_priority & (if_info->vlan_priority &
ISCSI_MAX_VLAN_ID)); ISCSI_MAX_VLAN_ID));
break; break;
case ISCSI_NET_PARAM_VLAN_PRIORITY: case ISCSI_NET_PARAM_VLAN_PRIORITY:
if (if_info.vlan_priority == BEISCSI_VLAN_DISABLE) if (if_info->vlan_priority == BEISCSI_VLAN_DISABLE)
return -EINVAL; return -EINVAL;
else else
len = sprintf(buf, "%d\n", len = sprintf(buf, "%d\n",
((if_info.vlan_priority >> 13) & ((if_info->vlan_priority >> 13) &
ISCSI_MAX_VLAN_PRIORITY)); ISCSI_MAX_VLAN_PRIORITY));
break; break;
default: default:
WARN_ON(1); WARN_ON(1);
} }
kfree(if_info);
return len; return len;
} }
...@@ -577,6 +600,12 @@ int be2iscsi_iface_get_param(struct iscsi_iface *iface, ...@@ -577,6 +600,12 @@ int be2iscsi_iface_get_param(struct iscsi_iface *iface,
struct be_cmd_get_def_gateway_resp gateway; struct be_cmd_get_def_gateway_resp gateway;
int len = -ENOSYS; int len = -ENOSYS;
if (phba->state & BE_ADAPTER_PCI_ERR) {
beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
"BS_%d : In PCI_ERROR Recovery\n");
return -EBUSY;
}
switch (param) { switch (param) {
case ISCSI_NET_PARAM_IPV4_ADDR: case ISCSI_NET_PARAM_IPV4_ADDR:
case ISCSI_NET_PARAM_IPV4_SUBNET: case ISCSI_NET_PARAM_IPV4_SUBNET:
...@@ -672,8 +701,7 @@ int beiscsi_set_param(struct iscsi_cls_conn *cls_conn, ...@@ -672,8 +701,7 @@ int beiscsi_set_param(struct iscsi_cls_conn *cls_conn,
session->max_burst = 262144; session->max_burst = 262144;
break; break;
case ISCSI_PARAM_MAX_XMIT_DLENGTH: case ISCSI_PARAM_MAX_XMIT_DLENGTH:
if ((conn->max_xmit_dlength > 65536) || if (conn->max_xmit_dlength > 65536)
(conn->max_xmit_dlength == 0))
conn->max_xmit_dlength = 65536; conn->max_xmit_dlength = 65536;
default: default:
return 0; return 0;
...@@ -727,7 +755,7 @@ static void beiscsi_get_port_state(struct Scsi_Host *shost) ...@@ -727,7 +755,7 @@ static void beiscsi_get_port_state(struct Scsi_Host *shost)
struct beiscsi_hba *phba = iscsi_host_priv(shost); struct beiscsi_hba *phba = iscsi_host_priv(shost);
struct iscsi_cls_host *ihost = shost->shost_data; struct iscsi_cls_host *ihost = shost->shost_data;
ihost->port_state = (phba->state == BE_ADAPTER_UP) ? ihost->port_state = (phba->state == BE_ADAPTER_LINK_UP) ?
ISCSI_PORT_STATE_UP : ISCSI_PORT_STATE_DOWN; ISCSI_PORT_STATE_UP : ISCSI_PORT_STATE_DOWN;
} }
...@@ -795,9 +823,16 @@ int beiscsi_get_host_param(struct Scsi_Host *shost, ...@@ -795,9 +823,16 @@ int beiscsi_get_host_param(struct Scsi_Host *shost,
struct beiscsi_hba *phba = iscsi_host_priv(shost); struct beiscsi_hba *phba = iscsi_host_priv(shost);
int status = 0; int status = 0;
beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
"BS_%d : In beiscsi_get_host_param," if (phba->state & BE_ADAPTER_PCI_ERR) {
" param= %d\n", param); beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
"BS_%d : In PCI_ERROR Recovery\n");
return -EBUSY;
} else {
beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
"BS_%d : In beiscsi_get_host_param,"
" param = %d\n", param);
}
switch (param) { switch (param) {
case ISCSI_HOST_PARAM_HWADDRESS: case ISCSI_HOST_PARAM_HWADDRESS:
...@@ -840,7 +875,7 @@ int beiscsi_get_macaddr(char *buf, struct beiscsi_hba *phba) ...@@ -840,7 +875,7 @@ int beiscsi_get_macaddr(char *buf, struct beiscsi_hba *phba)
struct be_cmd_get_nic_conf_resp resp; struct be_cmd_get_nic_conf_resp resp;
int rc; int rc;
if (strlen(phba->mac_address)) if (phba->mac_addr_set)
return sysfs_format_mac(buf, phba->mac_address, ETH_ALEN); return sysfs_format_mac(buf, phba->mac_address, ETH_ALEN);
memset(&resp, 0, sizeof(resp)); memset(&resp, 0, sizeof(resp));
...@@ -848,6 +883,7 @@ int beiscsi_get_macaddr(char *buf, struct beiscsi_hba *phba) ...@@ -848,6 +883,7 @@ int beiscsi_get_macaddr(char *buf, struct beiscsi_hba *phba)
if (rc) if (rc)
return rc; return rc;
phba->mac_addr_set = true;
memcpy(phba->mac_address, resp.mac_address, ETH_ALEN); memcpy(phba->mac_address, resp.mac_address, ETH_ALEN);
return sysfs_format_mac(buf, phba->mac_address, ETH_ALEN); return sysfs_format_mac(buf, phba->mac_address, ETH_ALEN);
} }
...@@ -923,6 +959,10 @@ static void beiscsi_set_params_for_offld(struct beiscsi_conn *beiscsi_conn, ...@@ -923,6 +959,10 @@ static void beiscsi_set_params_for_offld(struct beiscsi_conn *beiscsi_conn,
session->max_r2t); session->max_r2t);
AMAP_SET_BITS(struct amap_beiscsi_offload_params, exp_statsn, params, AMAP_SET_BITS(struct amap_beiscsi_offload_params, exp_statsn, params,
(conn->exp_statsn - 1)); (conn->exp_statsn - 1));
AMAP_SET_BITS(struct amap_beiscsi_offload_params,
max_recv_data_segment_length, params,
conn->max_recv_dlength);
} }
/** /**
...@@ -935,10 +975,19 @@ int beiscsi_conn_start(struct iscsi_cls_conn *cls_conn) ...@@ -935,10 +975,19 @@ int beiscsi_conn_start(struct iscsi_cls_conn *cls_conn)
struct beiscsi_conn *beiscsi_conn = conn->dd_data; struct beiscsi_conn *beiscsi_conn = conn->dd_data;
struct beiscsi_endpoint *beiscsi_ep; struct beiscsi_endpoint *beiscsi_ep;
struct beiscsi_offload_params params; struct beiscsi_offload_params params;
struct beiscsi_hba *phba;
beiscsi_log(beiscsi_conn->phba, KERN_INFO, phba = ((struct beiscsi_conn *)conn->dd_data)->phba;
BEISCSI_LOG_CONFIG,
"BS_%d : In beiscsi_conn_start\n"); if (phba->state & BE_ADAPTER_PCI_ERR) {
beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
"BS_%d : In PCI_ERROR Recovery\n");
return -EBUSY;
} else {
beiscsi_log(beiscsi_conn->phba, KERN_INFO,
BEISCSI_LOG_CONFIG,
"BS_%d : In beiscsi_conn_start\n");
}
memset(&params, 0, sizeof(struct beiscsi_offload_params)); memset(&params, 0, sizeof(struct beiscsi_offload_params));
beiscsi_ep = beiscsi_conn->ep; beiscsi_ep = beiscsi_conn->ep;
...@@ -960,15 +1009,31 @@ int beiscsi_conn_start(struct iscsi_cls_conn *cls_conn) ...@@ -960,15 +1009,31 @@ int beiscsi_conn_start(struct iscsi_cls_conn *cls_conn)
*/ */
static int beiscsi_get_cid(struct beiscsi_hba *phba) static int beiscsi_get_cid(struct beiscsi_hba *phba)
{ {
unsigned short cid = 0xFFFF; unsigned short cid = 0xFFFF, cid_from_ulp;
struct ulp_cid_info *cid_info = NULL;
if (!phba->avlbl_cids) uint16_t cid_avlbl_ulp0, cid_avlbl_ulp1;
return cid;
/* Find the ULP which has more CID available */
cid = phba->cid_array[phba->cid_alloc++]; cid_avlbl_ulp0 = (phba->cid_array_info[BEISCSI_ULP0]) ?
if (phba->cid_alloc == phba->params.cxns_per_ctrl) BEISCSI_ULP0_AVLBL_CID(phba) : 0;
phba->cid_alloc = 0; cid_avlbl_ulp1 = (phba->cid_array_info[BEISCSI_ULP1]) ?
phba->avlbl_cids--; BEISCSI_ULP1_AVLBL_CID(phba) : 0;
cid_from_ulp = (cid_avlbl_ulp0 > cid_avlbl_ulp1) ?
BEISCSI_ULP0 : BEISCSI_ULP1;
if (test_bit(cid_from_ulp, (void *)&phba->fw_config.ulp_supported)) {
cid_info = phba->cid_array_info[cid_from_ulp];
if (!cid_info->avlbl_cids)
return cid;
cid = cid_info->cid_array[cid_info->cid_alloc++];
if (cid_info->cid_alloc == BEISCSI_GET_CID_COUNT(
phba, cid_from_ulp))
cid_info->cid_alloc = 0;
cid_info->avlbl_cids--;
}
return cid; return cid;
} }
...@@ -979,10 +1044,22 @@ static int beiscsi_get_cid(struct beiscsi_hba *phba) ...@@ -979,10 +1044,22 @@ static int beiscsi_get_cid(struct beiscsi_hba *phba)
*/ */
static void beiscsi_put_cid(struct beiscsi_hba *phba, unsigned short cid) static void beiscsi_put_cid(struct beiscsi_hba *phba, unsigned short cid)
{ {
phba->avlbl_cids++; uint16_t cid_post_ulp;
phba->cid_array[phba->cid_free++] = cid; struct hwi_controller *phwi_ctrlr;
if (phba->cid_free == phba->params.cxns_per_ctrl) struct hwi_wrb_context *pwrb_context;
phba->cid_free = 0; struct ulp_cid_info *cid_info = NULL;
uint16_t cri_index = BE_GET_CRI_FROM_CID(cid);
phwi_ctrlr = phba->phwi_ctrlr;
pwrb_context = &phwi_ctrlr->wrb_context[cri_index];
cid_post_ulp = pwrb_context->ulp_num;
cid_info = phba->cid_array_info[cid_post_ulp];
cid_info->avlbl_cids++;
cid_info->cid_array[cid_info->cid_free++] = cid;
if (cid_info->cid_free == BEISCSI_GET_CID_COUNT(phba, cid_post_ulp))
cid_info->cid_free = 0;
} }
/** /**
...@@ -1135,7 +1212,12 @@ beiscsi_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr, ...@@ -1135,7 +1212,12 @@ beiscsi_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr,
return ERR_PTR(ret); return ERR_PTR(ret);
} }
if (phba->state != BE_ADAPTER_UP) { if (phba->state & BE_ADAPTER_PCI_ERR) {
ret = -EBUSY;
beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
"BS_%d : In PCI_ERROR Recovery\n");
return ERR_PTR(ret);
} else if (phba->state & BE_ADAPTER_LINK_DOWN) {
ret = -EBUSY; ret = -EBUSY;
beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG, beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
"BS_%d : The Adapter Port state is Down!!!\n"); "BS_%d : The Adapter Port state is Down!!!\n");
...@@ -1260,6 +1342,12 @@ void beiscsi_ep_disconnect(struct iscsi_endpoint *ep) ...@@ -1260,6 +1342,12 @@ void beiscsi_ep_disconnect(struct iscsi_endpoint *ep)
tcp_upload_flag = CONNECTION_UPLOAD_ABORT; tcp_upload_flag = CONNECTION_UPLOAD_ABORT;
} }
if (phba->state & BE_ADAPTER_PCI_ERR) {
beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
"BS_%d : PCI_ERROR Recovery\n");
goto free_ep;
}
tag = mgmt_invalidate_connection(phba, beiscsi_ep, tag = mgmt_invalidate_connection(phba, beiscsi_ep,
beiscsi_ep->ep_cid, beiscsi_ep->ep_cid,
mgmt_invalidate_flag, mgmt_invalidate_flag,
...@@ -1272,6 +1360,7 @@ void beiscsi_ep_disconnect(struct iscsi_endpoint *ep) ...@@ -1272,6 +1360,7 @@ void beiscsi_ep_disconnect(struct iscsi_endpoint *ep)
beiscsi_mccq_compl(phba, tag, NULL, NULL); beiscsi_mccq_compl(phba, tag, NULL, NULL);
beiscsi_close_conn(beiscsi_ep, tcp_upload_flag); beiscsi_close_conn(beiscsi_ep, tcp_upload_flag);
free_ep:
beiscsi_free_ep(beiscsi_ep); beiscsi_free_ep(beiscsi_ep);
beiscsi_unbind_conn_to_cid(phba, beiscsi_ep->ep_cid); beiscsi_unbind_conn_to_cid(phba, beiscsi_ep->ep_cid);
iscsi_destroy_endpoint(beiscsi_ep->openiscsi_ep); iscsi_destroy_endpoint(beiscsi_ep->openiscsi_ep);
......
此差异已折叠。
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include <linux/in.h> #include <linux/in.h>
#include <linux/ctype.h> #include <linux/ctype.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/aer.h>
#include <scsi/scsi.h> #include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h> #include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h> #include <scsi/scsi_device.h>
...@@ -34,9 +35,8 @@ ...@@ -34,9 +35,8 @@
#include <scsi/libiscsi.h> #include <scsi/libiscsi.h>
#include <scsi/scsi_transport_iscsi.h> #include <scsi/scsi_transport_iscsi.h>
#include "be.h"
#define DRV_NAME "be2iscsi" #define DRV_NAME "be2iscsi"
#define BUILD_STR "10.0.467.0" #define BUILD_STR "10.0.659.0"
#define BE_NAME "Emulex OneConnect" \ #define BE_NAME "Emulex OneConnect" \
"Open-iSCSI Driver version" BUILD_STR "Open-iSCSI Driver version" BUILD_STR
#define DRV_DESC BE_NAME " " "Driver" #define DRV_DESC BE_NAME " " "Driver"
...@@ -66,7 +66,6 @@ ...@@ -66,7 +66,6 @@
#define MAX_CPUS 64 #define MAX_CPUS 64
#define BEISCSI_MAX_NUM_CPUS 7 #define BEISCSI_MAX_NUM_CPUS 7
#define OC_SKH_MAX_NUM_CPUS 31
#define BEISCSI_VER_STRLEN 32 #define BEISCSI_VER_STRLEN 32
...@@ -74,6 +73,7 @@ ...@@ -74,6 +73,7 @@
#define BEISCSI_CMD_PER_LUN 128 /* scsi_host->cmd_per_lun */ #define BEISCSI_CMD_PER_LUN 128 /* scsi_host->cmd_per_lun */
#define BEISCSI_MAX_SECTORS 2048 /* scsi_host->max_sectors */ #define BEISCSI_MAX_SECTORS 2048 /* scsi_host->max_sectors */
#define BEISCSI_TEMPLATE_HDR_PER_CXN_SIZE 128 /* Template size per cxn */
#define BEISCSI_MAX_CMD_LEN 16 /* scsi_host->max_cmd_len */ #define BEISCSI_MAX_CMD_LEN 16 /* scsi_host->max_cmd_len */
#define BEISCSI_NUM_MAX_LUN 256 /* scsi_host->max_lun */ #define BEISCSI_NUM_MAX_LUN 256 /* scsi_host->max_lun */
...@@ -97,14 +97,19 @@ ...@@ -97,14 +97,19 @@
#define INVALID_SESS_HANDLE 0xFFFFFFFF #define INVALID_SESS_HANDLE 0xFFFFFFFF
#define BE_ADAPTER_UP 0x00000000 #define BE_ADAPTER_LINK_UP 0x001
#define BE_ADAPTER_LINK_DOWN 0x00000001 #define BE_ADAPTER_LINK_DOWN 0x002
#define BE_ADAPTER_PCI_ERR 0x004
#define BEISCSI_CLEAN_UNLOAD 0x01
#define BEISCSI_EEH_UNLOAD 0x02
/** /**
* hardware needs the async PDU buffers to be posted in multiples of 8 * hardware needs the async PDU buffers to be posted in multiples of 8
* So have atleast 8 of them by default * So have atleast 8 of them by default
*/ */
#define HWI_GET_ASYNC_PDU_CTX(phwi) (phwi->phwi_ctxt->pasync_ctx) #define HWI_GET_ASYNC_PDU_CTX(phwi, ulp_num) \
(phwi->phwi_ctxt->pasync_ctx[ulp_num])
/********* Memory BAR register ************/ /********* Memory BAR register ************/
#define PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET 0xfc #define PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET 0xfc
...@@ -149,29 +154,41 @@ ...@@ -149,29 +154,41 @@
#define DB_CQ_REARM_SHIFT (29) /* bit 29 */ #define DB_CQ_REARM_SHIFT (29) /* bit 29 */
#define GET_HWI_CONTROLLER_WS(pc) (pc->phwi_ctrlr) #define GET_HWI_CONTROLLER_WS(pc) (pc->phwi_ctrlr)
#define HWI_GET_DEF_BUFQ_ID(pc) (((struct hwi_controller *)\ #define HWI_GET_DEF_BUFQ_ID(pc, ulp_num) (((struct hwi_controller *)\
(GET_HWI_CONTROLLER_WS(pc)))->default_pdu_data.id) (GET_HWI_CONTROLLER_WS(pc)))->default_pdu_data[ulp_num].id)
#define HWI_GET_DEF_HDRQ_ID(pc) (((struct hwi_controller *)\ #define HWI_GET_DEF_HDRQ_ID(pc, ulp_num) (((struct hwi_controller *)\
(GET_HWI_CONTROLLER_WS(pc)))->default_pdu_hdr.id) (GET_HWI_CONTROLLER_WS(pc)))->default_pdu_hdr[ulp_num].id)
#define PAGES_REQUIRED(x) \ #define PAGES_REQUIRED(x) \
((x < PAGE_SIZE) ? 1 : ((x + PAGE_SIZE - 1) / PAGE_SIZE)) ((x < PAGE_SIZE) ? 1 : ((x + PAGE_SIZE - 1) / PAGE_SIZE))
#define BEISCSI_MSI_NAME 20 /* size of msi_name string */ #define BEISCSI_MSI_NAME 20 /* size of msi_name string */
#define MEM_DESCR_OFFSET 8
#define BEISCSI_DEFQ_HDR 1
#define BEISCSI_DEFQ_DATA 0
enum be_mem_enum { enum be_mem_enum {
HWI_MEM_ADDN_CONTEXT, HWI_MEM_ADDN_CONTEXT,
HWI_MEM_WRB, HWI_MEM_WRB,
HWI_MEM_WRBH, HWI_MEM_WRBH,
HWI_MEM_SGLH, HWI_MEM_SGLH,
HWI_MEM_SGE, HWI_MEM_SGE,
HWI_MEM_ASYNC_HEADER_BUF, /* 5 */ HWI_MEM_TEMPLATE_HDR_ULP0,
HWI_MEM_ASYNC_DATA_BUF, HWI_MEM_ASYNC_HEADER_BUF_ULP0, /* 6 */
HWI_MEM_ASYNC_HEADER_RING, HWI_MEM_ASYNC_DATA_BUF_ULP0,
HWI_MEM_ASYNC_DATA_RING, HWI_MEM_ASYNC_HEADER_RING_ULP0,
HWI_MEM_ASYNC_HEADER_HANDLE, HWI_MEM_ASYNC_DATA_RING_ULP0,
HWI_MEM_ASYNC_DATA_HANDLE, /* 10 */ HWI_MEM_ASYNC_HEADER_HANDLE_ULP0,
HWI_MEM_ASYNC_PDU_CONTEXT, HWI_MEM_ASYNC_DATA_HANDLE_ULP0, /* 11 */
HWI_MEM_ASYNC_PDU_CONTEXT_ULP0,
HWI_MEM_TEMPLATE_HDR_ULP1,
HWI_MEM_ASYNC_HEADER_BUF_ULP1, /* 14 */
HWI_MEM_ASYNC_DATA_BUF_ULP1,
HWI_MEM_ASYNC_HEADER_RING_ULP1,
HWI_MEM_ASYNC_DATA_RING_ULP1,
HWI_MEM_ASYNC_HEADER_HANDLE_ULP1,
HWI_MEM_ASYNC_DATA_HANDLE_ULP1, /* 19 */
HWI_MEM_ASYNC_PDU_CONTEXT_ULP1,
ISCSI_MEM_GLOBAL_HEADER, ISCSI_MEM_GLOBAL_HEADER,
SE_MEM_MAX SE_MEM_MAX
}; };
...@@ -266,9 +283,49 @@ struct invalidate_command_table { ...@@ -266,9 +283,49 @@ struct invalidate_command_table {
unsigned short cid; unsigned short cid;
} __packed; } __packed;
#define BEISCSI_GET_ULP_FROM_CRI(phwi_ctrlr, cri) \
(phwi_ctrlr->wrb_context[cri].ulp_num)
struct hwi_wrb_context {
struct list_head wrb_handle_list;
struct list_head wrb_handle_drvr_list;
struct wrb_handle **pwrb_handle_base;
struct wrb_handle **pwrb_handle_basestd;
struct iscsi_wrb *plast_wrb;
unsigned short alloc_index;
unsigned short free_index;
unsigned short wrb_handles_available;
unsigned short cid;
uint8_t ulp_num; /* ULP to which CID binded */
uint16_t register_set;
uint16_t doorbell_format;
uint32_t doorbell_offset;
};
struct ulp_cid_info {
unsigned short *cid_array;
unsigned short avlbl_cids;
unsigned short cid_alloc;
unsigned short cid_free;
};
#include "be.h"
#define chip_be2(phba) (phba->generation == BE_GEN2) #define chip_be2(phba) (phba->generation == BE_GEN2)
#define chip_be3_r(phba) (phba->generation == BE_GEN3) #define chip_be3_r(phba) (phba->generation == BE_GEN3)
#define is_chip_be2_be3r(phba) (chip_be3_r(phba) || (chip_be2(phba))) #define is_chip_be2_be3r(phba) (chip_be3_r(phba) || (chip_be2(phba)))
#define BEISCSI_ULP0 0
#define BEISCSI_ULP1 1
#define BEISCSI_ULP_COUNT 2
#define BEISCSI_ULP0_LOADED 0x01
#define BEISCSI_ULP1_LOADED 0x02
#define BEISCSI_ULP_AVLBL_CID(phba, ulp_num) \
(((struct ulp_cid_info *)phba->cid_array_info[ulp_num])->avlbl_cids)
#define BEISCSI_ULP0_AVLBL_CID(phba) \
BEISCSI_ULP_AVLBL_CID(phba, BEISCSI_ULP0)
#define BEISCSI_ULP1_AVLBL_CID(phba) \
BEISCSI_ULP_AVLBL_CID(phba, BEISCSI_ULP1)
struct beiscsi_hba { struct beiscsi_hba {
struct hba_parameters params; struct hba_parameters params;
struct hwi_controller *phwi_ctrlr; struct hwi_controller *phwi_ctrlr;
...@@ -303,17 +360,15 @@ struct beiscsi_hba { ...@@ -303,17 +360,15 @@ struct beiscsi_hba {
spinlock_t io_sgl_lock; spinlock_t io_sgl_lock;
spinlock_t mgmt_sgl_lock; spinlock_t mgmt_sgl_lock;
spinlock_t isr_lock; spinlock_t isr_lock;
spinlock_t async_pdu_lock;
unsigned int age; unsigned int age;
unsigned short avlbl_cids;
unsigned short cid_alloc;
unsigned short cid_free;
struct list_head hba_queue; struct list_head hba_queue;
#define BE_MAX_SESSION 2048 #define BE_MAX_SESSION 2048
#define BE_SET_CID_TO_CRI(cri_index, cid) \ #define BE_SET_CID_TO_CRI(cri_index, cid) \
(phba->cid_to_cri_map[cid] = cri_index) (phba->cid_to_cri_map[cid] = cri_index)
#define BE_GET_CRI_FROM_CID(cid) (phba->cid_to_cri_map[cid]) #define BE_GET_CRI_FROM_CID(cid) (phba->cid_to_cri_map[cid])
unsigned short cid_to_cri_map[BE_MAX_SESSION]; unsigned short cid_to_cri_map[BE_MAX_SESSION];
unsigned short *cid_array; struct ulp_cid_info *cid_array_info[BEISCSI_ULP_COUNT];
struct iscsi_endpoint **ep_array; struct iscsi_endpoint **ep_array;
struct beiscsi_conn **conn_table; struct beiscsi_conn **conn_table;
struct iscsi_boot_kset *boot_kset; struct iscsi_boot_kset *boot_kset;
...@@ -325,20 +380,21 @@ struct beiscsi_hba { ...@@ -325,20 +380,21 @@ struct beiscsi_hba {
* group together since they are used most frequently * group together since they are used most frequently
* for cid to cri conversion * for cid to cri conversion
*/ */
unsigned int iscsi_cid_start;
unsigned int phys_port; unsigned int phys_port;
unsigned int eqid_count;
unsigned int cqid_count;
unsigned int iscsi_cid_start[BEISCSI_ULP_COUNT];
#define BEISCSI_GET_CID_COUNT(phba, ulp_num) \
(phba->fw_config.iscsi_cid_count[ulp_num])
unsigned int iscsi_cid_count[BEISCSI_ULP_COUNT];
unsigned int iscsi_icd_count[BEISCSI_ULP_COUNT];
unsigned int iscsi_icd_start[BEISCSI_ULP_COUNT];
unsigned int iscsi_chain_start[BEISCSI_ULP_COUNT];
unsigned int iscsi_chain_count[BEISCSI_ULP_COUNT];
unsigned int isr_offset;
unsigned int iscsi_icd_start;
unsigned int iscsi_cid_count;
unsigned int iscsi_icd_count;
unsigned int pci_function;
unsigned short cid_alloc;
unsigned short cid_free;
unsigned short avlbl_cids;
unsigned short iscsi_features; unsigned short iscsi_features;
spinlock_t cid_lock; uint16_t dual_ulp_aware;
unsigned long ulp_supported;
} fw_config; } fw_config;
unsigned int state; unsigned int state;
...@@ -346,6 +402,7 @@ struct beiscsi_hba { ...@@ -346,6 +402,7 @@ struct beiscsi_hba {
bool ue_detected; bool ue_detected;
struct delayed_work beiscsi_hw_check_task; struct delayed_work beiscsi_hw_check_task;
bool mac_addr_set;
u8 mac_address[ETH_ALEN]; u8 mac_address[ETH_ALEN];
char fw_ver_str[BEISCSI_VER_STRLEN]; char fw_ver_str[BEISCSI_VER_STRLEN];
char wq_name[20]; char wq_name[20];
...@@ -374,6 +431,7 @@ struct beiscsi_conn { ...@@ -374,6 +431,7 @@ struct beiscsi_conn {
struct iscsi_conn *conn; struct iscsi_conn *conn;
struct beiscsi_hba *phba; struct beiscsi_hba *phba;
u32 exp_statsn; u32 exp_statsn;
u32 doorbell_offset;
u32 beiscsi_conn_cid; u32 beiscsi_conn_cid;
struct beiscsi_endpoint *ep; struct beiscsi_endpoint *ep;
unsigned short login_in_progress; unsigned short login_in_progress;
...@@ -474,7 +532,7 @@ struct amap_iscsi_sge { ...@@ -474,7 +532,7 @@ struct amap_iscsi_sge {
}; };
struct beiscsi_offload_params { struct beiscsi_offload_params {
u32 dw[5]; u32 dw[6];
}; };
#define OFFLD_PARAMS_ERL 0x00000003 #define OFFLD_PARAMS_ERL 0x00000003
...@@ -504,6 +562,7 @@ struct amap_beiscsi_offload_params { ...@@ -504,6 +562,7 @@ struct amap_beiscsi_offload_params {
u8 max_r2t[16]; u8 max_r2t[16];
u8 pad[8]; u8 pad[8];
u8 exp_statsn[32]; u8 exp_statsn[32];
u8 max_recv_data_segment_length[32];
}; };
/* void hwi_complete_drvr_msgs(struct beiscsi_conn *beiscsi_conn, /* void hwi_complete_drvr_msgs(struct beiscsi_conn *beiscsi_conn,
...@@ -567,7 +626,8 @@ struct hwi_async_pdu_context { ...@@ -567,7 +626,8 @@ struct hwi_async_pdu_context {
unsigned int buffer_size; unsigned int buffer_size;
unsigned int num_entries; unsigned int num_entries;
#define BE_GET_ASYNC_CRI_FROM_CID(cid) (pasync_ctx->cid_to_async_cri_map[cid])
unsigned short cid_to_async_cri_map[BE_MAX_SESSION];
/** /**
* This is a varying size list! Do not add anything * This is a varying size list! Do not add anything
* after this entry!! * after this entry!!
...@@ -885,30 +945,32 @@ struct amap_iscsi_target_context_update_wrb_v2 { ...@@ -885,30 +945,32 @@ struct amap_iscsi_target_context_update_wrb_v2 {
u8 first_burst_length[24]; /* DWORD 3 */ u8 first_burst_length[24]; /* DWORD 3 */
u8 rsvd3[8]; /* DOWRD 3 */ u8 rsvd3[8]; /* DOWRD 3 */
u8 max_r2t[16]; /* DWORD 4 */ u8 max_r2t[16]; /* DWORD 4 */
u8 rsvd4[10]; /* DWORD 4 */ u8 rsvd4; /* DWORD 4 */
u8 hde; /* DWORD 4 */ u8 hde; /* DWORD 4 */
u8 dde; /* DWORD 4 */ u8 dde; /* DWORD 4 */
u8 erl[2]; /* DWORD 4 */ u8 erl[2]; /* DWORD 4 */
u8 rsvd5[6]; /* DWORD 4 */
u8 imd; /* DWORD 4 */ u8 imd; /* DWORD 4 */
u8 ir2t; /* DWORD 4 */ u8 ir2t; /* DWORD 4 */
u8 rsvd6[3]; /* DWORD 4 */
u8 stat_sn[32]; /* DWORD 5 */ u8 stat_sn[32]; /* DWORD 5 */
u8 rsvd5[32]; /* DWORD 6 */ u8 rsvd7[32]; /* DWORD 6 */
u8 rsvd6[32]; /* DWORD 7 */ u8 rsvd8[32]; /* DWORD 7 */
u8 max_recv_dataseg_len[24]; /* DWORD 8 */ u8 max_recv_dataseg_len[24]; /* DWORD 8 */
u8 rsvd7[8]; /* DWORD 8 */ u8 rsvd9[8]; /* DWORD 8 */
u8 rsvd8[32]; /* DWORD 9 */ u8 rsvd10[32]; /* DWORD 9 */
u8 rsvd9[32]; /* DWORD 10 */ u8 rsvd11[32]; /* DWORD 10 */
u8 max_cxns[16]; /* DWORD 11 */ u8 max_cxns[16]; /* DWORD 11 */
u8 rsvd10[11]; /* DWORD 11*/ u8 rsvd12[11]; /* DWORD 11*/
u8 invld; /* DWORD 11 */ u8 invld; /* DWORD 11 */
u8 rsvd11;/* DWORD 11*/ u8 rsvd13;/* DWORD 11*/
u8 dmsg; /* DWORD 11 */ u8 dmsg; /* DWORD 11 */
u8 data_seq_inorder; /* DWORD 11 */ u8 data_seq_inorder; /* DWORD 11 */
u8 pdu_seq_inorder; /* DWORD 11 */ u8 pdu_seq_inorder; /* DWORD 11 */
u8 rsvd12[32]; /*DWORD 12 */ u8 rsvd14[32]; /*DWORD 12 */
u8 rsvd13[32]; /* DWORD 13 */ u8 rsvd15[32]; /* DWORD 13 */
u8 rsvd14[32]; /* DWORD 14 */ u8 rsvd16[32]; /* DWORD 14 */
u8 rsvd15[32]; /* DWORD 15 */ u8 rsvd17[32]; /* DWORD 15 */
} __packed; } __packed;
...@@ -919,6 +981,10 @@ struct be_ring { ...@@ -919,6 +981,10 @@ struct be_ring {
u32 cidx; /* consumer index */ u32 cidx; /* consumer index */
u32 pidx; /* producer index -- not used by most rings */ u32 pidx; /* producer index -- not used by most rings */
u32 item_size; /* size in bytes of one object */ u32 item_size; /* size in bytes of one object */
u8 ulp_num; /* ULP to which CID binded */
u16 register_set;
u16 doorbell_format;
u32 doorbell_offset;
void *va; /* The virtual address of the ring. This void *va; /* The virtual address of the ring. This
* should be last to allow 32 & 64 bit debugger * should be last to allow 32 & 64 bit debugger
...@@ -926,18 +992,6 @@ struct be_ring { ...@@ -926,18 +992,6 @@ struct be_ring {
*/ */
}; };
struct hwi_wrb_context {
struct list_head wrb_handle_list;
struct list_head wrb_handle_drvr_list;
struct wrb_handle **pwrb_handle_base;
struct wrb_handle **pwrb_handle_basestd;
struct iscsi_wrb *plast_wrb;
unsigned short alloc_index;
unsigned short free_index;
unsigned short wrb_handles_available;
unsigned short cid;
};
struct hwi_controller { struct hwi_controller {
struct list_head io_sgl_list; struct list_head io_sgl_list;
struct list_head eh_sgl_list; struct list_head eh_sgl_list;
...@@ -946,8 +1000,8 @@ struct hwi_controller { ...@@ -946,8 +1000,8 @@ struct hwi_controller {
struct hwi_wrb_context *wrb_context; struct hwi_wrb_context *wrb_context;
struct mcc_wrb *pmcc_wrb_base; struct mcc_wrb *pmcc_wrb_base;
struct be_ring default_pdu_hdr; struct be_ring default_pdu_hdr[BEISCSI_ULP_COUNT];
struct be_ring default_pdu_data; struct be_ring default_pdu_data[BEISCSI_ULP_COUNT];
struct hwi_context_memory *phwi_ctxt; struct hwi_context_memory *phwi_ctxt;
}; };
...@@ -978,11 +1032,10 @@ struct hwi_context_memory { ...@@ -978,11 +1032,10 @@ struct hwi_context_memory {
struct be_eq_obj be_eq[MAX_CPUS]; struct be_eq_obj be_eq[MAX_CPUS];
struct be_queue_info be_cq[MAX_CPUS - 1]; struct be_queue_info be_cq[MAX_CPUS - 1];
struct be_queue_info be_def_hdrq;
struct be_queue_info be_def_dataq;
struct be_queue_info *be_wrbq; struct be_queue_info *be_wrbq;
struct hwi_async_pdu_context *pasync_ctx; struct be_queue_info be_def_hdrq[BEISCSI_ULP_COUNT];
struct be_queue_info be_def_dataq[BEISCSI_ULP_COUNT];
struct hwi_async_pdu_context *pasync_ctx[BEISCSI_ULP_COUNT];
}; };
/* Logging related definitions */ /* Logging related definitions */
...@@ -992,6 +1045,7 @@ struct hwi_context_memory { ...@@ -992,6 +1045,7 @@ struct hwi_context_memory {
#define BEISCSI_LOG_EH 0x0008 /* Error Handler */ #define BEISCSI_LOG_EH 0x0008 /* Error Handler */
#define BEISCSI_LOG_IO 0x0010 /* IO Code Path */ #define BEISCSI_LOG_IO 0x0010 /* IO Code Path */
#define BEISCSI_LOG_CONFIG 0x0020 /* CONFIG Code Path */ #define BEISCSI_LOG_CONFIG 0x0020 /* CONFIG Code Path */
#define BEISCSI_LOG_ISCSI 0x0040 /* SCSI/iSCSI Protocol related Logs */
#define beiscsi_log(phba, level, mask, fmt, arg...) \ #define beiscsi_log(phba, level, mask, fmt, arg...) \
do { \ do { \
......
...@@ -278,6 +278,18 @@ unsigned int mgmt_get_session_info(struct beiscsi_hba *phba, ...@@ -278,6 +278,18 @@ unsigned int mgmt_get_session_info(struct beiscsi_hba *phba,
return tag; return tag;
} }
/**
* mgmt_get_fw_config()- Get the FW config for the function
* @ctrl: ptr to Ctrl Info
* @phba: ptr to the dev priv structure
*
* Get the FW config and resources available for the function.
* The resources are created based on the count received here.
*
* return
* Success: 0
* Failure: Non-Zero Value
**/
int mgmt_get_fw_config(struct be_ctrl_info *ctrl, int mgmt_get_fw_config(struct be_ctrl_info *ctrl,
struct beiscsi_hba *phba) struct beiscsi_hba *phba)
{ {
...@@ -291,31 +303,79 @@ int mgmt_get_fw_config(struct be_ctrl_info *ctrl, ...@@ -291,31 +303,79 @@ int mgmt_get_fw_config(struct be_ctrl_info *ctrl,
be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
OPCODE_COMMON_QUERY_FIRMWARE_CONFIG, sizeof(*req)); OPCODE_COMMON_QUERY_FIRMWARE_CONFIG,
EMBED_MBX_MAX_PAYLOAD_SIZE);
status = be_mbox_notify(ctrl); status = be_mbox_notify(ctrl);
if (!status) { if (!status) {
uint8_t ulp_num = 0;
struct be_fw_cfg *pfw_cfg; struct be_fw_cfg *pfw_cfg;
pfw_cfg = req; pfw_cfg = req;
if (!is_chip_be2_be3r(phba)) {
phba->fw_config.eqid_count = pfw_cfg->eqid_count;
phba->fw_config.cqid_count = pfw_cfg->cqid_count;
beiscsi_log(phba, KERN_INFO,
BEISCSI_LOG_INIT,
"BG_%d : EQ_Count : %d CQ_Count : %d\n",
phba->fw_config.eqid_count,
phba->fw_config.cqid_count);
}
for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++)
if (pfw_cfg->ulp[ulp_num].ulp_mode &
BEISCSI_ULP_ISCSI_INI_MODE)
set_bit(ulp_num,
&phba->fw_config.ulp_supported);
phba->fw_config.phys_port = pfw_cfg->phys_port; phba->fw_config.phys_port = pfw_cfg->phys_port;
phba->fw_config.iscsi_icd_start = for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) {
pfw_cfg->ulp[0].icd_base; if (test_bit(ulp_num, &phba->fw_config.ulp_supported)) {
phba->fw_config.iscsi_icd_count =
pfw_cfg->ulp[0].icd_count; phba->fw_config.iscsi_cid_start[ulp_num] =
phba->fw_config.iscsi_cid_start = pfw_cfg->ulp[ulp_num].sq_base;
pfw_cfg->ulp[0].sq_base; phba->fw_config.iscsi_cid_count[ulp_num] =
phba->fw_config.iscsi_cid_count = pfw_cfg->ulp[ulp_num].sq_count;
pfw_cfg->ulp[0].sq_count;
if (phba->fw_config.iscsi_cid_count > (BE2_MAX_SESSIONS / 2)) { phba->fw_config.iscsi_icd_start[ulp_num] =
beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT, pfw_cfg->ulp[ulp_num].icd_base;
"BG_%d : FW reported MAX CXNS as %d\t" phba->fw_config.iscsi_icd_count[ulp_num] =
"Max Supported = %d.\n", pfw_cfg->ulp[ulp_num].icd_count;
phba->fw_config.iscsi_cid_count,
BE2_MAX_SESSIONS); phba->fw_config.iscsi_chain_start[ulp_num] =
phba->fw_config.iscsi_cid_count = BE2_MAX_SESSIONS / 2; pfw_cfg->chain_icd[ulp_num].chain_base;
phba->fw_config.iscsi_chain_count[ulp_num] =
pfw_cfg->chain_icd[ulp_num].chain_count;
beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
"BG_%d : Function loaded on ULP : %d\n"
"\tiscsi_cid_count : %d\n"
"\tiscsi_cid_start : %d\n"
"\t iscsi_icd_count : %d\n"
"\t iscsi_icd_start : %d\n",
ulp_num,
phba->fw_config.
iscsi_cid_count[ulp_num],
phba->fw_config.
iscsi_cid_start[ulp_num],
phba->fw_config.
iscsi_icd_count[ulp_num],
phba->fw_config.
iscsi_icd_start[ulp_num]);
}
} }
phba->fw_config.dual_ulp_aware = (pfw_cfg->function_mode &
BEISCSI_FUNC_DUA_MODE);
beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
"BG_%d : DUA Mode : 0x%x\n",
phba->fw_config.dual_ulp_aware);
} else { } else {
beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_INIT, beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
"BG_%d : Failed in mgmt_get_fw_config\n"); "BG_%d : Failed in mgmt_get_fw_config\n");
status = -EINVAL;
} }
spin_unlock(&ctrl->mbox_lock); spin_unlock(&ctrl->mbox_lock);
...@@ -448,7 +508,16 @@ unsigned int mgmt_vendor_specific_fw_cmd(struct be_ctrl_info *ctrl, ...@@ -448,7 +508,16 @@ unsigned int mgmt_vendor_specific_fw_cmd(struct be_ctrl_info *ctrl,
return tag; return tag;
} }
int mgmt_epfw_cleanup(struct beiscsi_hba *phba, unsigned short chute) /**
* mgmt_epfw_cleanup()- Inform FW to cleanup data structures.
* @phba: pointer to dev priv structure
* @ulp_num: ULP number.
*
* return
* Success: 0
* Failure: Non-Zero Value
**/
int mgmt_epfw_cleanup(struct beiscsi_hba *phba, unsigned short ulp_num)
{ {
struct be_ctrl_info *ctrl = &phba->ctrl; struct be_ctrl_info *ctrl = &phba->ctrl;
struct be_mcc_wrb *wrb = wrb_from_mccq(phba); struct be_mcc_wrb *wrb = wrb_from_mccq(phba);
...@@ -462,9 +531,9 @@ int mgmt_epfw_cleanup(struct beiscsi_hba *phba, unsigned short chute) ...@@ -462,9 +531,9 @@ int mgmt_epfw_cleanup(struct beiscsi_hba *phba, unsigned short chute)
be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI, be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
OPCODE_COMMON_ISCSI_CLEANUP, sizeof(*req)); OPCODE_COMMON_ISCSI_CLEANUP, sizeof(*req));
req->chute = chute; req->chute = (1 << ulp_num);
req->hdr_ring_id = cpu_to_le16(HWI_GET_DEF_HDRQ_ID(phba)); req->hdr_ring_id = cpu_to_le16(HWI_GET_DEF_HDRQ_ID(phba, ulp_num));
req->data_ring_id = cpu_to_le16(HWI_GET_DEF_BUFQ_ID(phba)); req->data_ring_id = cpu_to_le16(HWI_GET_DEF_BUFQ_ID(phba, ulp_num));
status = be_mcc_notify_wait(phba); status = be_mcc_notify_wait(phba);
if (status) if (status)
...@@ -585,6 +654,16 @@ unsigned int mgmt_upload_connection(struct beiscsi_hba *phba, ...@@ -585,6 +654,16 @@ unsigned int mgmt_upload_connection(struct beiscsi_hba *phba,
return tag; return tag;
} }
/**
* mgmt_open_connection()- Establish a TCP CXN
* @dst_addr: Destination Address
* @beiscsi_ep: ptr to device endpoint struct
* @nonemb_cmd: ptr to memory allocated for command
*
* return
* Success: Tag number of the MBX Command issued
* Failure: Error code
**/
int mgmt_open_connection(struct beiscsi_hba *phba, int mgmt_open_connection(struct beiscsi_hba *phba,
struct sockaddr *dst_addr, struct sockaddr *dst_addr,
struct beiscsi_endpoint *beiscsi_ep, struct beiscsi_endpoint *beiscsi_ep,
...@@ -602,14 +681,17 @@ int mgmt_open_connection(struct beiscsi_hba *phba, ...@@ -602,14 +681,17 @@ int mgmt_open_connection(struct beiscsi_hba *phba,
struct phys_addr template_address = { 0, 0 }; struct phys_addr template_address = { 0, 0 };
struct phys_addr *ptemplate_address; struct phys_addr *ptemplate_address;
unsigned int tag = 0; unsigned int tag = 0;
unsigned int i; unsigned int i, ulp_num;
unsigned short cid = beiscsi_ep->ep_cid; unsigned short cid = beiscsi_ep->ep_cid;
struct be_sge *sge; struct be_sge *sge;
phwi_ctrlr = phba->phwi_ctrlr; phwi_ctrlr = phba->phwi_ctrlr;
phwi_context = phwi_ctrlr->phwi_ctxt; phwi_context = phwi_ctrlr->phwi_ctxt;
def_hdr_id = (unsigned short)HWI_GET_DEF_HDRQ_ID(phba);
def_data_id = (unsigned short)HWI_GET_DEF_BUFQ_ID(phba); ulp_num = phwi_ctrlr->wrb_context[BE_GET_CRI_FROM_CID(cid)].ulp_num;
def_hdr_id = (unsigned short)HWI_GET_DEF_HDRQ_ID(phba, ulp_num);
def_data_id = (unsigned short)HWI_GET_DEF_BUFQ_ID(phba, ulp_num);
ptemplate_address = &template_address; ptemplate_address = &template_address;
ISCSI_GET_PDU_TEMPLATE_ADDRESS(phba, ptemplate_address); ISCSI_GET_PDU_TEMPLATE_ADDRESS(phba, ptemplate_address);
...@@ -748,11 +830,14 @@ static int mgmt_exec_nonemb_cmd(struct beiscsi_hba *phba, ...@@ -748,11 +830,14 @@ static int mgmt_exec_nonemb_cmd(struct beiscsi_hba *phba,
rc = beiscsi_mccq_compl(phba, tag, NULL, nonemb_cmd->va); rc = beiscsi_mccq_compl(phba, tag, NULL, nonemb_cmd->va);
if (rc) { if (rc) {
/* Check if the IOCTL needs to be re-issued */
if (rc == -EAGAIN)
return rc;
beiscsi_log(phba, KERN_ERR, beiscsi_log(phba, KERN_ERR,
BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX, BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
"BG_%d : mgmt_exec_nonemb_cmd Failed status\n"); "BG_%d : mgmt_exec_nonemb_cmd Failed status\n");
rc = -EIO;
goto free_cmd; goto free_cmd;
} }
...@@ -861,7 +946,7 @@ int mgmt_set_ip(struct beiscsi_hba *phba, ...@@ -861,7 +946,7 @@ int mgmt_set_ip(struct beiscsi_hba *phba,
uint32_t boot_proto) uint32_t boot_proto)
{ {
struct be_cmd_get_def_gateway_resp gtway_addr_set; struct be_cmd_get_def_gateway_resp gtway_addr_set;
struct be_cmd_get_if_info_resp if_info; struct be_cmd_get_if_info_resp *if_info;
struct be_cmd_set_dhcp_req *dhcpreq; struct be_cmd_set_dhcp_req *dhcpreq;
struct be_cmd_rel_dhcp_req *reldhcp; struct be_cmd_rel_dhcp_req *reldhcp;
struct be_dma_mem nonemb_cmd; struct be_dma_mem nonemb_cmd;
...@@ -872,16 +957,17 @@ int mgmt_set_ip(struct beiscsi_hba *phba, ...@@ -872,16 +957,17 @@ int mgmt_set_ip(struct beiscsi_hba *phba,
if (mgmt_get_all_if_id(phba)) if (mgmt_get_all_if_id(phba))
return -EIO; return -EIO;
memset(&if_info, 0, sizeof(if_info));
ip_type = (ip_param->param == ISCSI_NET_PARAM_IPV6_ADDR) ? ip_type = (ip_param->param == ISCSI_NET_PARAM_IPV6_ADDR) ?
BE2_IPV6 : BE2_IPV4 ; BE2_IPV6 : BE2_IPV4 ;
rc = mgmt_get_if_info(phba, ip_type, &if_info); rc = mgmt_get_if_info(phba, ip_type, &if_info);
if (rc) if (rc) {
kfree(if_info);
return rc; return rc;
}
if (boot_proto == ISCSI_BOOTPROTO_DHCP) { if (boot_proto == ISCSI_BOOTPROTO_DHCP) {
if (if_info.dhcp_state) { if (if_info->dhcp_state) {
beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG, beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
"BG_%d : DHCP Already Enabled\n"); "BG_%d : DHCP Already Enabled\n");
return 0; return 0;
...@@ -894,9 +980,9 @@ int mgmt_set_ip(struct beiscsi_hba *phba, ...@@ -894,9 +980,9 @@ int mgmt_set_ip(struct beiscsi_hba *phba,
IP_V6_LEN : IP_V4_LEN; IP_V6_LEN : IP_V4_LEN;
} else { } else {
if (if_info.dhcp_state) { if (if_info->dhcp_state) {
memset(&if_info, 0, sizeof(if_info)); memset(if_info, 0, sizeof(*if_info));
rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd, rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
OPCODE_COMMON_ISCSI_NTWK_REL_STATELESS_IP_ADDR, OPCODE_COMMON_ISCSI_NTWK_REL_STATELESS_IP_ADDR,
sizeof(*reldhcp)); sizeof(*reldhcp));
...@@ -919,8 +1005,8 @@ int mgmt_set_ip(struct beiscsi_hba *phba, ...@@ -919,8 +1005,8 @@ int mgmt_set_ip(struct beiscsi_hba *phba,
} }
/* Delete the Static IP Set */ /* Delete the Static IP Set */
if (if_info.ip_addr.addr[0]) { if (if_info->ip_addr.addr[0]) {
rc = mgmt_static_ip_modify(phba, &if_info, ip_param, NULL, rc = mgmt_static_ip_modify(phba, if_info, ip_param, NULL,
IP_ACTION_DEL); IP_ACTION_DEL);
if (rc) if (rc)
return rc; return rc;
...@@ -966,7 +1052,7 @@ int mgmt_set_ip(struct beiscsi_hba *phba, ...@@ -966,7 +1052,7 @@ int mgmt_set_ip(struct beiscsi_hba *phba,
return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0); return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
} else { } else {
return mgmt_static_ip_modify(phba, &if_info, ip_param, return mgmt_static_ip_modify(phba, if_info, ip_param,
subnet_param, IP_ACTION_ADD); subnet_param, IP_ACTION_ADD);
} }
...@@ -1031,27 +1117,64 @@ int mgmt_get_gateway(struct beiscsi_hba *phba, int ip_type, ...@@ -1031,27 +1117,64 @@ int mgmt_get_gateway(struct beiscsi_hba *phba, int ip_type,
} }
int mgmt_get_if_info(struct beiscsi_hba *phba, int ip_type, int mgmt_get_if_info(struct beiscsi_hba *phba, int ip_type,
struct be_cmd_get_if_info_resp *if_info) struct be_cmd_get_if_info_resp **if_info)
{ {
struct be_cmd_get_if_info_req *req; struct be_cmd_get_if_info_req *req;
struct be_dma_mem nonemb_cmd; struct be_dma_mem nonemb_cmd;
uint32_t ioctl_size = sizeof(struct be_cmd_get_if_info_resp);
int rc; int rc;
if (mgmt_get_all_if_id(phba)) if (mgmt_get_all_if_id(phba))
return -EIO; return -EIO;
rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd, do {
OPCODE_COMMON_ISCSI_NTWK_GET_IF_INFO, rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
sizeof(*if_info)); OPCODE_COMMON_ISCSI_NTWK_GET_IF_INFO,
if (rc) ioctl_size);
return rc; if (rc)
return rc;
req = nonemb_cmd.va; req = nonemb_cmd.va;
req->interface_hndl = phba->interface_handle; req->interface_hndl = phba->interface_handle;
req->ip_type = ip_type; req->ip_type = ip_type;
/* Allocate memory for if_info */
*if_info = kzalloc(ioctl_size, GFP_KERNEL);
if (!*if_info) {
beiscsi_log(phba, KERN_ERR,
BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
"BG_%d : Memory Allocation Failure\n");
/* Free the DMA memory for the IOCTL issuing */
pci_free_consistent(phba->ctrl.pdev,
nonemb_cmd.size,
nonemb_cmd.va,
nonemb_cmd.dma);
return -ENOMEM;
}
rc = mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, *if_info,
ioctl_size);
/* Check if the error is because of Insufficent_Buffer */
if (rc == -EAGAIN) {
/* Get the new memory size */
ioctl_size = ((struct be_cmd_resp_hdr *)
nonemb_cmd.va)->actual_resp_len;
ioctl_size += sizeof(struct be_cmd_req_hdr);
return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, if_info, /* Free the previous allocated DMA memory */
sizeof(*if_info)); pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
nonemb_cmd.va,
nonemb_cmd.dma);
/* Free the virtual memory */
kfree(*if_info);
} else
break;
} while (true);
return rc;
} }
int mgmt_get_nic_conf(struct beiscsi_hba *phba, int mgmt_get_nic_conf(struct beiscsi_hba *phba,
...@@ -1281,7 +1404,7 @@ beiscsi_fw_ver_disp(struct device *dev, struct device_attribute *attr, ...@@ -1281,7 +1404,7 @@ beiscsi_fw_ver_disp(struct device *dev, struct device_attribute *attr,
} }
/** /**
* beiscsi_active_cid_disp()- Display Sessions Active * beiscsi_active_session_disp()- Display Sessions Active
* @dev: ptr to device not used. * @dev: ptr to device not used.
* @attr: device attribute, not used. * @attr: device attribute, not used.
* @buf: contains formatted text Session Count * @buf: contains formatted text Session Count
...@@ -1290,14 +1413,56 @@ beiscsi_fw_ver_disp(struct device *dev, struct device_attribute *attr, ...@@ -1290,14 +1413,56 @@ beiscsi_fw_ver_disp(struct device *dev, struct device_attribute *attr,
* size of the formatted string * size of the formatted string
**/ **/
ssize_t ssize_t
beiscsi_active_cid_disp(struct device *dev, struct device_attribute *attr, beiscsi_active_session_disp(struct device *dev, struct device_attribute *attr,
char *buf) char *buf)
{ {
struct Scsi_Host *shost = class_to_shost(dev); struct Scsi_Host *shost = class_to_shost(dev);
struct beiscsi_hba *phba = iscsi_host_priv(shost); struct beiscsi_hba *phba = iscsi_host_priv(shost);
uint16_t avlbl_cids = 0, ulp_num, len = 0, total_cids = 0;
for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) {
if (test_bit(ulp_num, (void *)&phba->fw_config.ulp_supported)) {
avlbl_cids = BEISCSI_ULP_AVLBL_CID(phba, ulp_num);
total_cids = BEISCSI_GET_CID_COUNT(phba, ulp_num);
len += snprintf(buf+len, PAGE_SIZE - len,
"ULP%d : %d\n", ulp_num,
(total_cids - avlbl_cids));
} else
len += snprintf(buf+len, PAGE_SIZE - len,
"ULP%d : %d\n", ulp_num, 0);
}
return snprintf(buf, PAGE_SIZE, "%d\n", return len;
(phba->params.cxns_per_ctrl - phba->avlbl_cids)); }
/**
* beiscsi_free_session_disp()- Display Avaliable Session
* @dev: ptr to device not used.
* @attr: device attribute, not used.
* @buf: contains formatted text Session Count
*
* return
* size of the formatted string
**/
ssize_t
beiscsi_free_session_disp(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct Scsi_Host *shost = class_to_shost(dev);
struct beiscsi_hba *phba = iscsi_host_priv(shost);
uint16_t ulp_num, len = 0;
for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) {
if (test_bit(ulp_num, (void *)&phba->fw_config.ulp_supported))
len += snprintf(buf+len, PAGE_SIZE - len,
"ULP%d : %d\n", ulp_num,
BEISCSI_ULP_AVLBL_CID(phba, ulp_num));
else
len += snprintf(buf+len, PAGE_SIZE - len,
"ULP%d : %d\n", ulp_num, 0);
}
return len;
} }
/** /**
...@@ -1338,6 +1503,25 @@ beiscsi_adap_family_disp(struct device *dev, struct device_attribute *attr, ...@@ -1338,6 +1503,25 @@ beiscsi_adap_family_disp(struct device *dev, struct device_attribute *attr,
} }
} }
/**
* beiscsi_phys_port()- Display Physical Port Identifier
* @dev: ptr to device not used.
* @attr: device attribute, not used.
* @buf: contains formatted text port identifier
*
* return
* size of the formatted string
**/
ssize_t
beiscsi_phys_port_disp(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct Scsi_Host *shost = class_to_shost(dev);
struct beiscsi_hba *phba = iscsi_host_priv(shost);
return snprintf(buf, PAGE_SIZE, "Port Identifier : %d\n",
phba->fw_config.phys_port);
}
void beiscsi_offload_cxn_v0(struct beiscsi_offload_params *params, void beiscsi_offload_cxn_v0(struct beiscsi_offload_params *params,
struct wrb_handle *pwrb_handle, struct wrb_handle *pwrb_handle,
...@@ -1411,10 +1595,6 @@ void beiscsi_offload_cxn_v2(struct beiscsi_offload_params *params, ...@@ -1411,10 +1595,6 @@ void beiscsi_offload_cxn_v2(struct beiscsi_offload_params *params,
memset(pwrb, 0, sizeof(*pwrb)); memset(pwrb, 0, sizeof(*pwrb));
AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
max_burst_length, pwrb, params->dw[offsetof
(struct amap_beiscsi_offload_params,
max_burst_length) / 32]);
AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
max_burst_length, pwrb, params->dw[offsetof max_burst_length, pwrb, params->dw[offsetof
(struct amap_beiscsi_offload_params, (struct amap_beiscsi_offload_params,
...@@ -1436,7 +1616,9 @@ void beiscsi_offload_cxn_v2(struct beiscsi_offload_params *params, ...@@ -1436,7 +1616,9 @@ void beiscsi_offload_cxn_v2(struct beiscsi_offload_params *params,
params->dw[offsetof(struct amap_beiscsi_offload_params, params->dw[offsetof(struct amap_beiscsi_offload_params,
first_burst_length) / 32]); first_burst_length) / 32]);
AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
max_recv_dataseg_len, pwrb, BEISCSI_MAX_RECV_DATASEG_LEN); max_recv_dataseg_len, pwrb,
params->dw[offsetof(struct amap_beiscsi_offload_params,
max_recv_data_segment_length) / 32]);
AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
max_cxns, pwrb, BEISCSI_MAX_CXNS); max_cxns, pwrb, BEISCSI_MAX_CXNS);
AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, erl, pwrb, AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, erl, pwrb,
......
...@@ -294,7 +294,7 @@ int mgmt_get_nic_conf(struct beiscsi_hba *phba, ...@@ -294,7 +294,7 @@ int mgmt_get_nic_conf(struct beiscsi_hba *phba,
struct be_cmd_get_nic_conf_resp *mac); struct be_cmd_get_nic_conf_resp *mac);
int mgmt_get_if_info(struct beiscsi_hba *phba, int ip_type, int mgmt_get_if_info(struct beiscsi_hba *phba, int ip_type,
struct be_cmd_get_if_info_resp *if_info); struct be_cmd_get_if_info_resp **if_info);
int mgmt_get_gateway(struct beiscsi_hba *phba, int ip_type, int mgmt_get_gateway(struct beiscsi_hba *phba, int ip_type,
struct be_cmd_get_def_gateway_resp *gateway); struct be_cmd_get_def_gateway_resp *gateway);
...@@ -315,12 +315,19 @@ ssize_t beiscsi_drvr_ver_disp(struct device *dev, ...@@ -315,12 +315,19 @@ ssize_t beiscsi_drvr_ver_disp(struct device *dev,
ssize_t beiscsi_fw_ver_disp(struct device *dev, ssize_t beiscsi_fw_ver_disp(struct device *dev,
struct device_attribute *attr, char *buf); struct device_attribute *attr, char *buf);
ssize_t beiscsi_active_cid_disp(struct device *dev, ssize_t beiscsi_active_session_disp(struct device *dev,
struct device_attribute *attr, char *buf); struct device_attribute *attr, char *buf);
ssize_t beiscsi_adap_family_disp(struct device *dev, ssize_t beiscsi_adap_family_disp(struct device *dev,
struct device_attribute *attr, char *buf); struct device_attribute *attr, char *buf);
ssize_t beiscsi_free_session_disp(struct device *dev,
struct device_attribute *attr, char *buf);
ssize_t beiscsi_phys_port_disp(struct device *dev,
struct device_attribute *attr, char *buf);
void beiscsi_offload_cxn_v0(struct beiscsi_offload_params *params, void beiscsi_offload_cxn_v0(struct beiscsi_offload_params *params,
struct wrb_handle *pwrb_handle, struct wrb_handle *pwrb_handle,
struct be_mem_descriptor *mem_descr); struct be_mem_descriptor *mem_descr);
......
...@@ -64,7 +64,7 @@ ...@@ -64,7 +64,7 @@
#include "bnx2fc_constants.h" #include "bnx2fc_constants.h"
#define BNX2FC_NAME "bnx2fc" #define BNX2FC_NAME "bnx2fc"
#define BNX2FC_VERSION "1.0.14" #define BNX2FC_VERSION "2.4.1"
#define PFX "bnx2fc: " #define PFX "bnx2fc: "
......
...@@ -22,7 +22,7 @@ DEFINE_PER_CPU(struct bnx2fc_percpu_s, bnx2fc_percpu); ...@@ -22,7 +22,7 @@ DEFINE_PER_CPU(struct bnx2fc_percpu_s, bnx2fc_percpu);
#define DRV_MODULE_NAME "bnx2fc" #define DRV_MODULE_NAME "bnx2fc"
#define DRV_MODULE_VERSION BNX2FC_VERSION #define DRV_MODULE_VERSION BNX2FC_VERSION
#define DRV_MODULE_RELDATE "Mar 08, 2013" #define DRV_MODULE_RELDATE "Sep 17, 2013"
static char version[] = static char version[] =
...@@ -542,8 +542,7 @@ static void bnx2fc_recv_frame(struct sk_buff *skb) ...@@ -542,8 +542,7 @@ static void bnx2fc_recv_frame(struct sk_buff *skb)
vn_port = fc_vport_id_lookup(lport, ntoh24(fh->fh_d_id)); vn_port = fc_vport_id_lookup(lport, ntoh24(fh->fh_d_id));
if (vn_port) { if (vn_port) {
port = lport_priv(vn_port); port = lport_priv(vn_port);
if (compare_ether_addr(port->data_src_addr, dest_mac) if (!ether_addr_equal(port->data_src_addr, dest_mac)) {
!= 0) {
BNX2FC_HBA_DBG(lport, "fpma mismatch\n"); BNX2FC_HBA_DBG(lport, "fpma mismatch\n");
put_cpu(); put_cpu();
kfree_skb(skb); kfree_skb(skb);
...@@ -1381,6 +1380,7 @@ struct bnx2fc_interface *bnx2fc_interface_create(struct bnx2fc_hba *hba, ...@@ -1381,6 +1380,7 @@ struct bnx2fc_interface *bnx2fc_interface_create(struct bnx2fc_hba *hba,
return NULL; return NULL;
} }
ctlr = fcoe_ctlr_device_priv(ctlr_dev); ctlr = fcoe_ctlr_device_priv(ctlr_dev);
ctlr->cdev = ctlr_dev;
interface = fcoe_ctlr_priv(ctlr); interface = fcoe_ctlr_priv(ctlr);
dev_hold(netdev); dev_hold(netdev);
kref_init(&interface->kref); kref_init(&interface->kref);
...@@ -2004,6 +2004,24 @@ static void bnx2fc_ulp_init(struct cnic_dev *dev) ...@@ -2004,6 +2004,24 @@ static void bnx2fc_ulp_init(struct cnic_dev *dev)
set_bit(BNX2FC_CNIC_REGISTERED, &hba->reg_with_cnic); set_bit(BNX2FC_CNIC_REGISTERED, &hba->reg_with_cnic);
} }
/* Assumes rtnl_lock and the bnx2fc_dev_lock are already taken */
static int __bnx2fc_disable(struct fcoe_ctlr *ctlr)
{
struct bnx2fc_interface *interface = fcoe_ctlr_priv(ctlr);
if (interface->enabled == true) {
if (!ctlr->lp) {
pr_err(PFX "__bnx2fc_disable: lport not found\n");
return -ENODEV;
} else {
interface->enabled = false;
fcoe_ctlr_link_down(ctlr);
fcoe_clean_pending_queue(ctlr->lp);
}
}
return 0;
}
/** /**
* Deperecated: Use bnx2fc_enabled() * Deperecated: Use bnx2fc_enabled()
*/ */
...@@ -2018,20 +2036,34 @@ static int bnx2fc_disable(struct net_device *netdev) ...@@ -2018,20 +2036,34 @@ static int bnx2fc_disable(struct net_device *netdev)
interface = bnx2fc_interface_lookup(netdev); interface = bnx2fc_interface_lookup(netdev);
ctlr = bnx2fc_to_ctlr(interface); ctlr = bnx2fc_to_ctlr(interface);
if (!interface || !ctlr->lp) {
if (!interface) {
rc = -ENODEV; rc = -ENODEV;
printk(KERN_ERR PFX "bnx2fc_disable: interface or lport not found\n"); pr_err(PFX "bnx2fc_disable: interface not found\n");
} else { } else {
interface->enabled = false; rc = __bnx2fc_disable(ctlr);
fcoe_ctlr_link_down(ctlr);
fcoe_clean_pending_queue(ctlr->lp);
} }
mutex_unlock(&bnx2fc_dev_lock); mutex_unlock(&bnx2fc_dev_lock);
rtnl_unlock(); rtnl_unlock();
return rc; return rc;
} }
static int __bnx2fc_enable(struct fcoe_ctlr *ctlr)
{
struct bnx2fc_interface *interface = fcoe_ctlr_priv(ctlr);
if (interface->enabled == false) {
if (!ctlr->lp) {
pr_err(PFX "__bnx2fc_enable: lport not found\n");
return -ENODEV;
} else if (!bnx2fc_link_ok(ctlr->lp)) {
fcoe_ctlr_link_up(ctlr);
interface->enabled = true;
}
}
return 0;
}
/** /**
* Deprecated: Use bnx2fc_enabled() * Deprecated: Use bnx2fc_enabled()
*/ */
...@@ -2046,12 +2078,11 @@ static int bnx2fc_enable(struct net_device *netdev) ...@@ -2046,12 +2078,11 @@ static int bnx2fc_enable(struct net_device *netdev)
interface = bnx2fc_interface_lookup(netdev); interface = bnx2fc_interface_lookup(netdev);
ctlr = bnx2fc_to_ctlr(interface); ctlr = bnx2fc_to_ctlr(interface);
if (!interface || !ctlr->lp) { if (!interface) {
rc = -ENODEV; rc = -ENODEV;
printk(KERN_ERR PFX "bnx2fc_enable: interface or lport not found\n"); pr_err(PFX "bnx2fc_enable: interface not found\n");
} else if (!bnx2fc_link_ok(ctlr->lp)) { } else {
fcoe_ctlr_link_up(ctlr); rc = __bnx2fc_enable(ctlr);
interface->enabled = true;
} }
mutex_unlock(&bnx2fc_dev_lock); mutex_unlock(&bnx2fc_dev_lock);
...@@ -2072,14 +2103,12 @@ static int bnx2fc_enable(struct net_device *netdev) ...@@ -2072,14 +2103,12 @@ static int bnx2fc_enable(struct net_device *netdev)
static int bnx2fc_ctlr_enabled(struct fcoe_ctlr_device *cdev) static int bnx2fc_ctlr_enabled(struct fcoe_ctlr_device *cdev)
{ {
struct fcoe_ctlr *ctlr = fcoe_ctlr_device_priv(cdev); struct fcoe_ctlr *ctlr = fcoe_ctlr_device_priv(cdev);
struct fc_lport *lport = ctlr->lp;
struct net_device *netdev = bnx2fc_netdev(lport);
switch (cdev->enabled) { switch (cdev->enabled) {
case FCOE_CTLR_ENABLED: case FCOE_CTLR_ENABLED:
return bnx2fc_enable(netdev); return __bnx2fc_enable(ctlr);
case FCOE_CTLR_DISABLED: case FCOE_CTLR_DISABLED:
return bnx2fc_disable(netdev); return __bnx2fc_disable(ctlr);
case FCOE_CTLR_UNUSED: case FCOE_CTLR_UNUSED:
default: default:
return -ENOTSUPP; return -ENOTSUPP;
......
...@@ -1246,6 +1246,12 @@ int bnx2fc_eh_abort(struct scsi_cmnd *sc_cmd) ...@@ -1246,6 +1246,12 @@ int bnx2fc_eh_abort(struct scsi_cmnd *sc_cmd)
kref_put(&io_req->refcount, kref_put(&io_req->refcount,
bnx2fc_cmd_release); /* drop timer hold */ bnx2fc_cmd_release); /* drop timer hold */
rc = bnx2fc_expl_logo(lport, io_req); rc = bnx2fc_expl_logo(lport, io_req);
/* This only occurs when an task abort was requested while ABTS
is in progress. Setting the IO_CLEANUP flag will skip the
RRQ process in the case when the fw generated SCSI_CMD cmpl
was a result from the ABTS request rather than the CLEANUP
request */
set_bit(BNX2FC_FLAG_IO_CLEANUP, &io_req->req_flags);
goto out; goto out;
} }
......
...@@ -308,6 +308,8 @@ struct AdapterCtlBlk { ...@@ -308,6 +308,8 @@ struct AdapterCtlBlk {
struct timer_list waiting_timer; struct timer_list waiting_timer;
struct timer_list selto_timer; struct timer_list selto_timer;
unsigned long last_reset;
u16 srb_count; u16 srb_count;
u8 sel_timeout; u8 sel_timeout;
...@@ -860,9 +862,9 @@ static void waiting_set_timer(struct AdapterCtlBlk *acb, unsigned long to) ...@@ -860,9 +862,9 @@ static void waiting_set_timer(struct AdapterCtlBlk *acb, unsigned long to)
init_timer(&acb->waiting_timer); init_timer(&acb->waiting_timer);
acb->waiting_timer.function = waiting_timeout; acb->waiting_timer.function = waiting_timeout;
acb->waiting_timer.data = (unsigned long) acb; acb->waiting_timer.data = (unsigned long) acb;
if (time_before(jiffies + to, acb->scsi_host->last_reset - HZ / 2)) if (time_before(jiffies + to, acb->last_reset - HZ / 2))
acb->waiting_timer.expires = acb->waiting_timer.expires =
acb->scsi_host->last_reset - HZ / 2 + 1; acb->last_reset - HZ / 2 + 1;
else else
acb->waiting_timer.expires = jiffies + to + 1; acb->waiting_timer.expires = jiffies + to + 1;
add_timer(&acb->waiting_timer); add_timer(&acb->waiting_timer);
...@@ -1319,7 +1321,7 @@ static int __dc395x_eh_bus_reset(struct scsi_cmnd *cmd) ...@@ -1319,7 +1321,7 @@ static int __dc395x_eh_bus_reset(struct scsi_cmnd *cmd)
udelay(500); udelay(500);
/* We may be in serious trouble. Wait some seconds */ /* We may be in serious trouble. Wait some seconds */
acb->scsi_host->last_reset = acb->last_reset =
jiffies + 3 * HZ / 2 + jiffies + 3 * HZ / 2 +
HZ * acb->eeprom.delay_time; HZ * acb->eeprom.delay_time;
...@@ -1462,9 +1464,9 @@ static void selto_timer(struct AdapterCtlBlk *acb) ...@@ -1462,9 +1464,9 @@ static void selto_timer(struct AdapterCtlBlk *acb)
acb->selto_timer.function = selection_timeout_missed; acb->selto_timer.function = selection_timeout_missed;
acb->selto_timer.data = (unsigned long) acb; acb->selto_timer.data = (unsigned long) acb;
if (time_before if (time_before
(jiffies + HZ, acb->scsi_host->last_reset + HZ / 2)) (jiffies + HZ, acb->last_reset + HZ / 2))
acb->selto_timer.expires = acb->selto_timer.expires =
acb->scsi_host->last_reset + HZ / 2 + 1; acb->last_reset + HZ / 2 + 1;
else else
acb->selto_timer.expires = jiffies + HZ + 1; acb->selto_timer.expires = jiffies + HZ + 1;
add_timer(&acb->selto_timer); add_timer(&acb->selto_timer);
...@@ -1535,7 +1537,7 @@ static u8 start_scsi(struct AdapterCtlBlk* acb, struct DeviceCtlBlk* dcb, ...@@ -1535,7 +1537,7 @@ static u8 start_scsi(struct AdapterCtlBlk* acb, struct DeviceCtlBlk* dcb,
} }
/* Allow starting of SCSI commands half a second before we allow the mid-level /* Allow starting of SCSI commands half a second before we allow the mid-level
* to queue them again after a reset */ * to queue them again after a reset */
if (time_before(jiffies, acb->scsi_host->last_reset - HZ / 2)) { if (time_before(jiffies, acb->last_reset - HZ / 2)) {
dprintkdbg(DBG_KG, "start_scsi: Refuse cmds (reset wait)\n"); dprintkdbg(DBG_KG, "start_scsi: Refuse cmds (reset wait)\n");
return 1; return 1;
} }
...@@ -3031,7 +3033,7 @@ static void disconnect(struct AdapterCtlBlk *acb) ...@@ -3031,7 +3033,7 @@ static void disconnect(struct AdapterCtlBlk *acb)
dprintkl(KERN_ERR, "disconnect: No such device\n"); dprintkl(KERN_ERR, "disconnect: No such device\n");
udelay(500); udelay(500);
/* Suspend queue for a while */ /* Suspend queue for a while */
acb->scsi_host->last_reset = acb->last_reset =
jiffies + HZ / 2 + jiffies + HZ / 2 +
HZ * acb->eeprom.delay_time; HZ * acb->eeprom.delay_time;
clear_fifo(acb, "disconnectEx"); clear_fifo(acb, "disconnectEx");
...@@ -3053,7 +3055,7 @@ static void disconnect(struct AdapterCtlBlk *acb) ...@@ -3053,7 +3055,7 @@ static void disconnect(struct AdapterCtlBlk *acb)
waiting_process_next(acb); waiting_process_next(acb);
} else if (srb->state & SRB_ABORT_SENT) { } else if (srb->state & SRB_ABORT_SENT) {
dcb->flag &= ~ABORT_DEV_; dcb->flag &= ~ABORT_DEV_;
acb->scsi_host->last_reset = jiffies + HZ / 2 + 1; acb->last_reset = jiffies + HZ / 2 + 1;
dprintkl(KERN_ERR, "disconnect: SRB_ABORT_SENT\n"); dprintkl(KERN_ERR, "disconnect: SRB_ABORT_SENT\n");
doing_srb_done(acb, DID_ABORT, srb->cmd, 1); doing_srb_done(acb, DID_ABORT, srb->cmd, 1);
waiting_process_next(acb); waiting_process_next(acb);
...@@ -3649,7 +3651,7 @@ static void scsi_reset_detect(struct AdapterCtlBlk *acb) ...@@ -3649,7 +3651,7 @@ static void scsi_reset_detect(struct AdapterCtlBlk *acb)
/*DC395x_write8(acb, TRM_S1040_DMA_CONTROL,STOPDMAXFER); */ /*DC395x_write8(acb, TRM_S1040_DMA_CONTROL,STOPDMAXFER); */
udelay(500); udelay(500);
/* Maybe we locked up the bus? Then lets wait even longer ... */ /* Maybe we locked up the bus? Then lets wait even longer ... */
acb->scsi_host->last_reset = acb->last_reset =
jiffies + 5 * HZ / 2 + jiffies + 5 * HZ / 2 +
HZ * acb->eeprom.delay_time; HZ * acb->eeprom.delay_time;
...@@ -4426,7 +4428,7 @@ static void adapter_init_scsi_host(struct Scsi_Host *host) ...@@ -4426,7 +4428,7 @@ static void adapter_init_scsi_host(struct Scsi_Host *host)
host->dma_channel = -1; host->dma_channel = -1;
host->unique_id = acb->io_port_base; host->unique_id = acb->io_port_base;
host->irq = acb->irq_level; host->irq = acb->irq_level;
host->last_reset = jiffies; acb->last_reset = jiffies;
host->max_id = 16; host->max_id = 16;
if (host->max_id - 1 == eeprom->scsi_id) if (host->max_id - 1 == eeprom->scsi_id)
...@@ -4484,7 +4486,7 @@ static void adapter_init_chip(struct AdapterCtlBlk *acb) ...@@ -4484,7 +4486,7 @@ static void adapter_init_chip(struct AdapterCtlBlk *acb)
/*spin_unlock_irq (&io_request_lock); */ /*spin_unlock_irq (&io_request_lock); */
udelay(500); udelay(500);
acb->scsi_host->last_reset = acb->last_reset =
jiffies + HZ / 2 + jiffies + HZ / 2 +
HZ * acb->eeprom.delay_time; HZ * acb->eeprom.delay_time;
......
...@@ -481,6 +481,11 @@ static int alua_check_sense(struct scsi_device *sdev, ...@@ -481,6 +481,11 @@ static int alua_check_sense(struct scsi_device *sdev,
* Power On, Reset, or Bus Device Reset, just retry. * Power On, Reset, or Bus Device Reset, just retry.
*/ */
return ADD_TO_MLQUEUE; return ADD_TO_MLQUEUE;
if (sense_hdr->asc == 0x29 && sense_hdr->ascq == 0x04)
/*
* Device internal reset
*/
return ADD_TO_MLQUEUE;
if (sense_hdr->asc == 0x2a && sense_hdr->ascq == 0x01) if (sense_hdr->asc == 0x2a && sense_hdr->ascq == 0x01)
/* /*
* Mode Parameters Changed * Mode Parameters Changed
...@@ -517,12 +522,13 @@ static int alua_check_sense(struct scsi_device *sdev, ...@@ -517,12 +522,13 @@ static int alua_check_sense(struct scsi_device *sdev,
/* /*
* alua_rtpg - Evaluate REPORT TARGET GROUP STATES * alua_rtpg - Evaluate REPORT TARGET GROUP STATES
* @sdev: the device to be evaluated. * @sdev: the device to be evaluated.
* @wait_for_transition: if nonzero, wait ALUA_FAILOVER_TIMEOUT seconds for device to exit transitioning state
* *
* Evaluate the Target Port Group State. * Evaluate the Target Port Group State.
* Returns SCSI_DH_DEV_OFFLINED if the path is * Returns SCSI_DH_DEV_OFFLINED if the path is
* found to be unusable. * found to be unusable.
*/ */
static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h) static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h, int wait_for_transition)
{ {
struct scsi_sense_hdr sense_hdr; struct scsi_sense_hdr sense_hdr;
int len, k, off, valid_states = 0; int len, k, off, valid_states = 0;
...@@ -594,7 +600,7 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h) ...@@ -594,7 +600,7 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h)
else else
h->transition_tmo = ALUA_FAILOVER_TIMEOUT; h->transition_tmo = ALUA_FAILOVER_TIMEOUT;
if (orig_transition_tmo != h->transition_tmo) { if (wait_for_transition && (orig_transition_tmo != h->transition_tmo)) {
sdev_printk(KERN_INFO, sdev, sdev_printk(KERN_INFO, sdev,
"%s: transition timeout set to %d seconds\n", "%s: transition timeout set to %d seconds\n",
ALUA_DH_NAME, h->transition_tmo); ALUA_DH_NAME, h->transition_tmo);
...@@ -632,14 +638,19 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h) ...@@ -632,14 +638,19 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h)
switch (h->state) { switch (h->state) {
case TPGS_STATE_TRANSITIONING: case TPGS_STATE_TRANSITIONING:
if (time_before(jiffies, expiry)) { if (wait_for_transition) {
/* State transition, retry */ if (time_before(jiffies, expiry)) {
interval += 2000; /* State transition, retry */
msleep(interval); interval += 2000;
goto retry; msleep(interval);
goto retry;
}
err = SCSI_DH_RETRY;
} else {
err = SCSI_DH_OK;
} }
/* Transitioning time exceeded, set port to standby */ /* Transitioning time exceeded, set port to standby */
err = SCSI_DH_RETRY;
h->state = TPGS_STATE_STANDBY; h->state = TPGS_STATE_STANDBY;
break; break;
case TPGS_STATE_OFFLINE: case TPGS_STATE_OFFLINE:
...@@ -673,7 +684,7 @@ static int alua_initialize(struct scsi_device *sdev, struct alua_dh_data *h) ...@@ -673,7 +684,7 @@ static int alua_initialize(struct scsi_device *sdev, struct alua_dh_data *h)
if (err != SCSI_DH_OK) if (err != SCSI_DH_OK)
goto out; goto out;
err = alua_rtpg(sdev, h); err = alua_rtpg(sdev, h, 0);
if (err != SCSI_DH_OK) if (err != SCSI_DH_OK)
goto out; goto out;
...@@ -733,7 +744,7 @@ static int alua_activate(struct scsi_device *sdev, ...@@ -733,7 +744,7 @@ static int alua_activate(struct scsi_device *sdev,
int err = SCSI_DH_OK; int err = SCSI_DH_OK;
int stpg = 0; int stpg = 0;
err = alua_rtpg(sdev, h); err = alua_rtpg(sdev, h, 1);
if (err != SCSI_DH_OK) if (err != SCSI_DH_OK)
goto out; goto out;
......
...@@ -786,6 +786,7 @@ static const struct scsi_dh_devlist rdac_dev_list[] = { ...@@ -786,6 +786,7 @@ static const struct scsi_dh_devlist rdac_dev_list[] = {
{"IBM", "1742"}, {"IBM", "1742"},
{"IBM", "1745"}, {"IBM", "1745"},
{"IBM", "1746"}, {"IBM", "1746"},
{"IBM", "1813"},
{"IBM", "1814"}, {"IBM", "1814"},
{"IBM", "1815"}, {"IBM", "1815"},
{"IBM", "1818"}, {"IBM", "1818"},
......
...@@ -448,19 +448,8 @@ static int adpt_queue_lck(struct scsi_cmnd * cmd, void (*done) (struct scsi_cmnd ...@@ -448,19 +448,8 @@ static int adpt_queue_lck(struct scsi_cmnd * cmd, void (*done) (struct scsi_cmnd
} }
rmb(); rmb();
/* if ((pHba->state) & DPTI_STATE_RESET)
* TODO: I need to block here if I am processing ioctl cmds return SCSI_MLQUEUE_HOST_BUSY;
* but if the outstanding cmds all finish before the ioctl,
* the scsi-core will not know to start sending cmds to me again.
* I need to a way to restart the scsi-cores queues or should I block
* calling scsi_done on the outstanding cmds instead
* for now we don't set the IOCTL state
*/
if(((pHba->state) & DPTI_STATE_IOCTL) || ((pHba->state) & DPTI_STATE_RESET)) {
pHba->host->last_reset = jiffies;
pHba->host->resetting = 1;
return 1;
}
// TODO if the cmd->device if offline then I may need to issue a bus rescan // TODO if the cmd->device if offline then I may need to issue a bus rescan
// followed by a get_lct to see if the device is there anymore // followed by a get_lct to see if the device is there anymore
...@@ -1811,21 +1800,23 @@ static int adpt_i2o_passthru(adpt_hba* pHba, u32 __user *arg) ...@@ -1811,21 +1800,23 @@ static int adpt_i2o_passthru(adpt_hba* pHba, u32 __user *arg)
} }
do { do {
if(pHba->host) /*
* Stop any new commands from enterring the
* controller while processing the ioctl
*/
if (pHba->host) {
scsi_block_requests(pHba->host);
spin_lock_irqsave(pHba->host->host_lock, flags); spin_lock_irqsave(pHba->host->host_lock, flags);
// This state stops any new commands from enterring the }
// controller while processing the ioctl
// pHba->state |= DPTI_STATE_IOCTL;
// We can't set this now - The scsi subsystem sets host_blocked and
// the queue empties and stops. We need a way to restart the queue
rcode = adpt_i2o_post_wait(pHba, msg, size, FOREVER); rcode = adpt_i2o_post_wait(pHba, msg, size, FOREVER);
if (rcode != 0) if (rcode != 0)
printk("adpt_i2o_passthru: post wait failed %d %p\n", printk("adpt_i2o_passthru: post wait failed %d %p\n",
rcode, reply); rcode, reply);
// pHba->state &= ~DPTI_STATE_IOCTL; if (pHba->host) {
if(pHba->host)
spin_unlock_irqrestore(pHba->host->host_lock, flags); spin_unlock_irqrestore(pHba->host->host_lock, flags);
} while(rcode == -ETIMEDOUT); scsi_unblock_requests(pHba->host);
}
} while (rcode == -ETIMEDOUT);
if(rcode){ if(rcode){
goto cleanup; goto cleanup;
......
...@@ -202,7 +202,6 @@ struct adpt_channel { ...@@ -202,7 +202,6 @@ struct adpt_channel {
// HBA state flags // HBA state flags
#define DPTI_STATE_RESET (0x01) #define DPTI_STATE_RESET (0x01)
#define DPTI_STATE_IOCTL (0x02)
typedef struct _adpt_hba { typedef struct _adpt_hba {
struct _adpt_hba *next; struct _adpt_hba *next;
......
...@@ -799,47 +799,47 @@ struct esas2r_adapter { ...@@ -799,47 +799,47 @@ struct esas2r_adapter {
struct esas2r_target *targetdb_end; struct esas2r_target *targetdb_end;
unsigned char *regs; unsigned char *regs;
unsigned char *data_window; unsigned char *data_window;
u32 volatile flags; long flags;
#define AF_PORT_CHANGE (u32)(0x00000001) #define AF_PORT_CHANGE 0
#define AF_CHPRST_NEEDED (u32)(0x00000004) #define AF_CHPRST_NEEDED 1
#define AF_CHPRST_PENDING (u32)(0x00000008) #define AF_CHPRST_PENDING 2
#define AF_CHPRST_DETECTED (u32)(0x00000010) #define AF_CHPRST_DETECTED 3
#define AF_BUSRST_NEEDED (u32)(0x00000020) #define AF_BUSRST_NEEDED 4
#define AF_BUSRST_PENDING (u32)(0x00000040) #define AF_BUSRST_PENDING 5
#define AF_BUSRST_DETECTED (u32)(0x00000080) #define AF_BUSRST_DETECTED 6
#define AF_DISABLED (u32)(0x00000100) #define AF_DISABLED 7
#define AF_FLASH_LOCK (u32)(0x00000200) #define AF_FLASH_LOCK 8
#define AF_OS_RESET (u32)(0x00002000) #define AF_OS_RESET 9
#define AF_FLASHING (u32)(0x00004000) #define AF_FLASHING 10
#define AF_POWER_MGT (u32)(0x00008000) #define AF_POWER_MGT 11
#define AF_NVR_VALID (u32)(0x00010000) #define AF_NVR_VALID 12
#define AF_DEGRADED_MODE (u32)(0x00020000) #define AF_DEGRADED_MODE 13
#define AF_DISC_PENDING (u32)(0x00040000) #define AF_DISC_PENDING 14
#define AF_TASKLET_SCHEDULED (u32)(0x00080000) #define AF_TASKLET_SCHEDULED 15
#define AF_HEARTBEAT (u32)(0x00200000) #define AF_HEARTBEAT 16
#define AF_HEARTBEAT_ENB (u32)(0x00400000) #define AF_HEARTBEAT_ENB 17
#define AF_NOT_PRESENT (u32)(0x00800000) #define AF_NOT_PRESENT 18
#define AF_CHPRST_STARTED (u32)(0x01000000) #define AF_CHPRST_STARTED 19
#define AF_FIRST_INIT (u32)(0x02000000) #define AF_FIRST_INIT 20
#define AF_POWER_DOWN (u32)(0x04000000) #define AF_POWER_DOWN 21
#define AF_DISC_IN_PROG (u32)(0x08000000) #define AF_DISC_IN_PROG 22
#define AF_COMM_LIST_TOGGLE (u32)(0x10000000) #define AF_COMM_LIST_TOGGLE 23
#define AF_LEGACY_SGE_MODE (u32)(0x20000000) #define AF_LEGACY_SGE_MODE 24
#define AF_DISC_POLLED (u32)(0x40000000) #define AF_DISC_POLLED 25
u32 volatile flags2; long flags2;
#define AF2_SERIAL_FLASH (u32)(0x00000001) #define AF2_SERIAL_FLASH 0
#define AF2_DEV_SCAN (u32)(0x00000002) #define AF2_DEV_SCAN 1
#define AF2_DEV_CNT_OK (u32)(0x00000004) #define AF2_DEV_CNT_OK 2
#define AF2_COREDUMP_AVAIL (u32)(0x00000008) #define AF2_COREDUMP_AVAIL 3
#define AF2_COREDUMP_SAVED (u32)(0x00000010) #define AF2_COREDUMP_SAVED 4
#define AF2_VDA_POWER_DOWN (u32)(0x00000100) #define AF2_VDA_POWER_DOWN 5
#define AF2_THUNDERLINK (u32)(0x00000200) #define AF2_THUNDERLINK 6
#define AF2_THUNDERBOLT (u32)(0x00000400) #define AF2_THUNDERBOLT 7
#define AF2_INIT_DONE (u32)(0x00000800) #define AF2_INIT_DONE 8
#define AF2_INT_PENDING (u32)(0x00001000) #define AF2_INT_PENDING 9
#define AF2_TIMER_TICK (u32)(0x00002000) #define AF2_TIMER_TICK 10
#define AF2_IRQ_CLAIMED (u32)(0x00004000) #define AF2_IRQ_CLAIMED 11
#define AF2_MSI_ENABLED (u32)(0x00008000) #define AF2_MSI_ENABLED 12
atomic_t disable_cnt; atomic_t disable_cnt;
atomic_t dis_ints_cnt; atomic_t dis_ints_cnt;
u32 int_stat; u32 int_stat;
...@@ -1150,16 +1150,6 @@ void esas2r_queue_fw_event(struct esas2r_adapter *a, ...@@ -1150,16 +1150,6 @@ void esas2r_queue_fw_event(struct esas2r_adapter *a,
int data_sz); int data_sz);
/* Inline functions */ /* Inline functions */
static inline u32 esas2r_lock_set_flags(volatile u32 *flags, u32 bits)
{
return test_and_set_bit(ilog2(bits), (volatile unsigned long *)flags);
}
static inline u32 esas2r_lock_clear_flags(volatile u32 *flags, u32 bits)
{
return test_and_clear_bit(ilog2(bits),
(volatile unsigned long *)flags);
}
/* Allocate a chip scatter/gather list entry */ /* Allocate a chip scatter/gather list entry */
static inline struct esas2r_mem_desc *esas2r_alloc_sgl(struct esas2r_adapter *a) static inline struct esas2r_mem_desc *esas2r_alloc_sgl(struct esas2r_adapter *a)
...@@ -1217,7 +1207,6 @@ static inline void esas2r_rq_init_request(struct esas2r_request *rq, ...@@ -1217,7 +1207,6 @@ static inline void esas2r_rq_init_request(struct esas2r_request *rq,
struct esas2r_adapter *a) struct esas2r_adapter *a)
{ {
union atto_vda_req *vrq = rq->vrq; union atto_vda_req *vrq = rq->vrq;
u32 handle;
INIT_LIST_HEAD(&rq->sg_table_head); INIT_LIST_HEAD(&rq->sg_table_head);
rq->data_buf = (void *)(vrq + 1); rq->data_buf = (void *)(vrq + 1);
...@@ -1253,11 +1242,9 @@ static inline void esas2r_rq_init_request(struct esas2r_request *rq, ...@@ -1253,11 +1242,9 @@ static inline void esas2r_rq_init_request(struct esas2r_request *rq,
/* /*
* add a reference number to the handle to make it unique (until it * add a reference number to the handle to make it unique (until it
* wraps of course) while preserving the upper word * wraps of course) while preserving the least significant word
*/ */
vrq->scsi.handle = (a->cmd_ref_no++ << 16) | (u16)vrq->scsi.handle;
handle = be32_to_cpu(vrq->scsi.handle) & 0xFFFF0000;
vrq->scsi.handle = cpu_to_be32(handle + a->cmd_ref_no++);
/* /*
* the following formats a SCSI request. the caller can override as * the following formats a SCSI request. the caller can override as
...@@ -1303,10 +1290,13 @@ static inline void esas2r_rq_destroy_request(struct esas2r_request *rq, ...@@ -1303,10 +1290,13 @@ static inline void esas2r_rq_destroy_request(struct esas2r_request *rq,
static inline bool esas2r_is_tasklet_pending(struct esas2r_adapter *a) static inline bool esas2r_is_tasklet_pending(struct esas2r_adapter *a)
{ {
return (a->flags & (AF_BUSRST_NEEDED | AF_BUSRST_DETECTED
| AF_CHPRST_NEEDED | AF_CHPRST_DETECTED return test_bit(AF_BUSRST_NEEDED, &a->flags) ||
| AF_PORT_CHANGE)) test_bit(AF_BUSRST_DETECTED, &a->flags) ||
? true : false; test_bit(AF_CHPRST_NEEDED, &a->flags) ||
test_bit(AF_CHPRST_DETECTED, &a->flags) ||
test_bit(AF_PORT_CHANGE, &a->flags);
} }
/* /*
...@@ -1345,24 +1335,24 @@ static inline void esas2r_enable_chip_interrupts(struct esas2r_adapter *a) ...@@ -1345,24 +1335,24 @@ static inline void esas2r_enable_chip_interrupts(struct esas2r_adapter *a)
static inline void esas2r_schedule_tasklet(struct esas2r_adapter *a) static inline void esas2r_schedule_tasklet(struct esas2r_adapter *a)
{ {
/* make sure we don't schedule twice */ /* make sure we don't schedule twice */
if (!(esas2r_lock_set_flags(&a->flags, AF_TASKLET_SCHEDULED) & if (!test_and_set_bit(AF_TASKLET_SCHEDULED, &a->flags))
ilog2(AF_TASKLET_SCHEDULED)))
tasklet_hi_schedule(&a->tasklet); tasklet_hi_schedule(&a->tasklet);
} }
static inline void esas2r_enable_heartbeat(struct esas2r_adapter *a) static inline void esas2r_enable_heartbeat(struct esas2r_adapter *a)
{ {
if (!(a->flags & (AF_DEGRADED_MODE | AF_CHPRST_PENDING)) if (!test_bit(AF_DEGRADED_MODE, &a->flags) &&
&& (a->nvram->options2 & SASNVR2_HEARTBEAT)) !test_bit(AF_CHPRST_PENDING, &a->flags) &&
esas2r_lock_set_flags(&a->flags, AF_HEARTBEAT_ENB); (a->nvram->options2 & SASNVR2_HEARTBEAT))
set_bit(AF_HEARTBEAT_ENB, &a->flags);
else else
esas2r_lock_clear_flags(&a->flags, AF_HEARTBEAT_ENB); clear_bit(AF_HEARTBEAT_ENB, &a->flags);
} }
static inline void esas2r_disable_heartbeat(struct esas2r_adapter *a) static inline void esas2r_disable_heartbeat(struct esas2r_adapter *a)
{ {
esas2r_lock_clear_flags(&a->flags, AF_HEARTBEAT_ENB); clear_bit(AF_HEARTBEAT_ENB, &a->flags);
esas2r_lock_clear_flags(&a->flags, AF_HEARTBEAT); clear_bit(AF_HEARTBEAT, &a->flags);
} }
/* Set the initial state for resetting the adapter on the next pass through /* Set the initial state for resetting the adapter on the next pass through
...@@ -1372,9 +1362,9 @@ static inline void esas2r_local_reset_adapter(struct esas2r_adapter *a) ...@@ -1372,9 +1362,9 @@ static inline void esas2r_local_reset_adapter(struct esas2r_adapter *a)
{ {
esas2r_disable_heartbeat(a); esas2r_disable_heartbeat(a);
esas2r_lock_set_flags(&a->flags, AF_CHPRST_NEEDED); set_bit(AF_CHPRST_NEEDED, &a->flags);
esas2r_lock_set_flags(&a->flags, AF_CHPRST_PENDING); set_bit(AF_CHPRST_PENDING, &a->flags);
esas2r_lock_set_flags(&a->flags, AF_DISC_PENDING); set_bit(AF_DISC_PENDING, &a->flags);
} }
/* See if an interrupt is pending on the adapter. */ /* See if an interrupt is pending on the adapter. */
......
...@@ -86,9 +86,9 @@ void esas2r_disc_initialize(struct esas2r_adapter *a) ...@@ -86,9 +86,9 @@ void esas2r_disc_initialize(struct esas2r_adapter *a)
esas2r_trace_enter(); esas2r_trace_enter();
esas2r_lock_clear_flags(&a->flags, AF_DISC_IN_PROG); clear_bit(AF_DISC_IN_PROG, &a->flags);
esas2r_lock_clear_flags(&a->flags2, AF2_DEV_SCAN); clear_bit(AF2_DEV_SCAN, &a->flags2);
esas2r_lock_clear_flags(&a->flags2, AF2_DEV_CNT_OK); clear_bit(AF2_DEV_CNT_OK, &a->flags2);
a->disc_start_time = jiffies_to_msecs(jiffies); a->disc_start_time = jiffies_to_msecs(jiffies);
a->disc_wait_time = nvr->dev_wait_time * 1000; a->disc_wait_time = nvr->dev_wait_time * 1000;
...@@ -107,7 +107,8 @@ void esas2r_disc_initialize(struct esas2r_adapter *a) ...@@ -107,7 +107,8 @@ void esas2r_disc_initialize(struct esas2r_adapter *a)
a->general_req.interrupt_cx = NULL; a->general_req.interrupt_cx = NULL;
if (a->flags & (AF_CHPRST_DETECTED | AF_POWER_MGT)) { if (test_bit(AF_CHPRST_DETECTED, &a->flags) ||
test_bit(AF_POWER_MGT, &a->flags)) {
if (a->prev_dev_cnt == 0) { if (a->prev_dev_cnt == 0) {
/* Don't bother waiting if there is nothing to wait /* Don't bother waiting if there is nothing to wait
* for. * for.
...@@ -212,9 +213,7 @@ void esas2r_disc_check_complete(struct esas2r_adapter *a) ...@@ -212,9 +213,7 @@ void esas2r_disc_check_complete(struct esas2r_adapter *a)
|| a->disc_wait_cnt == 0)) { || a->disc_wait_cnt == 0)) {
/* After three seconds of waiting, schedule a scan. */ /* After three seconds of waiting, schedule a scan. */
if (time >= 3000 if (time >= 3000
&& !(esas2r_lock_set_flags(&a->flags2, && !test_and_set_bit(AF2_DEV_SCAN, &a->flags2)) {
AF2_DEV_SCAN) &
ilog2(AF2_DEV_SCAN))) {
spin_lock_irqsave(&a->mem_lock, flags); spin_lock_irqsave(&a->mem_lock, flags);
esas2r_disc_queue_event(a, DCDE_DEV_SCAN); esas2r_disc_queue_event(a, DCDE_DEV_SCAN);
spin_unlock_irqrestore(&a->mem_lock, flags); spin_unlock_irqrestore(&a->mem_lock, flags);
...@@ -228,18 +227,14 @@ void esas2r_disc_check_complete(struct esas2r_adapter *a) ...@@ -228,18 +227,14 @@ void esas2r_disc_check_complete(struct esas2r_adapter *a)
* We are done waiting...we think. Adjust the wait time to * We are done waiting...we think. Adjust the wait time to
* consume events after the count is met. * consume events after the count is met.
*/ */
if (!(esas2r_lock_set_flags(&a->flags2, AF2_DEV_CNT_OK) if (!test_and_set_bit(AF2_DEV_CNT_OK, &a->flags2))
& ilog2(AF2_DEV_CNT_OK)))
a->disc_wait_time = time + 3000; a->disc_wait_time = time + 3000;
/* If we haven't done a full scan yet, do it now. */ /* If we haven't done a full scan yet, do it now. */
if (!(esas2r_lock_set_flags(&a->flags2, if (!test_and_set_bit(AF2_DEV_SCAN, &a->flags2)) {
AF2_DEV_SCAN) &
ilog2(AF2_DEV_SCAN))) {
spin_lock_irqsave(&a->mem_lock, flags); spin_lock_irqsave(&a->mem_lock, flags);
esas2r_disc_queue_event(a, DCDE_DEV_SCAN); esas2r_disc_queue_event(a, DCDE_DEV_SCAN);
spin_unlock_irqrestore(&a->mem_lock, flags); spin_unlock_irqrestore(&a->mem_lock, flags);
esas2r_trace_exit(); esas2r_trace_exit();
return; return;
} }
...@@ -253,9 +248,7 @@ void esas2r_disc_check_complete(struct esas2r_adapter *a) ...@@ -253,9 +248,7 @@ void esas2r_disc_check_complete(struct esas2r_adapter *a)
return; return;
} }
} else { } else {
if (!(esas2r_lock_set_flags(&a->flags2, if (!test_and_set_bit(AF2_DEV_SCAN, &a->flags2)) {
AF2_DEV_SCAN) &
ilog2(AF2_DEV_SCAN))) {
spin_lock_irqsave(&a->mem_lock, flags); spin_lock_irqsave(&a->mem_lock, flags);
esas2r_disc_queue_event(a, DCDE_DEV_SCAN); esas2r_disc_queue_event(a, DCDE_DEV_SCAN);
spin_unlock_irqrestore(&a->mem_lock, flags); spin_unlock_irqrestore(&a->mem_lock, flags);
...@@ -265,8 +258,8 @@ void esas2r_disc_check_complete(struct esas2r_adapter *a) ...@@ -265,8 +258,8 @@ void esas2r_disc_check_complete(struct esas2r_adapter *a)
/* We want to stop waiting for devices. */ /* We want to stop waiting for devices. */
a->disc_wait_time = 0; a->disc_wait_time = 0;
if ((a->flags & AF_DISC_POLLED) if (test_bit(AF_DISC_POLLED, &a->flags) &&
&& (a->flags & AF_DISC_IN_PROG)) { test_bit(AF_DISC_IN_PROG, &a->flags)) {
/* /*
* Polled discovery is still pending so continue the active * Polled discovery is still pending so continue the active
* discovery until it is done. At that point, we will stop * discovery until it is done. At that point, we will stop
...@@ -280,14 +273,14 @@ void esas2r_disc_check_complete(struct esas2r_adapter *a) ...@@ -280,14 +273,14 @@ void esas2r_disc_check_complete(struct esas2r_adapter *a)
* driven; i.e. There is no transition. * driven; i.e. There is no transition.
*/ */
esas2r_disc_fix_curr_requests(a); esas2r_disc_fix_curr_requests(a);
esas2r_lock_clear_flags(&a->flags, AF_DISC_PENDING); clear_bit(AF_DISC_PENDING, &a->flags);
/* /*
* We have deferred target state changes until now because we * We have deferred target state changes until now because we
* don't want to report any removals (due to the first arrival) * don't want to report any removals (due to the first arrival)
* until the device wait time expires. * until the device wait time expires.
*/ */
esas2r_lock_set_flags(&a->flags, AF_PORT_CHANGE); set_bit(AF_PORT_CHANGE, &a->flags);
} }
esas2r_trace_exit(); esas2r_trace_exit();
...@@ -308,7 +301,8 @@ void esas2r_disc_queue_event(struct esas2r_adapter *a, u8 disc_evt) ...@@ -308,7 +301,8 @@ void esas2r_disc_queue_event(struct esas2r_adapter *a, u8 disc_evt)
* Don't start discovery before or during polled discovery. if we did, * Don't start discovery before or during polled discovery. if we did,
* we would have a deadlock if we are in the ISR already. * we would have a deadlock if we are in the ISR already.
*/ */
if (!(a->flags & (AF_CHPRST_PENDING | AF_DISC_POLLED))) if (!test_bit(AF_CHPRST_PENDING, &a->flags) &&
!test_bit(AF_DISC_POLLED, &a->flags))
esas2r_disc_start_port(a); esas2r_disc_start_port(a);
esas2r_trace_exit(); esas2r_trace_exit();
...@@ -322,7 +316,7 @@ bool esas2r_disc_start_port(struct esas2r_adapter *a) ...@@ -322,7 +316,7 @@ bool esas2r_disc_start_port(struct esas2r_adapter *a)
esas2r_trace_enter(); esas2r_trace_enter();
if (a->flags & AF_DISC_IN_PROG) { if (test_bit(AF_DISC_IN_PROG, &a->flags)) {
esas2r_trace_exit(); esas2r_trace_exit();
return false; return false;
...@@ -330,7 +324,7 @@ bool esas2r_disc_start_port(struct esas2r_adapter *a) ...@@ -330,7 +324,7 @@ bool esas2r_disc_start_port(struct esas2r_adapter *a)
/* If there is a discovery waiting, process it. */ /* If there is a discovery waiting, process it. */
if (dc->disc_evt) { if (dc->disc_evt) {
if ((a->flags & AF_DISC_POLLED) if (test_bit(AF_DISC_POLLED, &a->flags)
&& a->disc_wait_time == 0) { && a->disc_wait_time == 0) {
/* /*
* We are doing polled discovery, but we no longer want * We are doing polled discovery, but we no longer want
...@@ -347,7 +341,7 @@ bool esas2r_disc_start_port(struct esas2r_adapter *a) ...@@ -347,7 +341,7 @@ bool esas2r_disc_start_port(struct esas2r_adapter *a)
esas2r_hdebug("disc done"); esas2r_hdebug("disc done");
esas2r_lock_set_flags(&a->flags, AF_PORT_CHANGE); set_bit(AF_PORT_CHANGE, &a->flags);
esas2r_trace_exit(); esas2r_trace_exit();
...@@ -356,10 +350,10 @@ bool esas2r_disc_start_port(struct esas2r_adapter *a) ...@@ -356,10 +350,10 @@ bool esas2r_disc_start_port(struct esas2r_adapter *a)
/* Handle the discovery context */ /* Handle the discovery context */
esas2r_trace("disc_evt: %d", dc->disc_evt); esas2r_trace("disc_evt: %d", dc->disc_evt);
esas2r_lock_set_flags(&a->flags, AF_DISC_IN_PROG); set_bit(AF_DISC_IN_PROG, &a->flags);
dc->flags = 0; dc->flags = 0;
if (a->flags & AF_DISC_POLLED) if (test_bit(AF_DISC_POLLED, &a->flags))
dc->flags |= DCF_POLLED; dc->flags |= DCF_POLLED;
rq->interrupt_cx = dc; rq->interrupt_cx = dc;
...@@ -379,7 +373,7 @@ bool esas2r_disc_start_port(struct esas2r_adapter *a) ...@@ -379,7 +373,7 @@ bool esas2r_disc_start_port(struct esas2r_adapter *a)
} }
/* Continue interrupt driven discovery */ /* Continue interrupt driven discovery */
if (!(a->flags & AF_DISC_POLLED)) if (!test_bit(AF_DISC_POLLED, &a->flags))
ret = esas2r_disc_continue(a, rq); ret = esas2r_disc_continue(a, rq);
else else
ret = true; ret = true;
...@@ -453,10 +447,10 @@ static bool esas2r_disc_continue(struct esas2r_adapter *a, ...@@ -453,10 +447,10 @@ static bool esas2r_disc_continue(struct esas2r_adapter *a,
/* Discovery is done...for now. */ /* Discovery is done...for now. */
rq->interrupt_cx = NULL; rq->interrupt_cx = NULL;
if (!(a->flags & AF_DISC_PENDING)) if (!test_bit(AF_DISC_PENDING, &a->flags))
esas2r_disc_fix_curr_requests(a); esas2r_disc_fix_curr_requests(a);
esas2r_lock_clear_flags(&a->flags, AF_DISC_IN_PROG); clear_bit(AF_DISC_IN_PROG, &a->flags);
/* Start the next discovery. */ /* Start the next discovery. */
return esas2r_disc_start_port(a); return esas2r_disc_start_port(a);
...@@ -480,7 +474,8 @@ static bool esas2r_disc_start_request(struct esas2r_adapter *a, ...@@ -480,7 +474,8 @@ static bool esas2r_disc_start_request(struct esas2r_adapter *a,
spin_lock_irqsave(&a->queue_lock, flags); spin_lock_irqsave(&a->queue_lock, flags);
if (!(a->flags & (AF_CHPRST_PENDING | AF_FLASHING))) if (!test_bit(AF_CHPRST_PENDING, &a->flags) &&
!test_bit(AF_FLASHING, &a->flags))
esas2r_disc_local_start_request(a, rq); esas2r_disc_local_start_request(a, rq);
else else
list_add_tail(&rq->req_list, &a->defer_list); list_add_tail(&rq->req_list, &a->defer_list);
......
...@@ -231,7 +231,7 @@ static bool load_image(struct esas2r_adapter *a, struct esas2r_request *rq) ...@@ -231,7 +231,7 @@ static bool load_image(struct esas2r_adapter *a, struct esas2r_request *rq)
* RS_PENDING, FM API tasks will continue. * RS_PENDING, FM API tasks will continue.
*/ */
rq->req_stat = RS_PENDING; rq->req_stat = RS_PENDING;
if (a->flags & AF_DEGRADED_MODE) if (test_bit(AF_DEGRADED_MODE, &a->flags))
/* not suppported for now */; /* not suppported for now */;
else else
build_flash_msg(a, rq); build_flash_msg(a, rq);
...@@ -315,7 +315,7 @@ static bool complete_fmapi_req(struct esas2r_adapter *a, ...@@ -315,7 +315,7 @@ static bool complete_fmapi_req(struct esas2r_adapter *a,
memset(fc->scratch, 0, FM_BUF_SZ); memset(fc->scratch, 0, FM_BUF_SZ);
esas2r_enable_heartbeat(a); esas2r_enable_heartbeat(a);
esas2r_lock_clear_flags(&a->flags, AF_FLASH_LOCK); clear_bit(AF_FLASH_LOCK, &a->flags);
return false; return false;
} }
...@@ -526,7 +526,7 @@ static void fw_download_proc(struct esas2r_adapter *a, ...@@ -526,7 +526,7 @@ static void fw_download_proc(struct esas2r_adapter *a,
* The download is complete. If in degraded mode, * The download is complete. If in degraded mode,
* attempt a chip reset. * attempt a chip reset.
*/ */
if (a->flags & AF_DEGRADED_MODE) if (test_bit(AF_DEGRADED_MODE, &a->flags))
esas2r_local_reset_adapter(a); esas2r_local_reset_adapter(a);
a->flash_ver = fi->cmp_hdr[CH_IT_BIOS].version; a->flash_ver = fi->cmp_hdr[CH_IT_BIOS].version;
...@@ -890,7 +890,7 @@ bool esas2r_process_fs_ioctl(struct esas2r_adapter *a, ...@@ -890,7 +890,7 @@ bool esas2r_process_fs_ioctl(struct esas2r_adapter *a,
} }
} }
if (a->flags & AF_DEGRADED_MODE) { if (test_bit(AF_DEGRADED_MODE, &a->flags)) {
fs->status = ATTO_STS_DEGRADED; fs->status = ATTO_STS_DEGRADED;
return false; return false;
} }
...@@ -945,8 +945,12 @@ static bool esas2r_flash_access(struct esas2r_adapter *a, u32 function) ...@@ -945,8 +945,12 @@ static bool esas2r_flash_access(struct esas2r_adapter *a, u32 function)
/* Now wait for the firmware to process it */ /* Now wait for the firmware to process it */
starttime = jiffies_to_msecs(jiffies); starttime = jiffies_to_msecs(jiffies);
timeout = a->flags &
(AF_CHPRST_PENDING | AF_DISC_PENDING) ? 40000 : 5000; if (test_bit(AF_CHPRST_PENDING, &a->flags) ||
test_bit(AF_DISC_PENDING, &a->flags))
timeout = 40000;
else
timeout = 5000;
while (true) { while (true) {
intstat = esas2r_read_register_dword(a, MU_INT_STATUS_OUT); intstat = esas2r_read_register_dword(a, MU_INT_STATUS_OUT);
...@@ -1008,7 +1012,7 @@ bool esas2r_read_flash_block(struct esas2r_adapter *a, ...@@ -1008,7 +1012,7 @@ bool esas2r_read_flash_block(struct esas2r_adapter *a,
u32 offset; u32 offset;
u32 iatvr; u32 iatvr;
if (a->flags2 & AF2_SERIAL_FLASH) if (test_bit(AF2_SERIAL_FLASH, &a->flags2))
iatvr = MW_DATA_ADDR_SER_FLASH + (from & -WINDOW_SIZE); iatvr = MW_DATA_ADDR_SER_FLASH + (from & -WINDOW_SIZE);
else else
iatvr = MW_DATA_ADDR_PAR_FLASH + (from & -WINDOW_SIZE); iatvr = MW_DATA_ADDR_PAR_FLASH + (from & -WINDOW_SIZE);
...@@ -1236,9 +1240,9 @@ static void esas2r_nvram_callback(struct esas2r_adapter *a, ...@@ -1236,9 +1240,9 @@ static void esas2r_nvram_callback(struct esas2r_adapter *a,
if (rq->req_stat != RS_PENDING) { if (rq->req_stat != RS_PENDING) {
/* update the NVRAM state */ /* update the NVRAM state */
if (rq->req_stat == RS_SUCCESS) if (rq->req_stat == RS_SUCCESS)
esas2r_lock_set_flags(&a->flags, AF_NVR_VALID); set_bit(AF_NVR_VALID, &a->flags);
else else
esas2r_lock_clear_flags(&a->flags, AF_NVR_VALID); clear_bit(AF_NVR_VALID, &a->flags);
esas2r_enable_heartbeat(a); esas2r_enable_heartbeat(a);
...@@ -1258,7 +1262,7 @@ bool esas2r_nvram_write(struct esas2r_adapter *a, struct esas2r_request *rq, ...@@ -1258,7 +1262,7 @@ bool esas2r_nvram_write(struct esas2r_adapter *a, struct esas2r_request *rq,
u32 *sas_address_dwords = (u32 *)&sas_address_bytes[0]; u32 *sas_address_dwords = (u32 *)&sas_address_bytes[0];
struct atto_vda_flash_req *vrq = &rq->vrq->flash; struct atto_vda_flash_req *vrq = &rq->vrq->flash;
if (a->flags & AF_DEGRADED_MODE) if (test_bit(AF_DEGRADED_MODE, &a->flags))
return false; return false;
if (down_interruptible(&a->nvram_semaphore)) if (down_interruptible(&a->nvram_semaphore))
...@@ -1302,7 +1306,7 @@ bool esas2r_nvram_write(struct esas2r_adapter *a, struct esas2r_request *rq, ...@@ -1302,7 +1306,7 @@ bool esas2r_nvram_write(struct esas2r_adapter *a, struct esas2r_request *rq,
FLS_OFFSET_NVR, FLS_OFFSET_NVR,
sizeof(struct esas2r_sas_nvram)); sizeof(struct esas2r_sas_nvram));
if (a->flags & AF_LEGACY_SGE_MODE) { if (test_bit(AF_LEGACY_SGE_MODE, &a->flags)) {
vrq->data.sge[0].length = vrq->data.sge[0].length =
cpu_to_le32(SGE_LAST | cpu_to_le32(SGE_LAST |
...@@ -1337,7 +1341,7 @@ bool esas2r_nvram_validate(struct esas2r_adapter *a) ...@@ -1337,7 +1341,7 @@ bool esas2r_nvram_validate(struct esas2r_adapter *a)
} else if (n->version > SASNVR_VERSION) { } else if (n->version > SASNVR_VERSION) {
esas2r_hdebug("invalid NVRAM version"); esas2r_hdebug("invalid NVRAM version");
} else { } else {
esas2r_lock_set_flags(&a->flags, AF_NVR_VALID); set_bit(AF_NVR_VALID, &a->flags);
rslt = true; rslt = true;
} }
...@@ -1359,7 +1363,7 @@ void esas2r_nvram_set_defaults(struct esas2r_adapter *a) ...@@ -1359,7 +1363,7 @@ void esas2r_nvram_set_defaults(struct esas2r_adapter *a)
struct esas2r_sas_nvram *n = a->nvram; struct esas2r_sas_nvram *n = a->nvram;
u32 time = jiffies_to_msecs(jiffies); u32 time = jiffies_to_msecs(jiffies);
esas2r_lock_clear_flags(&a->flags, AF_NVR_VALID); clear_bit(AF_NVR_VALID, &a->flags);
*n = default_sas_nvram; *n = default_sas_nvram;
n->sas_addr[3] |= 0x0F; n->sas_addr[3] |= 0x0F;
n->sas_addr[4] = HIBYTE(LOWORD(time)); n->sas_addr[4] = HIBYTE(LOWORD(time));
...@@ -1389,7 +1393,7 @@ bool esas2r_fm_api(struct esas2r_adapter *a, struct esas2r_flash_img *fi, ...@@ -1389,7 +1393,7 @@ bool esas2r_fm_api(struct esas2r_adapter *a, struct esas2r_flash_img *fi,
u8 j; u8 j;
struct esas2r_component_header *ch; struct esas2r_component_header *ch;
if (esas2r_lock_set_flags(&a->flags, AF_FLASH_LOCK) & AF_FLASH_LOCK) { if (test_and_set_bit(AF_FLASH_LOCK, &a->flags)) {
/* flag was already set */ /* flag was already set */
fi->status = FI_STAT_BUSY; fi->status = FI_STAT_BUSY;
return false; return false;
...@@ -1413,7 +1417,7 @@ bool esas2r_fm_api(struct esas2r_adapter *a, struct esas2r_flash_img *fi, ...@@ -1413,7 +1417,7 @@ bool esas2r_fm_api(struct esas2r_adapter *a, struct esas2r_flash_img *fi,
return complete_fmapi_req(a, rq, FI_STAT_IMG_VER); return complete_fmapi_req(a, rq, FI_STAT_IMG_VER);
} }
if (a->flags & AF_DEGRADED_MODE) if (test_bit(AF_DEGRADED_MODE, &a->flags))
return complete_fmapi_req(a, rq, FI_STAT_DEGRADED); return complete_fmapi_req(a, rq, FI_STAT_DEGRADED);
switch (fi->action) { switch (fi->action) {
......
...@@ -216,7 +216,7 @@ static void esas2r_setup_interrupts(struct esas2r_adapter *a, int intr_mode) ...@@ -216,7 +216,7 @@ static void esas2r_setup_interrupts(struct esas2r_adapter *a, int intr_mode)
goto use_legacy_interrupts; goto use_legacy_interrupts;
} }
a->intr_mode = INTR_MODE_MSI; a->intr_mode = INTR_MODE_MSI;
esas2r_lock_set_flags(&a->flags2, AF2_MSI_ENABLED); set_bit(AF2_MSI_ENABLED, &a->flags2);
break; break;
...@@ -252,7 +252,7 @@ static void esas2r_claim_interrupts(struct esas2r_adapter *a) ...@@ -252,7 +252,7 @@ static void esas2r_claim_interrupts(struct esas2r_adapter *a)
return; return;
} }
esas2r_lock_set_flags(&a->flags2, AF2_IRQ_CLAIMED); set_bit(AF2_IRQ_CLAIMED, &a->flags2);
esas2r_log(ESAS2R_LOG_INFO, esas2r_log(ESAS2R_LOG_INFO,
"claimed IRQ %d flags: 0x%lx", "claimed IRQ %d flags: 0x%lx",
a->pcid->irq, flags); a->pcid->irq, flags);
...@@ -380,10 +380,10 @@ int esas2r_init_adapter(struct Scsi_Host *host, struct pci_dev *pcid, ...@@ -380,10 +380,10 @@ int esas2r_init_adapter(struct Scsi_Host *host, struct pci_dev *pcid,
/* interrupts will be disabled until we are done with init */ /* interrupts will be disabled until we are done with init */
atomic_inc(&a->dis_ints_cnt); atomic_inc(&a->dis_ints_cnt);
atomic_inc(&a->disable_cnt); atomic_inc(&a->disable_cnt);
a->flags |= AF_CHPRST_PENDING set_bit(AF_CHPRST_PENDING, &a->flags);
| AF_DISC_PENDING set_bit(AF_DISC_PENDING, &a->flags);
| AF_FIRST_INIT set_bit(AF_FIRST_INIT, &a->flags);
| AF_LEGACY_SGE_MODE; set_bit(AF_LEGACY_SGE_MODE, &a->flags);
a->init_msg = ESAS2R_INIT_MSG_START; a->init_msg = ESAS2R_INIT_MSG_START;
a->max_vdareq_size = 128; a->max_vdareq_size = 128;
...@@ -440,11 +440,11 @@ int esas2r_init_adapter(struct Scsi_Host *host, struct pci_dev *pcid, ...@@ -440,11 +440,11 @@ int esas2r_init_adapter(struct Scsi_Host *host, struct pci_dev *pcid,
esas2r_claim_interrupts(a); esas2r_claim_interrupts(a);
if (a->flags2 & AF2_IRQ_CLAIMED) if (test_bit(AF2_IRQ_CLAIMED, &a->flags2))
esas2r_enable_chip_interrupts(a); esas2r_enable_chip_interrupts(a);
esas2r_lock_set_flags(&a->flags2, AF2_INIT_DONE); set_bit(AF2_INIT_DONE, &a->flags2);
if (!(a->flags & AF_DEGRADED_MODE)) if (!test_bit(AF_DEGRADED_MODE, &a->flags))
esas2r_kickoff_timer(a); esas2r_kickoff_timer(a);
esas2r_debug("esas2r_init_adapter done for %p (%d)", esas2r_debug("esas2r_init_adapter done for %p (%d)",
a, a->disable_cnt); a, a->disable_cnt);
...@@ -457,8 +457,8 @@ static void esas2r_adapter_power_down(struct esas2r_adapter *a, ...@@ -457,8 +457,8 @@ static void esas2r_adapter_power_down(struct esas2r_adapter *a,
{ {
struct esas2r_mem_desc *memdesc, *next; struct esas2r_mem_desc *memdesc, *next;
if ((a->flags2 & AF2_INIT_DONE) if ((test_bit(AF2_INIT_DONE, &a->flags2))
&& (!(a->flags & AF_DEGRADED_MODE))) { && (!test_bit(AF_DEGRADED_MODE, &a->flags))) {
if (!power_management) { if (!power_management) {
del_timer_sync(&a->timer); del_timer_sync(&a->timer);
tasklet_kill(&a->tasklet); tasklet_kill(&a->tasklet);
...@@ -508,19 +508,19 @@ static void esas2r_adapter_power_down(struct esas2r_adapter *a, ...@@ -508,19 +508,19 @@ static void esas2r_adapter_power_down(struct esas2r_adapter *a,
} }
/* Clean up interrupts */ /* Clean up interrupts */
if (a->flags2 & AF2_IRQ_CLAIMED) { if (test_bit(AF2_IRQ_CLAIMED, &a->flags2)) {
esas2r_log_dev(ESAS2R_LOG_INFO, esas2r_log_dev(ESAS2R_LOG_INFO,
&(a->pcid->dev), &(a->pcid->dev),
"free_irq(%d) called", a->pcid->irq); "free_irq(%d) called", a->pcid->irq);
free_irq(a->pcid->irq, a); free_irq(a->pcid->irq, a);
esas2r_debug("IRQ released"); esas2r_debug("IRQ released");
esas2r_lock_clear_flags(&a->flags2, AF2_IRQ_CLAIMED); clear_bit(AF2_IRQ_CLAIMED, &a->flags2);
} }
if (a->flags2 & AF2_MSI_ENABLED) { if (test_bit(AF2_MSI_ENABLED, &a->flags2)) {
pci_disable_msi(a->pcid); pci_disable_msi(a->pcid);
esas2r_lock_clear_flags(&a->flags2, AF2_MSI_ENABLED); clear_bit(AF2_MSI_ENABLED, &a->flags2);
esas2r_debug("MSI disabled"); esas2r_debug("MSI disabled");
} }
...@@ -641,12 +641,10 @@ void esas2r_kill_adapter(int i) ...@@ -641,12 +641,10 @@ void esas2r_kill_adapter(int i)
pci_set_drvdata(a->pcid, NULL); pci_set_drvdata(a->pcid, NULL);
esas2r_adapters[i] = NULL; esas2r_adapters[i] = NULL;
if (a->flags2 & AF2_INIT_DONE) { if (test_bit(AF2_INIT_DONE, &a->flags2)) {
esas2r_lock_clear_flags(&a->flags2, clear_bit(AF2_INIT_DONE, &a->flags2);
AF2_INIT_DONE);
esas2r_lock_set_flags(&a->flags, set_bit(AF_DEGRADED_MODE, &a->flags);
AF_DEGRADED_MODE);
esas2r_log_dev(ESAS2R_LOG_INFO, esas2r_log_dev(ESAS2R_LOG_INFO,
&(a->host->shost_gendev), &(a->host->shost_gendev),
...@@ -759,7 +757,7 @@ int esas2r_resume(struct pci_dev *pdev) ...@@ -759,7 +757,7 @@ int esas2r_resume(struct pci_dev *pdev)
esas2r_claim_interrupts(a); esas2r_claim_interrupts(a);
if (a->flags2 & AF2_IRQ_CLAIMED) { if (test_bit(AF2_IRQ_CLAIMED, &a->flags2)) {
/* /*
* Now that system interrupt(s) are claimed, we can enable * Now that system interrupt(s) are claimed, we can enable
* chip interrupts. * chip interrupts.
...@@ -781,7 +779,7 @@ int esas2r_resume(struct pci_dev *pdev) ...@@ -781,7 +779,7 @@ int esas2r_resume(struct pci_dev *pdev)
bool esas2r_set_degraded_mode(struct esas2r_adapter *a, char *error_str) bool esas2r_set_degraded_mode(struct esas2r_adapter *a, char *error_str)
{ {
esas2r_lock_set_flags(&a->flags, AF_DEGRADED_MODE); set_bit(AF_DEGRADED_MODE, &a->flags);
esas2r_log(ESAS2R_LOG_CRIT, esas2r_log(ESAS2R_LOG_CRIT,
"setting adapter to degraded mode: %s\n", error_str); "setting adapter to degraded mode: %s\n", error_str);
return false; return false;
...@@ -809,7 +807,7 @@ static void esas2r_init_pci_cfg_space(struct esas2r_adapter *a) ...@@ -809,7 +807,7 @@ static void esas2r_init_pci_cfg_space(struct esas2r_adapter *a)
int pcie_cap_reg; int pcie_cap_reg;
pcie_cap_reg = pci_find_capability(a->pcid, PCI_CAP_ID_EXP); pcie_cap_reg = pci_find_capability(a->pcid, PCI_CAP_ID_EXP);
if (0xffff & pcie_cap_reg) { if (pcie_cap_reg) {
u16 devcontrol; u16 devcontrol;
pci_read_config_word(a->pcid, pcie_cap_reg + PCI_EXP_DEVCTL, pci_read_config_word(a->pcid, pcie_cap_reg + PCI_EXP_DEVCTL,
...@@ -896,7 +894,7 @@ bool esas2r_init_adapter_struct(struct esas2r_adapter *a, ...@@ -896,7 +894,7 @@ bool esas2r_init_adapter_struct(struct esas2r_adapter *a,
&& (a->pcid->subsystem_device & ATTO_SSDID_TBT)) && (a->pcid->subsystem_device & ATTO_SSDID_TBT))
a->flags2 |= AF2_THUNDERBOLT; a->flags2 |= AF2_THUNDERBOLT;
if (a->flags2 & AF2_THUNDERBOLT) if (test_bit(AF2_THUNDERBOLT, &a->flags2))
a->flags2 |= AF2_SERIAL_FLASH; a->flags2 |= AF2_SERIAL_FLASH;
if (a->pcid->subsystem_device == ATTO_TLSH_1068) if (a->pcid->subsystem_device == ATTO_TLSH_1068)
...@@ -956,14 +954,14 @@ bool esas2r_init_adapter_struct(struct esas2r_adapter *a, ...@@ -956,14 +954,14 @@ bool esas2r_init_adapter_struct(struct esas2r_adapter *a,
a->outbound_copy = (u32 volatile *)high; a->outbound_copy = (u32 volatile *)high;
high += sizeof(u32); high += sizeof(u32);
if (!(a->flags & AF_NVR_VALID)) if (!test_bit(AF_NVR_VALID, &a->flags))
esas2r_nvram_set_defaults(a); esas2r_nvram_set_defaults(a);
/* update the caller's uncached memory area pointer */ /* update the caller's uncached memory area pointer */
*uncached_area = (void *)high; *uncached_area = (void *)high;
/* initialize the allocated memory */ /* initialize the allocated memory */
if (a->flags & AF_FIRST_INIT) { if (test_bit(AF_FIRST_INIT, &a->flags)) {
memset(a->req_table, 0, memset(a->req_table, 0,
(num_requests + num_ae_requests + (num_requests + num_ae_requests +
1) * sizeof(struct esas2r_request *)); 1) * sizeof(struct esas2r_request *));
...@@ -1019,7 +1017,7 @@ bool esas2r_check_adapter(struct esas2r_adapter *a) ...@@ -1019,7 +1017,7 @@ bool esas2r_check_adapter(struct esas2r_adapter *a)
* if the chip reset detected flag is set, we can bypass a bunch of * if the chip reset detected flag is set, we can bypass a bunch of
* stuff. * stuff.
*/ */
if (a->flags & AF_CHPRST_DETECTED) if (test_bit(AF_CHPRST_DETECTED, &a->flags))
goto skip_chip_reset; goto skip_chip_reset;
/* /*
...@@ -1057,14 +1055,12 @@ bool esas2r_check_adapter(struct esas2r_adapter *a) ...@@ -1057,14 +1055,12 @@ bool esas2r_check_adapter(struct esas2r_adapter *a)
doorbell); doorbell);
if (ver == DRBL_FW_VER_0) { if (ver == DRBL_FW_VER_0) {
esas2r_lock_set_flags(&a->flags, set_bit(AF_LEGACY_SGE_MODE, &a->flags);
AF_LEGACY_SGE_MODE);
a->max_vdareq_size = 128; a->max_vdareq_size = 128;
a->build_sgl = esas2r_build_sg_list_sge; a->build_sgl = esas2r_build_sg_list_sge;
} else if (ver == DRBL_FW_VER_1) { } else if (ver == DRBL_FW_VER_1) {
esas2r_lock_clear_flags(&a->flags, clear_bit(AF_LEGACY_SGE_MODE, &a->flags);
AF_LEGACY_SGE_MODE);
a->max_vdareq_size = 1024; a->max_vdareq_size = 1024;
a->build_sgl = esas2r_build_sg_list_prd; a->build_sgl = esas2r_build_sg_list_prd;
...@@ -1139,7 +1135,7 @@ bool esas2r_check_adapter(struct esas2r_adapter *a) ...@@ -1139,7 +1135,7 @@ bool esas2r_check_adapter(struct esas2r_adapter *a)
*a->outbound_copy = *a->outbound_copy =
a->last_write = a->last_write =
a->last_read = a->list_size - 1; a->last_read = a->list_size - 1;
esas2r_lock_set_flags(&a->flags, AF_COMM_LIST_TOGGLE); set_bit(AF_COMM_LIST_TOGGLE, &a->flags);
esas2r_write_register_dword(a, MU_IN_LIST_WRITE, MU_ILW_TOGGLE | esas2r_write_register_dword(a, MU_IN_LIST_WRITE, MU_ILW_TOGGLE |
a->last_write); a->last_write);
esas2r_write_register_dword(a, MU_OUT_LIST_COPY, MU_OLC_TOGGLE | esas2r_write_register_dword(a, MU_OUT_LIST_COPY, MU_OLC_TOGGLE |
...@@ -1204,9 +1200,9 @@ bool esas2r_check_adapter(struct esas2r_adapter *a) ...@@ -1204,9 +1200,9 @@ bool esas2r_check_adapter(struct esas2r_adapter *a)
*/ */
doorbell = esas2r_read_register_dword(a, MU_DOORBELL_IN_ENB); doorbell = esas2r_read_register_dword(a, MU_DOORBELL_IN_ENB);
if (doorbell & DRBL_POWER_DOWN) if (doorbell & DRBL_POWER_DOWN)
esas2r_lock_set_flags(&a->flags2, AF2_VDA_POWER_DOWN); set_bit(AF2_VDA_POWER_DOWN, &a->flags2);
else else
esas2r_lock_clear_flags(&a->flags2, AF2_VDA_POWER_DOWN); clear_bit(AF2_VDA_POWER_DOWN, &a->flags2);
/* /*
* enable assertion of outbound queue and doorbell interrupts in the * enable assertion of outbound queue and doorbell interrupts in the
...@@ -1239,8 +1235,8 @@ static bool esas2r_format_init_msg(struct esas2r_adapter *a, ...@@ -1239,8 +1235,8 @@ static bool esas2r_format_init_msg(struct esas2r_adapter *a,
0, 0,
NULL); NULL);
ci = (struct atto_vda_cfg_init *)&rq->vrq->cfg.data.init; ci = (struct atto_vda_cfg_init *)&rq->vrq->cfg.data.init;
ci->sgl_page_size = sgl_page_size; ci->sgl_page_size = cpu_to_le32(sgl_page_size);
ci->epoch_time = now.tv_sec; ci->epoch_time = cpu_to_le32(now.tv_sec);
rq->flags |= RF_FAILURE_OK; rq->flags |= RF_FAILURE_OK;
a->init_msg = ESAS2R_INIT_MSG_INIT; a->init_msg = ESAS2R_INIT_MSG_INIT;
break; break;
...@@ -1250,12 +1246,15 @@ static bool esas2r_format_init_msg(struct esas2r_adapter *a, ...@@ -1250,12 +1246,15 @@ static bool esas2r_format_init_msg(struct esas2r_adapter *a,
if (rq->req_stat == RS_SUCCESS) { if (rq->req_stat == RS_SUCCESS) {
u32 major; u32 major;
u32 minor; u32 minor;
u16 fw_release;
a->fw_version = le16_to_cpu( a->fw_version = le16_to_cpu(
rq->func_rsp.cfg_rsp.vda_version); rq->func_rsp.cfg_rsp.vda_version);
a->fw_build = rq->func_rsp.cfg_rsp.fw_build; a->fw_build = rq->func_rsp.cfg_rsp.fw_build;
major = LOBYTE(rq->func_rsp.cfg_rsp.fw_release); fw_release = le16_to_cpu(
minor = HIBYTE(rq->func_rsp.cfg_rsp.fw_release); rq->func_rsp.cfg_rsp.fw_release);
major = LOBYTE(fw_release);
minor = HIBYTE(fw_release);
a->fw_version += (major << 16) + (minor << 24); a->fw_version += (major << 16) + (minor << 24);
} else { } else {
esas2r_hdebug("FAILED"); esas2r_hdebug("FAILED");
...@@ -1266,9 +1265,8 @@ static bool esas2r_format_init_msg(struct esas2r_adapter *a, ...@@ -1266,9 +1265,8 @@ static bool esas2r_format_init_msg(struct esas2r_adapter *a,
* unsupported config requests correctly. * unsupported config requests correctly.
*/ */
if ((a->flags2 & AF2_THUNDERBOLT) if ((test_bit(AF2_THUNDERBOLT, &a->flags2))
|| (be32_to_cpu(a->fw_version) > || (be32_to_cpu(a->fw_version) > 0x00524702)) {
be32_to_cpu(0x47020052))) {
esas2r_hdebug("CFG get init"); esas2r_hdebug("CFG get init");
esas2r_build_cfg_req(a, esas2r_build_cfg_req(a,
rq, rq,
...@@ -1361,10 +1359,10 @@ bool esas2r_init_adapter_hw(struct esas2r_adapter *a, bool init_poll) ...@@ -1361,10 +1359,10 @@ bool esas2r_init_adapter_hw(struct esas2r_adapter *a, bool init_poll)
struct esas2r_request *rq; struct esas2r_request *rq;
u32 i; u32 i;
if (a->flags & AF_DEGRADED_MODE) if (test_bit(AF_DEGRADED_MODE, &a->flags))
goto exit; goto exit;
if (!(a->flags & AF_NVR_VALID)) { if (!test_bit(AF_NVR_VALID, &a->flags)) {
if (!esas2r_nvram_read_direct(a)) if (!esas2r_nvram_read_direct(a))
esas2r_log(ESAS2R_LOG_WARN, esas2r_log(ESAS2R_LOG_WARN,
"invalid/missing NVRAM parameters"); "invalid/missing NVRAM parameters");
...@@ -1376,8 +1374,8 @@ bool esas2r_init_adapter_hw(struct esas2r_adapter *a, bool init_poll) ...@@ -1376,8 +1374,8 @@ bool esas2r_init_adapter_hw(struct esas2r_adapter *a, bool init_poll)
} }
/* The firmware is ready. */ /* The firmware is ready. */
esas2r_lock_clear_flags(&a->flags, AF_DEGRADED_MODE); clear_bit(AF_DEGRADED_MODE, &a->flags);
esas2r_lock_clear_flags(&a->flags, AF_CHPRST_PENDING); clear_bit(AF_CHPRST_PENDING, &a->flags);
/* Post all the async event requests */ /* Post all the async event requests */
for (i = 0, rq = a->first_ae_req; i < num_ae_requests; i++, rq++) for (i = 0, rq = a->first_ae_req; i < num_ae_requests; i++, rq++)
...@@ -1398,8 +1396,8 @@ bool esas2r_init_adapter_hw(struct esas2r_adapter *a, bool init_poll) ...@@ -1398,8 +1396,8 @@ bool esas2r_init_adapter_hw(struct esas2r_adapter *a, bool init_poll)
esas2r_hdebug("firmware revision: %s", a->fw_rev); esas2r_hdebug("firmware revision: %s", a->fw_rev);
if ((a->flags & AF_CHPRST_DETECTED) if (test_bit(AF_CHPRST_DETECTED, &a->flags)
&& (a->flags & AF_FIRST_INIT)) { && (test_bit(AF_FIRST_INIT, &a->flags))) {
esas2r_enable_chip_interrupts(a); esas2r_enable_chip_interrupts(a);
return true; return true;
} }
...@@ -1423,18 +1421,18 @@ bool esas2r_init_adapter_hw(struct esas2r_adapter *a, bool init_poll) ...@@ -1423,18 +1421,18 @@ bool esas2r_init_adapter_hw(struct esas2r_adapter *a, bool init_poll)
* Block Tasklets from getting scheduled and indicate this is * Block Tasklets from getting scheduled and indicate this is
* polled discovery. * polled discovery.
*/ */
esas2r_lock_set_flags(&a->flags, AF_TASKLET_SCHEDULED); set_bit(AF_TASKLET_SCHEDULED, &a->flags);
esas2r_lock_set_flags(&a->flags, AF_DISC_POLLED); set_bit(AF_DISC_POLLED, &a->flags);
/* /*
* Temporarily bring the disable count to zero to enable * Temporarily bring the disable count to zero to enable
* deferred processing. Note that the count is already zero * deferred processing. Note that the count is already zero
* after the first initialization. * after the first initialization.
*/ */
if (a->flags & AF_FIRST_INIT) if (test_bit(AF_FIRST_INIT, &a->flags))
atomic_dec(&a->disable_cnt); atomic_dec(&a->disable_cnt);
while (a->flags & AF_DISC_PENDING) { while (test_bit(AF_DISC_PENDING, &a->flags)) {
schedule_timeout_interruptible(msecs_to_jiffies(100)); schedule_timeout_interruptible(msecs_to_jiffies(100));
/* /*
...@@ -1453,7 +1451,7 @@ bool esas2r_init_adapter_hw(struct esas2r_adapter *a, bool init_poll) ...@@ -1453,7 +1451,7 @@ bool esas2r_init_adapter_hw(struct esas2r_adapter *a, bool init_poll)
* we have to make sure the timer tick processes the * we have to make sure the timer tick processes the
* doorbell indicating the firmware is ready. * doorbell indicating the firmware is ready.
*/ */
if (!(a->flags & AF_CHPRST_PENDING)) if (!test_bit(AF_CHPRST_PENDING, &a->flags))
esas2r_disc_check_for_work(a); esas2r_disc_check_for_work(a);
/* Simulate a timer tick. */ /* Simulate a timer tick. */
...@@ -1473,11 +1471,11 @@ bool esas2r_init_adapter_hw(struct esas2r_adapter *a, bool init_poll) ...@@ -1473,11 +1471,11 @@ bool esas2r_init_adapter_hw(struct esas2r_adapter *a, bool init_poll)
} }
if (a->flags & AF_FIRST_INIT) if (test_bit(AF_FIRST_INIT, &a->flags))
atomic_inc(&a->disable_cnt); atomic_inc(&a->disable_cnt);
esas2r_lock_clear_flags(&a->flags, AF_DISC_POLLED); clear_bit(AF_DISC_POLLED, &a->flags);
esas2r_lock_clear_flags(&a->flags, AF_TASKLET_SCHEDULED); clear_bit(AF_TASKLET_SCHEDULED, &a->flags);
} }
...@@ -1504,26 +1502,26 @@ bool esas2r_init_adapter_hw(struct esas2r_adapter *a, bool init_poll) ...@@ -1504,26 +1502,26 @@ bool esas2r_init_adapter_hw(struct esas2r_adapter *a, bool init_poll)
* need to get done before we exit. * need to get done before we exit.
*/ */
if ((a->flags & AF_CHPRST_DETECTED) if (test_bit(AF_CHPRST_DETECTED, &a->flags) &&
&& (a->flags & AF_FIRST_INIT)) { test_bit(AF_FIRST_INIT, &a->flags)) {
/* /*
* Reinitialization was performed during the first * Reinitialization was performed during the first
* initialization. Only clear the chip reset flag so the * initialization. Only clear the chip reset flag so the
* original device polling is not cancelled. * original device polling is not cancelled.
*/ */
if (!rslt) if (!rslt)
esas2r_lock_clear_flags(&a->flags, AF_CHPRST_PENDING); clear_bit(AF_CHPRST_PENDING, &a->flags);
} else { } else {
/* First initialization or a subsequent re-init is complete. */ /* First initialization or a subsequent re-init is complete. */
if (!rslt) { if (!rslt) {
esas2r_lock_clear_flags(&a->flags, AF_CHPRST_PENDING); clear_bit(AF_CHPRST_PENDING, &a->flags);
esas2r_lock_clear_flags(&a->flags, AF_DISC_PENDING); clear_bit(AF_DISC_PENDING, &a->flags);
} }
/* Enable deferred processing after the first initialization. */ /* Enable deferred processing after the first initialization. */
if (a->flags & AF_FIRST_INIT) { if (test_bit(AF_FIRST_INIT, &a->flags)) {
esas2r_lock_clear_flags(&a->flags, AF_FIRST_INIT); clear_bit(AF_FIRST_INIT, &a->flags);
if (atomic_dec_return(&a->disable_cnt) == 0) if (atomic_dec_return(&a->disable_cnt) == 0)
esas2r_do_deferred_processes(a); esas2r_do_deferred_processes(a);
...@@ -1535,7 +1533,7 @@ bool esas2r_init_adapter_hw(struct esas2r_adapter *a, bool init_poll) ...@@ -1535,7 +1533,7 @@ bool esas2r_init_adapter_hw(struct esas2r_adapter *a, bool init_poll)
void esas2r_reset_adapter(struct esas2r_adapter *a) void esas2r_reset_adapter(struct esas2r_adapter *a)
{ {
esas2r_lock_set_flags(&a->flags, AF_OS_RESET); set_bit(AF_OS_RESET, &a->flags);
esas2r_local_reset_adapter(a); esas2r_local_reset_adapter(a);
esas2r_schedule_tasklet(a); esas2r_schedule_tasklet(a);
} }
...@@ -1550,17 +1548,17 @@ void esas2r_reset_chip(struct esas2r_adapter *a) ...@@ -1550,17 +1548,17 @@ void esas2r_reset_chip(struct esas2r_adapter *a)
* dump is located in the upper 512KB of the onchip SRAM. Make sure * dump is located in the upper 512KB of the onchip SRAM. Make sure
* to not overwrite a previous crash that was saved. * to not overwrite a previous crash that was saved.
*/ */
if ((a->flags2 & AF2_COREDUMP_AVAIL) if (test_bit(AF2_COREDUMP_AVAIL, &a->flags2) &&
&& !(a->flags2 & AF2_COREDUMP_SAVED)) { !test_bit(AF2_COREDUMP_SAVED, &a->flags2)) {
esas2r_read_mem_block(a, esas2r_read_mem_block(a,
a->fw_coredump_buff, a->fw_coredump_buff,
MW_DATA_ADDR_SRAM + 0x80000, MW_DATA_ADDR_SRAM + 0x80000,
ESAS2R_FWCOREDUMP_SZ); ESAS2R_FWCOREDUMP_SZ);
esas2r_lock_set_flags(&a->flags2, AF2_COREDUMP_SAVED); set_bit(AF2_COREDUMP_SAVED, &a->flags2);
} }
esas2r_lock_clear_flags(&a->flags2, AF2_COREDUMP_AVAIL); clear_bit(AF2_COREDUMP_AVAIL, &a->flags2);
/* Reset the chip */ /* Reset the chip */
if (a->pcid->revision == MVR_FREY_B2) if (a->pcid->revision == MVR_FREY_B2)
...@@ -1606,10 +1604,10 @@ static void esas2r_power_down_notify_firmware(struct esas2r_adapter *a) ...@@ -1606,10 +1604,10 @@ static void esas2r_power_down_notify_firmware(struct esas2r_adapter *a)
*/ */
void esas2r_power_down(struct esas2r_adapter *a) void esas2r_power_down(struct esas2r_adapter *a)
{ {
esas2r_lock_set_flags(&a->flags, AF_POWER_MGT); set_bit(AF_POWER_MGT, &a->flags);
esas2r_lock_set_flags(&a->flags, AF_POWER_DOWN); set_bit(AF_POWER_DOWN, &a->flags);
if (!(a->flags & AF_DEGRADED_MODE)) { if (!test_bit(AF_DEGRADED_MODE, &a->flags)) {
u32 starttime; u32 starttime;
u32 doorbell; u32 doorbell;
...@@ -1649,14 +1647,14 @@ void esas2r_power_down(struct esas2r_adapter *a) ...@@ -1649,14 +1647,14 @@ void esas2r_power_down(struct esas2r_adapter *a)
* For versions of firmware that support it tell them the driver * For versions of firmware that support it tell them the driver
* is powering down. * is powering down.
*/ */
if (a->flags2 & AF2_VDA_POWER_DOWN) if (test_bit(AF2_VDA_POWER_DOWN, &a->flags2))
esas2r_power_down_notify_firmware(a); esas2r_power_down_notify_firmware(a);
} }
/* Suspend I/O processing. */ /* Suspend I/O processing. */
esas2r_lock_set_flags(&a->flags, AF_OS_RESET); set_bit(AF_OS_RESET, &a->flags);
esas2r_lock_set_flags(&a->flags, AF_DISC_PENDING); set_bit(AF_DISC_PENDING, &a->flags);
esas2r_lock_set_flags(&a->flags, AF_CHPRST_PENDING); set_bit(AF_CHPRST_PENDING, &a->flags);
esas2r_process_adapter_reset(a); esas2r_process_adapter_reset(a);
...@@ -1673,9 +1671,9 @@ bool esas2r_power_up(struct esas2r_adapter *a, bool init_poll) ...@@ -1673,9 +1671,9 @@ bool esas2r_power_up(struct esas2r_adapter *a, bool init_poll)
{ {
bool ret; bool ret;
esas2r_lock_clear_flags(&a->flags, AF_POWER_DOWN); clear_bit(AF_POWER_DOWN, &a->flags);
esas2r_init_pci_cfg_space(a); esas2r_init_pci_cfg_space(a);
esas2r_lock_set_flags(&a->flags, AF_FIRST_INIT); set_bit(AF_FIRST_INIT, &a->flags);
atomic_inc(&a->disable_cnt); atomic_inc(&a->disable_cnt);
/* reinitialize the adapter */ /* reinitialize the adapter */
...@@ -1687,17 +1685,17 @@ bool esas2r_power_up(struct esas2r_adapter *a, bool init_poll) ...@@ -1687,17 +1685,17 @@ bool esas2r_power_up(struct esas2r_adapter *a, bool init_poll)
esas2r_send_reset_ae(a, true); esas2r_send_reset_ae(a, true);
/* clear this flag after initialization. */ /* clear this flag after initialization. */
esas2r_lock_clear_flags(&a->flags, AF_POWER_MGT); clear_bit(AF_POWER_MGT, &a->flags);
return ret; return ret;
} }
bool esas2r_is_adapter_present(struct esas2r_adapter *a) bool esas2r_is_adapter_present(struct esas2r_adapter *a)
{ {
if (a->flags & AF_NOT_PRESENT) if (test_bit(AF_NOT_PRESENT, &a->flags))
return false; return false;
if (esas2r_read_register_dword(a, MU_DOORBELL_OUT) == 0xFFFFFFFF) { if (esas2r_read_register_dword(a, MU_DOORBELL_OUT) == 0xFFFFFFFF) {
esas2r_lock_set_flags(&a->flags, AF_NOT_PRESENT); set_bit(AF_NOT_PRESENT, &a->flags);
return false; return false;
} }
......
此差异已折叠。
此差异已折叠。
...@@ -347,7 +347,7 @@ static bool csmi_ioctl_tunnel(struct esas2r_adapter *a, ...@@ -347,7 +347,7 @@ static bool csmi_ioctl_tunnel(struct esas2r_adapter *a,
{ {
struct atto_vda_ioctl_req *ioctl = &rq->vrq->ioctl; struct atto_vda_ioctl_req *ioctl = &rq->vrq->ioctl;
if (a->flags & AF_DEGRADED_MODE) if (test_bit(AF_DEGRADED_MODE, &a->flags))
return false; return false;
esas2r_sgc_init(sgc, a, rq, rq->vrq->ioctl.sge); esas2r_sgc_init(sgc, a, rq, rq->vrq->ioctl.sge);
...@@ -463,7 +463,7 @@ static int csmi_ioctl_callback(struct esas2r_adapter *a, ...@@ -463,7 +463,7 @@ static int csmi_ioctl_callback(struct esas2r_adapter *a,
gcc->bios_minor_rev = LOBYTE(HIWORD(a->flash_ver)); gcc->bios_minor_rev = LOBYTE(HIWORD(a->flash_ver));
gcc->bios_build_rev = LOWORD(a->flash_ver); gcc->bios_build_rev = LOWORD(a->flash_ver);
if (a->flags2 & AF2_THUNDERLINK) if (test_bit(AF2_THUNDERLINK, &a->flags2))
gcc->cntlr_flags = CSMI_CNTLRF_SAS_HBA gcc->cntlr_flags = CSMI_CNTLRF_SAS_HBA
| CSMI_CNTLRF_SATA_HBA; | CSMI_CNTLRF_SATA_HBA;
else else
...@@ -485,7 +485,7 @@ static int csmi_ioctl_callback(struct esas2r_adapter *a, ...@@ -485,7 +485,7 @@ static int csmi_ioctl_callback(struct esas2r_adapter *a,
{ {
struct atto_csmi_get_cntlr_sts *gcs = &ioctl_csmi->cntlr_sts; struct atto_csmi_get_cntlr_sts *gcs = &ioctl_csmi->cntlr_sts;
if (a->flags & AF_DEGRADED_MODE) if (test_bit(AF_DEGRADED_MODE, &a->flags))
gcs->status = CSMI_CNTLR_STS_FAILED; gcs->status = CSMI_CNTLR_STS_FAILED;
else else
gcs->status = CSMI_CNTLR_STS_GOOD; gcs->status = CSMI_CNTLR_STS_GOOD;
...@@ -819,10 +819,10 @@ static int hba_ioctl_callback(struct esas2r_adapter *a, ...@@ -819,10 +819,10 @@ static int hba_ioctl_callback(struct esas2r_adapter *a,
gai->adap_type = ATTO_GAI_AT_ESASRAID2; gai->adap_type = ATTO_GAI_AT_ESASRAID2;
if (a->flags2 & AF2_THUNDERLINK) if (test_bit(AF2_THUNDERLINK, &a->flags2))
gai->adap_type = ATTO_GAI_AT_TLSASHBA; gai->adap_type = ATTO_GAI_AT_TLSASHBA;
if (a->flags & AF_DEGRADED_MODE) if (test_bit(AF_DEGRADED_MODE, &a->flags))
gai->adap_flags |= ATTO_GAI_AF_DEGRADED; gai->adap_flags |= ATTO_GAI_AF_DEGRADED;
gai->adap_flags |= ATTO_GAI_AF_SPT_SUPP | gai->adap_flags |= ATTO_GAI_AF_SPT_SUPP |
...@@ -938,7 +938,7 @@ static int hba_ioctl_callback(struct esas2r_adapter *a, ...@@ -938,7 +938,7 @@ static int hba_ioctl_callback(struct esas2r_adapter *a,
u32 total_len = ESAS2R_FWCOREDUMP_SZ; u32 total_len = ESAS2R_FWCOREDUMP_SZ;
/* Size is zero if a core dump isn't present */ /* Size is zero if a core dump isn't present */
if (!(a->flags2 & AF2_COREDUMP_SAVED)) if (!test_bit(AF2_COREDUMP_SAVED, &a->flags2))
total_len = 0; total_len = 0;
if (len > total_len) if (len > total_len)
...@@ -960,8 +960,7 @@ static int hba_ioctl_callback(struct esas2r_adapter *a, ...@@ -960,8 +960,7 @@ static int hba_ioctl_callback(struct esas2r_adapter *a,
memset(a->fw_coredump_buff, 0, memset(a->fw_coredump_buff, 0,
ESAS2R_FWCOREDUMP_SZ); ESAS2R_FWCOREDUMP_SZ);
esas2r_lock_clear_flags(&a->flags2, clear_bit(AF2_COREDUMP_SAVED, &a->flags2);
AF2_COREDUMP_SAVED);
} else if (trc->trace_func != ATTO_TRC_TF_GET_INFO) { } else if (trc->trace_func != ATTO_TRC_TF_GET_INFO) {
hi->status = ATTO_STS_UNSUPPORTED; hi->status = ATTO_STS_UNSUPPORTED;
break; break;
...@@ -973,7 +972,7 @@ static int hba_ioctl_callback(struct esas2r_adapter *a, ...@@ -973,7 +972,7 @@ static int hba_ioctl_callback(struct esas2r_adapter *a,
trc->total_length = ESAS2R_FWCOREDUMP_SZ; trc->total_length = ESAS2R_FWCOREDUMP_SZ;
/* Return zero length buffer if core dump not present */ /* Return zero length buffer if core dump not present */
if (!(a->flags2 & AF2_COREDUMP_SAVED)) if (!test_bit(AF2_COREDUMP_SAVED, &a->flags2))
trc->total_length = 0; trc->total_length = 0;
} else { } else {
hi->status = ATTO_STS_UNSUPPORTED; hi->status = ATTO_STS_UNSUPPORTED;
...@@ -1048,6 +1047,7 @@ static int hba_ioctl_callback(struct esas2r_adapter *a, ...@@ -1048,6 +1047,7 @@ static int hba_ioctl_callback(struct esas2r_adapter *a,
else if (spt->flags & ATTO_SPTF_HEAD_OF_Q) else if (spt->flags & ATTO_SPTF_HEAD_OF_Q)
rq->vrq->scsi.flags |= cpu_to_le32(FCP_CMND_TA_HEAD_Q); rq->vrq->scsi.flags |= cpu_to_le32(FCP_CMND_TA_HEAD_Q);
if (!esas2r_build_sg_list(a, rq, sgc)) { if (!esas2r_build_sg_list(a, rq, sgc)) {
hi->status = ATTO_STS_OUT_OF_RSRC; hi->status = ATTO_STS_OUT_OF_RSRC;
break; break;
...@@ -1139,15 +1139,15 @@ static int hba_ioctl_callback(struct esas2r_adapter *a, ...@@ -1139,15 +1139,15 @@ static int hba_ioctl_callback(struct esas2r_adapter *a,
break; break;
} }
if (a->flags & AF_CHPRST_NEEDED) if (test_bit(AF_CHPRST_NEEDED, &a->flags))
ac->adap_state = ATTO_AC_AS_RST_SCHED; ac->adap_state = ATTO_AC_AS_RST_SCHED;
else if (a->flags & AF_CHPRST_PENDING) else if (test_bit(AF_CHPRST_PENDING, &a->flags))
ac->adap_state = ATTO_AC_AS_RST_IN_PROG; ac->adap_state = ATTO_AC_AS_RST_IN_PROG;
else if (a->flags & AF_DISC_PENDING) else if (test_bit(AF_DISC_PENDING, &a->flags))
ac->adap_state = ATTO_AC_AS_RST_DISC; ac->adap_state = ATTO_AC_AS_RST_DISC;
else if (a->flags & AF_DISABLED) else if (test_bit(AF_DISABLED, &a->flags))
ac->adap_state = ATTO_AC_AS_DISABLED; ac->adap_state = ATTO_AC_AS_DISABLED;
else if (a->flags & AF_DEGRADED_MODE) else if (test_bit(AF_DEGRADED_MODE, &a->flags))
ac->adap_state = ATTO_AC_AS_DEGRADED; ac->adap_state = ATTO_AC_AS_DEGRADED;
else else
ac->adap_state = ATTO_AC_AS_OK; ac->adap_state = ATTO_AC_AS_OK;
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册