Commit 523ec773 authored by Andrew Vasquez's avatar Andrew Vasquez Committed by James Bottomley

[SCSI] qla2xxx: Add midlayer target/device reset support.

Now that infrastructure is present within the midlayer and there
is a clear distinction between what is expected from a device and
target reset, convert the current device-reset codes to a
target-reset, and add codes to perform a proper device-reset (LUN
reset).

In the process of adding reset support, collapse and consolidate
large sections of mailbox-command (TMF issuance) codes,
generalize the two 'wait-for-commands-to-complete' functions, and
add a generic-reset routine for use by midlayer reset functions.
Signed-off-by: default avatarAndrew Vasquez <andrew.vasquez@qlogic.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@HansenPartnership.com>
parent 3fe7cfb9
......@@ -2062,7 +2062,8 @@ struct isp_operations {
void (*disable_intrs) (struct scsi_qla_host *);
int (*abort_command) (struct scsi_qla_host *, srb_t *);
int (*abort_target) (struct fc_port *);
int (*target_reset) (struct fc_port *, unsigned int);
int (*lun_reset) (struct fc_port *, unsigned int);
int (*fabric_login) (struct scsi_qla_host *, uint16_t, uint8_t,
uint8_t, uint8_t, uint16_t *, uint8_t);
int (*fabric_logout) (struct scsi_qla_host *, uint16_t, uint8_t,
......
......@@ -719,7 +719,7 @@ struct tsk_mgmt_entry {
uint16_t timeout; /* Command timeout. */
uint8_t lun[8]; /* FCP LUN (BE). */
struct scsi_lun lun; /* FCP LUN (BE). */
uint32_t control_flags; /* Control Flags. */
#define TCF_NOTMCMD_TO_TARGET BIT_31
......
......@@ -153,7 +153,10 @@ extern int
qla2x00_abort_command(scsi_qla_host_t *, srb_t *);
extern int
qla2x00_abort_target(fc_port_t *);
qla2x00_abort_target(struct fc_port *, unsigned int);
extern int
qla2x00_lun_reset(struct fc_port *, unsigned int);
extern int
qla2x00_get_adapter_id(scsi_qla_host_t *, uint16_t *, uint8_t *, uint8_t *,
......@@ -219,7 +222,8 @@ qla24xx_get_isp_stats(scsi_qla_host_t *, struct link_statistics *,
dma_addr_t);
extern int qla24xx_abort_command(scsi_qla_host_t *, srb_t *);
extern int qla24xx_abort_target(fc_port_t *);
extern int qla24xx_abort_target(struct fc_port *, unsigned int);
extern int qla24xx_lun_reset(struct fc_port *, unsigned int);
extern int
qla2x00_set_serdes_params(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t);
......
......@@ -784,35 +784,20 @@ qla2x00_abort_command(scsi_qla_host_t *ha, srb_t *sp)
return rval;
}
/*
* qla2x00_abort_target
* Issue abort target mailbox command.
*
* Input:
* ha = adapter block pointer.
*
* Returns:
* qla2x00 local function return status code.
*
* Context:
* Kernel context.
*/
int
qla2x00_abort_target(fc_port_t *fcport)
qla2x00_abort_target(struct fc_port *fcport, unsigned int l)
{
int rval;
int rval, rval2;
mbx_cmd_t mc;
mbx_cmd_t *mcp = &mc;
scsi_qla_host_t *ha;
if (fcport == NULL)
return 0;
DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->ha->host_no));
l = l;
ha = fcport->ha;
mcp->mb[0] = MBC_ABORT_TARGET;
mcp->out_mb = MBX_2|MBX_1|MBX_0;
mcp->out_mb = MBX_9|MBX_2|MBX_1|MBX_0;
if (HAS_EXTENDED_IDS(ha)) {
mcp->mb[1] = fcport->loop_id;
mcp->mb[10] = 0;
......@@ -821,22 +806,66 @@ qla2x00_abort_target(fc_port_t *fcport)
mcp->mb[1] = fcport->loop_id << 8;
}
mcp->mb[2] = ha->loop_reset_delay;
mcp->mb[9] = ha->vp_idx;
mcp->in_mb = MBX_0;
mcp->tov = 30;
mcp->flags = 0;
rval = qla2x00_mailbox_command(ha, mcp);
if (rval != QLA_SUCCESS) {
DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__,
ha->host_no, rval));
}
/* Issue marker IOCB. */
rval2 = qla2x00_marker(ha, fcport->loop_id, 0, MK_SYNC_ID);
if (rval2 != QLA_SUCCESS) {
DEBUG2_3_11(printk("%s(%ld): failed to issue Marker IOCB "
"(%x).\n", __func__, ha->host_no, rval2));
} else {
DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no));
}
return rval;
}
int
qla2x00_lun_reset(struct fc_port *fcport, unsigned int l)
{
int rval, rval2;
mbx_cmd_t mc;
mbx_cmd_t *mcp = &mc;
scsi_qla_host_t *ha;
DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->ha->host_no));
/* Issue marker command. */
ha->marker_needed = 1;
ha = fcport->ha;
mcp->mb[0] = MBC_LUN_RESET;
mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0;
if (HAS_EXTENDED_IDS(ha))
mcp->mb[1] = fcport->loop_id;
else
mcp->mb[1] = fcport->loop_id << 8;
mcp->mb[2] = l;
mcp->mb[3] = 0;
mcp->mb[9] = ha->vp_idx;
mcp->in_mb = MBX_0;
mcp->tov = 30;
mcp->flags = 0;
rval = qla2x00_mailbox_command(ha, mcp);
if (rval != QLA_SUCCESS) {
DEBUG2_3_11(printk("qla2x00_abort_target(%ld): failed=%x.\n",
DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__,
ha->host_no, rval));
}
/* Issue marker IOCB. */
rval2 = qla2x00_marker(ha, fcport->loop_id, l, MK_SYNC_ID_LUN);
if (rval2 != QLA_SUCCESS) {
DEBUG2_3_11(printk("%s(%ld): failed to issue Marker IOCB "
"(%x).\n", __func__, ha->host_no, rval2));
} else {
/*EMPTY*/
DEBUG11(printk("qla2x00_abort_target(%ld): done.\n",
ha->host_no));
DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no));
}
return rval;
......@@ -2186,17 +2215,15 @@ struct tsk_mgmt_cmd {
} p;
};
int
qla24xx_abort_target(fc_port_t *fcport)
static int
__qla24xx_issue_tmf(char *name, uint32_t type, struct fc_port *fcport,
unsigned int l)
{
int rval;
int rval, rval2;
struct tsk_mgmt_cmd *tsk;
dma_addr_t tsk_dma;
scsi_qla_host_t *ha, *pha;
if (fcport == NULL)
return 0;
DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->ha->host_no));
ha = fcport->ha;
......@@ -2213,47 +2240,61 @@ qla24xx_abort_target(fc_port_t *fcport)
tsk->p.tsk.entry_count = 1;
tsk->p.tsk.nport_handle = cpu_to_le16(fcport->loop_id);
tsk->p.tsk.timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
tsk->p.tsk.control_flags = __constant_cpu_to_le32(TCF_TARGET_RESET);
tsk->p.tsk.control_flags = cpu_to_le32(type);
tsk->p.tsk.port_id[0] = fcport->d_id.b.al_pa;
tsk->p.tsk.port_id[1] = fcport->d_id.b.area;
tsk->p.tsk.port_id[2] = fcport->d_id.b.domain;
tsk->p.tsk.vp_index = fcport->vp_idx;
if (type == TCF_LUN_RESET) {
int_to_scsilun(l, &tsk->p.tsk.lun);
host_to_fcp_swap((uint8_t *)&tsk->p.tsk.lun,
sizeof(tsk->p.tsk.lun));
}
rval = qla2x00_issue_iocb(ha, tsk, tsk_dma, 0);
if (rval != QLA_SUCCESS) {
DEBUG2_3_11(printk("%s(%ld): failed to issue Target Reset IOCB "
"(%x).\n", __func__, ha->host_no, rval));
goto atarget_done;
DEBUG2_3_11(printk("%s(%ld): failed to issue %s Reset IOCB "
"(%x).\n", __func__, ha->host_no, name, rval));
} else if (tsk->p.sts.entry_status != 0) {
DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB "
"-- error status (%x).\n", __func__, ha->host_no,
tsk->p.sts.entry_status));
rval = QLA_FUNCTION_FAILED;
goto atarget_done;
} else if (tsk->p.sts.comp_status !=
__constant_cpu_to_le16(CS_COMPLETE)) {
DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB "
"-- completion status (%x).\n", __func__,
ha->host_no, le16_to_cpu(tsk->p.sts.comp_status)));
rval = QLA_FUNCTION_FAILED;
goto atarget_done;
}
/* Issue marker IOCB. */
rval = qla2x00_marker(ha, fcport->loop_id, 0, MK_SYNC_ID);
if (rval != QLA_SUCCESS) {
rval2 = qla2x00_marker(ha, fcport->loop_id, l,
type == TCF_LUN_RESET ? MK_SYNC_ID_LUN: MK_SYNC_ID);
if (rval2 != QLA_SUCCESS) {
DEBUG2_3_11(printk("%s(%ld): failed to issue Marker IOCB "
"(%x).\n", __func__, ha->host_no, rval));
"(%x).\n", __func__, ha->host_no, rval2));
} else {
DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no));
}
atarget_done:
dma_pool_free(pha->s_dma_pool, tsk, tsk_dma);
return rval;
}
int
qla24xx_abort_target(struct fc_port *fcport, unsigned int l)
{
return __qla24xx_issue_tmf("Target", TCF_TARGET_RESET, fcport, l);
}
int
qla24xx_lun_reset(struct fc_port *fcport, unsigned int l)
{
return __qla24xx_issue_tmf("Lun", TCF_LUN_RESET, fcport, l);
}
#if 0
int
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment