diff options
author | James Smart <James.Smart@Emulex.Com> | 2007-06-17 20:56:38 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2007-06-17 23:27:39 -0400 |
commit | 92d7f7b0cde3ad2260e7462b40867b57efd49851 (patch) | |
tree | fadb1d8f1a817c2f85937b5e9c3b830bdecb5555 /drivers/scsi/lpfc/lpfc_mbox.c | |
parent | ed957684294618602b48f1950b0c9bbcb036583f (diff) |
[SCSI] lpfc: NPIV: add NPIV support on top of SLI-3
NPIV support is added to the driver. It utilizes the interfaces of
the fc transport for the creation and deletion of vports. Within the
driver, a new Scsi_Host is created for each NPIV instance, and is
paired with a new instance of a FC port. This allows N FC Port
elements to share a single Adapter.
Signed-off-by: James Smart <James.Smart@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_mbox.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_mbox.c | 131 |
1 files changed, 96 insertions, 35 deletions
diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c index 977799c2b2c2..277eb6132e81 100644 --- a/drivers/scsi/lpfc/lpfc_mbox.c +++ b/drivers/scsi/lpfc/lpfc_mbox.c | |||
@@ -106,7 +106,7 @@ lpfc_read_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb, struct lpfc_dmabuf *mp) | |||
106 | */ | 106 | */ |
107 | pmb->context1 = (uint8_t *) mp; | 107 | pmb->context1 = (uint8_t *) mp; |
108 | mb->mbxOwner = OWN_HOST; | 108 | mb->mbxOwner = OWN_HOST; |
109 | return 0; | 109 | return (0); |
110 | } | 110 | } |
111 | 111 | ||
112 | /**********************************************/ | 112 | /**********************************************/ |
@@ -209,7 +209,7 @@ lpfc_init_link(struct lpfc_hba * phba, | |||
209 | */ | 209 | */ |
210 | vpd = &phba->vpd; | 210 | vpd = &phba->vpd; |
211 | if (vpd->rev.feaLevelHigh >= 0x02){ | 211 | if (vpd->rev.feaLevelHigh >= 0x02){ |
212 | switch (linkspeed){ | 212 | switch(linkspeed){ |
213 | case LINK_SPEED_1G: | 213 | case LINK_SPEED_1G: |
214 | case LINK_SPEED_2G: | 214 | case LINK_SPEED_2G: |
215 | case LINK_SPEED_4G: | 215 | case LINK_SPEED_4G: |
@@ -232,7 +232,6 @@ lpfc_init_link(struct lpfc_hba * phba, | |||
232 | mb->mbxCommand = (volatile uint8_t)MBX_INIT_LINK; | 232 | mb->mbxCommand = (volatile uint8_t)MBX_INIT_LINK; |
233 | mb->mbxOwner = OWN_HOST; | 233 | mb->mbxOwner = OWN_HOST; |
234 | mb->un.varInitLnk.fabric_AL_PA = phba->fc_pref_ALPA; | 234 | mb->un.varInitLnk.fabric_AL_PA = phba->fc_pref_ALPA; |
235 | mb->un.varInitLnk.link_flags |= FLAGS_UNREG_LOGIN_ALL; | ||
236 | return; | 235 | return; |
237 | } | 236 | } |
238 | 237 | ||
@@ -241,7 +240,7 @@ lpfc_init_link(struct lpfc_hba * phba, | |||
241 | /* mailbox command */ | 240 | /* mailbox command */ |
242 | /**********************************************/ | 241 | /**********************************************/ |
243 | int | 242 | int |
244 | lpfc_read_sparam(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | 243 | lpfc_read_sparam(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb, int vpi) |
245 | { | 244 | { |
246 | struct lpfc_dmabuf *mp; | 245 | struct lpfc_dmabuf *mp; |
247 | MAILBOX_t *mb; | 246 | MAILBOX_t *mb; |
@@ -265,18 +264,19 @@ lpfc_read_sparam(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |||
265 | LOG_MBOX, | 264 | LOG_MBOX, |
266 | "%d:0301 READ_SPARAM: no buffers\n", | 265 | "%d:0301 READ_SPARAM: no buffers\n", |
267 | phba->brd_no); | 266 | phba->brd_no); |
268 | return 1; | 267 | return (1); |
269 | } | 268 | } |
270 | INIT_LIST_HEAD(&mp->list); | 269 | INIT_LIST_HEAD(&mp->list); |
271 | mb->mbxCommand = MBX_READ_SPARM64; | 270 | mb->mbxCommand = MBX_READ_SPARM64; |
272 | mb->un.varRdSparm.un.sp64.tus.f.bdeSize = sizeof (struct serv_parm); | 271 | mb->un.varRdSparm.un.sp64.tus.f.bdeSize = sizeof (struct serv_parm); |
273 | mb->un.varRdSparm.un.sp64.addrHigh = putPaddrHigh(mp->phys); | 272 | mb->un.varRdSparm.un.sp64.addrHigh = putPaddrHigh(mp->phys); |
274 | mb->un.varRdSparm.un.sp64.addrLow = putPaddrLow(mp->phys); | 273 | mb->un.varRdSparm.un.sp64.addrLow = putPaddrLow(mp->phys); |
274 | mb->un.varRdSparm.vpi = vpi; | ||
275 | 275 | ||
276 | /* save address for completion */ | 276 | /* save address for completion */ |
277 | pmb->context1 = mp; | 277 | pmb->context1 = mp; |
278 | 278 | ||
279 | return 0; | 279 | return (0); |
280 | } | 280 | } |
281 | 281 | ||
282 | /********************************************/ | 282 | /********************************************/ |
@@ -284,7 +284,8 @@ lpfc_read_sparam(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |||
284 | /* mailbox command */ | 284 | /* mailbox command */ |
285 | /********************************************/ | 285 | /********************************************/ |
286 | void | 286 | void |
287 | lpfc_unreg_did(struct lpfc_hba *phba, uint32_t did, LPFC_MBOXQ_t *pmb) | 287 | lpfc_unreg_did(struct lpfc_hba * phba, uint16_t vpi, uint32_t did, |
288 | LPFC_MBOXQ_t * pmb) | ||
288 | { | 289 | { |
289 | MAILBOX_t *mb; | 290 | MAILBOX_t *mb; |
290 | 291 | ||
@@ -292,6 +293,7 @@ lpfc_unreg_did(struct lpfc_hba *phba, uint32_t did, LPFC_MBOXQ_t *pmb) | |||
292 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); | 293 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); |
293 | 294 | ||
294 | mb->un.varUnregDID.did = did; | 295 | mb->un.varUnregDID.did = did; |
296 | mb->un.varUnregDID.vpi = vpi; | ||
295 | 297 | ||
296 | mb->mbxCommand = MBX_UNREG_D_ID; | 298 | mb->mbxCommand = MBX_UNREG_D_ID; |
297 | mb->mbxOwner = OWN_HOST; | 299 | mb->mbxOwner = OWN_HOST; |
@@ -337,8 +339,8 @@ lpfc_read_lnk_stat(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |||
337 | /* mailbox command */ | 339 | /* mailbox command */ |
338 | /********************************************/ | 340 | /********************************************/ |
339 | int | 341 | int |
340 | lpfc_reg_login(struct lpfc_hba *phba, uint32_t did, uint8_t *param, | 342 | lpfc_reg_login(struct lpfc_hba *phba, uint16_t vpi, uint32_t did, |
341 | LPFC_MBOXQ_t *pmb, uint32_t flag) | 343 | uint8_t *param, LPFC_MBOXQ_t *pmb, uint32_t flag) |
342 | { | 344 | { |
343 | MAILBOX_t *mb = &pmb->mb; | 345 | MAILBOX_t *mb = &pmb->mb; |
344 | uint8_t *sparam; | 346 | uint8_t *sparam; |
@@ -347,6 +349,7 @@ lpfc_reg_login(struct lpfc_hba *phba, uint32_t did, uint8_t *param, | |||
347 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); | 349 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); |
348 | 350 | ||
349 | mb->un.varRegLogin.rpi = 0; | 351 | mb->un.varRegLogin.rpi = 0; |
352 | mb->un.varRegLogin.vpi = vpi; | ||
350 | mb->un.varRegLogin.did = did; | 353 | mb->un.varRegLogin.did = did; |
351 | mb->un.varWords[30] = flag; /* Set flag to issue action on cmpl */ | 354 | mb->un.varWords[30] = flag; /* Set flag to issue action on cmpl */ |
352 | 355 | ||
@@ -358,13 +361,11 @@ lpfc_reg_login(struct lpfc_hba *phba, uint32_t did, uint8_t *param, | |||
358 | kfree(mp); | 361 | kfree(mp); |
359 | mb->mbxCommand = MBX_REG_LOGIN64; | 362 | mb->mbxCommand = MBX_REG_LOGIN64; |
360 | /* REG_LOGIN: no buffers */ | 363 | /* REG_LOGIN: no buffers */ |
361 | lpfc_printf_log(phba, | 364 | lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX, |
362 | KERN_WARNING, | 365 | "%d (%d):0302 REG_LOGIN: no buffers, DID x%x, " |
363 | LOG_MBOX, | 366 | "flag x%x\n", |
364 | "%d:0302 REG_LOGIN: no buffers Data x%x x%x\n", | 367 | phba->brd_no, vpi, did, flag); |
365 | phba->brd_no, | 368 | return (1); |
366 | (uint32_t) did, (uint32_t) flag); | ||
367 | return 1; | ||
368 | } | 369 | } |
369 | INIT_LIST_HEAD(&mp->list); | 370 | INIT_LIST_HEAD(&mp->list); |
370 | sparam = mp->virt; | 371 | sparam = mp->virt; |
@@ -380,7 +381,7 @@ lpfc_reg_login(struct lpfc_hba *phba, uint32_t did, uint8_t *param, | |||
380 | mb->un.varRegLogin.un.sp64.addrHigh = putPaddrHigh(mp->phys); | 381 | mb->un.varRegLogin.un.sp64.addrHigh = putPaddrHigh(mp->phys); |
381 | mb->un.varRegLogin.un.sp64.addrLow = putPaddrLow(mp->phys); | 382 | mb->un.varRegLogin.un.sp64.addrLow = putPaddrLow(mp->phys); |
382 | 383 | ||
383 | return 0; | 384 | return (0); |
384 | } | 385 | } |
385 | 386 | ||
386 | /**********************************************/ | 387 | /**********************************************/ |
@@ -388,7 +389,8 @@ lpfc_reg_login(struct lpfc_hba *phba, uint32_t did, uint8_t *param, | |||
388 | /* mailbox command */ | 389 | /* mailbox command */ |
389 | /**********************************************/ | 390 | /**********************************************/ |
390 | void | 391 | void |
391 | lpfc_unreg_login(struct lpfc_hba *phba, uint32_t rpi, LPFC_MBOXQ_t * pmb) | 392 | lpfc_unreg_login(struct lpfc_hba *phba, uint16_t vpi, uint32_t rpi, |
393 | LPFC_MBOXQ_t * pmb) | ||
392 | { | 394 | { |
393 | MAILBOX_t *mb; | 395 | MAILBOX_t *mb; |
394 | 396 | ||
@@ -397,12 +399,52 @@ lpfc_unreg_login(struct lpfc_hba *phba, uint32_t rpi, LPFC_MBOXQ_t * pmb) | |||
397 | 399 | ||
398 | mb->un.varUnregLogin.rpi = (uint16_t) rpi; | 400 | mb->un.varUnregLogin.rpi = (uint16_t) rpi; |
399 | mb->un.varUnregLogin.rsvd1 = 0; | 401 | mb->un.varUnregLogin.rsvd1 = 0; |
402 | mb->un.varUnregLogin.vpi = vpi; | ||
400 | 403 | ||
401 | mb->mbxCommand = MBX_UNREG_LOGIN; | 404 | mb->mbxCommand = MBX_UNREG_LOGIN; |
402 | mb->mbxOwner = OWN_HOST; | 405 | mb->mbxOwner = OWN_HOST; |
403 | return; | 406 | return; |
404 | } | 407 | } |
405 | 408 | ||
409 | /**************************************************/ | ||
410 | /* lpfc_reg_vpi Issue a REG_VPI */ | ||
411 | /* mailbox command */ | ||
412 | /**************************************************/ | ||
413 | void | ||
414 | lpfc_reg_vpi(struct lpfc_hba *phba, uint16_t vpi, uint32_t sid, | ||
415 | LPFC_MBOXQ_t *pmb) | ||
416 | { | ||
417 | MAILBOX_t *mb = &pmb->mb; | ||
418 | |||
419 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); | ||
420 | |||
421 | mb->un.varRegVpi.vpi = vpi; | ||
422 | mb->un.varRegVpi.sid = sid; | ||
423 | |||
424 | mb->mbxCommand = MBX_REG_VPI; | ||
425 | mb->mbxOwner = OWN_HOST; | ||
426 | return; | ||
427 | |||
428 | } | ||
429 | |||
430 | /**************************************************/ | ||
431 | /* lpfc_unreg_vpi Issue a UNREG_VNPI */ | ||
432 | /* mailbox command */ | ||
433 | /**************************************************/ | ||
434 | void | ||
435 | lpfc_unreg_vpi(struct lpfc_hba *phba, uint16_t vpi, LPFC_MBOXQ_t *pmb) | ||
436 | { | ||
437 | MAILBOX_t *mb = &pmb->mb; | ||
438 | memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); | ||
439 | |||
440 | mb->un.varUnregVpi.vpi = vpi; | ||
441 | |||
442 | mb->mbxCommand = MBX_UNREG_VPI; | ||
443 | mb->mbxOwner = OWN_HOST; | ||
444 | return; | ||
445 | |||
446 | } | ||
447 | |||
406 | static void | 448 | static void |
407 | lpfc_config_pcb_setup(struct lpfc_hba * phba) | 449 | lpfc_config_pcb_setup(struct lpfc_hba * phba) |
408 | { | 450 | { |
@@ -420,9 +462,9 @@ lpfc_config_pcb_setup(struct lpfc_hba * phba) | |||
420 | pring = &psli->ring[i]; | 462 | pring = &psli->ring[i]; |
421 | 463 | ||
422 | pring->sizeCiocb = phba->sli_rev == 3 ? SLI3_IOCB_CMD_SIZE: | 464 | pring->sizeCiocb = phba->sli_rev == 3 ? SLI3_IOCB_CMD_SIZE: |
423 | SLI2_IOCB_CMD_SIZE; | 465 | SLI2_IOCB_CMD_SIZE; |
424 | pring->sizeRiocb = phba->sli_rev == 3 ? SLI3_IOCB_RSP_SIZE: | 466 | pring->sizeRiocb = phba->sli_rev == 3 ? SLI3_IOCB_RSP_SIZE: |
425 | SLI2_IOCB_RSP_SIZE; | 467 | SLI2_IOCB_RSP_SIZE; |
426 | /* A ring MUST have both cmd and rsp entries defined to be | 468 | /* A ring MUST have both cmd and rsp entries defined to be |
427 | valid */ | 469 | valid */ |
428 | if ((pring->numCiocb == 0) || (pring->numRiocb == 0)) { | 470 | if ((pring->numCiocb == 0) || (pring->numRiocb == 0)) { |
@@ -437,18 +479,18 @@ lpfc_config_pcb_setup(struct lpfc_hba * phba) | |||
437 | continue; | 479 | continue; |
438 | } | 480 | } |
439 | /* Command ring setup for ring */ | 481 | /* Command ring setup for ring */ |
440 | pring->cmdringaddr = (void *)&phba->slim2p->IOCBs[iocbCnt]; | 482 | pring->cmdringaddr = (void *) &phba->slim2p->IOCBs[iocbCnt]; |
441 | pcbp->rdsc[i].cmdEntries = pring->numCiocb; | 483 | pcbp->rdsc[i].cmdEntries = pring->numCiocb; |
442 | 484 | ||
443 | offset = (uint8_t *)&phba->slim2p->IOCBs[iocbCnt] - | 485 | offset = (uint8_t *) &phba->slim2p->IOCBs[iocbCnt] - |
444 | (uint8_t *)phba->slim2p; | 486 | (uint8_t *) phba->slim2p; |
445 | pdma_addr = phba->slim2p_mapping + offset; | 487 | pdma_addr = phba->slim2p_mapping + offset; |
446 | pcbp->rdsc[i].cmdAddrHigh = putPaddrHigh(pdma_addr); | 488 | pcbp->rdsc[i].cmdAddrHigh = putPaddrHigh(pdma_addr); |
447 | pcbp->rdsc[i].cmdAddrLow = putPaddrLow(pdma_addr); | 489 | pcbp->rdsc[i].cmdAddrLow = putPaddrLow(pdma_addr); |
448 | iocbCnt += pring->numCiocb; | 490 | iocbCnt += pring->numCiocb; |
449 | 491 | ||
450 | /* Response ring setup for ring */ | 492 | /* Response ring setup for ring */ |
451 | pring->rspringaddr = (void *)&phba->slim2p->IOCBs[iocbCnt]; | 493 | pring->rspringaddr = (void *) &phba->slim2p->IOCBs[iocbCnt]; |
452 | 494 | ||
453 | pcbp->rdsc[i].rspEntries = pring->numRiocb; | 495 | pcbp->rdsc[i].rspEntries = pring->numRiocb; |
454 | offset = (uint8_t *)&phba->slim2p->IOCBs[iocbCnt] - | 496 | offset = (uint8_t *)&phba->slim2p->IOCBs[iocbCnt] - |
@@ -519,7 +561,7 @@ lpfc_config_hbq(struct lpfc_hba *phba, struct lpfc_hbq_init *hbq_desc, | |||
519 | * Notification */ | 561 | * Notification */ |
520 | hbqmb->numMask = hbq_desc->mask_count; /* # R_CTL/TYPE masks | 562 | hbqmb->numMask = hbq_desc->mask_count; /* # R_CTL/TYPE masks |
521 | * # in words 0-19 */ | 563 | * # in words 0-19 */ |
522 | hbqmb->profile = hbq_desc->profile; /* Selection profile: | 564 | hbqmb->profile = hbq_desc->profile; /* Selection profile: |
523 | * 0 = all, | 565 | * 0 = all, |
524 | * 7 = logentry */ | 566 | * 7 = logentry */ |
525 | hbqmb->ringMask = hbq_desc->ring_mask; /* Binds HBQ to a ring | 567 | hbqmb->ringMask = hbq_desc->ring_mask; /* Binds HBQ to a ring |
@@ -538,9 +580,9 @@ lpfc_config_hbq(struct lpfc_hba *phba, struct lpfc_hbq_init *hbq_desc, | |||
538 | mb->mbxCommand = MBX_CONFIG_HBQ; | 580 | mb->mbxCommand = MBX_CONFIG_HBQ; |
539 | mb->mbxOwner = OWN_HOST; | 581 | mb->mbxOwner = OWN_HOST; |
540 | 582 | ||
541 | /* Copy info for profiles 2,3,5. Other | 583 | /* Copy info for profiles 2,3,5. Other |
542 | * profiles this area is reserved | 584 | * profiles this area is reserved |
543 | */ | 585 | */ |
544 | if (hbq_desc->profile == 2) | 586 | if (hbq_desc->profile == 2) |
545 | lpfc_build_hbq_profile2(hbqmb, hbq_desc); | 587 | lpfc_build_hbq_profile2(hbqmb, hbq_desc); |
546 | else if (hbq_desc->profile == 3) | 588 | else if (hbq_desc->profile == 3) |
@@ -563,6 +605,8 @@ lpfc_config_hbq(struct lpfc_hba *phba, struct lpfc_hbq_init *hbq_desc, | |||
563 | return; | 605 | return; |
564 | } | 606 | } |
565 | 607 | ||
608 | |||
609 | |||
566 | void | 610 | void |
567 | lpfc_config_ring(struct lpfc_hba * phba, int ring, LPFC_MBOXQ_t * pmb) | 611 | lpfc_config_ring(struct lpfc_hba * phba, int ring, LPFC_MBOXQ_t * pmb) |
568 | { | 612 | { |
@@ -605,7 +649,7 @@ lpfc_config_ring(struct lpfc_hba * phba, int ring, LPFC_MBOXQ_t * pmb) | |||
605 | } | 649 | } |
606 | 650 | ||
607 | void | 651 | void |
608 | lpfc_config_port(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | 652 | lpfc_config_port(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) |
609 | { | 653 | { |
610 | MAILBOX_t __iomem *mb_slim = (MAILBOX_t __iomem *) phba->MBslimaddr; | 654 | MAILBOX_t __iomem *mb_slim = (MAILBOX_t __iomem *) phba->MBslimaddr; |
611 | MAILBOX_t *mb = &pmb->mb; | 655 | MAILBOX_t *mb = &pmb->mb; |
@@ -629,11 +673,19 @@ lpfc_config_port(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |||
629 | 673 | ||
630 | /* If HBA supports SLI=3 ask for it */ | 674 | /* If HBA supports SLI=3 ask for it */ |
631 | 675 | ||
632 | mb->un.varCfgPort.sli_mode = phba->sli_rev; | 676 | if (phba->sli_rev == 3 && phba->vpd.sli3Feat.cerbm) { |
633 | if (phba->sli_rev == 3) { | ||
634 | mb->un.varCfgPort.cerbm = 1; /* Request HBQs */ | 677 | mb->un.varCfgPort.cerbm = 1; /* Request HBQs */ |
635 | mb->un.varCfgPort.max_hbq = 1; /* Requesting 2 HBQs */ | 678 | mb->un.varCfgPort.max_hbq = 1; /* Requesting 2 HBQs */ |
636 | } | 679 | if (phba->max_vpi && lpfc_npiv_enable && |
680 | phba->vpd.sli3Feat.cmv) { | ||
681 | mb->un.varCfgPort.max_vpi = phba->max_vpi; | ||
682 | mb->un.varCfgPort.cmv = 1; | ||
683 | phba->sli3_options |= LPFC_SLI3_NPIV_ENABLED; | ||
684 | } else | ||
685 | mb->un.varCfgPort.max_vpi = phba->max_vpi = 0; | ||
686 | } else | ||
687 | phba->sli_rev = 2; | ||
688 | mb->un.varCfgPort.sli_mode = phba->sli_rev; | ||
637 | 689 | ||
638 | /* Now setup pcb */ | 690 | /* Now setup pcb */ |
639 | phba->slim2p->pcb.type = TYPE_NATIVE_SLI2; | 691 | phba->slim2p->pcb.type = TYPE_NATIVE_SLI2; |
@@ -748,7 +800,7 @@ lpfc_config_port(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |||
748 | 800 | ||
749 | /* Swap PCB if needed */ | 801 | /* Swap PCB if needed */ |
750 | lpfc_sli_pcimem_bcopy(&phba->slim2p->pcb, &phba->slim2p->pcb, | 802 | lpfc_sli_pcimem_bcopy(&phba->slim2p->pcb, &phba->slim2p->pcb, |
751 | sizeof (PCB_t)); | 803 | sizeof(PCB_t)); |
752 | } | 804 | } |
753 | 805 | ||
754 | void | 806 | void |
@@ -783,13 +835,22 @@ lpfc_mbox_get(struct lpfc_hba * phba) | |||
783 | struct lpfc_sli *psli = &phba->sli; | 835 | struct lpfc_sli *psli = &phba->sli; |
784 | 836 | ||
785 | list_remove_head((&psli->mboxq), mbq, LPFC_MBOXQ_t, list); | 837 | list_remove_head((&psli->mboxq), mbq, LPFC_MBOXQ_t, list); |
786 | if (mbq) { | 838 | if (mbq) |
787 | psli->mboxq_cnt--; | 839 | psli->mboxq_cnt--; |
788 | } | ||
789 | 840 | ||
790 | return mbq; | 841 | return mbq; |
791 | } | 842 | } |
792 | 843 | ||
844 | void | ||
845 | lpfc_mbox_cmpl_put(struct lpfc_hba * phba, LPFC_MBOXQ_t * mbq) | ||
846 | { | ||
847 | /* This function expects to be called from interupt context */ | ||
848 | spin_lock(&phba->hbalock); | ||
849 | list_add_tail(&mbq->list, &phba->sli.mboxq_cmpl); | ||
850 | spin_unlock(&phba->hbalock); | ||
851 | return; | ||
852 | } | ||
853 | |||
793 | int | 854 | int |
794 | lpfc_mbox_tmo_val(struct lpfc_hba *phba, int cmd) | 855 | lpfc_mbox_tmo_val(struct lpfc_hba *phba, int cmd) |
795 | { | 856 | { |