diff options
Diffstat (limited to 'drivers/scsi/qla2xxx')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_def.h | 3 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_init.c | 26 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_os.c | 21 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_rscn.c | 3 |
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 | ||
1671 | static void | ||
1672 | qla2x00_rport_add(void *data) | ||
1673 | { | ||
1674 | fc_port_t *fcport = data; | ||
1675 | |||
1676 | qla2x00_reg_remote_port(fcport->ha, fcport); | ||
1677 | } | ||
1678 | |||
1679 | static void | ||
1680 | qla2x00_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 | ||