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

Commit 09a0f719 authored by Vikas Chaudhary's avatar Vikas Chaudhary Committed by James Bottomley
Browse files

[SCSI] qla4xxx: added support for abort task management command



* Handles SCSI command aborts.
* Serialization srb between error handler and command
  completion path.

Signed-off-by: default avatarVikas Chaudhary <vikas.chaudhary@qlogic.com>
Signed-off-by: default avatarRavi Anand <ravi.anand@qlogic.com>
Reviewed-by: default avatarMike Christie <michaelc@cs.wisc.edu>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@suse.de>
parent 5369887a
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -172,7 +172,7 @@ struct srb {

	struct scsi_cmnd *cmd;	/* (4) SCSI command block */
	dma_addr_t dma_handle;	/* (4) for unmap of single transfers */
	atomic_t ref_count;	/* reference count for this srb */
	struct kref srb_ref;	/* reference count for this srb */
	uint32_t fw_ddb_index;
	uint8_t err_id;		/* error id */
#define SRB_ERR_PORT	   1	/* Request failed because "port down" */
+1 −0
Original line number Diff line number Diff line
@@ -215,6 +215,7 @@ union external_hw_config_reg {
/*  Mailbox command definitions */
#define MBOX_CMD_ABOUT_FW			0x0009
#define MBOX_CMD_PING				0x000B
#define MBOX_CMD_ABORT_TASK			0x0015
#define MBOX_CMD_LUN_RESET			0x0016
#define MBOX_CMD_TARGET_WARM_RESET		0x0017
#define MBOX_CMD_GET_MANAGEMENT_DATA		0x001E
+2 −1
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ void qla4xxx_process_aen(struct scsi_qla_host * ha, uint8_t process_aen);
int qla4xxx_get_dhcp_ip_address(struct scsi_qla_host * ha);
int qla4xxx_relogin_device(struct scsi_qla_host * ha,
			   struct ddb_entry * ddb_entry);
int qla4xxx_abort_task(struct scsi_qla_host *ha, struct srb *srb);
int qla4xxx_reset_lun(struct scsi_qla_host * ha, struct ddb_entry * ddb_entry,
		      int lun);
int qla4xxx_reset_target(struct scsi_qla_host * ha,
@@ -65,7 +66,7 @@ void qla4xxx_interrupt_service_routine(struct scsi_qla_host * ha,
int qla4xxx_init_rings(struct scsi_qla_host * ha);
struct srb * qla4xxx_del_from_active_array(struct scsi_qla_host *ha,
					uint32_t index);
void qla4xxx_srb_compl(struct scsi_qla_host *ha, struct srb *srb);
void qla4xxx_srb_compl(struct kref *ref);
int qla4xxx_reinitialize_ddb_list(struct scsi_qla_host * ha);
int qla4xxx_process_ddb_changed(struct scsi_qla_host *ha, uint32_t fw_ddb_index,
		uint32_t state, uint32_t conn_error);
+3 −3
Original line number Diff line number Diff line
@@ -97,7 +97,7 @@ qla4xxx_status_cont_entry(struct scsi_qla_host *ha,

	/* Place command on done queue. */
	if (srb->req_sense_len == 0) {
		qla4xxx_srb_compl(ha, srb);
		kref_put(&srb->srb_ref, qla4xxx_srb_compl);
		ha->status_srb = NULL;
	}
}
@@ -329,7 +329,7 @@ status_entry_exit:
	/* complete the request, if not waiting for status_continuation pkt */
	srb->cc_stat = sts_entry->completionStatus;
	if (ha->status_srb == NULL)
		qla4xxx_srb_compl(ha, srb);
		kref_put(&srb->srb_ref, qla4xxx_srb_compl);
}

/**
@@ -393,7 +393,7 @@ static void qla4xxx_process_response_queue(struct scsi_qla_host * ha)
			/* ETRY normally by sending it back with
			 * DID_BUS_BUSY */
			srb->cmd->result = DID_BUS_BUSY << 16;
			qla4xxx_srb_compl(ha, srb);
			kref_put(&srb->srb_ref, qla4xxx_srb_compl);
			break;

		case ET_CONTINUE:
+53 −0
Original line number Diff line number Diff line
@@ -761,6 +761,59 @@ exit_get_event_log:
				  event_log_dma);
}

/**
 * qla4xxx_abort_task - issues Abort Task
 * @ha: Pointer to host adapter structure.
 * @srb: Pointer to srb entry
 *
 * This routine performs a LUN RESET on the specified target/lun.
 * The caller must ensure that the ddb_entry and lun_entry pointers
 * are valid before calling this routine.
 **/
int qla4xxx_abort_task(struct scsi_qla_host *ha, struct srb *srb)
{
	uint32_t mbox_cmd[MBOX_REG_COUNT];
	uint32_t mbox_sts[MBOX_REG_COUNT];
	struct scsi_cmnd *cmd = srb->cmd;
	int status = QLA_SUCCESS;
	unsigned long flags = 0;
	uint32_t index;

	/*
	 * Send abort task command to ISP, so that the ISP will return
	 * request with ABORT status
	 */
	memset(&mbox_cmd, 0, sizeof(mbox_cmd));
	memset(&mbox_sts, 0, sizeof(mbox_sts));

	spin_lock_irqsave(&ha->hardware_lock, flags);
	index = (unsigned long)(unsigned char *)cmd->host_scribble;
	spin_unlock_irqrestore(&ha->hardware_lock, flags);

	/* Firmware already posted completion on response queue */
	if (index == MAX_SRBS)
		return status;

	mbox_cmd[0] = MBOX_CMD_ABORT_TASK;
	mbox_cmd[1] = srb->fw_ddb_index;
	mbox_cmd[2] = index;
	/* Immediate Command Enable */
	mbox_cmd[5] = 0x01;

	qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 5, &mbox_cmd[0],
	    &mbox_sts[0]);
	if (mbox_sts[0] != MBOX_STS_COMMAND_COMPLETE) {
		status = QLA_ERROR;

		DEBUG2(printk(KERN_WARNING "scsi%ld:%d:%d: abort task FAILED: "
		    "mbx0=%04X, mb1=%04X, mb2=%04X, mb3=%04X, mb4=%04X\n",
		    ha->host_no, cmd->device->id, cmd->device->lun, mbox_sts[0],
		    mbox_sts[1], mbox_sts[2], mbox_sts[3], mbox_sts[4]));
	}

	return status;
}

/**
 * qla4xxx_reset_lun - issues LUN Reset
 * @ha: Pointer to host adapter structure.
Loading