Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0d522ee7 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
  ...
parents 5eea9be8 323f6226
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1867,7 +1867,7 @@ S: Supported
F:	drivers/net/wireless/brcm80211/

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
S:	Supported
F:	drivers/scsi/bnx2fc/
+23 −13
Original line number Diff line number Diff line
@@ -26,8 +26,8 @@

*/

#define blogic_drvr_version		"2.1.16"
#define blogic_drvr_date		"18 July 2002"
#define blogic_drvr_version		"2.1.17"
#define blogic_drvr_date		"12 September 2013"

#include <linux/module.h>
#include <linux/init.h>
@@ -311,11 +311,13 @@ static struct blogic_ccb *blogic_alloc_ccb(struct blogic_adapter *adapter)
  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;

	if (ccb->command != NULL)
		scsi_dma_unmap(ccb->command);
	if (dma_unmap)
		pci_unmap_single(adapter->pci_device, ccb->sensedata,
			 ccb->sense_datalen, PCI_DMA_FROMDEVICE);

@@ -2762,7 +2764,7 @@ static void blogic_process_ccbs(struct blogic_adapter *adapter)
			/*
			   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 */
			/*
			   Bus Device Reset CCBs have the command field
@@ -2791,7 +2793,7 @@ static void blogic_process_ccbs(struct blogic_adapter *adapter)
				if (ccb->status == BLOGIC_CCB_RESET &&
						ccb->tgt_id == tgt_id) {
					command = ccb->command;
					blogic_dealloc_ccb(ccb);
					blogic_dealloc_ccb(ccb, 1);
					adapter->active_cmds[tgt_id]--;
					command->result = DID_RESET << 16;
					command->scsi_done(command);
@@ -2862,7 +2864,7 @@ static void blogic_process_ccbs(struct blogic_adapter *adapter)
			/*
			   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.
			 */
@@ -3034,6 +3036,7 @@ static int blogic_qcmd_lck(struct scsi_cmnd *command,
	int buflen = scsi_bufflen(command);
	int count;
	struct blogic_ccb *ccb;
	dma_addr_t sense_buf;

	/*
	   SCSI REQUEST_SENSE commands will be executed automatically by the
@@ -3179,10 +3182,17 @@ static int blogic_qcmd_lck(struct scsi_cmnd *command,
	}
	memcpy(ccb->cdb, cdb, cdblen);
	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,
				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;
	if (blogic_multimaster_type(adapter)) {
		/*
@@ -3203,7 +3213,7 @@ static int blogic_qcmd_lck(struct scsi_cmnd *command,
			if (!blogic_write_outbox(adapter, BLOGIC_MBOX_START,
						ccb)) {
				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->scsi_done(command);
			}
@@ -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)
		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
	 * initiates a SCSI Bus Reset and issuing any SCSI Commands.  Some
+4 −4
Original line number Diff line number Diff line
@@ -2511,8 +2511,8 @@ static void asc_prt_scsi_host(struct Scsi_Host *s)
	struct asc_board *boardp = shost_priv(s);

	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",
	       s->host_busy, s->host_no, (unsigned)s->last_reset);
	printk(" host_busy %u, host_no %d,\n",
	       s->host_busy, s->host_no);

	printk(" base 0x%lx, io_port 0x%lx, irq %d,\n",
	       (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)
		shost->host_no);

	seq_printf(m,
		   " host_busy %u, last_reset %lu, max_id %u, max_lun %u, max_channel %u\n",
		   shost->host_busy, shost->last_reset, shost->max_id,
		   " host_busy %u, max_id %u, max_lun %u, max_channel %u\n",
		   shost->host_busy, shost->max_id,
		   shost->max_lun, shost->max_channel);

	seq_printf(m,
+1 −1
Original line number Diff line number Diff line
@@ -128,7 +128,7 @@ struct be_ctrl_info {

#define PAGE_SHIFT_4K 12
#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 */
#define PAGES_4K_SPANNED(_address, size)				\
+172 −28
Original line number Diff line number Diff line
@@ -17,9 +17,9 @@

#include <scsi/iscsi_proto.h>

#include "be_main.h"
#include "be.h"
#include "be_mgmt.h"
#include "be_main.h"

int beiscsi_pci_soft_reset(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_queue_info *mccq = &phba->ctrl.mcc_obj.q;

	if (beiscsi_error(phba))
	if (beiscsi_error(phba)) {
		free_mcc_tag(&phba->ctrl, tag);
		return -EIO;
	}

	/* wait for the mccq completion */
	rc = wait_event_interruptible_timeout(
@@ -173,7 +175,11 @@ int beiscsi_mccq_compl(struct beiscsi_hba *phba,
			    BEISCSI_LOG_INIT | BEISCSI_LOG_EH |
			    BEISCSI_LOG_CONFIG,
			    "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;
	} else
		rc = 0;
@@ -208,10 +214,18 @@ int beiscsi_mccq_compl(struct beiscsi_hba *phba,

		if (status == MCC_STATUS_INSUFFICIENT_BUFFER) {
			ioctl_resp_hdr = (struct be_cmd_resp_hdr *) ioctl_hdr;
			if (ioctl_resp_hdr->response_length)
			beiscsi_log(phba, KERN_WARNING,
				    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:
@@ -363,7 +377,7 @@ void beiscsi_async_link_state_process(struct beiscsi_hba *phba,
	} else if ((evt->port_link_status & ASYNC_EVENT_LINK_UP) ||
		    ((evt->port_link_status & ASYNC_EVENT_LOGICAL) &&
		     (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_CONFIG | BEISCSI_LOG_INIT,
@@ -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)
{
#define BEISCSI_MBX_RDY_BIT_TIMEOUT	4000	/* 4sec */
	void __iomem *db = ctrl->db + MPU_MAILBOX_DB_OFFSET;
	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;

	do {
	DECLARE_WAIT_QUEUE_HEAD_ONSTACK(rdybit_check_q);

	if (beiscsi_error(phba))
		return -EIO;

	timeout = jiffies + (HZ * 110);

	do {
		for (i = 0; i < BEISCSI_MBX_RDY_BIT_TIMEOUT; i++) {
			ready = ioread32(db) & MPU_MAILBOX_DB_RDY_MASK;
		if (ready)
			if (ready) {
				read_flag = true;
				break;
			}
			mdelay(1);
		}

		if (!read_flag) {
			wait_event_timeout(rdybit_check_q,
					  (read_flag != true),
					   HZ * 5);
		}
	} while ((time_before(jiffies, timeout)) && !read_flag);

		if (wait > BEISCSI_HOST_MBX_TIMEOUT) {
	if (!read_flag) {
		beiscsi_log(phba, KERN_ERR,
			    BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
			    "BC_%d : FW Timed Out\n");
			phba->fw_timeout = true;
			beiscsi_ue_detect(phba);
			return -EBUSY;
			ret = -EBUSY;
	}

		mdelay(1);
		wait++;
	} while (true);
	return 0;
	return ret;
}

/*
@@ -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_mcc_wrb *wrb;

	BUG_ON(atomic_read(&mccq->used) >= mccq->len);
	WARN_ON(atomic_read(&mccq->used) >= mccq->len);
	wrb = queue_head_node(mccq);
	memset(wrb, 0, sizeof(*wrb));
	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,
	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,
				    struct be_queue_info *cq,
				    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_defq_create_req *req = embedded_payload(wrb);
@@ -1030,6 +1077,11 @@ int be_cmd_create_default_pdu_queue(struct be_ctrl_info *ctrl,
			   OPCODE_COMMON_ISCSI_DEFQ_CREATE, sizeof(*req));

	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)) {
		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,

	status = be_mbox_notify(ctrl);
	if (!status) {
		struct be_ring *defq_ring;
		struct be_defq_create_resp *resp = embedded_payload(wrb);

		dq->id = le16_to_cpu(resp->id);
		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);

	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_wrbq_create_req *req = embedded_payload(wrb);
	struct be_wrbq_create_resp *resp = embedded_payload(wrb);
	struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev);
	int status;

	spin_lock(&ctrl->mbox_lock);
@@ -1093,13 +1176,74 @@ 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,
		OPCODE_COMMON_ISCSI_WRBQ_CREATE, sizeof(*req));
	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);

	status = be_mbox_notify(ctrl);
	if (!status) {
		wrbq->id = le16_to_cpu(resp->cid);
		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);
	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;
}
Loading