Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 19113
b: refs/heads/master
c: d97994d
h: refs/heads/master
i:
  19111: 3f17165
v: v3
  • Loading branch information
andrew.vasquez@qlogic.com authored and James Bottomley committed Jan 26, 2006
1 parent d345e80 commit 01ba41d
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 35 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 1d12d98d284665c37b75b9538916b5fbb8fcde37
refs/heads/master: d97994dc1fddcbb8212b745d9c9c9ce96262155c
4 changes: 3 additions & 1 deletion trunk/drivers/scsi/qla2xxx/qla_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -1680,7 +1680,8 @@ typedef struct fc_port {
uint8_t mp_byte; /* multi-path byte (not used) */
uint8_t cur_path; /* current path id */

struct fc_rport *rport;
spinlock_t rport_lock;
struct fc_rport *rport, *drport;
u32 supported_classes;
struct work_struct rport_add_work;
struct work_struct rport_del_work;
Expand Down Expand Up @@ -2270,6 +2271,7 @@ typedef struct scsi_qla_host {
#define LOOP_RESET_NEEDED 24
#define BEACON_BLINK_NEEDED 25
#define REGISTER_FDMI_NEEDED 26
#define FCPORT_UPDATE_NEEDED 27

uint32_t device_flags;
#define DFLG_LOCAL_DEVICES BIT_0
Expand Down
5 changes: 3 additions & 2 deletions trunk/drivers/scsi/qla2xxx/qla_gbl.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ extern int qla2x00_local_device_login(scsi_qla_host_t *, uint16_t);
extern void qla2x00_restart_queues(scsi_qla_host_t *, uint8_t);

extern void qla2x00_rescan_fcports(scsi_qla_host_t *);
extern void qla2x00_update_fcports(scsi_qla_host_t *);

extern int qla2x00_abort_isp(scsi_qla_host_t *);

Expand All @@ -70,8 +71,8 @@ extern char *qla2x00_get_fw_version_str(struct scsi_qla_host *, char *);

extern void qla2x00_cmd_timeout(srb_t *);

extern void qla2x00_mark_device_lost(scsi_qla_host_t *, fc_port_t *, int);
extern void qla2x00_mark_all_devices_lost(scsi_qla_host_t *);
extern void qla2x00_mark_device_lost(scsi_qla_host_t *, fc_port_t *, int, int);
extern void qla2x00_mark_all_devices_lost(scsi_qla_host_t *, int);

extern void qla2x00_blink_led(scsi_qla_host_t *);

Expand Down
54 changes: 38 additions & 16 deletions trunk/drivers/scsi/qla2xxx/qla_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -1688,10 +1688,16 @@ static void
qla2x00_rport_del(void *data)
{
fc_port_t *fcport = data;
struct fc_rport *rport;
unsigned long flags;

spin_lock_irqsave(&fcport->rport_lock, flags);
rport = fcport->drport;
fcport->drport = NULL;
spin_unlock_irqrestore(&fcport->rport_lock, flags);
if (rport)
fc_remote_port_delete(rport);

if (fcport->rport)
fc_remote_port_delete(fcport->rport);
fcport->rport = NULL;
}

/**
Expand Down Expand Up @@ -1719,6 +1725,7 @@ qla2x00_alloc_fcport(scsi_qla_host_t *ha, gfp_t flags)
atomic_set(&fcport->state, FCS_UNCONFIGURED);
fcport->flags = FCF_RLC_SUPPORT;
fcport->supported_classes = FC_COS_UNSPECIFIED;
spin_lock_init(&fcport->rport_lock);
INIT_WORK(&fcport->rport_add_work, qla2x00_rport_add, fcport);
INIT_WORK(&fcport->rport_del_work, qla2x00_rport_del, fcport);

Expand Down Expand Up @@ -2008,7 +2015,7 @@ qla2x00_probe_for_all_luns(scsi_qla_host_t *ha)
{
fc_port_t *fcport;

qla2x00_mark_all_devices_lost(ha);
qla2x00_mark_all_devices_lost(ha, 0);
list_for_each_entry(fcport, &ha->fcports, list) {
if (fcport->port_type != FCT_TARGET)
continue;
Expand Down Expand Up @@ -2084,24 +2091,29 @@ qla2x00_reg_remote_port(scsi_qla_host_t *ha, fc_port_t *fcport)
{
struct fc_rport_identifiers rport_ids;
struct fc_rport *rport;
unsigned long flags;

if (fcport->rport) {
fc_remote_port_delete(fcport->rport);
fcport->rport = NULL;
}
if (fcport->drport)
qla2x00_rport_del(fcport);
if (fcport->rport)
return;

rport_ids.node_name = wwn_to_u64(fcport->node_name);
rport_ids.port_name = wwn_to_u64(fcport->port_name);
rport_ids.port_id = fcport->d_id.b.domain << 16 |
fcport->d_id.b.area << 8 | fcport->d_id.b.al_pa;
rport_ids.roles = FC_RPORT_ROLE_UNKNOWN;
fcport->rport = rport = fc_remote_port_add(ha->host, 0, &rport_ids);
rport = fc_remote_port_add(ha->host, 0, &rport_ids);
if (!rport) {
qla_printk(KERN_WARNING, ha,
"Unable to allocate fc remote port!\n");
return;
}
spin_lock_irqsave(&fcport->rport_lock, flags);
fcport->rport = rport;
*((fc_port_t **)rport->dd_data) = fcport;
spin_unlock_irqrestore(&fcport->rport_lock, flags);

rport->supported_classes = fcport->supported_classes;

rport_ids.roles = FC_RPORT_ROLE_UNKNOWN;
Expand Down Expand Up @@ -2217,12 +2229,11 @@ qla2x00_configure_fabric(scsi_qla_host_t *ha)

if (atomic_read(&fcport->state) == FCS_DEVICE_LOST) {
qla2x00_mark_device_lost(ha, fcport,
ql2xplogiabsentdevice);
ql2xplogiabsentdevice, 0);
if (fcport->loop_id != FC_NO_LOOP_ID &&
(fcport->flags & FCF_TAPE_PRESENT) == 0 &&
fcport->port_type != FCT_INITIATOR &&
fcport->port_type != FCT_BROADCAST) {

ha->isp_ops.fabric_logout(ha,
fcport->loop_id,
fcport->d_id.b.domain,
Expand Down Expand Up @@ -2694,7 +2705,8 @@ qla2x00_device_resync(scsi_qla_host_t *ha)
if (atomic_read(&fcport->state) == FCS_ONLINE) {
if (format != 3 ||
fcport->port_type != FCT_INITIATOR) {
qla2x00_mark_device_lost(ha, fcport, 0);
qla2x00_mark_device_lost(ha, fcport,
0, 0);
}
}
fcport->flags &= ~FCF_FARP_DONE;
Expand Down Expand Up @@ -2741,8 +2753,7 @@ qla2x00_fabric_dev_login(scsi_qla_host_t *ha, fc_port_t *fcport,
ha->isp_ops.fabric_logout(ha, fcport->loop_id,
fcport->d_id.b.domain, fcport->d_id.b.area,
fcport->d_id.b.al_pa);
qla2x00_mark_device_lost(ha, fcport, 1);

qla2x00_mark_device_lost(ha, fcport, 1, 0);
} else {
qla2x00_update_fcport(ha, fcport);
}
Expand Down Expand Up @@ -2855,7 +2866,7 @@ qla2x00_fabric_login(scsi_qla_host_t *ha, fc_port_t *fcport,
ha->isp_ops.fabric_logout(ha, fcport->loop_id,
fcport->d_id.b.domain, fcport->d_id.b.area,
fcport->d_id.b.al_pa);
qla2x00_mark_device_lost(ha, fcport, 1);
qla2x00_mark_device_lost(ha, fcport, 1, 0);

rval = 1;
break;
Expand Down Expand Up @@ -2990,6 +3001,17 @@ qla2x00_rescan_fcports(scsi_qla_host_t *ha)
qla2x00_probe_for_all_luns(ha);
}

void
qla2x00_update_fcports(scsi_qla_host_t *ha)
{
fc_port_t *fcport;

/* Go with deferred removal of rport references. */
list_for_each_entry(fcport, &ha->fcports, list)
if (fcport->drport)
qla2x00_rport_del(fcport);
}

/*
* qla2x00_abort_isp
* Resets ISP and aborts all outstanding commands.
Expand Down Expand Up @@ -3019,7 +3041,7 @@ qla2x00_abort_isp(scsi_qla_host_t *ha)
atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME);
if (atomic_read(&ha->loop_state) != LOOP_DOWN) {
atomic_set(&ha->loop_state, LOOP_DOWN);
qla2x00_mark_all_devices_lost(ha);
qla2x00_mark_all_devices_lost(ha, 0);
} else {
if (!atomic_read(&ha->loop_down_timer))
atomic_set(&ha->loop_down_timer,
Expand Down
16 changes: 8 additions & 8 deletions trunk/drivers/scsi/qla2xxx/qla_isr.c
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
if (atomic_read(&ha->loop_state) != LOOP_DOWN) {
atomic_set(&ha->loop_state, LOOP_DOWN);
atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME);
qla2x00_mark_all_devices_lost(ha);
qla2x00_mark_all_devices_lost(ha, 1);
}

set_bit(REGISTER_FC4_NEEDED, &ha->dpc_flags);
Expand Down Expand Up @@ -432,7 +432,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
atomic_set(&ha->loop_state, LOOP_DOWN);
atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME);
ha->device_flags |= DFLG_NO_CABLE;
qla2x00_mark_all_devices_lost(ha);
qla2x00_mark_all_devices_lost(ha, 1);
}

ha->flags.management_server_logged_in = 0;
Expand All @@ -453,7 +453,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
if (atomic_read(&ha->loop_state) != LOOP_DOWN) {
atomic_set(&ha->loop_state, LOOP_DOWN);
atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME);
qla2x00_mark_all_devices_lost(ha);
qla2x00_mark_all_devices_lost(ha, 1);
}

set_bit(RESET_MARKER_NEEDED, &ha->dpc_flags);
Expand Down Expand Up @@ -482,7 +482,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
if (!atomic_read(&ha->loop_down_timer))
atomic_set(&ha->loop_down_timer,
LOOP_DOWN_TIME);
qla2x00_mark_all_devices_lost(ha);
qla2x00_mark_all_devices_lost(ha, 1);
}

if (!(test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags))) {
Expand All @@ -506,7 +506,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
if (!atomic_read(&ha->loop_down_timer))
atomic_set(&ha->loop_down_timer,
LOOP_DOWN_TIME);
qla2x00_mark_all_devices_lost(ha);
qla2x00_mark_all_devices_lost(ha, 1);
}

set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags);
Expand Down Expand Up @@ -580,7 +580,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
*/
atomic_set(&ha->loop_state, LOOP_UP);

qla2x00_mark_all_devices_lost(ha);
qla2x00_mark_all_devices_lost(ha, 1);

ha->flags.rscn_queue_overflow = 1;

Expand Down Expand Up @@ -1091,7 +1091,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt)

