aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/qla2xxx')
-rw-r--r--drivers/scsi/qla2xxx/qla_def.h3
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c26
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c21
-rw-r--r--drivers/scsi/qla2xxx/qla_rscn.c3
4 files changed, 40 insertions, 13 deletions
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index fc3234c3625b..7096945ea234 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -21,6 +21,7 @@
21#include <linux/spinlock.h> 21#include <linux/spinlock.h>
22#include <linux/completion.h> 22#include <linux/completion.h>
23#include <linux/interrupt.h> 23#include <linux/interrupt.h>
24#include <linux/workqueue.h>
24#include <asm/semaphore.h> 25#include <asm/semaphore.h>
25 26
26#include <scsi/scsi.h> 27#include <scsi/scsi.h>
@@ -1665,6 +1666,8 @@ typedef struct fc_port {
1665 1666
1666 struct fc_rport *rport; 1667 struct fc_rport *rport;
1667 u32 supported_classes; 1668 u32 supported_classes;
1669 struct work_struct rport_add_work;
1670 struct work_struct rport_del_work;
1668} fc_port_t; 1671} fc_port_t;
1669 1672
1670/* 1673/*
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index ce7e712ebe8d..290a6b92616c 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -1668,6 +1668,24 @@ qla2x00_nvram_config(scsi_qla_host_t *ha)
1668 return (rval); 1668 return (rval);
1669} 1669}
1670 1670
1671static void
1672qla2x00_rport_add(void *data)
1673{
1674 fc_port_t *fcport = data;
1675
1676 qla2x00_reg_remote_port(fcport->ha, fcport);
1677}
1678
1679static void
1680qla2x00_rport_del(void *data)
1681{
1682 fc_port_t *fcport = data;
1683
1684 if (fcport->rport)
1685 fc_remote_port_delete(fcport->rport);
1686 fcport->rport = NULL;
1687}
1688
1671/** 1689/**
1672 * qla2x00_alloc_fcport() - Allocate a generic fcport. 1690 * qla2x00_alloc_fcport() - Allocate a generic fcport.
1673 * @ha: HA context 1691 * @ha: HA context
@@ -1693,6 +1711,8 @@ qla2x00_alloc_fcport(scsi_qla_host_t *ha, gfp_t flags)
1693 atomic_set(&fcport->state, FCS_UNCONFIGURED); 1711 atomic_set(&fcport->state, FCS_UNCONFIGURED);
1694 fcport->flags = FCF_RLC_SUPPORT; 1712 fcport->flags = FCF_RLC_SUPPORT;
1695 fcport->supported_classes = FC_COS_UNSPECIFIED; 1713 fcport->supported_classes = FC_COS_UNSPECIFIED;
1714 INIT_WORK(&fcport->rport_add_work, qla2x00_rport_add, fcport);
1715 INIT_WORK(&fcport->rport_del_work, qla2x00_rport_del, fcport);
1696 1716
1697 return (fcport); 1717 return (fcport);
1698} 1718}
@@ -2056,8 +2076,8 @@ qla2x00_reg_remote_port(scsi_qla_host_t *ha, fc_port_t *fcport)
2056 struct fc_rport *rport; 2076 struct fc_rport *rport;
2057 2077
2058 if (fcport->rport) { 2078 if (fcport->rport) {
2059 fc_remote_port_unblock(fcport->rport); 2079 fc_remote_port_delete(fcport->rport);
2060 return; 2080 fcport->rport = NULL;
2061 } 2081 }
2062 2082
2063 rport_ids.node_name = wwn_to_u64(fcport->node_name); 2083 rport_ids.node_name = wwn_to_u64(fcport->node_name);
@@ -2071,7 +2091,7 @@ qla2x00_reg_remote_port(scsi_qla_host_t *ha, fc_port_t *fcport)
2071 "Unable to allocate fc remote port!\n"); 2091 "Unable to allocate fc remote port!\n");
2072 return; 2092 return;
2073 } 2093 }
2074 rport->dd_data = fcport; 2094 *((fc_port_t **)rport->dd_data) = fcport;
2075 rport->supported_classes = fcport->supported_classes; 2095 rport->supported_classes = fcport->supported_classes;
2076 2096
2077 rport_ids.roles = FC_RPORT_ROLE_UNKNOWN; 2097 rport_ids.roles = FC_RPORT_ROLE_UNKNOWN;
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index b899282a856e..c58c9d97b041 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -348,11 +348,13 @@ qla2x00_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
348{ 348{
349 scsi_qla_host_t *ha = to_qla_host(cmd->device->host); 349 scsi_qla_host_t *ha = to_qla_host(cmd->device->host);
350 fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata; 350 fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata;
351 struct fc_rport *rport = starget_to_rport(scsi_target(cmd->device));
351 srb_t *sp; 352 srb_t *sp;
352 int rval; 353 int rval;
353 354
354 if (!fcport) { 355 rval = fc_remote_port_chkready(rport);
355 cmd->result = DID_NO_CONNECT << 16; 356 if (rval) {
357 cmd->result = rval;
356 goto qc_fail_command; 358 goto qc_fail_command;
357 } 359 }
358 360
@@ -401,11 +403,13 @@ qla24xx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
401{ 403{
402 scsi_qla_host_t *ha = to_qla_host(cmd->device->host); 404 scsi_qla_host_t *ha = to_qla_host(cmd->device->host);
403 fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata; 405 fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata;
406 struct fc_rport *rport = starget_to_rport(scsi_target(cmd->device));
404 srb_t *sp; 407 srb_t *sp;
405 int rval; 408 int rval;
406 409
407 if (!fcport) { 410 rval = fc_remote_port_chkready(rport);
408 cmd->result = DID_NO_CONNECT << 16; 411 if (rval) {
412 cmd->result = rval;
409 goto qc24_fail_command; 413 goto qc24_fail_command;
410 } 414 }
411 415
@@ -1041,10 +1045,10 @@ qla2xxx_slave_alloc(struct scsi_device *sdev)
1041{ 1045{
1042 struct fc_rport *rport = starget_to_rport(scsi_target(sdev)); 1046 struct fc_rport *rport = starget_to_rport(scsi_target(sdev));
1043 1047
1044 if (!rport) 1048 if (!rport || fc_remote_port_chkready(rport))
1045 return -ENXIO; 1049 return -ENXIO;
1046 1050
1047 sdev->hostdata = rport->dd_data; 1051 sdev->hostdata = *(fc_port_t **)rport->dd_data;
1048 1052
1049 return 0; 1053 return 0;
1050} 1054}
@@ -1636,7 +1640,8 @@ void qla2x00_mark_device_lost(scsi_qla_host_t *ha, fc_port_t *fcport,
1636 int do_login) 1640 int do_login)
1637{ 1641{
1638 if (atomic_read(&fcport->state) == FCS_ONLINE && fcport->rport) 1642 if (atomic_read(&fcport->state) == FCS_ONLINE && fcport->rport)
1639 fc_remote_port_block(fcport->rport); 1643 schedule_work(&fcport->rport_del_work);
1644
1640 /* 1645 /*
1641 * We may need to retry the login, so don't change the state of the 1646 * We may need to retry the login, so don't change the state of the
1642 * port but do the retries. 1647 * port but do the retries.
@@ -1697,7 +1702,7 @@ qla2x00_mark_all_devices_lost(scsi_qla_host_t *ha)
1697 if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD) 1702 if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD)
1698 continue; 1703 continue;
1699 if (atomic_read(&fcport->state) == FCS_ONLINE && fcport->rport) 1704 if (atomic_read(&fcport->state) == FCS_ONLINE && fcport->rport)
1700 fc_remote_port_block(fcport->rport); 1705 schedule_work(&fcport->rport_del_work);
1701 atomic_set(&fcport->state, FCS_DEVICE_LOST); 1706 atomic_set(&fcport->state, FCS_DEVICE_LOST);
1702 } 1707 }
1703} 1708}
diff --git a/drivers/scsi/qla2xxx/qla_rscn.c b/drivers/scsi/qla2xxx/qla_rscn.c
index 3e53f62d640d..2c3342108dd8 100644
--- a/drivers/scsi/qla2xxx/qla_rscn.c
+++ b/drivers/scsi/qla2xxx/qla_rscn.c
@@ -320,8 +320,7 @@ qla2x00_update_login_fcport(scsi_qla_host_t *ha, struct mbx_entry *mbxstat,
320 fcport->flags &= ~FCF_FAILOVER_NEEDED; 320 fcport->flags &= ~FCF_FAILOVER_NEEDED;
321 fcport->iodesc_idx_sent = IODESC_INVALID_INDEX; 321 fcport->iodesc_idx_sent = IODESC_INVALID_INDEX;
322 atomic_set(&fcport->state, FCS_ONLINE); 322 atomic_set(&fcport->state, FCS_ONLINE);
323 if (fcport->rport) 323 schedule_work(&fcport->rport_add_work);
324 fc_remote_port_unblock(fcport->rport);
325} 324}
326 325
327 326