aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/qla2xxx')
-rw-r--r--drivers/scsi/qla2xxx/qla_attr.c9
-rw-r--r--drivers/scsi/qla2xxx/qla_def.h39
-rw-r--r--drivers/scsi/qla2xxx/qla_fw.h2
-rw-r--r--drivers/scsi/qla2xxx/qla_gbl.h20
-rw-r--r--drivers/scsi/qla2xxx/qla_gs.c4
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c239
-rw-r--r--drivers/scsi/qla2xxx/qla_iocb.c206
-rw-r--r--drivers/scsi/qla2xxx/qla_isr.c309
-rw-r--r--drivers/scsi/qla2xxx/qla_mbx.c7
-rw-r--r--drivers/scsi/qla2xxx/qla_mid.c27
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c141
-rw-r--r--drivers/scsi/qla2xxx/qla_version.h2
12 files changed, 936 insertions, 69 deletions
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index 0f8796201504..fbcb82a2f7f4 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -1670,7 +1670,7 @@ qla24xx_vport_create(struct fc_vport *fc_vport, bool disable)
1670 1670
1671 qla24xx_vport_disable(fc_vport, disable); 1671 qla24xx_vport_disable(fc_vport, disable);
1672 1672
1673 if (ql2xmultique_tag) { 1673 if (ha->flags.cpu_affinity_enabled) {
1674 req = ha->req_q_map[1]; 1674 req = ha->req_q_map[1];
1675 goto vport_queue; 1675 goto vport_queue;
1676 } else if (ql2xmaxqueues == 1 || !ha->npiv_info) 1676 } else if (ql2xmaxqueues == 1 || !ha->npiv_info)
@@ -1736,6 +1736,11 @@ qla24xx_vport_delete(struct fc_vport *fc_vport)
1736 1736
1737 qla24xx_deallocate_vp_id(vha); 1737 qla24xx_deallocate_vp_id(vha);
1738 1738
1739 mutex_lock(&ha->vport_lock);
1740 ha->cur_vport_count--;
1741 clear_bit(vha->vp_idx, ha->vp_idx_map);
1742 mutex_unlock(&ha->vport_lock);
1743
1739 if (vha->timer_active) { 1744 if (vha->timer_active) {
1740 qla2x00_vp_stop_timer(vha); 1745 qla2x00_vp_stop_timer(vha);
1741 DEBUG15(printk ("scsi(%ld): timer for the vport[%d] = %p " 1746 DEBUG15(printk ("scsi(%ld): timer for the vport[%d] = %p "
@@ -1743,7 +1748,7 @@ qla24xx_vport_delete(struct fc_vport *fc_vport)
1743 vha->host_no, vha->vp_idx, vha)); 1748 vha->host_no, vha->vp_idx, vha));
1744 } 1749 }
1745 1750
1746 if (vha->req->id && !ql2xmultique_tag) { 1751 if (vha->req->id && !ha->flags.cpu_affinity_enabled) {
1747 if (qla25xx_delete_req_que(vha, vha->req) != QLA_SUCCESS) 1752 if (qla25xx_delete_req_que(vha, vha->req) != QLA_SUCCESS)
1748 qla_printk(KERN_WARNING, ha, 1753 qla_printk(KERN_WARNING, ha,
1749 "Queue delete failed.\n"); 1754 "Queue delete failed.\n");
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 00aa48d975a6..215061861794 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -189,6 +189,7 @@ struct req_que;
189 */ 189 */
190typedef struct srb { 190typedef struct srb {
191 struct fc_port *fcport; 191 struct fc_port *fcport;
192 uint32_t handle;
192 193
193 struct scsi_cmnd *cmd; /* Linux SCSI command pkt */ 194 struct scsi_cmnd *cmd; /* Linux SCSI command pkt */
194 195
@@ -196,6 +197,8 @@ typedef struct srb {
196 197
197 uint32_t request_sense_length; 198 uint32_t request_sense_length;
198 uint8_t *request_sense_ptr; 199 uint8_t *request_sense_ptr;
200
201 void *ctx;
199} srb_t; 202} srb_t;
200 203
201/* 204/*
@@ -204,6 +207,28 @@ typedef struct srb {
204#define SRB_DMA_VALID BIT_0 /* Command sent to ISP */ 207#define SRB_DMA_VALID BIT_0 /* Command sent to ISP */
205 208
206/* 209/*
210 * SRB extensions.
211 */
212struct srb_ctx {
213#define SRB_LOGIN_CMD 1
214#define SRB_LOGOUT_CMD 2
215 uint16_t type;
216 struct timer_list timer;
217
218 void (*free)(srb_t *sp);
219 void (*timeout)(srb_t *sp);
220};
221
222struct srb_logio {
223 struct srb_ctx ctx;
224
225#define SRB_LOGIN_RETRIED BIT_0
226#define SRB_LOGIN_COND_PLOGI BIT_1
227#define SRB_LOGIN_SKIP_PRLI BIT_2
228 uint16_t flags;
229};
230
231/*
207 * ISP I/O Register Set structure definitions. 232 * ISP I/O Register Set structure definitions.
208 */ 233 */
209struct device_reg_2xxx { 234struct device_reg_2xxx {
@@ -1482,7 +1507,7 @@ typedef union {
1482 uint8_t domain; 1507 uint8_t domain;
1483 uint8_t area; 1508 uint8_t area;
1484 uint8_t al_pa; 1509 uint8_t al_pa;
1485#elif __LITTLE_ENDIAN 1510#elif defined(__LITTLE_ENDIAN)
1486 uint8_t al_pa; 1511 uint8_t al_pa;
1487 uint8_t area; 1512 uint8_t area;
1488 uint8_t domain; 1513 uint8_t domain;
@@ -1565,6 +1590,7 @@ typedef struct fc_port {
1565#define FCF_FABRIC_DEVICE BIT_0 1590#define FCF_FABRIC_DEVICE BIT_0
1566#define FCF_LOGIN_NEEDED BIT_1 1591#define FCF_LOGIN_NEEDED BIT_1
1567#define FCF_TAPE_PRESENT BIT_2 1592#define FCF_TAPE_PRESENT BIT_2
1593#define FCF_FCP2_DEVICE BIT_3
1568 1594
1569/* No loop ID flag. */ 1595/* No loop ID flag. */
1570#define FC_NO_LOOP_ID 0x1000 1596#define FC_NO_LOOP_ID 0x1000
@@ -2093,6 +2119,10 @@ struct qla_msix_entry {
2093enum qla_work_type { 2119enum qla_work_type {
2094 QLA_EVT_AEN, 2120 QLA_EVT_AEN,
2095 QLA_EVT_IDC_ACK, 2121 QLA_EVT_IDC_ACK,
2122 QLA_EVT_ASYNC_LOGIN,
2123 QLA_EVT_ASYNC_LOGIN_DONE,
2124 QLA_EVT_ASYNC_LOGOUT,
2125 QLA_EVT_ASYNC_LOGOUT_DONE,
2096}; 2126};
2097 2127
2098 2128
@@ -2111,6 +2141,11 @@ struct qla_work_evt {
2111#define QLA_IDC_ACK_REGS 7 2141#define QLA_IDC_ACK_REGS 7
2112 uint16_t mb[QLA_IDC_ACK_REGS]; 2142 uint16_t mb[QLA_IDC_ACK_REGS];
2113 } idc_ack; 2143 } idc_ack;
2144 struct {
2145 struct fc_port *fcport;
2146#define QLA_LOGIO_LOGIN_RETRIED BIT_0
2147 u16 data[2];
2148 } logio;
2114 } u; 2149 } u;
2115}; 2150};
2116 2151
@@ -2224,6 +2259,7 @@ struct qla_hw_data {
2224 uint32_t chip_reset_done :1; 2259 uint32_t chip_reset_done :1;
2225 uint32_t port0 :1; 2260 uint32_t port0 :1;
2226 uint32_t running_gold_fw :1; 2261 uint32_t running_gold_fw :1;
2262 uint32_t cpu_affinity_enabled :1;
2227 } flags; 2263 } flags;
2228 2264
2229 /* This spinlock is used to protect "io transactions", you must 2265 /* This spinlock is used to protect "io transactions", you must
@@ -2350,6 +2386,7 @@ struct qla_hw_data {
2350 (ha)->flags.msix_enabled) 2386 (ha)->flags.msix_enabled)
2351#define IS_FAC_REQUIRED(ha) (IS_QLA81XX(ha)) 2387#define IS_FAC_REQUIRED(ha) (IS_QLA81XX(ha))
2352#define IS_NOCACHE_VPD_TYPE(ha) (IS_QLA81XX(ha)) 2388#define IS_NOCACHE_VPD_TYPE(ha) (IS_QLA81XX(ha))
2389#define IS_ALOGIO_CAPABLE(ha) (IS_QLA23XX(ha) || IS_FWI2_CAPABLE(ha))
2353 2390
2354#define IS_IIDMA_CAPABLE(ha) ((ha)->device_type & DT_IIDMA) 2391#define IS_IIDMA_CAPABLE(ha) ((ha)->device_type & DT_IIDMA)
2355#define IS_FWI2_CAPABLE(ha) ((ha)->device_type & DT_FWI2) 2392#define IS_FWI2_CAPABLE(ha) ((ha)->device_type & DT_FWI2)
diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h
index dfde2dd865cb..66a8da5d7d08 100644
--- a/drivers/scsi/qla2xxx/qla_fw.h
+++ b/drivers/scsi/qla2xxx/qla_fw.h
@@ -1126,7 +1126,7 @@ struct vp_config_entry_24xx {
1126 uint16_t id; 1126 uint16_t id;
1127 uint16_t reserved_4; 1127 uint16_t reserved_4;
1128 uint16_t hopct; 1128 uint16_t hopct;
1129 uint8_t reserved_5; 1129 uint8_t reserved_5[2];
1130}; 1130};
1131 1131
1132#define VP_RPT_ID_IOCB_TYPE 0x32 /* Report ID Acquisition entry. */ 1132#define VP_RPT_ID_IOCB_TYPE 0x32 /* Report ID Acquisition entry. */
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index 65b12d82867c..f3d1d1afa95b 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -52,6 +52,14 @@ extern void qla2x00_try_to_stop_firmware(scsi_qla_host_t *);
52 52
53extern void qla84xx_put_chip(struct scsi_qla_host *); 53extern void qla84xx_put_chip(struct scsi_qla_host *);
54 54
55extern int qla2x00_async_login(struct scsi_qla_host *, fc_port_t *,
56 uint16_t *);
57extern int qla2x00_async_logout(struct scsi_qla_host *, fc_port_t *);
58extern int qla2x00_async_login_done(struct scsi_qla_host *, fc_port_t *,
59 uint16_t *);
60extern int qla2x00_async_logout_done(struct scsi_qla_host *, fc_port_t *,
61 uint16_t *);
62
55/* 63/*
56 * Global Data in qla_os.c source file. 64 * Global Data in qla_os.c source file.
57 */ 65 */
@@ -76,6 +84,15 @@ extern void qla2x00_abort_all_cmds(scsi_qla_host_t *, int);
76extern int qla2x00_post_aen_work(struct scsi_qla_host *, enum 84extern int qla2x00_post_aen_work(struct scsi_qla_host *, enum
77 fc_host_event_code, u32); 85 fc_host_event_code, u32);
78extern int qla2x00_post_idc_ack_work(struct scsi_qla_host *, uint16_t *); 86extern int qla2x00_post_idc_ack_work(struct scsi_qla_host *, uint16_t *);
87extern int qla2x00_post_async_login_work(struct scsi_qla_host *, fc_port_t *,
88 uint16_t *);
89extern int qla2x00_post_async_login_done_work(struct scsi_qla_host *,
90 fc_port_t *, uint16_t *);
91extern int qla2x00_post_async_logout_work(struct scsi_qla_host *, fc_port_t *,
92 uint16_t *);
93extern int qla2x00_post_async_logout_done_work(struct scsi_qla_host *,
94 fc_port_t *, uint16_t *);
95
79extern int qla81xx_restart_mpi_firmware(scsi_qla_host_t *); 96extern int qla81xx_restart_mpi_firmware(scsi_qla_host_t *);
80 97
81extern void qla2x00_abort_fcport_cmds(fc_port_t *); 98extern void qla2x00_abort_fcport_cmds(fc_port_t *);
@@ -83,6 +100,8 @@ extern struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *,
83 struct qla_hw_data *); 100 struct qla_hw_data *);
84extern void qla2x00_free_host(struct scsi_qla_host *); 101extern void qla2x00_free_host(struct scsi_qla_host *);
85extern void qla2x00_relogin(struct scsi_qla_host *); 102extern void qla2x00_relogin(struct scsi_qla_host *);
103extern void qla2x00_do_work(struct scsi_qla_host *);
104
86/* 105/*
87 * Global Functions in qla_mid.c source file. 106 * Global Functions in qla_mid.c source file.
88 */ 107 */
@@ -135,6 +154,7 @@ int qla2x00_marker(struct scsi_qla_host *, struct req_que *, struct rsp_que *,
135 uint16_t, uint16_t, uint8_t); 154 uint16_t, uint16_t, uint8_t);
136int __qla2x00_marker(struct scsi_qla_host *, struct req_que *, struct rsp_que *, 155int __qla2x00_marker(struct scsi_qla_host *, struct req_que *, struct rsp_que *,
137 uint16_t, uint16_t, uint8_t); 156 uint16_t, uint16_t, uint8_t);
157extern int qla2x00_start_sp(srb_t *);
138 158
139/* 159/*
140 * Global Function Prototypes in qla_mbx.c source file. 160 * Global Function Prototypes in qla_mbx.c source file.
diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c
index 917534b9f221..4647015eba63 100644
--- a/drivers/scsi/qla2xxx/qla_gs.c
+++ b/drivers/scsi/qla2xxx/qla_gs.c
@@ -1674,6 +1674,10 @@ int
1674qla2x00_fdmi_register(scsi_qla_host_t *vha) 1674qla2x00_fdmi_register(scsi_qla_host_t *vha)
1675{ 1675{
1676 int rval; 1676 int rval;
1677 struct qla_hw_data *ha = vha->hw;
1678
1679 if (IS_QLA2100(ha) || IS_QLA2200(ha))
1680 return QLA_FUNCTION_FAILED;
1677 1681
1678 rval = qla2x00_mgmt_svr_login(vha); 1682 rval = qla2x00_mgmt_svr_login(vha);
1679 if (rval) 1683 if (rval)
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index f2ce8e3cc91b..9e3eaac25596 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -40,6 +40,210 @@ static struct qla_chip_state_84xx *qla84xx_get_chip(struct scsi_qla_host *);
40static int qla84xx_init_chip(scsi_qla_host_t *); 40static int qla84xx_init_chip(scsi_qla_host_t *);
41static int qla25xx_init_queues(struct qla_hw_data *); 41static int qla25xx_init_queues(struct qla_hw_data *);
42 42
43/* SRB Extensions ---------------------------------------------------------- */
44
45static void
46qla2x00_ctx_sp_timeout(unsigned long __data)
47{
48 srb_t *sp = (srb_t *)__data;
49 struct srb_ctx *ctx;
50 fc_port_t *fcport = sp->fcport;
51 struct qla_hw_data *ha = fcport->vha->hw;
52 struct req_que *req;
53 unsigned long flags;
54
55 spin_lock_irqsave(&ha->hardware_lock, flags);
56 req = ha->req_q_map[0];
57 req->outstanding_cmds[sp->handle] = NULL;
58 ctx = sp->ctx;
59 ctx->timeout(sp);
60 spin_unlock_irqrestore(&ha->hardware_lock, flags);
61
62 ctx->free(sp);
63}
64
65static void
66qla2x00_ctx_sp_free(srb_t *sp)
67{
68 struct srb_ctx *ctx = sp->ctx;
69
70 kfree(ctx);
71 mempool_free(sp, sp->fcport->vha->hw->srb_mempool);
72}
73
74inline srb_t *
75qla2x00_get_ctx_sp(scsi_qla_host_t *vha, fc_port_t *fcport, size_t size,
76 unsigned long tmo)
77{
78 srb_t *sp;
79 struct qla_hw_data *ha = vha->hw;
80 struct srb_ctx *ctx;
81
82 sp = mempool_alloc(ha->srb_mempool, GFP_KERNEL);
83 if (!sp)
84 goto done;
85 ctx = kzalloc(size, GFP_KERNEL);
86 if (!ctx) {
87 mempool_free(sp, ha->srb_mempool);
88 goto done;
89 }
90
91 memset(sp, 0, sizeof(*sp));
92 sp->fcport = fcport;
93 sp->ctx = ctx;
94 ctx->free = qla2x00_ctx_sp_free;
95
96 init_timer(&ctx->timer);
97 if (!tmo)
98 goto done;
99 ctx->timer.expires = jiffies + tmo * HZ;
100 ctx->timer.data = (unsigned long)sp;
101 ctx->timer.function = qla2x00_ctx_sp_timeout;
102 add_timer(&ctx->timer);
103done:
104 return sp;
105}
106
107/* Asynchronous Login/Logout Routines -------------------------------------- */
108
109#define ELS_TMO_2_RATOV(ha) ((ha)->r_a_tov / 10 * 2)
110
111static void
112qla2x00_async_logio_timeout(srb_t *sp)
113{
114 fc_port_t *fcport = sp->fcport;
115 struct srb_logio *lio = sp->ctx;
116
117 DEBUG2(printk(KERN_WARNING
118 "scsi(%ld:%x): Async-%s timeout.\n",
119 fcport->vha->host_no, sp->handle,
120 lio->ctx.type == SRB_LOGIN_CMD ? "login": "logout"));
121
122 if (lio->ctx.type == SRB_LOGIN_CMD)
123 qla2x00_post_async_logout_work(fcport->vha, fcport, NULL);
124}
125
126int
127qla2x00_async_login(struct scsi_qla_host *vha, fc_port_t *fcport,
128 uint16_t *data)
129{
130 struct qla_hw_data *ha = vha->hw;
131 srb_t *sp;
132 struct srb_logio *lio;
133 int rval;
134
135 rval = QLA_FUNCTION_FAILED;
136 sp = qla2x00_get_ctx_sp(vha, fcport, sizeof(struct srb_logio),
137 ELS_TMO_2_RATOV(ha) + 2);
138 if (!sp)
139 goto done;
140
141 lio = sp->ctx;
142 lio->ctx.type = SRB_LOGIN_CMD;
143 lio->ctx.timeout = qla2x00_async_logio_timeout;
144 lio->flags |= SRB_LOGIN_COND_PLOGI;
145 if (data[1] & QLA_LOGIO_LOGIN_RETRIED)
146 lio->flags |= SRB_LOGIN_RETRIED;
147 rval = qla2x00_start_sp(sp);
148 if (rval != QLA_SUCCESS)
149 goto done_free_sp;
150
151 DEBUG2(printk(KERN_DEBUG
152 "scsi(%ld:%x): Async-login - loop-id=%x portid=%02x%02x%02x "
153 "retries=%d.\n", fcport->vha->host_no, sp->handle, fcport->loop_id,
154 fcport->d_id.b.domain, fcport->d_id.b.area, fcport->d_id.b.al_pa,
155 fcport->login_retry));
156 return rval;
157
158done_free_sp:
159 del_timer_sync(&lio->ctx.timer);
160 lio->ctx.free(sp);
161done:
162 return rval;
163}
164
165int
166qla2x00_async_logout(struct scsi_qla_host *vha, fc_port_t *fcport)
167{
168 struct qla_hw_data *ha = vha->hw;
169 srb_t *sp;
170 struct srb_logio *lio;
171 int rval;
172
173 rval = QLA_FUNCTION_FAILED;
174 sp = qla2x00_get_ctx_sp(vha, fcport, sizeof(struct srb_logio),
175 ELS_TMO_2_RATOV(ha) + 2);
176 if (!sp)
177 goto done;
178
179 lio = sp->ctx;
180 lio->ctx.type = SRB_LOGOUT_CMD;
181 lio->ctx.timeout = qla2x00_async_logio_timeout;
182 rval = qla2x00_start_sp(sp);
183 if (rval != QLA_SUCCESS)
184 goto done_free_sp;
185
186 DEBUG2(printk(KERN_DEBUG
187 "scsi(%ld:%x): Async-logout - loop-id=%x portid=%02x%02x%02x.\n",
188 fcport->vha->host_no, sp->handle, fcport->loop_id,
189 fcport->d_id.b.domain, fcport->d_id.b.area, fcport->d_id.b.al_pa));
190 return rval;
191
192done_free_sp:
193 del_timer_sync(&lio->ctx.timer);
194 lio->ctx.free(sp);
195done:
196 return rval;
197}
198
199int
200qla2x00_async_login_done(struct scsi_qla_host *vha, fc_port_t *fcport,
201 uint16_t *data)
202{
203 int rval;
204 uint8_t opts = 0;
205
206 switch (data[0]) {
207 case MBS_COMMAND_COMPLETE:
208 if (fcport->flags & FCF_TAPE_PRESENT)
209 opts |= BIT_1;
210 rval = qla2x00_get_port_database(vha, fcport, opts);
211 if (rval != QLA_SUCCESS)
212 qla2x00_mark_device_lost(vha, fcport, 1, 0);
213 else
214 qla2x00_update_fcport(vha, fcport);
215 break;
216 case MBS_COMMAND_ERROR:
217 if (data[1] & QLA_LOGIO_LOGIN_RETRIED)
218 set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
219 else
220 qla2x00_mark_device_lost(vha, fcport, 1, 0);
221 break;
222 case MBS_PORT_ID_USED:
223 fcport->loop_id = data[1];
224 qla2x00_post_async_login_work(vha, fcport, NULL);
225 break;
226 case MBS_LOOP_ID_USED:
227 fcport->loop_id++;
228 rval = qla2x00_find_new_loop_id(vha, fcport);
229 if (rval != QLA_SUCCESS) {
230 qla2x00_mark_device_lost(vha, fcport, 1, 0);
231 break;
232 }
233 qla2x00_post_async_login_work(vha, fcport, NULL);
234 break;
235 }
236 return QLA_SUCCESS;
237}
238
239int
240qla2x00_async_logout_done(struct scsi_qla_host *vha, fc_port_t *fcport,
241 uint16_t *data)
242{
243 qla2x00_mark_device_lost(vha, fcport, 1, 0);
244 return QLA_SUCCESS;
245}
246
43/****************************************************************************/ 247/****************************************************************************/
44/* QLogic ISP2x00 Hardware Support Functions. */ 248/* QLogic ISP2x00 Hardware Support Functions. */
45/****************************************************************************/ 249/****************************************************************************/
@@ -987,7 +1191,6 @@ qla2x00_setup_chip(scsi_qla_host_t *vha)
987 ha->phy_version); 1191 ha->phy_version);
988 if (rval != QLA_SUCCESS) 1192 if (rval != QLA_SUCCESS)
989 goto failed; 1193 goto failed;
990
991 ha->flags.npiv_supported = 0; 1194 ha->flags.npiv_supported = 0;
992 if (IS_QLA2XXX_MIDTYPE(ha) && 1195 if (IS_QLA2XXX_MIDTYPE(ha) &&
993 (ha->fw_attributes & BIT_2)) { 1196 (ha->fw_attributes & BIT_2)) {
@@ -1591,7 +1794,8 @@ qla2x00_set_model_info(scsi_qla_host_t *vha, uint8_t *model, size_t len,
1591 char *st, *en; 1794 char *st, *en;
1592 uint16_t index; 1795 uint16_t index;
1593 struct qla_hw_data *ha = vha->hw; 1796 struct qla_hw_data *ha = vha->hw;
1594 int use_tbl = !IS_QLA25XX(ha) && !IS_QLA81XX(ha); 1797 int use_tbl = !IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha) &&
1798 !IS_QLA81XX(ha);
1595 1799
1596 if (memcmp(model, BINZERO, len) != 0) { 1800 if (memcmp(model, BINZERO, len) != 0) {
1597 strncpy(ha->model_number, model, len); 1801 strncpy(ha->model_number, model, len);
@@ -1978,7 +2182,7 @@ qla2x00_rport_del(void *data)
1978 struct fc_rport *rport; 2182 struct fc_rport *rport;
1979 2183
1980 spin_lock_irq(fcport->vha->host->host_lock); 2184 spin_lock_irq(fcport->vha->host->host_lock);
1981 rport = fcport->drport; 2185 rport = fcport->drport ? fcport->drport: fcport->rport;
1982 fcport->drport = NULL; 2186 fcport->drport = NULL;
1983 spin_unlock_irq(fcport->vha->host->host_lock); 2187 spin_unlock_irq(fcport->vha->host->host_lock);
1984 if (rport) 2188 if (rport)
@@ -2345,8 +2549,7 @@ qla2x00_reg_remote_port(scsi_qla_host_t *vha, fc_port_t *fcport)
2345 struct fc_rport *rport; 2549 struct fc_rport *rport;
2346 struct qla_hw_data *ha = vha->hw; 2550 struct qla_hw_data *ha = vha->hw;
2347 2551
2348 if (fcport->drport) 2552 qla2x00_rport_del(fcport);
2349 qla2x00_rport_del(fcport);
2350 2553
2351 rport_ids.node_name = wwn_to_u64(fcport->node_name); 2554 rport_ids.node_name = wwn_to_u64(fcport->node_name);
2352 rport_ids.port_name = wwn_to_u64(fcport->port_name); 2555 rport_ids.port_name = wwn_to_u64(fcport->port_name);
@@ -3039,6 +3242,12 @@ qla2x00_fabric_dev_login(scsi_qla_host_t *vha, fc_port_t *fcport,
3039 rval = QLA_SUCCESS; 3242 rval = QLA_SUCCESS;
3040 retry = 0; 3243 retry = 0;
3041 3244
3245 if (IS_ALOGIO_CAPABLE(ha)) {
3246 rval = qla2x00_post_async_login_work(vha, fcport, NULL);
3247 if (!rval)
3248 return rval;
3249 }
3250
3042 rval = qla2x00_fabric_login(vha, fcport, next_loopid); 3251 rval = qla2x00_fabric_login(vha, fcport, next_loopid);
3043 if (rval == QLA_SUCCESS) { 3252 if (rval == QLA_SUCCESS) {
3044 /* Send an ADISC to tape devices.*/ 3253 /* Send an ADISC to tape devices.*/
@@ -3133,7 +3342,7 @@ qla2x00_fabric_login(scsi_qla_host_t *vha, fc_port_t *fcport,
3133 } else { 3342 } else {
3134 fcport->port_type = FCT_TARGET; 3343 fcport->port_type = FCT_TARGET;
3135 if (mb[1] & BIT_1) { 3344 if (mb[1] & BIT_1) {
3136 fcport->flags |= FCF_TAPE_PRESENT; 3345 fcport->flags |= FCF_FCP2_DEVICE;
3137 } 3346 }
3138 } 3347 }
3139 3348
@@ -3244,7 +3453,7 @@ qla2x00_loop_resync(scsi_qla_host_t *vha)
3244 struct req_que *req; 3453 struct req_que *req;
3245 struct rsp_que *rsp; 3454 struct rsp_que *rsp;
3246 3455
3247 if (ql2xmultique_tag) 3456 if (vha->hw->flags.cpu_affinity_enabled)
3248 req = vha->hw->req_q_map[0]; 3457 req = vha->hw->req_q_map[0];
3249 else 3458 else
3250 req = vha->req; 3459 req = vha->req;
@@ -3286,15 +3495,17 @@ qla2x00_loop_resync(scsi_qla_host_t *vha)
3286} 3495}
3287 3496
3288void 3497void
3289qla2x00_update_fcports(scsi_qla_host_t *vha) 3498qla2x00_update_fcports(scsi_qla_host_t *base_vha)
3290{ 3499{
3291 fc_port_t *fcport; 3500 fc_port_t *fcport;
3501 struct scsi_qla_host *tvp, *vha;
3292 3502
3293 /* Go with deferred removal of rport references. */ 3503 /* Go with deferred removal of rport references. */
3294 list_for_each_entry(fcport, &vha->vp_fcports, list) 3504 list_for_each_entry_safe(vha, tvp, &base_vha->hw->vp_list, list)
3295 if (fcport && fcport->drport && 3505 list_for_each_entry(fcport, &vha->vp_fcports, list)
3296 atomic_read(&fcport->state) != FCS_UNCONFIGURED) 3506 if (fcport && fcport->drport &&
3297 qla2x00_rport_del(fcport); 3507 atomic_read(&fcport->state) != FCS_UNCONFIGURED)
3508 qla2x00_rport_del(fcport);
3298} 3509}
3299 3510
3300/* 3511/*
@@ -3331,8 +3542,6 @@ qla2x00_abort_isp(scsi_qla_host_t *vha)
3331 if (atomic_read(&vha->loop_state) != LOOP_DOWN) { 3542 if (atomic_read(&vha->loop_state) != LOOP_DOWN) {
3332 atomic_set(&vha->loop_state, LOOP_DOWN); 3543 atomic_set(&vha->loop_state, LOOP_DOWN);
3333 qla2x00_mark_all_devices_lost(vha, 0); 3544 qla2x00_mark_all_devices_lost(vha, 0);
3334 list_for_each_entry_safe(vp, tvp, &ha->vp_list, list)
3335 qla2x00_mark_all_devices_lost(vp, 0);
3336 } else { 3545 } else {
3337 if (!atomic_read(&vha->loop_down_timer)) 3546 if (!atomic_read(&vha->loop_down_timer))
3338 atomic_set(&vha->loop_down_timer, 3547 atomic_set(&vha->loop_down_timer,
@@ -4264,7 +4473,7 @@ qla24xx_configure_vhba(scsi_qla_host_t *vha)
4264 return -EINVAL; 4473 return -EINVAL;
4265 4474
4266 rval = qla2x00_fw_ready(base_vha); 4475 rval = qla2x00_fw_ready(base_vha);
4267 if (ql2xmultique_tag) 4476 if (ha->flags.cpu_affinity_enabled)
4268 req = ha->req_q_map[0]; 4477 req = ha->req_q_map[0];
4269 else 4478 else
4270 req = vha->req; 4479 req = vha->req;
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c
index 13396beae2ce..c5ccac0bef76 100644
--- a/drivers/scsi/qla2xxx/qla_iocb.c
+++ b/drivers/scsi/qla2xxx/qla_iocb.c
@@ -350,6 +350,7 @@ qla2x00_start_scsi(srb_t *sp)
350 /* Build command packet */ 350 /* Build command packet */
351 req->current_outstanding_cmd = handle; 351 req->current_outstanding_cmd = handle;
352 req->outstanding_cmds[handle] = sp; 352 req->outstanding_cmds[handle] = sp;
353 sp->handle = handle;
353 sp->cmd->host_scribble = (unsigned char *)(unsigned long)handle; 354 sp->cmd->host_scribble = (unsigned char *)(unsigned long)handle;
354 req->cnt -= req_cnt; 355 req->cnt -= req_cnt;
355 356
@@ -778,6 +779,7 @@ qla24xx_start_scsi(srb_t *sp)
778 /* Build command packet. */ 779 /* Build command packet. */
779 req->current_outstanding_cmd = handle; 780 req->current_outstanding_cmd = handle;
780 req->outstanding_cmds[handle] = sp; 781 req->outstanding_cmds[handle] = sp;
782 sp->handle = handle;
781 sp->cmd->host_scribble = (unsigned char *)(unsigned long)handle; 783 sp->cmd->host_scribble = (unsigned char *)(unsigned long)handle;
782 req->cnt -= req_cnt; 784 req->cnt -= req_cnt;
783 785
@@ -852,9 +854,211 @@ static void qla25xx_set_que(srb_t *sp, struct rsp_que **rsp)
852 struct qla_hw_data *ha = sp->fcport->vha->hw; 854 struct qla_hw_data *ha = sp->fcport->vha->hw;
853 int affinity = cmd->request->cpu; 855 int affinity = cmd->request->cpu;
854 856
855 if (ql2xmultique_tag && affinity >= 0 && 857 if (ha->flags.cpu_affinity_enabled && affinity >= 0 &&
856 affinity < ha->max_rsp_queues - 1) 858 affinity < ha->max_rsp_queues - 1)
857 *rsp = ha->rsp_q_map[affinity + 1]; 859 *rsp = ha->rsp_q_map[affinity + 1];
858 else 860 else
859 *rsp = ha->rsp_q_map[0]; 861 *rsp = ha->rsp_q_map[0];
860} 862}
863
864/* Generic Control-SRB manipulation functions. */
865
866static void *
867qla2x00_alloc_iocbs(srb_t *sp)
868{
869 scsi_qla_host_t *vha = sp->fcport->vha;
870 struct qla_hw_data *ha = vha->hw;
871 struct req_que *req = ha->req_q_map[0];
872 device_reg_t __iomem *reg = ISP_QUE_REG(ha, req->id);
873 uint32_t index, handle;
874 request_t *pkt;
875 uint16_t cnt, req_cnt;
876
877 pkt = NULL;
878 req_cnt = 1;
879
880 /* Check for room in outstanding command list. */
881 handle = req->current_outstanding_cmd;
882 for (index = 1; index < MAX_OUTSTANDING_COMMANDS; index++) {
883 handle++;
884 if (handle == MAX_OUTSTANDING_COMMANDS)
885 handle = 1;
886 if (!req->outstanding_cmds[handle])
887 break;
888 }
889 if (index == MAX_OUTSTANDING_COMMANDS)
890 goto queuing_error;
891
892 /* Check for room on request queue. */
893 if (req->cnt < req_cnt) {
894 if (ha->mqenable)
895 cnt = RD_REG_DWORD(&reg->isp25mq.req_q_out);
896 else if (IS_FWI2_CAPABLE(ha))
897 cnt = RD_REG_DWORD(&reg->isp24.req_q_out);
898 else
899 cnt = qla2x00_debounce_register(
900 ISP_REQ_Q_OUT(ha, &reg->isp));
901
902 if (req->ring_index < cnt)
903 req->cnt = cnt - req->ring_index;
904 else
905 req->cnt = req->length -
906 (req->ring_index - cnt);
907 }
908 if (req->cnt < req_cnt)
909 goto queuing_error;
910
911 /* Prep packet */
912 req->current_outstanding_cmd = handle;
913 req->outstanding_cmds[handle] = sp;
914 req->cnt -= req_cnt;
915
916 pkt = req->ring_ptr;
917 memset(pkt, 0, REQUEST_ENTRY_SIZE);
918 pkt->entry_count = req_cnt;
919 pkt->handle = handle;
920 sp->handle = handle;
921
922queuing_error:
923 return pkt;
924}
925
926static void
927qla2x00_start_iocbs(srb_t *sp)
928{
929 struct qla_hw_data *ha = sp->fcport->vha->hw;
930 struct req_que *req = ha->req_q_map[0];
931 device_reg_t __iomem *reg = ISP_QUE_REG(ha, req->id);
932 struct device_reg_2xxx __iomem *ioreg = &ha->iobase->isp;
933
934 /* Adjust ring index. */
935 req->ring_index++;
936 if (req->ring_index == req->length) {
937 req->ring_index = 0;
938 req->ring_ptr = req->ring;
939 } else
940 req->ring_ptr++;
941
942 /* Set chip new ring index. */
943 if (ha->mqenable) {
944 WRT_REG_DWORD(&reg->isp25mq.req_q_in, req->ring_index);
945 RD_REG_DWORD(&ioreg->hccr);
946 } else if (IS_FWI2_CAPABLE(ha)) {
947 WRT_REG_DWORD(&reg->isp24.req_q_in, req->ring_index);
948 RD_REG_DWORD_RELAXED(&reg->isp24.req_q_in);
949 } else {
950 WRT_REG_WORD(ISP_REQ_Q_IN(ha, &reg->isp), req->ring_index);
951 RD_REG_WORD_RELAXED(ISP_REQ_Q_IN(ha, &reg->isp));
952 }
953}
954
955static void
956qla24xx_login_iocb(srb_t *sp, struct logio_entry_24xx *logio)
957{
958 struct srb_logio *lio = sp->ctx;
959
960 logio->entry_type = LOGINOUT_PORT_IOCB_TYPE;
961 logio->control_flags = cpu_to_le16(LCF_COMMAND_PLOGI);
962 if (lio->flags & SRB_LOGIN_COND_PLOGI)
963 logio->control_flags |= cpu_to_le16(LCF_COND_PLOGI);
964 if (lio->flags & SRB_LOGIN_SKIP_PRLI)
965 logio->control_flags |= cpu_to_le16(LCF_SKIP_PRLI);
966 logio->nport_handle = cpu_to_le16(sp->fcport->loop_id);
967 logio->port_id[0] = sp->fcport->d_id.b.al_pa;
968 logio->port_id[1] = sp->fcport->d_id.b.area;
969 logio->port_id[2] = sp->fcport->d_id.b.domain;
970 logio->vp_index = sp->fcport->vp_idx;
971}
972
973static void
974qla2x00_login_iocb(srb_t *sp, struct mbx_entry *mbx)
975{
976 struct qla_hw_data *ha = sp->fcport->vha->hw;
977 struct srb_logio *lio = sp->ctx;
978 uint16_t opts;
979
980 mbx->entry_type = MBX_IOCB_TYPE;;
981 SET_TARGET_ID(ha, mbx->loop_id, sp->fcport->loop_id);
982 mbx->mb0 = cpu_to_le16(MBC_LOGIN_FABRIC_PORT);
983 opts = lio->flags & SRB_LOGIN_COND_PLOGI ? BIT_0: 0;
984 opts |= lio->flags & SRB_LOGIN_SKIP_PRLI ? BIT_1: 0;
985 if (HAS_EXTENDED_IDS(ha)) {
986 mbx->mb1 = cpu_to_le16(sp->fcport->loop_id);
987 mbx->mb10 = cpu_to_le16(opts);
988 } else {
989 mbx->mb1 = cpu_to_le16((sp->fcport->loop_id << 8) | opts);
990 }
991 mbx->mb2 = cpu_to_le16(sp->fcport->d_id.b.domain);
992 mbx->mb3 = cpu_to_le16(sp->fcport->d_id.b.area << 8 |
993 sp->fcport->d_id.b.al_pa);
994 mbx->mb9 = cpu_to_le16(sp->fcport->vp_idx);
995}
996
997static void
998qla24xx_logout_iocb(srb_t *sp, struct logio_entry_24xx *logio)
999{
1000 logio->entry_type = LOGINOUT_PORT_IOCB_TYPE;
1001 logio->control_flags =
1002 cpu_to_le16(LCF_COMMAND_LOGO|LCF_IMPL_LOGO);
1003 logio->nport_handle = cpu_to_le16(sp->fcport->loop_id);
1004 logio->port_id[0] = sp->fcport->d_id.b.al_pa;
1005 logio->port_id[1] = sp->fcport->d_id.b.area;
1006 logio->port_id[2] = sp->fcport->d_id.b.domain;
1007 logio->vp_index = sp->fcport->vp_idx;
1008}
1009
1010static void
1011qla2x00_logout_iocb(srb_t *sp, struct mbx_entry *mbx)
1012{
1013 struct qla_hw_data *ha = sp->fcport->vha->hw;
1014
1015 mbx->entry_type = MBX_IOCB_TYPE;;
1016 SET_TARGET_ID(ha, mbx->loop_id, sp->fcport->loop_id);
1017 mbx->mb0 = cpu_to_le16(MBC_LOGOUT_FABRIC_PORT);
1018 mbx->mb1 = HAS_EXTENDED_IDS(ha) ?
1019 cpu_to_le16(sp->fcport->loop_id):
1020 cpu_to_le16(sp->fcport->loop_id << 8);
1021 mbx->mb2 = cpu_to_le16(sp->fcport->d_id.b.domain);
1022 mbx->mb3 = cpu_to_le16(sp->fcport->d_id.b.area << 8 |
1023 sp->fcport->d_id.b.al_pa);
1024 mbx->mb9 = cpu_to_le16(sp->fcport->vp_idx);
1025 /* Implicit: mbx->mbx10 = 0. */
1026}
1027
1028int
1029qla2x00_start_sp(srb_t *sp)
1030{
1031 int rval;
1032 struct qla_hw_data *ha = sp->fcport->vha->hw;
1033 void *pkt;
1034 struct srb_ctx *ctx = sp->ctx;
1035 unsigned long flags;
1036
1037 rval = QLA_FUNCTION_FAILED;
1038 spin_lock_irqsave(&ha->hardware_lock, flags);
1039 pkt = qla2x00_alloc_iocbs(sp);
1040 if (!pkt)
1041 goto done;
1042
1043 rval = QLA_SUCCESS;
1044 switch (ctx->type) {
1045 case SRB_LOGIN_CMD:
1046 IS_FWI2_CAPABLE(ha) ?
1047 qla24xx_login_iocb(sp, pkt):
1048 qla2x00_login_iocb(sp, pkt);
1049 break;
1050 case SRB_LOGOUT_CMD:
1051 IS_FWI2_CAPABLE(ha) ?
1052 qla24xx_logout_iocb(sp, pkt):
1053 qla2x00_logout_iocb(sp, pkt);
1054 break;
1055 default:
1056 break;
1057 }
1058
1059 wmb();
1060 qla2x00_start_iocbs(sp);
1061done:
1062 spin_unlock_irqrestore(&ha->hardware_lock, flags);
1063 return rval;
1064}
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index 245e7afb4c4d..b20a7169aac2 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -598,9 +598,54 @@ skip_rio:
598 break; 598 break;
599 599
600 case MBA_PORT_UPDATE: /* Port database update */ 600 case MBA_PORT_UPDATE: /* Port database update */
601 /* Only handle SCNs for our Vport index. */ 601 /*
602 if (vha->vp_idx && vha->vp_idx != (mb[3] & 0xff)) 602 * Handle only global and vn-port update events
603 *
604 * Relevant inputs:
605 * mb[1] = N_Port handle of changed port
606 * OR 0xffff for global event
607 * mb[2] = New login state
608 * 7 = Port logged out
609 * mb[3] = LSB is vp_idx, 0xff = all vps
610 *
611 * Skip processing if:
612 * Event is global, vp_idx is NOT all vps,
613 * vp_idx does not match
614 * Event is not global, vp_idx does not match
615 */
616 if ((mb[1] == 0xffff && (mb[3] & 0xff) != 0xff)
617 || (mb[1] != 0xffff)) {
618 if (vha->vp_idx != (mb[3] & 0xff))
619 break;
620 }
621
622 /* Global event -- port logout or port unavailable. */
623 if (mb[1] == 0xffff && mb[2] == 0x7) {
624 DEBUG2(printk("scsi(%ld): Asynchronous PORT UPDATE.\n",
625 vha->host_no));
626 DEBUG(printk(KERN_INFO
627 "scsi(%ld): Port unavailable %04x %04x %04x.\n",
628 vha->host_no, mb[1], mb[2], mb[3]));
629
630 if (atomic_read(&vha->loop_state) != LOOP_DOWN) {
631 atomic_set(&vha->loop_state, LOOP_DOWN);
632 atomic_set(&vha->loop_down_timer,
633 LOOP_DOWN_TIME);
634 vha->device_flags |= DFLG_NO_CABLE;
635 qla2x00_mark_all_devices_lost(vha, 1);
636 }
637
638 if (vha->vp_idx) {
639 atomic_set(&vha->vp_state, VP_FAILED);
640 fc_vport_set_state(vha->fc_vport,
641 FC_VPORT_FAILED);
642 qla2x00_mark_all_devices_lost(vha, 1);
643 }
644
645 vha->flags.management_server_logged_in = 0;
646 ha->link_data_rate = PORT_SPEED_UNKNOWN;
603 break; 647 break;
648 }
604 649
605 /* 650 /*
606 * If PORT UPDATE is global (received LIP_OCCURRED/LIP_RESET 651 * If PORT UPDATE is global (received LIP_OCCURRED/LIP_RESET
@@ -640,8 +685,9 @@ skip_rio:
640 if (vha->vp_idx && test_bit(VP_SCR_NEEDED, &vha->vp_flags)) 685 if (vha->vp_idx && test_bit(VP_SCR_NEEDED, &vha->vp_flags))
641 break; 686 break;
642 /* Only handle SCNs for our Vport index. */ 687 /* Only handle SCNs for our Vport index. */
643 if (vha->vp_idx && vha->vp_idx != (mb[3] & 0xff)) 688 if (ha->flags.npiv_supported && vha->vp_idx != (mb[3] & 0xff))
644 break; 689 break;
690
645 DEBUG2(printk("scsi(%ld): Asynchronous RSCR UPDATE.\n", 691 DEBUG2(printk("scsi(%ld): Asynchronous RSCR UPDATE.\n",
646 vha->host_no)); 692 vha->host_no));
647 DEBUG(printk(KERN_INFO 693 DEBUG(printk(KERN_INFO
@@ -874,6 +920,249 @@ qla2x00_process_completed_request(struct scsi_qla_host *vha,
874 } 920 }
875} 921}
876 922
923static srb_t *
924qla2x00_get_sp_from_handle(scsi_qla_host_t *vha, const char *func,
925 struct req_que *req, void *iocb)
926{
927 struct qla_hw_data *ha = vha->hw;
928 sts_entry_t *pkt = iocb;
929 srb_t *sp = NULL;
930 uint16_t index;
931
932 index = LSW(pkt->handle);
933 if (index >= MAX_OUTSTANDING_COMMANDS) {
934 qla_printk(KERN_WARNING, ha,
935 "%s: Invalid completion handle (%x).\n", func, index);
936 set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
937 goto done;
938 }
939 sp = req->outstanding_cmds[index];
940 if (!sp) {
941 qla_printk(KERN_WARNING, ha,
942 "%s: Invalid completion handle (%x) -- timed-out.\n", func,
943 index);
944 return sp;
945 }
946 if (sp->handle != index) {
947 qla_printk(KERN_WARNING, ha,
948 "%s: SRB handle (%x) mismatch %x.\n", func, sp->handle,
949 index);
950 return NULL;
951 }
952 req->outstanding_cmds[index] = NULL;
953done:
954 return sp;
955}
956
957static void
958qla2x00_mbx_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
959 struct mbx_entry *mbx)
960{
961 const char func[] = "MBX-IOCB";
962 const char *type;
963 struct qla_hw_data *ha = vha->hw;
964 fc_port_t *fcport;
965 srb_t *sp;
966 struct srb_logio *lio;
967 uint16_t data[2];
968
969 sp = qla2x00_get_sp_from_handle(vha, func, req, mbx);
970 if (!sp)
971 return;
972
973 type = NULL;
974 lio = sp->ctx;
975 switch (lio->ctx.type) {
976 case SRB_LOGIN_CMD:
977 type = "login";
978 break;
979 case SRB_LOGOUT_CMD:
980 type = "logout";
981 break;
982 default:
983 qla_printk(KERN_WARNING, ha,
984 "%s: Unrecognized SRB: (%p) type=%d.\n", func, sp,
985 lio->ctx.type);
986 return;
987 }
988
989 del_timer(&lio->ctx.timer);
990 fcport = sp->fcport;
991
992 data[0] = data[1] = 0;
993 if (mbx->entry_status) {
994 DEBUG2(printk(KERN_WARNING
995 "scsi(%ld:%x): Async-%s error entry - entry-status=%x "
996 "status=%x state-flag=%x status-flags=%x.\n",
997 fcport->vha->host_no, sp->handle, type,
998 mbx->entry_status, le16_to_cpu(mbx->status),
999 le16_to_cpu(mbx->state_flags),
1000 le16_to_cpu(mbx->status_flags)));
1001 DEBUG2(qla2x00_dump_buffer((uint8_t *)mbx, sizeof(*mbx)));
1002
1003 data[0] = MBS_COMMAND_ERROR;
1004 data[1] = lio->flags & SRB_LOGIN_RETRIED ?
1005 QLA_LOGIO_LOGIN_RETRIED: 0;
1006 goto done_post_logio_done_work;
1007 }
1008
1009 if (!mbx->status && le16_to_cpu(mbx->mb0) == MBS_COMMAND_COMPLETE) {
1010 DEBUG2(printk(KERN_DEBUG
1011 "scsi(%ld:%x): Async-%s complete - mbx1=%x.\n",
1012 fcport->vha->host_no, sp->handle, type,
1013 le16_to_cpu(mbx->mb1)));
1014
1015 data[0] = MBS_COMMAND_COMPLETE;
1016 if (lio->ctx.type == SRB_LOGIN_CMD && le16_to_cpu(mbx->mb1) & BIT_1)
1017 fcport->flags |= FCF_FCP2_DEVICE;
1018
1019 goto done_post_logio_done_work;
1020 }
1021
1022 data[0] = le16_to_cpu(mbx->mb0);
1023 switch (data[0]) {
1024 case MBS_PORT_ID_USED:
1025 data[1] = le16_to_cpu(mbx->mb1);
1026 break;
1027 case MBS_LOOP_ID_USED:
1028 break;
1029 default:
1030 data[0] = MBS_COMMAND_ERROR;
1031 data[1] = lio->flags & SRB_LOGIN_RETRIED ?
1032 QLA_LOGIO_LOGIN_RETRIED: 0;
1033 break;
1034 }
1035
1036 DEBUG2(printk(KERN_WARNING
1037 "scsi(%ld:%x): Async-%s failed - status=%x mb0=%x mb1=%x mb2=%x "
1038 "mb6=%x mb7=%x.\n",
1039 fcport->vha->host_no, sp->handle, type, le16_to_cpu(mbx->status),
1040 le16_to_cpu(mbx->mb0), le16_to_cpu(mbx->mb1),
1041 le16_to_cpu(mbx->mb2), le16_to_cpu(mbx->mb6),
1042 le16_to_cpu(mbx->mb7)));
1043
1044done_post_logio_done_work:
1045 lio->ctx.type == SRB_LOGIN_CMD ?
1046 qla2x00_post_async_login_done_work(fcport->vha, fcport, data):
1047 qla2x00_post_async_logout_done_work(fcport->vha, fcport, data);
1048
1049 lio->ctx.free(sp);
1050}
1051
1052static void
1053qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req,
1054 struct logio_entry_24xx *logio)
1055{
1056 const char func[] = "LOGIO-IOCB";
1057 const char *type;
1058 struct qla_hw_data *ha = vha->hw;
1059 fc_port_t *fcport;
1060 srb_t *sp;
1061 struct srb_logio *lio;
1062 uint16_t data[2];
1063 uint32_t iop[2];
1064
1065 sp = qla2x00_get_sp_from_handle(vha, func, req, logio);
1066 if (!sp)
1067 return;
1068
1069 type = NULL;
1070 lio = sp->ctx;
1071 switch (lio->ctx.type) {
1072 case SRB_LOGIN_CMD:
1073 type = "login";
1074 break;
1075 case SRB_LOGOUT_CMD:
1076 type = "logout";
1077 break;
1078 default:
1079 qla_printk(KERN_WARNING, ha,
1080 "%s: Unrecognized SRB: (%p) type=%d.\n", func, sp,
1081 lio->ctx.type);
1082 return;
1083 }
1084
1085 del_timer(&lio->ctx.timer);
1086 fcport = sp->fcport;
1087
1088 data[0] = data[1] = 0;
1089 if (logio->entry_status) {
1090 DEBUG2(printk(KERN_WARNING
1091 "scsi(%ld:%x): Async-%s error entry - entry-status=%x.\n",
1092 fcport->vha->host_no, sp->handle, type,
1093 logio->entry_status));
1094 DEBUG2(qla2x00_dump_buffer((uint8_t *)logio, sizeof(*logio)));
1095
1096 data[0] = MBS_COMMAND_ERROR;
1097 data[1] = lio->flags & SRB_LOGIN_RETRIED ?
1098 QLA_LOGIO_LOGIN_RETRIED: 0;
1099 goto done_post_logio_done_work;
1100 }
1101
1102 if (le16_to_cpu(logio->comp_status) == CS_COMPLETE) {
1103 DEBUG2(printk(KERN_DEBUG
1104 "scsi(%ld:%x): Async-%s complete - iop0=%x.\n",
1105 fcport->vha->host_no, sp->handle, type,
1106 le32_to_cpu(logio->io_parameter[0])));
1107
1108 data[0] = MBS_COMMAND_COMPLETE;
1109 if (lio->ctx.type == SRB_LOGOUT_CMD)
1110 goto done_post_logio_done_work;
1111
1112 iop[0] = le32_to_cpu(logio->io_parameter[0]);
1113 if (iop[0] & BIT_4) {
1114 fcport->port_type = FCT_TARGET;
1115 if (iop[0] & BIT_8)
1116 fcport->flags |= FCF_FCP2_DEVICE;
1117 }
1118 if (iop[0] & BIT_5)
1119 fcport->port_type = FCT_INITIATOR;
1120 if (logio->io_parameter[7] || logio->io_parameter[8])
1121 fcport->supported_classes |= FC_COS_CLASS2;
1122 if (logio->io_parameter[9] || logio->io_parameter[10])
1123 fcport->supported_classes |= FC_COS_CLASS3;
1124
1125 goto done_post_logio_done_work;
1126 }
1127
1128 iop[0] = le32_to_cpu(logio->io_parameter[0]);
1129 iop[1] = le32_to_cpu(logio->io_parameter[1]);
1130 switch (iop[0]) {
1131 case LSC_SCODE_PORTID_USED:
1132 data[0] = MBS_PORT_ID_USED;
1133 data[1] = LSW(iop[1]);
1134 break;
1135 case LSC_SCODE_NPORT_USED:
1136 data[0] = MBS_LOOP_ID_USED;
1137 break;
1138 case LSC_SCODE_CMD_FAILED:
1139 if ((iop[1] & 0xff) == 0x05) {
1140 data[0] = MBS_NOT_LOGGED_IN;
1141 break;
1142 }
1143 /* Fall through. */
1144 default:
1145 data[0] = MBS_COMMAND_ERROR;
1146 data[1] = lio->flags & SRB_LOGIN_RETRIED ?
1147 QLA_LOGIO_LOGIN_RETRIED: 0;
1148 break;
1149 }
1150
1151 DEBUG2(printk(KERN_WARNING
1152 "scsi(%ld:%x): Async-%s failed - comp=%x iop0=%x iop1=%x.\n",
1153 fcport->vha->host_no, sp->handle, type,
1154 le16_to_cpu(logio->comp_status),
1155 le32_to_cpu(logio->io_parameter[0]),
1156 le32_to_cpu(logio->io_parameter[1])));
1157
1158done_post_logio_done_work:
1159 lio->ctx.type == SRB_LOGIN_CMD ?
1160 qla2x00_post_async_login_done_work(fcport->vha, fcport, data):
1161 qla2x00_post_async_logout_done_work(fcport->vha, fcport, data);
1162
1163 lio->ctx.free(sp);
1164}
1165
877/** 1166/**
878 * qla2x00_process_response_queue() - Process response queue entries. 1167 * qla2x00_process_response_queue() - Process response queue entries.
879 * @ha: SCSI driver HA context 1168 * @ha: SCSI driver HA context
@@ -935,6 +1224,9 @@ qla2x00_process_response_queue(struct rsp_que *rsp)
935 case STATUS_CONT_TYPE: 1224 case STATUS_CONT_TYPE:
936 qla2x00_status_cont_entry(rsp, (sts_cont_entry_t *)pkt); 1225 qla2x00_status_cont_entry(rsp, (sts_cont_entry_t *)pkt);
937 break; 1226 break;
1227 case MBX_IOCB_TYPE:
1228 qla2x00_mbx_iocb_entry(vha, rsp->req,
1229 (struct mbx_entry *)pkt);
938 default: 1230 default:
939 /* Type Not Supported. */ 1231 /* Type Not Supported. */
940 DEBUG4(printk(KERN_WARNING 1232 DEBUG4(printk(KERN_WARNING
@@ -1223,6 +1515,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
1223 cp->device->id, cp->device->lun, resid, 1515 cp->device->id, cp->device->lun, resid,
1224 scsi_bufflen(cp))); 1516 scsi_bufflen(cp)));
1225 1517
1518 scsi_set_resid(cp, resid);
1226 cp->result = DID_ERROR << 16; 1519 cp->result = DID_ERROR << 16;
1227 break; 1520 break;
1228 } 1521 }
@@ -1544,6 +1837,10 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
1544 qla24xx_report_id_acquisition(vha, 1837 qla24xx_report_id_acquisition(vha,
1545 (struct vp_rpt_id_entry_24xx *)pkt); 1838 (struct vp_rpt_id_entry_24xx *)pkt);
1546 break; 1839 break;
1840 case LOGINOUT_PORT_IOCB_TYPE:
1841 qla24xx_logio_entry(vha, rsp->req,
1842 (struct logio_entry_24xx *)pkt);
1843 break;
1547 default: 1844 default:
1548 /* Type Not Supported. */ 1845 /* Type Not Supported. */
1549 DEBUG4(printk(KERN_WARNING 1846 DEBUG4(printk(KERN_WARNING
@@ -1723,8 +2020,10 @@ qla24xx_msix_rsp_q(int irq, void *dev_id)
1723 2020
1724 vha = qla25xx_get_host(rsp); 2021 vha = qla25xx_get_host(rsp);
1725 qla24xx_process_response_queue(vha, rsp); 2022 qla24xx_process_response_queue(vha, rsp);
1726 WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT); 2023 if (!ha->mqenable) {
1727 2024 WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
2025 RD_REG_DWORD_RELAXED(&reg->hccr);
2026 }
1728 spin_unlock_irq(&ha->hardware_lock); 2027 spin_unlock_irq(&ha->hardware_lock);
1729 2028
1730 return IRQ_HANDLED; 2029 return IRQ_HANDLED;
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index fe69f3057671..b6202fe118ac 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -1507,7 +1507,7 @@ qla24xx_login_fabric(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
1507 1507
1508 DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no)); 1508 DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
1509 1509
1510 if (ql2xmultique_tag) 1510 if (ha->flags.cpu_affinity_enabled)
1511 req = ha->req_q_map[0]; 1511 req = ha->req_q_map[0];
1512 else 1512 else
1513 req = vha->req; 1513 req = vha->req;
@@ -2324,7 +2324,7 @@ __qla24xx_issue_tmf(char *name, uint32_t type, struct fc_port *fcport,
2324 vha = fcport->vha; 2324 vha = fcport->vha;
2325 ha = vha->hw; 2325 ha = vha->hw;
2326 req = vha->req; 2326 req = vha->req;
2327 if (ql2xmultique_tag) 2327 if (ha->flags.cpu_affinity_enabled)
2328 rsp = ha->rsp_q_map[tag + 1]; 2328 rsp = ha->rsp_q_map[tag + 1];
2329 else 2329 else
2330 rsp = req->rsp; 2330 rsp = req->rsp;
@@ -2746,7 +2746,8 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
2746 if (rptid_entry->format == 0) { 2746 if (rptid_entry->format == 0) {
2747 DEBUG15(printk("%s:format 0 : scsi(%ld) number of VPs setup %d," 2747 DEBUG15(printk("%s:format 0 : scsi(%ld) number of VPs setup %d,"
2748 " number of VPs acquired %d\n", __func__, vha->host_no, 2748 " number of VPs acquired %d\n", __func__, vha->host_no,
2749 MSB(rptid_entry->vp_count), LSB(rptid_entry->vp_count))); 2749 MSB(le16_to_cpu(rptid_entry->vp_count)),
2750 LSB(le16_to_cpu(rptid_entry->vp_count))));
2750 DEBUG15(printk("%s primary port id %02x%02x%02x\n", __func__, 2751 DEBUG15(printk("%s primary port id %02x%02x%02x\n", __func__,
2751 rptid_entry->port_id[2], rptid_entry->port_id[1], 2752 rptid_entry->port_id[2], rptid_entry->port_id[1],
2752 rptid_entry->port_id[0])); 2753 rptid_entry->port_id[0]));
diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c
index cd78c501803a..42b799abba57 100644
--- a/drivers/scsi/qla2xxx/qla_mid.c
+++ b/drivers/scsi/qla2xxx/qla_mid.c
@@ -42,7 +42,6 @@ qla24xx_allocate_vp_id(scsi_qla_host_t *vha)
42 42
43 set_bit(vp_id, ha->vp_idx_map); 43 set_bit(vp_id, ha->vp_idx_map);
44 ha->num_vhosts++; 44 ha->num_vhosts++;
45 ha->cur_vport_count++;
46 vha->vp_idx = vp_id; 45 vha->vp_idx = vp_id;
47 list_add_tail(&vha->list, &ha->vp_list); 46 list_add_tail(&vha->list, &ha->vp_list);
48 mutex_unlock(&ha->vport_lock); 47 mutex_unlock(&ha->vport_lock);
@@ -58,7 +57,6 @@ qla24xx_deallocate_vp_id(scsi_qla_host_t *vha)
58 mutex_lock(&ha->vport_lock); 57 mutex_lock(&ha->vport_lock);
59 vp_id = vha->vp_idx; 58 vp_id = vha->vp_idx;
60 ha->num_vhosts--; 59 ha->num_vhosts--;
61 ha->cur_vport_count--;
62 clear_bit(vp_id, ha->vp_idx_map); 60 clear_bit(vp_id, ha->vp_idx_map);
63 list_del(&vha->list); 61 list_del(&vha->list);
64 mutex_unlock(&ha->vport_lock); 62 mutex_unlock(&ha->vport_lock);
@@ -235,7 +233,11 @@ qla2x00_vp_abort_isp(scsi_qla_host_t *vha)
235 atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME); 233 atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME);
236 } 234 }
237 235
238 /* To exclusively reset vport, we need to log it out first.*/ 236 /*
237 * To exclusively reset vport, we need to log it out first. Note: this
238 * control_vp can fail if ISP reset is already issued, this is
239 * expected, as the vp would be already logged out due to ISP reset.
240 */
239 if (!test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags)) 241 if (!test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags))
240 qla24xx_control_vp(vha, VCE_COMMAND_DISABLE_VPS_LOGO_ALL); 242 qla24xx_control_vp(vha, VCE_COMMAND_DISABLE_VPS_LOGO_ALL);
241 243
@@ -247,18 +249,11 @@ qla2x00_vp_abort_isp(scsi_qla_host_t *vha)
247static int 249static int
248qla2x00_do_dpc_vp(scsi_qla_host_t *vha) 250qla2x00_do_dpc_vp(scsi_qla_host_t *vha)
249{ 251{
250 struct qla_hw_data *ha = vha->hw; 252 qla2x00_do_work(vha);
251 scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
252 253
253 if (test_and_clear_bit(VP_IDX_ACQUIRED, &vha->vp_flags)) { 254 if (test_and_clear_bit(VP_IDX_ACQUIRED, &vha->vp_flags)) {
254 /* VP acquired. complete port configuration */ 255 /* VP acquired. complete port configuration */
255 if (atomic_read(&base_vha->loop_state) == LOOP_READY) { 256 qla24xx_configure_vp(vha);
256 qla24xx_configure_vp(vha);
257 } else {
258 set_bit(VP_IDX_ACQUIRED, &vha->vp_flags);
259 set_bit(VP_DPC_NEEDED, &base_vha->dpc_flags);
260 }
261
262 return 0; 257 return 0;
263 } 258 }
264 259
@@ -309,6 +304,9 @@ qla2x00_do_dpc_all_vps(scsi_qla_host_t *vha)
309 304
310 clear_bit(VP_DPC_NEEDED, &vha->dpc_flags); 305 clear_bit(VP_DPC_NEEDED, &vha->dpc_flags);
311 306
307 if (!(ha->current_topology & ISP_CFG_F))
308 return;
309
312 list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) { 310 list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) {
313 if (vp->vp_idx) 311 if (vp->vp_idx)
314 ret = qla2x00_do_dpc_vp(vp); 312 ret = qla2x00_do_dpc_vp(vp);
@@ -413,6 +411,11 @@ qla24xx_create_vhost(struct fc_vport *fc_vport)
413 411
414 vha->flags.init_done = 1; 412 vha->flags.init_done = 1;
415 413
414 mutex_lock(&ha->vport_lock);
415 set_bit(vha->vp_idx, ha->vp_idx_map);
416 ha->cur_vport_count++;
417 mutex_unlock(&ha->vport_lock);
418
416 return vha; 419 return vha;
417 420
418create_vhost_failed: 421create_vhost_failed:
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index f0396e79b6fa..b79fca7d461b 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -287,9 +287,12 @@ static int qla25xx_setup_mode(struct scsi_qla_host *vha)
287 int ques, req, ret; 287 int ques, req, ret;
288 struct qla_hw_data *ha = vha->hw; 288 struct qla_hw_data *ha = vha->hw;
289 289
290 if (!(ha->fw_attributes & BIT_6)) {
291 qla_printk(KERN_INFO, ha,
292 "Firmware is not multi-queue capable\n");
293 goto fail;
294 }
290 if (ql2xmultique_tag) { 295 if (ql2xmultique_tag) {
291 /* CPU affinity mode */
292 ha->wq = create_workqueue("qla2xxx_wq");
293 /* create a request queue for IO */ 296 /* create a request queue for IO */
294 options |= BIT_7; 297 options |= BIT_7;
295 req = qla25xx_create_req_que(ha, options, 0, 0, -1, 298 req = qla25xx_create_req_que(ha, options, 0, 0, -1,
@@ -299,6 +302,7 @@ static int qla25xx_setup_mode(struct scsi_qla_host *vha)
299 "Can't create request queue\n"); 302 "Can't create request queue\n");
300 goto fail; 303 goto fail;
301 } 304 }
305 ha->wq = create_workqueue("qla2xxx_wq");
302 vha->req = ha->req_q_map[req]; 306 vha->req = ha->req_q_map[req];
303 options |= BIT_1; 307 options |= BIT_1;
304 for (ques = 1; ques < ha->max_rsp_queues; ques++) { 308 for (ques = 1; ques < ha->max_rsp_queues; ques++) {
@@ -309,6 +313,8 @@ static int qla25xx_setup_mode(struct scsi_qla_host *vha)
309 goto fail2; 313 goto fail2;
310 } 314 }
311 } 315 }
316 ha->flags.cpu_affinity_enabled = 1;
317
312 DEBUG2(qla_printk(KERN_INFO, ha, 318 DEBUG2(qla_printk(KERN_INFO, ha,
313 "CPU affinity mode enabled, no. of response" 319 "CPU affinity mode enabled, no. of response"
314 " queues:%d, no. of request queues:%d\n", 320 " queues:%d, no. of request queues:%d\n",
@@ -317,8 +323,13 @@ static int qla25xx_setup_mode(struct scsi_qla_host *vha)
317 return 0; 323 return 0;
318fail2: 324fail2:
319 qla25xx_delete_queues(vha); 325 qla25xx_delete_queues(vha);
326 destroy_workqueue(ha->wq);
327 ha->wq = NULL;
320fail: 328fail:
321 ha->mqenable = 0; 329 ha->mqenable = 0;
330 kfree(ha->req_q_map);
331 kfree(ha->rsp_q_map);
332 ha->max_req_queues = ha->max_rsp_queues = 1;
322 return 1; 333 return 1;
323} 334}
324 335
@@ -462,6 +473,7 @@ qla2x00_get_new_sp(scsi_qla_host_t *vha, fc_port_t *fcport,
462 sp->flags = 0; 473 sp->flags = 0;
463 CMD_SP(cmd) = (void *)sp; 474 CMD_SP(cmd) = (void *)sp;
464 cmd->scsi_done = done; 475 cmd->scsi_done = done;
476 sp->ctx = NULL;
465 477
466 return sp; 478 return sp;
467} 479}
@@ -556,11 +568,8 @@ qla2x00_eh_wait_on_command(struct scsi_cmnd *cmd)
556 unsigned long wait_iter = ABORT_WAIT_ITER; 568 unsigned long wait_iter = ABORT_WAIT_ITER;
557 int ret = QLA_SUCCESS; 569 int ret = QLA_SUCCESS;
558 570
559 while (CMD_SP(cmd)) { 571 while (CMD_SP(cmd) && wait_iter--) {
560 msleep(ABORT_POLLING_PERIOD); 572 msleep(ABORT_POLLING_PERIOD);
561
562 if (--wait_iter)
563 break;
564 } 573 }
565 if (CMD_SP(cmd)) 574 if (CMD_SP(cmd))
566 ret = QLA_FUNCTION_FAILED; 575 ret = QLA_FUNCTION_FAILED;
@@ -698,6 +707,8 @@ qla2x00_abort_fcport_cmds(fc_port_t *fcport)
698 continue; 707 continue;
699 if (sp->fcport != fcport) 708 if (sp->fcport != fcport)
700 continue; 709 continue;
710 if (sp->ctx)
711 continue;
701 712
702 spin_unlock_irqrestore(&ha->hardware_lock, flags); 713 spin_unlock_irqrestore(&ha->hardware_lock, flags);
703 if (ha->isp_ops->abort_command(sp)) { 714 if (ha->isp_ops->abort_command(sp)) {
@@ -783,7 +794,8 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
783 794
784 if (sp == NULL) 795 if (sp == NULL)
785 continue; 796 continue;
786 797 if (sp->ctx)
798 continue;
787 if (sp->cmd != cmd) 799 if (sp->cmd != cmd)
788 continue; 800 continue;
789 801
@@ -848,7 +860,8 @@ qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *vha, unsigned int t,
848 sp = req->outstanding_cmds[cnt]; 860 sp = req->outstanding_cmds[cnt];
849 if (!sp) 861 if (!sp)
850 continue; 862 continue;
851 863 if (sp->ctx)
864 continue;
852 if (vha->vp_idx != sp->fcport->vha->vp_idx) 865 if (vha->vp_idx != sp->fcport->vha->vp_idx)
853 continue; 866 continue;
854 match = 0; 867 match = 0;
@@ -1106,8 +1119,7 @@ qla2x00_loop_reset(scsi_qla_host_t *vha)
1106 struct fc_port *fcport; 1119 struct fc_port *fcport;
1107 struct qla_hw_data *ha = vha->hw; 1120 struct qla_hw_data *ha = vha->hw;
1108 1121
1109 if (ha->flags.enable_lip_full_login && !vha->vp_idx && 1122 if (ha->flags.enable_lip_full_login && !IS_QLA81XX(ha)) {
1110 !IS_QLA81XX(ha)) {
1111 ret = qla2x00_full_login_lip(vha); 1123 ret = qla2x00_full_login_lip(vha);
1112 if (ret != QLA_SUCCESS) { 1124 if (ret != QLA_SUCCESS) {
1113 DEBUG2_3(printk("%s(%ld): failed: " 1125 DEBUG2_3(printk("%s(%ld): failed: "
@@ -1120,7 +1132,7 @@ qla2x00_loop_reset(scsi_qla_host_t *vha)
1120 qla2x00_wait_for_loop_ready(vha); 1132 qla2x00_wait_for_loop_ready(vha);
1121 } 1133 }
1122 1134
1123 if (ha->flags.enable_lip_reset && !vha->vp_idx) { 1135 if (ha->flags.enable_lip_reset) {
1124 ret = qla2x00_lip_reset(vha); 1136 ret = qla2x00_lip_reset(vha);
1125 if (ret != QLA_SUCCESS) { 1137 if (ret != QLA_SUCCESS) {
1126 DEBUG2_3(printk("%s(%ld): failed: " 1138 DEBUG2_3(printk("%s(%ld): failed: "
@@ -1154,6 +1166,7 @@ qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res)
1154 int que, cnt; 1166 int que, cnt;
1155 unsigned long flags; 1167 unsigned long flags;
1156 srb_t *sp; 1168 srb_t *sp;
1169 struct srb_ctx *ctx;
1157 struct qla_hw_data *ha = vha->hw; 1170 struct qla_hw_data *ha = vha->hw;
1158 struct req_que *req; 1171 struct req_que *req;
1159 1172
@@ -1166,8 +1179,14 @@ qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res)
1166 sp = req->outstanding_cmds[cnt]; 1179 sp = req->outstanding_cmds[cnt];
1167 if (sp) { 1180 if (sp) {
1168 req->outstanding_cmds[cnt] = NULL; 1181 req->outstanding_cmds[cnt] = NULL;
1169 sp->cmd->result = res; 1182 if (!sp->ctx) {
1170 qla2x00_sp_compl(ha, sp); 1183 sp->cmd->result = res;
1184 qla2x00_sp_compl(ha, sp);
1185 } else {
1186 ctx = sp->ctx;
1187 del_timer_sync(&ctx->timer);
1188 ctx->free(sp);
1189 }
1171 } 1190 }
1172 } 1191 }
1173 } 1192 }
@@ -1193,6 +1212,7 @@ qla2xxx_slave_configure(struct scsi_device *sdev)
1193 scsi_qla_host_t *vha = shost_priv(sdev->host); 1212 scsi_qla_host_t *vha = shost_priv(sdev->host);
1194 struct qla_hw_data *ha = vha->hw; 1213 struct qla_hw_data *ha = vha->hw;
1195 struct fc_rport *rport = starget_to_rport(sdev->sdev_target); 1214 struct fc_rport *rport = starget_to_rport(sdev->sdev_target);
1215 fc_port_t *fcport = *(fc_port_t **)rport->dd_data;
1196 struct req_que *req = vha->req; 1216 struct req_que *req = vha->req;
1197 1217
1198 if (sdev->tagged_supported) 1218 if (sdev->tagged_supported)
@@ -1201,6 +1221,8 @@ qla2xxx_slave_configure(struct scsi_device *sdev)
1201 scsi_deactivate_tcq(sdev, req->max_q_depth); 1221 scsi_deactivate_tcq(sdev, req->max_q_depth);
1202 1222
1203 rport->dev_loss_tmo = ha->port_down_retry_count; 1223 rport->dev_loss_tmo = ha->port_down_retry_count;
1224 if (sdev->type == TYPE_TAPE)
1225 fcport->flags |= FCF_TAPE_PRESENT;
1204 1226
1205 return 0; 1227 return 0;
1206} 1228}
@@ -1923,6 +1945,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
1923 if (ret) 1945 if (ret)
1924 goto probe_init_failed; 1946 goto probe_init_failed;
1925 /* Alloc arrays of request and response ring ptrs */ 1947 /* Alloc arrays of request and response ring ptrs */
1948que_init:
1926 if (!qla2x00_alloc_queues(ha)) { 1949 if (!qla2x00_alloc_queues(ha)) {
1927 qla_printk(KERN_WARNING, ha, 1950 qla_printk(KERN_WARNING, ha,
1928 "[ERROR] Failed to allocate memory for queue" 1951 "[ERROR] Failed to allocate memory for queue"
@@ -1959,11 +1982,14 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
1959 goto probe_failed; 1982 goto probe_failed;
1960 } 1983 }
1961 1984
1962 if (ha->mqenable) 1985 if (ha->mqenable) {
1963 if (qla25xx_setup_mode(base_vha)) 1986 if (qla25xx_setup_mode(base_vha)) {
1964 qla_printk(KERN_WARNING, ha, 1987 qla_printk(KERN_WARNING, ha,
1965 "Can't create queues, falling back to single" 1988 "Can't create queues, falling back to single"
1966 " queue mode\n"); 1989 " queue mode\n");
1990 goto que_init;
1991 }
1992 }
1967 1993
1968 if (ha->flags.running_gold_fw) 1994 if (ha->flags.running_gold_fw)
1969 goto skip_dpc; 1995 goto skip_dpc;
@@ -2155,17 +2181,19 @@ qla2x00_schedule_rport_del(struct scsi_qla_host *vha, fc_port_t *fcport,
2155 int defer) 2181 int defer)
2156{ 2182{
2157 struct fc_rport *rport; 2183 struct fc_rport *rport;
2184 scsi_qla_host_t *base_vha;
2158 2185
2159 if (!fcport->rport) 2186 if (!fcport->rport)
2160 return; 2187 return;
2161 2188
2162 rport = fcport->rport; 2189 rport = fcport->rport;
2163 if (defer) { 2190 if (defer) {
2191 base_vha = pci_get_drvdata(vha->hw->pdev);
2164 spin_lock_irq(vha->host->host_lock); 2192 spin_lock_irq(vha->host->host_lock);
2165 fcport->drport = rport; 2193 fcport->drport = rport;
2166 spin_unlock_irq(vha->host->host_lock); 2194 spin_unlock_irq(vha->host->host_lock);
2167 set_bit(FCPORT_UPDATE_NEEDED, &vha->dpc_flags); 2195 set_bit(FCPORT_UPDATE_NEEDED, &base_vha->dpc_flags);
2168 qla2xxx_wake_dpc(vha); 2196 qla2xxx_wake_dpc(base_vha);
2169 } else 2197 } else
2170 fc_remote_port_delete(rport); 2198 fc_remote_port_delete(rport);
2171} 2199}
@@ -2237,8 +2265,9 @@ qla2x00_mark_all_devices_lost(scsi_qla_host_t *vha, int defer)
2237 fc_port_t *fcport; 2265 fc_port_t *fcport;
2238 2266
2239 list_for_each_entry(fcport, &vha->vp_fcports, list) { 2267 list_for_each_entry(fcport, &vha->vp_fcports, list) {
2240 if (vha->vp_idx != fcport->vp_idx) 2268 if (vha->vp_idx != 0 && vha->vp_idx != fcport->vp_idx)
2241 continue; 2269 continue;
2270
2242 /* 2271 /*
2243 * No point in marking the device as lost, if the device is 2272 * No point in marking the device as lost, if the device is
2244 * already DEAD. 2273 * already DEAD.
@@ -2246,10 +2275,12 @@ qla2x00_mark_all_devices_lost(scsi_qla_host_t *vha, int defer)
2246 if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD) 2275 if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD)
2247 continue; 2276 continue;
2248 if (atomic_read(&fcport->state) == FCS_ONLINE) { 2277 if (atomic_read(&fcport->state) == FCS_ONLINE) {
2249 atomic_set(&fcport->state, FCS_DEVICE_LOST); 2278 if (defer)
2250 qla2x00_schedule_rport_del(vha, fcport, defer); 2279 qla2x00_schedule_rport_del(vha, fcport, defer);
2251 } else 2280 else if (vha->vp_idx == fcport->vp_idx)
2252 atomic_set(&fcport->state, FCS_DEVICE_LOST); 2281 qla2x00_schedule_rport_del(vha, fcport, defer);
2282 }
2283 atomic_set(&fcport->state, FCS_DEVICE_LOST);
2253 } 2284 }
2254} 2285}
2255 2286
@@ -2598,7 +2629,31 @@ qla2x00_post_idc_ack_work(struct scsi_qla_host *vha, uint16_t *mb)
2598 return qla2x00_post_work(vha, e); 2629 return qla2x00_post_work(vha, e);
2599} 2630}
2600 2631
2601static void 2632#define qla2x00_post_async_work(name, type) \
2633int qla2x00_post_async_##name##_work( \
2634 struct scsi_qla_host *vha, \
2635 fc_port_t *fcport, uint16_t *data) \
2636{ \
2637 struct qla_work_evt *e; \
2638 \
2639 e = qla2x00_alloc_work(vha, type); \
2640 if (!e) \
2641 return QLA_FUNCTION_FAILED; \
2642 \
2643 e->u.logio.fcport = fcport; \
2644 if (data) { \
2645 e->u.logio.data[0] = data[0]; \
2646 e->u.logio.data[1] = data[1]; \
2647 } \
2648 return qla2x00_post_work(vha, e); \
2649}
2650
2651qla2x00_post_async_work(login, QLA_EVT_ASYNC_LOGIN);
2652qla2x00_post_async_work(login_done, QLA_EVT_ASYNC_LOGIN_DONE);
2653qla2x00_post_async_work(logout, QLA_EVT_ASYNC_LOGOUT);
2654qla2x00_post_async_work(logout_done, QLA_EVT_ASYNC_LOGOUT_DONE);
2655
2656void
2602qla2x00_do_work(struct scsi_qla_host *vha) 2657qla2x00_do_work(struct scsi_qla_host *vha)
2603{ 2658{
2604 struct qla_work_evt *e, *tmp; 2659 struct qla_work_evt *e, *tmp;
@@ -2620,6 +2675,21 @@ qla2x00_do_work(struct scsi_qla_host *vha)
2620 case QLA_EVT_IDC_ACK: 2675 case QLA_EVT_IDC_ACK:
2621 qla81xx_idc_ack(vha, e->u.idc_ack.mb); 2676 qla81xx_idc_ack(vha, e->u.idc_ack.mb);
2622 break; 2677 break;
2678 case QLA_EVT_ASYNC_LOGIN:
2679 qla2x00_async_login(vha, e->u.logio.fcport,
2680 e->u.logio.data);
2681 break;
2682 case QLA_EVT_ASYNC_LOGIN_DONE:
2683 qla2x00_async_login_done(vha, e->u.logio.fcport,
2684 e->u.logio.data);
2685 break;
2686 case QLA_EVT_ASYNC_LOGOUT:
2687 qla2x00_async_logout(vha, e->u.logio.fcport);
2688 break;
2689 case QLA_EVT_ASYNC_LOGOUT_DONE:
2690 qla2x00_async_logout_done(vha, e->u.logio.fcport,
2691 e->u.logio.data);
2692 break;
2623 } 2693 }
2624 if (e->flags & QLA_EVT_FLAG_FREE) 2694 if (e->flags & QLA_EVT_FLAG_FREE)
2625 kfree(e); 2695 kfree(e);
@@ -2635,6 +2705,7 @@ void qla2x00_relogin(struct scsi_qla_host *vha)
2635 int status; 2705 int status;
2636 uint16_t next_loopid = 0; 2706 uint16_t next_loopid = 0;
2637 struct qla_hw_data *ha = vha->hw; 2707 struct qla_hw_data *ha = vha->hw;
2708 uint16_t data[2];
2638 2709
2639 list_for_each_entry(fcport, &vha->vp_fcports, list) { 2710 list_for_each_entry(fcport, &vha->vp_fcports, list) {
2640 /* 2711 /*
@@ -2644,6 +2715,7 @@ void qla2x00_relogin(struct scsi_qla_host *vha)
2644 if (atomic_read(&fcport->state) != 2715 if (atomic_read(&fcport->state) !=
2645 FCS_ONLINE && fcport->login_retry) { 2716 FCS_ONLINE && fcport->login_retry) {
2646 2717
2718 fcport->login_retry--;
2647 if (fcport->flags & FCF_FABRIC_DEVICE) { 2719 if (fcport->flags & FCF_FABRIC_DEVICE) {
2648 if (fcport->flags & FCF_TAPE_PRESENT) 2720 if (fcport->flags & FCF_TAPE_PRESENT)
2649 ha->isp_ops->fabric_logout(vha, 2721 ha->isp_ops->fabric_logout(vha,
@@ -2652,13 +2724,22 @@ void qla2x00_relogin(struct scsi_qla_host *vha)
2652 fcport->d_id.b.area, 2724 fcport->d_id.b.area,
2653 fcport->d_id.b.al_pa); 2725 fcport->d_id.b.al_pa);
2654 2726
2655 status = qla2x00_fabric_login(vha, fcport, 2727 if (IS_ALOGIO_CAPABLE(ha)) {
2656 &next_loopid); 2728 data[0] = 0;
2729 data[1] = QLA_LOGIO_LOGIN_RETRIED;
2730 status = qla2x00_post_async_login_work(
2731 vha, fcport, data);
2732 if (status == QLA_SUCCESS)
2733 continue;
2734 /* Attempt a retry. */
2735 status = 1;
2736 } else
2737 status = qla2x00_fabric_login(vha,
2738 fcport, &next_loopid);
2657 } else 2739 } else
2658 status = qla2x00_local_device_login(vha, 2740 status = qla2x00_local_device_login(vha,
2659 fcport); 2741 fcport);
2660 2742
2661 fcport->login_retry--;
2662 if (status == QLA_SUCCESS) { 2743 if (status == QLA_SUCCESS) {
2663 fcport->old_loop_id = fcport->loop_id; 2744 fcport->old_loop_id = fcport->loop_id;
2664 2745
@@ -2831,6 +2912,9 @@ qla2x00_do_dpc(void *data)
2831 */ 2912 */
2832 ha->dpc_active = 0; 2913 ha->dpc_active = 0;
2833 2914
2915 /* Cleanup any residual CTX SRBs. */
2916 qla2x00_abort_all_cmds(base_vha, DID_NO_CONNECT << 16);
2917
2834 return 0; 2918 return 0;
2835} 2919}
2836 2920
@@ -2971,6 +3055,8 @@ qla2x00_timer(scsi_qla_host_t *vha)
2971 sp = req->outstanding_cmds[index]; 3055 sp = req->outstanding_cmds[index];
2972 if (!sp) 3056 if (!sp)
2973 continue; 3057 continue;
3058 if (sp->ctx)
3059 continue;
2974 sfcp = sp->fcport; 3060 sfcp = sp->fcport;
2975 if (!(sfcp->flags & FCF_TAPE_PRESENT)) 3061 if (!(sfcp->flags & FCF_TAPE_PRESENT))
2976 continue; 3062 continue;
@@ -2987,8 +3073,7 @@ qla2x00_timer(scsi_qla_host_t *vha)
2987 3073
2988 /* if the loop has been down for 4 minutes, reinit adapter */ 3074 /* if the loop has been down for 4 minutes, reinit adapter */
2989 if (atomic_dec_and_test(&vha->loop_down_timer) != 0) { 3075 if (atomic_dec_and_test(&vha->loop_down_timer) != 0) {
2990 if (!(vha->device_flags & DFLG_NO_CABLE) && 3076 if (!(vha->device_flags & DFLG_NO_CABLE)) {
2991 !vha->vp_idx) {
2992 DEBUG(printk("scsi(%ld): Loop down - " 3077 DEBUG(printk("scsi(%ld): Loop down - "
2993 "aborting ISP.\n", 3078 "aborting ISP.\n",
2994 vha->host_no)); 3079 vha->host_no));
diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h
index 84369705a9ad..ac107a2c34a4 100644
--- a/drivers/scsi/qla2xxx/qla_version.h
+++ b/drivers/scsi/qla2xxx/qla_version.h
@@ -7,7 +7,7 @@
7/* 7/*
8 * Driver version 8 * Driver version
9 */ 9 */
10#define QLA2XXX_VERSION "8.03.01-k4" 10#define QLA2XXX_VERSION "8.03.01-k6"
11 11
12#define QLA_DRIVER_MAJOR_VER 8 12#define QLA_DRIVER_MAJOR_VER 8
13#define QLA_DRIVER_MINOR_VER 3 13#define QLA_DRIVER_MINOR_VER 3