cp->result = DID_BUS_BUSY << 16;
if (atomic_read(&fcport->state) == FCS_ONLINE) {
qla2x00_mark_device_lost(ha, fcport, 1);
qla2x00_mark_device_lost(ha, fcport, 1, 1);
}
break;

Expand Down Expand Up @@ -1135,7 +1135,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt)

/* Check to see if logout occurred. */
if ((le16_to_cpu(sts->status_flags) & SF_LOGOUT_SENT))
qla2x00_mark_device_lost(ha, fcport, 1);
qla2x00_mark_device_lost(ha, fcport, 1, 1);
break;

case CS_QUEUE_FULL:
Expand Down
46 changes: 39 additions & 7 deletions trunk/drivers/scsi/qla2xxx/qla_os.c
Original file line number Diff line number Diff line change
Expand Up @@ -756,7 +756,7 @@ qla2xxx_eh_device_reset(struct scsi_cmnd *cmd)
if (ret == SUCCESS) {
if (fcport->flags & FC_FABRIC_DEVICE) {
ha->isp_ops.fabric_logout(ha, fcport->loop_id);
qla2x00_mark_device_lost(ha, fcport);
qla2x00_mark_device_lost(ha, fcport, 0, 0);
}
}
#endif
Expand Down Expand Up @@ -1642,6 +1642,31 @@ qla2x00_free_device(scsi_qla_host_t *ha)
pci_disable_device(ha->pdev);
}

