aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc
diff options
context:
space:
mode:
authorJames Smart <James.Smart@Emulex.Com>2009-11-18 15:39:44 -0500
committerJames Bottomley <James.Bottomley@suse.de>2009-12-04 13:01:51 -0500
commit5ffc266ee7a62741ebee89ede15049ec0f02fa75 (patch)
tree1ffd531c5b95d3e0c2bf0d905d34f497827ff0ee /drivers/scsi/lpfc
parentc868595d5686e97183bc1ad85502835d81d7a457 (diff)
[SCSI] lpfc 8.3.6 : FC Protocol Fixes
FC protocol fixes. - Fix send sequence logic to handle multi SGL IOCBs. - Fix FDISC completion always setting VPORT state to failed. - Ported the fix on reporting of max_vpi to uppper layer. - Fix incorrect number of Vports allowed to be created. - Fixed Dead FCoE port after creating vports. - Added handling of ELS request for Reinstate Recovery Qualifier (RRQ) - Handle unsolicited CT exchange initiator receiving CT exchange ABTS - Migrate LUN queue depth ramp up code to scsi mid-layer. - Made ABTS WQE go to the same WQ as the WQE to be aborted. - Fix Vport does not rediscover after FCF goes away. - Fixed lpfc_unreg_vfi failure after devloss timeout. - Fixed RPI bit leak. - Fix hbq pointer corruption during target discovery. Signed-off-by: James Smart <james.smart@emulex.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/lpfc')
-rw-r--r--drivers/scsi/lpfc/lpfc.h1
-rw-r--r--drivers/scsi/lpfc/lpfc_disc.h2
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c40
-rw-r--r--drivers/scsi/lpfc/lpfc_hw.h2
-rw-r--r--drivers/scsi/lpfc/lpfc_hw4.h23
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c3
-rw-r--r--drivers/scsi/lpfc/lpfc_nportdisc.c7
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c135
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c133
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.h1
-rw-r--r--drivers/scsi/lpfc/lpfc_sli4.h5
-rw-r--r--drivers/scsi/lpfc/lpfc_vport.c2
12 files changed, 235 insertions, 119 deletions
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index 2fd3e45c577e..1cc23a69db5e 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -202,6 +202,7 @@ struct lpfc_stats {
202 uint32_t elsRcvLIRR; 202 uint32_t elsRcvLIRR;
203 uint32_t elsRcvRPS; 203 uint32_t elsRcvRPS;
204 uint32_t elsRcvRPL; 204 uint32_t elsRcvRPL;
205 uint32_t elsRcvRRQ;
205 uint32_t elsXmitFLOGI; 206 uint32_t elsXmitFLOGI;
206 uint32_t elsXmitFDISC; 207 uint32_t elsXmitFDISC;
207 uint32_t elsXmitPLOGI; 208 uint32_t elsXmitPLOGI;
diff --git a/drivers/scsi/lpfc/lpfc_disc.h b/drivers/scsi/lpfc/lpfc_disc.h
index f26f6e160a2a..2851d75ffc6f 100644
--- a/drivers/scsi/lpfc/lpfc_disc.h
+++ b/drivers/scsi/lpfc/lpfc_disc.h
@@ -105,8 +105,6 @@ struct lpfc_nodelist {
105 struct lpfc_vport *vport; 105 struct lpfc_vport *vport;
106 struct lpfc_work_evt els_retry_evt; 106 struct lpfc_work_evt els_retry_evt;
107 struct lpfc_work_evt dev_loss_evt; 107 struct lpfc_work_evt dev_loss_evt;
108 unsigned long last_ramp_up_time; /* jiffy of last ramp up */
109 unsigned long last_q_full_time; /* jiffy of last queue full */
110 struct kref kref; 108 struct kref kref;
111 atomic_t cmd_pending; 109 atomic_t cmd_pending;
112 uint32_t cmd_qdepth; 110 uint32_t cmd_qdepth;
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index e9e423f28f8a..a079bbc03cf8 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -4521,6 +4521,29 @@ lpfc_els_rcv_lirr(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
4521} 4521}
4522 4522
4523/** 4523/**
4524 * lpfc_els_rcv_rrq - Process an unsolicited rrq iocb
4525 * @vport: pointer to a host virtual N_Port data structure.
4526 * @cmdiocb: pointer to lpfc command iocb data structure.
4527 * @ndlp: pointer to a node-list data structure.
4528 *
4529 * This routine processes a Reinstate Recovery Qualifier (RRQ) IOCB
4530 * received as an ELS unsolicited event. A request to RRQ shall only
4531 * be accepted if the Originator Nx_Port N_Port_ID or the Responder
4532 * Nx_Port N_Port_ID of the target Exchange is the same as the
4533 * N_Port_ID of the Nx_Port that makes the request. If the RRQ is
4534 * not accepted, an LS_RJT with reason code "Unable to perform
4535 * command request" and reason code explanation "Invalid Originator
4536 * S_ID" shall be returned. For now, we just unconditionally accept
4537 * RRQ from the target.
4538 **/
4539static void
4540lpfc_els_rcv_rrq(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
4541 struct lpfc_nodelist *ndlp)
4542{
4543 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
4544}
4545
4546/**
4524 * lpfc_els_rsp_rps_acc - Completion callbk func for MBX_READ_LNK_STAT mbox cmd 4547 * lpfc_els_rsp_rps_acc - Completion callbk func for MBX_READ_LNK_STAT mbox cmd
4525 * @phba: pointer to lpfc hba data structure. 4548 * @phba: pointer to lpfc hba data structure.
4526 * @pmb: pointer to the driver internal queue element for mailbox command. 4549 * @pmb: pointer to the driver internal queue element for mailbox command.
@@ -5636,6 +5659,16 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
5636 if (newnode) 5659 if (newnode)
5637 lpfc_nlp_put(ndlp); 5660 lpfc_nlp_put(ndlp);
5638 break; 5661 break;
5662 case ELS_CMD_RRQ:
5663 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
5664 "RCV RRQ: did:x%x/ste:x%x flg:x%x",
5665 did, vport->port_state, ndlp->nlp_flag);
5666
5667 phba->fc_stat.elsRcvRRQ++;
5668 lpfc_els_rcv_rrq(vport, elsiocb, ndlp);
5669 if (newnode)
5670 lpfc_nlp_put(ndlp);
5671 break;
5639 default: 5672 default:
5640 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, 5673 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
5641 "RCV ELS cmd: cmd:x%x did:x%x/ste:x%x", 5674 "RCV ELS cmd: cmd:x%x did:x%x/ste:x%x",
@@ -6042,11 +6075,6 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
6042 irsp->ulpStatus, irsp->un.ulpWord[4]); 6075 irsp->ulpStatus, irsp->un.ulpWord[4]);
6043 goto fdisc_failed; 6076 goto fdisc_failed;
6044 } 6077 }
6045 if (vport->fc_vport->vport_state == FC_VPORT_INITIALIZING)
6046 lpfc_vport_set_state(vport, FC_VPORT_FAILED);
6047 lpfc_nlp_put(ndlp);
6048 /* giving up on FDISC. Cancel discovery timer */
6049 lpfc_can_disctmo(vport);
6050 spin_lock_irq(shost->host_lock); 6078 spin_lock_irq(shost->host_lock);
6051 vport->fc_flag |= FC_FABRIC; 6079 vport->fc_flag |= FC_FABRIC;
6052 if (vport->phba->fc_topology == TOPOLOGY_LOOP) 6080 if (vport->phba->fc_topology == TOPOLOGY_LOOP)
@@ -6125,6 +6153,7 @@ lpfc_issue_els_fdisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
6125 int did = ndlp->nlp_DID; 6153 int did = ndlp->nlp_DID;
6126 int rc; 6154 int rc;
6127 6155
6156 vport->port_state = LPFC_FDISC;
6128 cmdsize = (sizeof(uint32_t) + sizeof(struct serv_parm)); 6157 cmdsize = (sizeof(uint32_t) + sizeof(struct serv_parm));
6129 elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp, did, 6158 elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp, did,
6130 ELS_CMD_FDISC); 6159 ELS_CMD_FDISC);
@@ -6190,7 +6219,6 @@ lpfc_issue_els_fdisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
6190 return 1; 6219 return 1;
6191 } 6220 }
6192 lpfc_vport_set_state(vport, FC_VPORT_INITIALIZING); 6221 lpfc_vport_set_state(vport, FC_VPORT_INITIALIZING);
6193 vport->port_state = LPFC_FDISC;
6194 return 0; 6222 return 0;
6195} 6223}
6196 6224
diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h
index 7070c77357a9..f279d191b628 100644
--- a/drivers/scsi/lpfc/lpfc_hw.h
+++ b/drivers/scsi/lpfc/lpfc_hw.h
@@ -3538,7 +3538,7 @@ typedef struct _IOCB { /* IOCB structure */
3538 ASYNCSTAT_FIELDS asyncstat; /* async_status iocb */ 3538 ASYNCSTAT_FIELDS asyncstat; /* async_status iocb */
3539 QUE_XRI64_CX_FIELDS quexri64cx; /* que_xri64_cx fields */ 3539 QUE_XRI64_CX_FIELDS quexri64cx; /* que_xri64_cx fields */
3540 struct rcv_seq64 rcvseq64; /* RCV_SEQ64 and RCV_CONT64 */ 3540 struct rcv_seq64 rcvseq64; /* RCV_SEQ64 and RCV_CONT64 */
3541 3541 struct sli4_bls_acc bls_acc; /* UNSOL ABTS BLS_ACC params */
3542 uint32_t ulpWord[IOCB_WORD_SZ - 2]; /* generic 6 'words' */ 3542 uint32_t ulpWord[IOCB_WORD_SZ - 2]; /* generic 6 'words' */
3543 } un; 3543 } un;
3544 union { 3544 union {
diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h
index 95f8b4e0063d..fa3306386786 100644
--- a/drivers/scsi/lpfc/lpfc_hw4.h
+++ b/drivers/scsi/lpfc/lpfc_hw4.h
@@ -194,6 +194,26 @@ struct lpfc_sli4_flags {
194#define lpfc_fip_flag_WORD word0 194#define lpfc_fip_flag_WORD word0
195}; 195};
196 196
197struct sli4_bls_acc {
198 uint32_t word0_rsvd; /* Word0 must be reserved */
199 uint32_t word1;
200#define lpfc_abts_orig_SHIFT 0
201#define lpfc_abts_orig_MASK 0x00000001
202#define lpfc_abts_orig_WORD word1
203#define LPFC_ABTS_UNSOL_RSP 1
204#define LPFC_ABTS_UNSOL_INT 0
205 uint32_t word2;
206#define lpfc_abts_rxid_SHIFT 0
207#define lpfc_abts_rxid_MASK 0x0000FFFF
208#define lpfc_abts_rxid_WORD word2
209#define lpfc_abts_oxid_SHIFT 16
210#define lpfc_abts_oxid_MASK 0x0000FFFF
211#define lpfc_abts_oxid_WORD word2
212 uint32_t word3;
213 uint32_t word4;
214 uint32_t word5_rsvd; /* Word5 must be reserved */
215};
216
197/* event queue entry structure */ 217/* event queue entry structure */
198struct lpfc_eqe { 218struct lpfc_eqe {
199 uint32_t word0; 219 uint32_t word0;
@@ -1980,7 +2000,8 @@ struct lpfc_bmbx_create {
1980#define SGL_ALIGN_SZ 64 2000#define SGL_ALIGN_SZ 64
1981#define SGL_PAGE_SIZE 4096 2001#define SGL_PAGE_SIZE 4096
1982/* align SGL addr on a size boundary - adjust address up */ 2002/* align SGL addr on a size boundary - adjust address up */
1983#define NO_XRI ((uint16_t)-1) 2003#define NO_XRI ((uint16_t)-1)
2004
1984struct wqe_common { 2005struct wqe_common {
1985 uint32_t word6; 2006 uint32_t word6;
1986#define wqe_xri_tag_SHIFT 0 2007#define wqe_xri_tag_SHIFT 0
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 02268a1eec69..6932657d74ad 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -4931,7 +4931,8 @@ lpfc_sli4_read_config(struct lpfc_hba *phba)
4931 phba->vpi_base = phba->sli4_hba.max_cfg_param.vpi_base; 4931 phba->vpi_base = phba->sli4_hba.max_cfg_param.vpi_base;
4932 phba->vfi_base = phba->sli4_hba.max_cfg_param.vfi_base; 4932 phba->vfi_base = phba->sli4_hba.max_cfg_param.vfi_base;
4933 phba->sli4_hba.next_rpi = phba->sli4_hba.max_cfg_param.rpi_base; 4933 phba->sli4_hba.next_rpi = phba->sli4_hba.max_cfg_param.rpi_base;
4934 phba->max_vpi = phba->sli4_hba.max_cfg_param.max_vpi; 4934 phba->max_vpi = (phba->sli4_hba.max_cfg_param.max_vpi > 0) ?
4935 (phba->sli4_hba.max_cfg_param.max_vpi - 1) : 0;
4935 phba->max_vports = phba->max_vpi; 4936 phba->max_vports = phba->max_vpi;
4936 lpfc_printf_log(phba, KERN_INFO, LOG_SLI, 4937 lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
4937 "2003 cfg params XRI(B:%d M:%d), " 4938 "2003 cfg params XRI(B:%d M:%d), "
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c
index 3e74136f1ede..2ed6af194932 100644
--- a/drivers/scsi/lpfc/lpfc_nportdisc.c
+++ b/drivers/scsi/lpfc/lpfc_nportdisc.c
@@ -1223,6 +1223,12 @@ lpfc_rcv_logo_reglogin_issue(struct lpfc_vport *vport,
1223 list_for_each_entry_safe(mb, nextmb, &phba->sli.mboxq, list) { 1223 list_for_each_entry_safe(mb, nextmb, &phba->sli.mboxq, list) {
1224 if ((mb->u.mb.mbxCommand == MBX_REG_LOGIN64) && 1224 if ((mb->u.mb.mbxCommand == MBX_REG_LOGIN64) &&
1225 (ndlp == (struct lpfc_nodelist *) mb->context2)) { 1225 (ndlp == (struct lpfc_nodelist *) mb->context2)) {
1226 if (phba->sli_rev == LPFC_SLI_REV4) {
1227 spin_unlock_irq(&phba->hbalock);
1228 lpfc_sli4_free_rpi(phba,
1229 mb->u.mb.un.varRegLogin.rpi);
1230 spin_lock_irq(&phba->hbalock);
1231 }
1226 mp = (struct lpfc_dmabuf *) (mb->context1); 1232 mp = (struct lpfc_dmabuf *) (mb->context1);
1227 if (mp) { 1233 if (mp) {
1228 __lpfc_mbuf_free(phba, mp->virt, mp->phys); 1234 __lpfc_mbuf_free(phba, mp->virt, mp->phys);
@@ -1230,6 +1236,7 @@ lpfc_rcv_logo_reglogin_issue(struct lpfc_vport *vport,
1230 } 1236 }
1231 lpfc_nlp_put(ndlp); 1237 lpfc_nlp_put(ndlp);
1232 list_del(&mb->list); 1238 list_del(&mb->list);
1239 phba->sli.mboxq_cnt--;
1233 mempool_free(mb, phba->mbox_mem_pool); 1240 mempool_free(mb, phba->mbox_mem_pool);
1234 } 1241 }
1235 } 1242 }
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index f5ab5dd9bbbf..bf80cdefb506 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -246,6 +246,36 @@ lpfc_send_sdev_queuedepth_change_event(struct lpfc_hba *phba,
246} 246}
247 247
248/** 248/**
249 * lpfc_change_queue_depth - Alter scsi device queue depth
250 * @sdev: Pointer the scsi device on which to change the queue depth.
251 * @qdepth: New queue depth to set the sdev to.
252 * @reason: The reason for the queue depth change.
253 *
254 * This function is called by the midlayer and the LLD to alter the queue
255 * depth for a scsi device. This function sets the queue depth to the new
256 * value and sends an event out to log the queue depth change.
257 **/
258int
259lpfc_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason)
260{
261 struct lpfc_vport *vport = (struct lpfc_vport *) sdev->host->hostdata;
262 struct lpfc_hba *phba = vport->phba;
263 struct lpfc_rport_data *rdata;
264 unsigned long new_queue_depth, old_queue_depth;
265
266 old_queue_depth = sdev->queue_depth;
267 scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), qdepth);
268 new_queue_depth = sdev->queue_depth;
269 rdata = sdev->hostdata;
270 if (rdata)
271 lpfc_send_sdev_queuedepth_change_event(phba, vport,
272 rdata->pnode, sdev->lun,
273 old_queue_depth,
274 new_queue_depth);
275 return sdev->queue_depth;
276}
277
278/**
249 * lpfc_rampdown_queue_depth - Post RAMP_DOWN_QUEUE event to worker thread 279 * lpfc_rampdown_queue_depth - Post RAMP_DOWN_QUEUE event to worker thread
250 * @phba: The Hba for which this call is being executed. 280 * @phba: The Hba for which this call is being executed.
251 * 281 *
@@ -309,8 +339,10 @@ lpfc_rampup_queue_depth(struct lpfc_vport *vport,
309 if (vport->cfg_lun_queue_depth <= queue_depth) 339 if (vport->cfg_lun_queue_depth <= queue_depth)
310 return; 340 return;
311 spin_lock_irqsave(&phba->hbalock, flags); 341 spin_lock_irqsave(&phba->hbalock, flags);
312 if (((phba->last_ramp_up_time + QUEUE_RAMP_UP_INTERVAL) > jiffies) || 342 if (time_before(jiffies,
313 ((phba->last_rsrc_error_time + QUEUE_RAMP_UP_INTERVAL ) > jiffies)) { 343 phba->last_ramp_up_time + QUEUE_RAMP_UP_INTERVAL) ||
344 time_before(jiffies,
345 phba->last_rsrc_error_time + QUEUE_RAMP_UP_INTERVAL)) {
314 spin_unlock_irqrestore(&phba->hbalock, flags); 346 spin_unlock_irqrestore(&phba->hbalock, flags);
315 return; 347 return;
316 } 348 }
@@ -342,10 +374,9 @@ lpfc_ramp_down_queue_handler(struct lpfc_hba *phba)
342 struct lpfc_vport **vports; 374 struct lpfc_vport **vports;
343 struct Scsi_Host *shost; 375 struct Scsi_Host *shost;
344 struct scsi_device *sdev; 376 struct scsi_device *sdev;
345 unsigned long new_queue_depth, old_queue_depth; 377 unsigned long new_queue_depth;
346 unsigned long num_rsrc_err, num_cmd_success; 378 unsigned long num_rsrc_err, num_cmd_success;
347 int i; 379 int i;
348 struct lpfc_rport_data *rdata;
349 380
350 num_rsrc_err = atomic_read(&phba->num_rsrc_err); 381 num_rsrc_err = atomic_read(&phba->num_rsrc_err);
351 num_cmd_success = atomic_read(&phba->num_cmd_success); 382 num_cmd_success = atomic_read(&phba->num_cmd_success);
@@ -363,22 +394,8 @@ lpfc_ramp_down_queue_handler(struct lpfc_hba *phba)
363 else 394 else
364 new_queue_depth = sdev->queue_depth - 395 new_queue_depth = sdev->queue_depth -
365 new_queue_depth; 396 new_queue_depth;
366 old_queue_depth = sdev->queue_depth; 397 lpfc_change_queue_depth(sdev, new_queue_depth,
367 if (sdev->ordered_tags) 398 SCSI_QDEPTH_DEFAULT);
368 scsi_adjust_queue_depth(sdev,
369 MSG_ORDERED_TAG,
370 new_queue_depth);
371 else
372 scsi_adjust_queue_depth(sdev,
373 MSG_SIMPLE_TAG,
374 new_queue_depth);
375 rdata = sdev->hostdata;
376 if (rdata)
377 lpfc_send_sdev_queuedepth_change_event(
378 phba, vports[i],
379 rdata->pnode,
380 sdev->lun, old_queue_depth,
381 new_queue_depth);
382 } 399 }
383 } 400 }
384 lpfc_destroy_vport_work_array(phba, vports); 401 lpfc_destroy_vport_work_array(phba, vports);
@@ -402,7 +419,6 @@ lpfc_ramp_up_queue_handler(struct lpfc_hba *phba)
402 struct Scsi_Host *shost; 419 struct Scsi_Host *shost;
403 struct scsi_device *sdev; 420 struct scsi_device *sdev;
404 int i; 421 int i;
405 struct lpfc_rport_data *rdata;
406 422
407 vports = lpfc_create_vport_work_array(phba); 423 vports = lpfc_create_vport_work_array(phba);
408 if (vports != NULL) 424 if (vports != NULL)
@@ -412,22 +428,9 @@ lpfc_ramp_up_queue_handler(struct lpfc_hba *phba)
412 if (vports[i]->cfg_lun_queue_depth <= 428 if (vports[i]->cfg_lun_queue_depth <=
413 sdev->queue_depth) 429 sdev->queue_depth)
414 continue; 430 continue;
415 if (sdev->ordered_tags) 431 lpfc_change_queue_depth(sdev,
416 scsi_adjust_queue_depth(sdev, 432 sdev->queue_depth+1,
417 MSG_ORDERED_TAG, 433 SCSI_QDEPTH_RAMP_UP);
418 sdev->queue_depth+1);
419 else
420 scsi_adjust_queue_depth(sdev,
421 MSG_SIMPLE_TAG,
422 sdev->queue_depth+1);
423 rdata = sdev->hostdata;
424 if (rdata)
425 lpfc_send_sdev_queuedepth_change_event(
426 phba, vports[i],
427 rdata->pnode,
428 sdev->lun,
429 sdev->queue_depth - 1,
430 sdev->queue_depth);
431 } 434 }
432 } 435 }
433 lpfc_destroy_vport_work_array(phba, vports); 436 lpfc_destroy_vport_work_array(phba, vports);
@@ -2208,7 +2211,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
2208 struct scsi_cmnd *cmd = lpfc_cmd->pCmd; 2211 struct scsi_cmnd *cmd = lpfc_cmd->pCmd;
2209 int result; 2212 int result;
2210 struct scsi_device *tmp_sdev; 2213 struct scsi_device *tmp_sdev;
2211 int depth = 0; 2214 int depth;
2212 unsigned long flags; 2215 unsigned long flags;
2213 struct lpfc_fast_path_event *fast_path_evt; 2216 struct lpfc_fast_path_event *fast_path_evt;
2214 struct Scsi_Host *shost = cmd->device->host; 2217 struct Scsi_Host *shost = cmd->device->host;
@@ -2375,67 +2378,29 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
2375 return; 2378 return;
2376 } 2379 }
2377 2380
2378
2379 if (!result) 2381 if (!result)
2380 lpfc_rampup_queue_depth(vport, queue_depth); 2382 lpfc_rampup_queue_depth(vport, queue_depth);
2381 2383
2382 if (!result && pnode && NLP_CHK_NODE_ACT(pnode) &&
2383 ((jiffies - pnode->last_ramp_up_time) >
2384 LPFC_Q_RAMP_UP_INTERVAL * HZ) &&
2385 ((jiffies - pnode->last_q_full_time) >
2386 LPFC_Q_RAMP_UP_INTERVAL * HZ) &&
2387 (vport->cfg_lun_queue_depth > queue_depth)) {
2388 shost_for_each_device(tmp_sdev, shost) {
2389 if (vport->cfg_lun_queue_depth > tmp_sdev->queue_depth){
2390 if (tmp_sdev->id != scsi_id)
2391 continue;
2392 if (tmp_sdev->ordered_tags)
2393 scsi_adjust_queue_depth(tmp_sdev,
2394 MSG_ORDERED_TAG,
2395 tmp_sdev->queue_depth+1);
2396 else
2397 scsi_adjust_queue_depth(tmp_sdev,
2398 MSG_SIMPLE_TAG,
2399 tmp_sdev->queue_depth+1);
2400
2401 pnode->last_ramp_up_time = jiffies;
2402 }
2403 }
2404 lpfc_send_sdev_queuedepth_change_event(phba, vport, pnode,
2405 0xFFFFFFFF,
2406 queue_depth , queue_depth + 1);
2407 }
2408
2409 /* 2384 /*
2410 * Check for queue full. If the lun is reporting queue full, then 2385 * Check for queue full. If the lun is reporting queue full, then
2411 * back off the lun queue depth to prevent target overloads. 2386 * back off the lun queue depth to prevent target overloads.
2412 */ 2387 */
2413 if (result == SAM_STAT_TASK_SET_FULL && pnode && 2388 if (result == SAM_STAT_TASK_SET_FULL && pnode &&
2414 NLP_CHK_NODE_ACT(pnode)) { 2389 NLP_CHK_NODE_ACT(pnode)) {
2415 pnode->last_q_full_time = jiffies;
2416
2417 shost_for_each_device(tmp_sdev, shost) { 2390 shost_for_each_device(tmp_sdev, shost) {
2418 if (tmp_sdev->id != scsi_id) 2391 if (tmp_sdev->id != scsi_id)
2419 continue; 2392 continue;
2420 depth = scsi_track_queue_full(tmp_sdev, 2393 depth = scsi_track_queue_full(tmp_sdev,
2421 tmp_sdev->queue_depth - 1); 2394 tmp_sdev->queue_depth-1);
2422 } 2395 if (depth <= 0)
2423 /* 2396 continue;
2424 * The queue depth cannot be lowered any more.
2425 * Modify the returned error code to store
2426 * the final depth value set by
2427 * scsi_track_queue_full.
2428 */
2429 if (depth == -1)
2430 depth = shost->cmd_per_lun;
2431
2432 if (depth) {
2433 lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP, 2397 lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP,
2434 "0711 detected queue full - lun queue " 2398 "0711 detected queue full - lun queue "
2435 "depth adjusted to %d.\n", depth); 2399 "depth adjusted to %d.\n", depth);
2436 lpfc_send_sdev_queuedepth_change_event(phba, vport, 2400 lpfc_send_sdev_queuedepth_change_event(phba, vport,
2437 pnode, 0xFFFFFFFF, 2401 pnode,
2438 depth+1, depth); 2402 tmp_sdev->lun,
2403 depth+1, depth);
2439 } 2404 }
2440 } 2405 }
2441 2406
@@ -3019,6 +2984,10 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd)
3019 2984
3020 icmd->ulpLe = 1; 2985 icmd->ulpLe = 1;
3021 icmd->ulpClass = cmd->ulpClass; 2986 icmd->ulpClass = cmd->ulpClass;
2987
2988 /* ABTS WQE must go to the same WQ as the WQE to be aborted */
2989 abtsiocb->fcp_wqidx = iocb->fcp_wqidx;
2990
3022 if (lpfc_is_link_up(phba)) 2991 if (lpfc_is_link_up(phba))
3023 icmd->ulpCommand = CMD_ABORT_XRI_CN; 2992 icmd->ulpCommand = CMD_ABORT_XRI_CN;
3024 else 2993 else
@@ -3596,6 +3565,7 @@ struct scsi_host_template lpfc_template = {
3596 .shost_attrs = lpfc_hba_attrs, 3565 .shost_attrs = lpfc_hba_attrs,
3597 .max_sectors = 0xFFFF, 3566 .max_sectors = 0xFFFF,
3598 .vendor_id = LPFC_NL_VENDOR_ID, 3567 .vendor_id = LPFC_NL_VENDOR_ID,
3568 .change_queue_depth = lpfc_change_queue_depth,
3599}; 3569};
3600 3570
3601struct scsi_host_template lpfc_vport_template = { 3571struct scsi_host_template lpfc_vport_template = {
@@ -3617,4 +3587,5 @@ struct scsi_host_template lpfc_vport_template = {
3617 .use_clustering = ENABLE_CLUSTERING, 3587 .use_clustering = ENABLE_CLUSTERING,
3618 .shost_attrs = lpfc_vport_attrs, 3588 .shost_attrs = lpfc_vport_attrs,
3619 .max_sectors = 0xFFFF, 3589 .max_sectors = 0xFFFF,
3590 .change_queue_depth = lpfc_change_queue_depth,
3620}; 3591};
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index ce0a1a1c4792..1d2f65c4eb0b 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -5748,7 +5748,7 @@ static int
5748lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, 5748lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
5749 union lpfc_wqe *wqe) 5749 union lpfc_wqe *wqe)
5750{ 5750{
5751 uint32_t payload_len = 0; 5751 uint32_t xmit_len = 0, total_len = 0;
5752 uint8_t ct = 0; 5752 uint8_t ct = 0;
5753 uint32_t fip; 5753 uint32_t fip;
5754 uint32_t abort_tag; 5754 uint32_t abort_tag;
@@ -5757,6 +5757,8 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
5757 uint16_t xritag; 5757 uint16_t xritag;
5758 struct ulp_bde64 *bpl = NULL; 5758 struct ulp_bde64 *bpl = NULL;
5759 uint32_t els_id = ELS_ID_DEFAULT; 5759 uint32_t els_id = ELS_ID_DEFAULT;
5760 int numBdes, i;
5761 struct ulp_bde64 bde;
5760 5762
5761 fip = phba->hba_flag & HBA_FIP_SUPPORT; 5763 fip = phba->hba_flag & HBA_FIP_SUPPORT;
5762 /* The fcp commands will set command type */ 5764 /* The fcp commands will set command type */
@@ -5774,6 +5776,8 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
5774 wqe->words[7] = 0; /* The ct field has moved so reset */ 5776 wqe->words[7] = 0; /* The ct field has moved so reset */
5775 /* words0-2 bpl convert bde */ 5777 /* words0-2 bpl convert bde */
5776 if (iocbq->iocb.un.genreq64.bdl.bdeFlags == BUFF_TYPE_BLP_64) { 5778 if (iocbq->iocb.un.genreq64.bdl.bdeFlags == BUFF_TYPE_BLP_64) {
5779 numBdes = iocbq->iocb.un.genreq64.bdl.bdeSize /
5780 sizeof(struct ulp_bde64);
5777 bpl = (struct ulp_bde64 *) 5781 bpl = (struct ulp_bde64 *)
5778 ((struct lpfc_dmabuf *)iocbq->context3)->virt; 5782 ((struct lpfc_dmabuf *)iocbq->context3)->virt;
5779 if (!bpl) 5783 if (!bpl)
@@ -5786,9 +5790,14 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
5786 * can assign it to the sgl. 5790 * can assign it to the sgl.
5787 */ 5791 */
5788 wqe->generic.bde.tus.w = le32_to_cpu(bpl->tus.w); 5792 wqe->generic.bde.tus.w = le32_to_cpu(bpl->tus.w);
5789 payload_len = wqe->generic.bde.tus.f.bdeSize; 5793 xmit_len = wqe->generic.bde.tus.f.bdeSize;
5794 total_len = 0;
5795 for (i = 0; i < numBdes; i++) {
5796 bde.tus.w = le32_to_cpu(bpl[i].tus.w);
5797 total_len += bde.tus.f.bdeSize;
5798 }
5790 } else 5799 } else
5791 payload_len = iocbq->iocb.un.fcpi64.bdl.bdeSize; 5800 xmit_len = iocbq->iocb.un.fcpi64.bdl.bdeSize;
5792 5801
5793 iocbq->iocb.ulpIoTag = iocbq->iotag; 5802 iocbq->iocb.ulpIoTag = iocbq->iotag;
5794 cmnd = iocbq->iocb.ulpCommand; 5803 cmnd = iocbq->iocb.ulpCommand;
@@ -5802,7 +5811,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
5802 iocbq->iocb.ulpCommand); 5811 iocbq->iocb.ulpCommand);
5803 return IOCB_ERROR; 5812 return IOCB_ERROR;
5804 } 5813 }
5805 wqe->els_req.payload_len = payload_len; 5814 wqe->els_req.payload_len = xmit_len;
5806 /* Els_reguest64 has a TMO */ 5815 /* Els_reguest64 has a TMO */
5807 bf_set(wqe_tmo, &wqe->els_req.wqe_com, 5816 bf_set(wqe_tmo, &wqe->els_req.wqe_com,
5808 iocbq->iocb.ulpTimeout); 5817 iocbq->iocb.ulpTimeout);
@@ -5831,6 +5840,15 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
5831 bf_set(lpfc_wqe_gen_els_id, &wqe->generic, els_id); 5840 bf_set(lpfc_wqe_gen_els_id, &wqe->generic, els_id);
5832 5841
5833 break; 5842 break;
5843 case CMD_XMIT_SEQUENCE64_CX:
5844 bf_set(lpfc_wqe_gen_context, &wqe->generic,
5845 iocbq->iocb.un.ulpWord[3]);
5846 wqe->generic.word3 = 0;
5847 bf_set(wqe_rcvoxid, &wqe->generic, iocbq->iocb.ulpContext);
5848 bf_set(wqe_xc, &wqe->generic, 1);
5849 /* The entire sequence is transmitted for this IOCB */
5850 xmit_len = total_len;
5851 cmnd = CMD_XMIT_SEQUENCE64_CR;
5834 case CMD_XMIT_SEQUENCE64_CR: 5852 case CMD_XMIT_SEQUENCE64_CR:
5835 /* word3 iocb=io_tag32 wqe=payload_offset */ 5853 /* word3 iocb=io_tag32 wqe=payload_offset */
5836 /* payload offset used for multilpe outstanding 5854 /* payload offset used for multilpe outstanding
@@ -5840,7 +5858,8 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
5840 /* word4 relative_offset memcpy */ 5858 /* word4 relative_offset memcpy */
5841 /* word5 r_ctl/df_ctl memcpy */ 5859 /* word5 r_ctl/df_ctl memcpy */
5842 bf_set(lpfc_wqe_gen_pu, &wqe->generic, 0); 5860 bf_set(lpfc_wqe_gen_pu, &wqe->generic, 0);
5843 wqe->xmit_sequence.xmit_len = payload_len; 5861 wqe->xmit_sequence.xmit_len = xmit_len;
5862 command_type = OTHER_COMMAND;
5844 break; 5863 break;
5845 case CMD_XMIT_BCAST64_CN: 5864 case CMD_XMIT_BCAST64_CN:
5846 /* word3 iocb=iotag32 wqe=payload_len */ 5865 /* word3 iocb=iotag32 wqe=payload_len */
@@ -5869,7 +5888,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
5869 case CMD_FCP_IREAD64_CR: 5888 case CMD_FCP_IREAD64_CR:
5870 /* FCP_CMD is always the 1st sgl entry */ 5889 /* FCP_CMD is always the 1st sgl entry */
5871 wqe->fcp_iread.payload_len = 5890 wqe->fcp_iread.payload_len =
5872 payload_len + sizeof(struct fcp_rsp); 5891 xmit_len + sizeof(struct fcp_rsp);
5873 5892
5874 /* word 4 (xfer length) should have been set on the memcpy */ 5893 /* word 4 (xfer length) should have been set on the memcpy */
5875 5894
@@ -5906,7 +5925,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
5906 * sgl[1] = rsp. 5925 * sgl[1] = rsp.
5907 * 5926 *
5908 */ 5927 */
5909 wqe->gen_req.command_len = payload_len; 5928 wqe->gen_req.command_len = xmit_len;
5910 /* Word4 parameter copied in the memcpy */ 5929 /* Word4 parameter copied in the memcpy */
5911 /* Word5 [rctl, type, df_ctl, la] copied in memcpy */ 5930 /* Word5 [rctl, type, df_ctl, la] copied in memcpy */
5912 /* word6 context tag copied in memcpy */ 5931 /* word6 context tag copied in memcpy */
@@ -5979,10 +5998,25 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
5979 * iocbq from scratch. 5998 * iocbq from scratch.
5980 */ 5999 */
5981 memset(wqe, 0, sizeof(union lpfc_wqe)); 6000 memset(wqe, 0, sizeof(union lpfc_wqe));
6001 /* OX_ID is invariable to who sent ABTS to CT exchange */
5982 bf_set(xmit_bls_rsp64_oxid, &wqe->xmit_bls_rsp, 6002 bf_set(xmit_bls_rsp64_oxid, &wqe->xmit_bls_rsp,
5983 iocbq->iocb.un.ulpWord[3]); 6003 bf_get(lpfc_abts_oxid, &iocbq->iocb.un.bls_acc));
5984 bf_set(xmit_bls_rsp64_rxid, &wqe->xmit_bls_rsp, 6004 if (bf_get(lpfc_abts_orig, &iocbq->iocb.un.bls_acc) ==
5985 iocbq->sli4_xritag); 6005 LPFC_ABTS_UNSOL_INT) {
6006 /* ABTS sent by initiator to CT exchange, the
6007 * RX_ID field will be filled with the newly
6008 * allocated responder XRI.
6009 */
6010 bf_set(xmit_bls_rsp64_rxid, &wqe->xmit_bls_rsp,
6011 iocbq->sli4_xritag);
6012 } else {
6013 /* ABTS sent by responder to CT exchange, the
6014 * RX_ID field will be filled with the responder
6015 * RX_ID from ABTS.
6016 */
6017 bf_set(xmit_bls_rsp64_rxid, &wqe->xmit_bls_rsp,
6018 bf_get(lpfc_abts_rxid, &iocbq->iocb.un.bls_acc));
6019 }
5986 bf_set(xmit_bls_rsp64_seqcnthi, &wqe->xmit_bls_rsp, 0xffff); 6020 bf_set(xmit_bls_rsp64_seqcnthi, &wqe->xmit_bls_rsp, 0xffff);
5987 bf_set(wqe_xmit_bls_pt, &wqe->xmit_bls_rsp.wqe_dest, 0x1); 6021 bf_set(wqe_xmit_bls_pt, &wqe->xmit_bls_rsp.wqe_dest, 0x1);
5988 bf_set(wqe_ctxt_tag, &wqe->xmit_bls_rsp.wqe_com, 6022 bf_set(wqe_ctxt_tag, &wqe->xmit_bls_rsp.wqe_com,
@@ -6044,7 +6078,6 @@ __lpfc_sli_issue_iocb_s4(struct lpfc_hba *phba, uint32_t ring_number,
6044 uint16_t xritag; 6078 uint16_t xritag;
6045 union lpfc_wqe wqe; 6079 union lpfc_wqe wqe;
6046 struct lpfc_sli_ring *pring = &phba->sli.ring[ring_number]; 6080 struct lpfc_sli_ring *pring = &phba->sli.ring[ring_number];
6047 uint32_t fcp_wqidx;
6048 6081
6049 if (piocb->sli4_xritag == NO_XRI) { 6082 if (piocb->sli4_xritag == NO_XRI) {
6050 if (piocb->iocb.ulpCommand == CMD_ABORT_XRI_CN || 6083 if (piocb->iocb.ulpCommand == CMD_ABORT_XRI_CN ||
@@ -6079,8 +6112,17 @@ __lpfc_sli_issue_iocb_s4(struct lpfc_hba *phba, uint32_t ring_number,
6079 return IOCB_ERROR; 6112 return IOCB_ERROR;
6080 6113
6081 if (piocb->iocb_flag & LPFC_IO_FCP) { 6114 if (piocb->iocb_flag & LPFC_IO_FCP) {
6082 fcp_wqidx = lpfc_sli4_scmd_to_wqidx_distr(phba); 6115 /*
6083 if (lpfc_sli4_wq_put(phba->sli4_hba.fcp_wq[fcp_wqidx], &wqe)) 6116 * For FCP command IOCB, get a new WQ index to distribute
6117 * WQE across the WQsr. On the other hand, for abort IOCB,
6118 * it carries the same WQ index to the original command
6119 * IOCB.
6120 */
6121 if ((piocb->iocb.ulpCommand != CMD_ABORT_XRI_CN) &&
6122 (piocb->iocb.ulpCommand != CMD_CLOSE_XRI_CN))
6123 piocb->fcp_wqidx = lpfc_sli4_scmd_to_wqidx_distr(phba);
6124 if (lpfc_sli4_wq_put(phba->sli4_hba.fcp_wq[piocb->fcp_wqidx],
6125 &wqe))
6084 return IOCB_ERROR; 6126 return IOCB_ERROR;
6085 } else { 6127 } else {
6086 if (lpfc_sli4_wq_put(phba->sli4_hba.els_wq, &wqe)) 6128 if (lpfc_sli4_wq_put(phba->sli4_hba.els_wq, &wqe))
@@ -7070,6 +7112,9 @@ lpfc_sli_issue_abort_iotag(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
7070 iabt->ulpLe = 1; 7112 iabt->ulpLe = 1;
7071 iabt->ulpClass = icmd->ulpClass; 7113 iabt->ulpClass = icmd->ulpClass;
7072 7114
7115 /* ABTS WQE must go to the same WQ as the WQE to be aborted */
7116 abtsiocbp->fcp_wqidx = cmdiocb->fcp_wqidx;
7117
7073 if (phba->link_state >= LPFC_LINK_UP) 7118 if (phba->link_state >= LPFC_LINK_UP)
7074 iabt->ulpCommand = CMD_ABORT_XRI_CN; 7119 iabt->ulpCommand = CMD_ABORT_XRI_CN;
7075 else 7120 else
@@ -7273,6 +7318,9 @@ lpfc_sli_abort_iocb(struct lpfc_vport *vport, struct lpfc_sli_ring *pring,
7273 abtsiocb->iocb.ulpClass = cmd->ulpClass; 7318 abtsiocb->iocb.ulpClass = cmd->ulpClass;
7274 abtsiocb->vport = phba->pport; 7319 abtsiocb->vport = phba->pport;
7275 7320
7321 /* ABTS WQE must go to the same WQ as the WQE to be aborted */
7322 abtsiocb->fcp_wqidx = iocbq->fcp_wqidx;
7323
7276 if (lpfc_is_link_up(phba)) 7324 if (lpfc_is_link_up(phba))
7277 abtsiocb->iocb.ulpCommand = CMD_ABORT_XRI_CN; 7325 abtsiocb->iocb.ulpCommand = CMD_ABORT_XRI_CN;
7278 else 7326 else
@@ -8671,7 +8719,6 @@ lpfc_sli4_sp_handle_rcqe(struct lpfc_hba *phba, struct lpfc_rcqe *rcqe)
8671 uint32_t status; 8719 uint32_t status;
8672 unsigned long iflags; 8720 unsigned long iflags;
8673 8721
8674 lpfc_sli4_rq_release(hrq, drq);
8675 if (bf_get(lpfc_rcqe_rq_id, rcqe) != hrq->queue_id) 8722 if (bf_get(lpfc_rcqe_rq_id, rcqe) != hrq->queue_id)
8676 goto out; 8723 goto out;
8677 8724
@@ -8681,6 +8728,7 @@ lpfc_sli4_sp_handle_rcqe(struct lpfc_hba *phba, struct lpfc_rcqe *rcqe)
8681 lpfc_printf_log(phba, KERN_ERR, LOG_SLI, 8728 lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
8682 "2537 Receive Frame Truncated!!\n"); 8729 "2537 Receive Frame Truncated!!\n");
8683 case FC_STATUS_RQ_SUCCESS: 8730 case FC_STATUS_RQ_SUCCESS:
8731 lpfc_sli4_rq_release(hrq, drq);
8684 spin_lock_irqsave(&phba->hbalock, iflags); 8732 spin_lock_irqsave(&phba->hbalock, iflags);
8685 dma_buf = lpfc_sli_hbqbuf_get(&phba->hbqs[0].hbq_buffer_list); 8733 dma_buf = lpfc_sli_hbqbuf_get(&phba->hbqs[0].hbq_buffer_list);
8686 if (!dma_buf) { 8734 if (!dma_buf) {
@@ -10997,8 +11045,8 @@ lpfc_sli4_seq_abort_acc(struct lpfc_hba *phba,
10997{ 11045{
10998 struct lpfc_iocbq *ctiocb = NULL; 11046 struct lpfc_iocbq *ctiocb = NULL;
10999 struct lpfc_nodelist *ndlp; 11047 struct lpfc_nodelist *ndlp;
11000 uint16_t oxid; 11048 uint16_t oxid, rxid;
11001 uint32_t sid; 11049 uint32_t sid, fctl;
11002 IOCB_t *icmd; 11050 IOCB_t *icmd;
11003 11051
11004 if (!lpfc_is_link_up(phba)) 11052 if (!lpfc_is_link_up(phba))
@@ -11006,6 +11054,7 @@ lpfc_sli4_seq_abort_acc(struct lpfc_hba *phba,
11006 11054
11007 sid = sli4_sid_from_fc_hdr(fc_hdr); 11055 sid = sli4_sid_from_fc_hdr(fc_hdr);
11008 oxid = be16_to_cpu(fc_hdr->fh_ox_id); 11056 oxid = be16_to_cpu(fc_hdr->fh_ox_id);
11057 rxid = be16_to_cpu(fc_hdr->fh_rx_id);
11009 11058
11010 ndlp = lpfc_findnode_did(phba->pport, sid); 11059 ndlp = lpfc_findnode_did(phba->pport, sid);
11011 if (!ndlp) { 11060 if (!ndlp) {
@@ -11020,9 +11069,12 @@ lpfc_sli4_seq_abort_acc(struct lpfc_hba *phba,
11020 if (!ctiocb) 11069 if (!ctiocb)
11021 return; 11070 return;
11022 11071
11072 /* Extract the F_CTL field from FC_HDR */
11073 fctl = sli4_fctl_from_fc_hdr(fc_hdr);
11074
11023 icmd = &ctiocb->iocb; 11075 icmd = &ctiocb->iocb;
11024 icmd->un.xseq64.bdl.ulpIoTag32 = 0;
11025 icmd->un.xseq64.bdl.bdeSize = 0; 11076 icmd->un.xseq64.bdl.bdeSize = 0;
11077 icmd->un.xseq64.bdl.ulpIoTag32 = 0;
11026 icmd->un.xseq64.w5.hcsw.Dfctl = 0; 11078 icmd->un.xseq64.w5.hcsw.Dfctl = 0;
11027 icmd->un.xseq64.w5.hcsw.Rctl = FC_RCTL_BA_ACC; 11079 icmd->un.xseq64.w5.hcsw.Rctl = FC_RCTL_BA_ACC;
11028 icmd->un.xseq64.w5.hcsw.Type = FC_TYPE_BLS; 11080 icmd->un.xseq64.w5.hcsw.Type = FC_TYPE_BLS;
@@ -11033,13 +11085,30 @@ lpfc_sli4_seq_abort_acc(struct lpfc_hba *phba,
11033 icmd->ulpLe = 1; 11085 icmd->ulpLe = 1;
11034 icmd->ulpClass = CLASS3; 11086 icmd->ulpClass = CLASS3;
11035 icmd->ulpContext = ndlp->nlp_rpi; 11087 icmd->ulpContext = ndlp->nlp_rpi;
11036 icmd->un.ulpWord[3] = oxid;
11037 11088
11038 ctiocb->sli4_xritag = NO_XRI;
11039 ctiocb->iocb_cmpl = NULL; 11089 ctiocb->iocb_cmpl = NULL;
11040 ctiocb->vport = phba->pport; 11090 ctiocb->vport = phba->pport;
11041 ctiocb->iocb_cmpl = lpfc_sli4_seq_abort_acc_cmpl; 11091 ctiocb->iocb_cmpl = lpfc_sli4_seq_abort_acc_cmpl;
11042 11092
11093 if (fctl & FC_FC_EX_CTX) {
11094 /* ABTS sent by responder to CT exchange, construction
11095 * of BA_ACC will use OX_ID from ABTS for the XRI_TAG
11096 * field and RX_ID from ABTS for RX_ID field.
11097 */
11098 bf_set(lpfc_abts_orig, &icmd->un.bls_acc, LPFC_ABTS_UNSOL_RSP);
11099 bf_set(lpfc_abts_rxid, &icmd->un.bls_acc, rxid);
11100 ctiocb->sli4_xritag = oxid;
11101 } else {
11102 /* ABTS sent by initiator to CT exchange, construction
11103 * of BA_ACC will need to allocate a new XRI as for the
11104 * XRI_TAG and RX_ID fields.
11105 */
11106 bf_set(lpfc_abts_orig, &icmd->un.bls_acc, LPFC_ABTS_UNSOL_INT);
11107 bf_set(lpfc_abts_rxid, &icmd->un.bls_acc, NO_XRI);
11108 ctiocb->sli4_xritag = NO_XRI;
11109 }
11110 bf_set(lpfc_abts_oxid, &icmd->un.bls_acc, oxid);
11111
11043 /* Xmit CT abts accept on exchange <xid> */ 11112 /* Xmit CT abts accept on exchange <xid> */
11044 lpfc_printf_log(phba, KERN_INFO, LOG_ELS, 11113 lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
11045 "1200 Xmit CT ABTS ACC on exchange x%x Data: x%x\n", 11114 "1200 Xmit CT ABTS ACC on exchange x%x Data: x%x\n",
@@ -11066,19 +11135,31 @@ lpfc_sli4_handle_unsol_abort(struct lpfc_vport *vport,
11066{ 11135{
11067 struct lpfc_hba *phba = vport->phba; 11136 struct lpfc_hba *phba = vport->phba;
11068 struct fc_frame_header fc_hdr; 11137 struct fc_frame_header fc_hdr;
11138 uint32_t fctl;
11069 bool abts_par; 11139 bool abts_par;
11070 11140
11071 /* Try to abort partially assembled seq */
11072 abts_par = lpfc_sli4_abort_partial_seq(vport, dmabuf);
11073
11074 /* Make a copy of fc_hdr before the dmabuf being released */ 11141 /* Make a copy of fc_hdr before the dmabuf being released */
11075 memcpy(&fc_hdr, dmabuf->hbuf.virt, sizeof(struct fc_frame_header)); 11142 memcpy(&fc_hdr, dmabuf->hbuf.virt, sizeof(struct fc_frame_header));
11143 fctl = sli4_fctl_from_fc_hdr(&fc_hdr);
11076 11144
11077 /* Send abort to ULP if partially seq abort failed */ 11145 if (fctl & FC_FC_EX_CTX) {
11078 if (abts_par == false) 11146 /*
11079 lpfc_sli4_send_seq_to_ulp(vport, dmabuf); 11147 * ABTS sent by responder to exchange, just free the buffer
11080 else 11148 */
11081 lpfc_in_buf_free(phba, &dmabuf->dbuf); 11149 lpfc_in_buf_free(phba, &dmabuf->dbuf);
11150 } else {
11151 /*
11152 * ABTS sent by initiator to exchange, need to do cleanup
11153 */
11154 /* Try to abort partially assembled seq */
11155 abts_par = lpfc_sli4_abort_partial_seq(vport, dmabuf);
11156
11157 /* Send abort to ULP if partially seq abort failed */
11158 if (abts_par == false)
11159 lpfc_sli4_send_seq_to_ulp(vport, dmabuf);
11160 else
11161 lpfc_in_buf_free(phba, &dmabuf->dbuf);
11162 }
11082 /* Send basic accept (BA_ACC) to the abort requester */ 11163 /* Send basic accept (BA_ACC) to the abort requester */
11083 lpfc_sli4_seq_abort_acc(phba, &fc_hdr); 11164 lpfc_sli4_seq_abort_acc(phba, &fc_hdr);
11084} 11165}
diff --git a/drivers/scsi/lpfc/lpfc_sli.h b/drivers/scsi/lpfc/lpfc_sli.h
index 174dcda32195..ba38de3c28f1 100644
--- a/drivers/scsi/lpfc/lpfc_sli.h
+++ b/drivers/scsi/lpfc/lpfc_sli.h
@@ -66,6 +66,7 @@ struct lpfc_iocbq {
66 uint8_t abort_count; 66 uint8_t abort_count;
67 uint8_t rsvd2; 67 uint8_t rsvd2;
68 uint32_t drvrTimeout; /* driver timeout in seconds */ 68 uint32_t drvrTimeout; /* driver timeout in seconds */
69 uint32_t fcp_wqidx; /* index to FCP work queue */
69 struct lpfc_vport *vport;/* virtual port pointer */ 70 struct lpfc_vport *vport;/* virtual port pointer */
70 void *context1; /* caller context information */ 71 void *context1; /* caller context information */
71 void *context2; /* caller context information */ 72 void *context2; /* caller context information */
diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h
index 4a9cf674555e..6a4558ba93b6 100644
--- a/drivers/scsi/lpfc/lpfc_sli4.h
+++ b/drivers/scsi/lpfc/lpfc_sli4.h
@@ -63,6 +63,11 @@
63 (fc_hdr)->fh_s_id[1] << 8 | \ 63 (fc_hdr)->fh_s_id[1] << 8 | \
64 (fc_hdr)->fh_s_id[2]) 64 (fc_hdr)->fh_s_id[2])
65 65
66#define sli4_fctl_from_fc_hdr(fc_hdr) \
67 ((fc_hdr)->fh_f_ctl[0] << 16 | \
68 (fc_hdr)->fh_f_ctl[1] << 8 | \
69 (fc_hdr)->fh_f_ctl[2])
70
66enum lpfc_sli4_queue_type { 71enum lpfc_sli4_queue_type {
67 LPFC_EQ, 72 LPFC_EQ,
68 LPFC_GCQ, 73 LPFC_GCQ,
diff --git a/drivers/scsi/lpfc/lpfc_vport.c b/drivers/scsi/lpfc/lpfc_vport.c
index 096d178c4c86..7d6dd83d3592 100644
--- a/drivers/scsi/lpfc/lpfc_vport.c
+++ b/drivers/scsi/lpfc/lpfc_vport.c
@@ -700,6 +700,8 @@ lpfc_vport_delete(struct fc_vport *fc_vport)
700 } 700 }
701 spin_unlock_irq(&phba->ndlp_lock); 701 spin_unlock_irq(&phba->ndlp_lock);
702 } 702 }
703 if (vport->vpi_state != LPFC_VPI_REGISTERED)
704 goto skip_logo;
703 vport->unreg_vpi_cmpl = VPORT_INVAL; 705 vport->unreg_vpi_cmpl = VPORT_INVAL;
704 timeout = msecs_to_jiffies(phba->fc_ratov * 2000); 706 timeout = msecs_to_jiffies(phba->fc_ratov * 2000);
705 if (!lpfc_issue_els_npiv_logo(vport, ndlp)) 707 if (!lpfc_issue_els_npiv_logo(vport, ndlp))