static inline void
qla2x00_schedule_rport_del(struct scsi_qla_host *ha, fc_port_t *fcport,
int defer)
{
unsigned long flags;
struct fc_rport *rport;

if (!fcport->rport)
return;

rport = fcport->rport;
if (defer) {
spin_lock_irqsave(&fcport->rport_lock, flags);
fcport->drport = rport;
fcport->rport = NULL;
spin_unlock_irqrestore(&fcport->rport_lock, flags);
set_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags);
} else {
spin_lock_irqsave(&fcport->rport_lock, flags);
fcport->rport = NULL;
spin_unlock_irqrestore(&fcport->rport_lock, flags);
fc_remote_port_delete(rport);
}
}

/*
* qla2x00_mark_device_lost Updates fcport state when device goes offline.
*
Expand All @@ -1652,10 +1677,10 @@ qla2x00_free_device(scsi_qla_host_t *ha)
* Context:
*/
void qla2x00_mark_device_lost(scsi_qla_host_t *ha, fc_port_t *fcport,
int do_login)
int do_login, int defer)
{
if (atomic_read(&fcport->state) == FCS_ONLINE && fcport->rport)
schedule_work(&fcport->rport_del_work);
if (atomic_read(&fcport->state) == FCS_ONLINE)
qla2x00_schedule_rport_del(ha, fcport, defer);

/*
* We may need to retry the login, so don't change the state of the
Expand Down Expand Up @@ -1702,7 +1727,7 @@ void qla2x00_mark_device_lost(scsi_qla_host_t *ha, fc_port_t *fcport,
* Context:
*/
void
qla2x00_mark_all_devices_lost(scsi_qla_host_t *ha)
qla2x00_mark_all_devices_lost(scsi_qla_host_t *ha, int defer)
{
fc_port_t *fcport;

Expand All @@ -1716,10 +1741,13 @@ qla2x00_mark_all_devices_lost(scsi_qla_host_t *ha)
*/
if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD)
continue;
if (atomic_read(&fcport->state) == FCS_ONLINE && fcport->rport)
schedule_work(&fcport->rport_del_work);
if (atomic_read(&fcport->state) == FCS_ONLINE)
qla2x00_schedule_rport_del(ha, fcport, defer);
atomic_set(&fcport->state, FCS_DEVICE_LOST);
}

if (defer && ha->dpc_wait && !ha->dpc_active)
up(ha->dpc_wait);
}

/*
Expand Down Expand Up @@ -2161,6 +2189,9 @@ qla2x00_do_dpc(void *data)
ha->host_no));
}

if (test_and_clear_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags))
qla2x00_update_fcports(ha);

if (test_and_clear_bit(LOOP_RESET_NEEDED, &ha->dpc_flags)) {
DEBUG(printk("scsi(%ld): dpc: sched loop_reset()\n",
ha->host_no));
Expand Down Expand Up @@ -2469,6 +2500,7 @@ qla2x00_timer(scsi_qla_host_t *ha)
if ((test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags) ||
test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags) ||
test_bit(LOOP_RESET_NEEDED, &ha->dpc_flags) ||
test_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags) ||
start_dpc ||
test_bit(LOGIN_RETRY_NEEDED, &ha->dpc_flags) ||
test_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) ||
Expand Down

0 comments on commit 01ba41d

Please sign in to comment.