diff options
Diffstat (limited to 'drivers/scsi/bfa/bfad_im.c')
-rw-r--r-- | drivers/scsi/bfa/bfad_im.c | 257 |
1 files changed, 123 insertions, 134 deletions
diff --git a/drivers/scsi/bfa/bfad_im.c b/drivers/scsi/bfa/bfad_im.c index 6ef87f6fcdbb..d950ee44016e 100644 --- a/drivers/scsi/bfa/bfad_im.c +++ b/drivers/scsi/bfa/bfad_im.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. | 2 | * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. |
3 | * All rights reserved | 3 | * All rights reserved |
4 | * www.brocade.com | 4 | * www.brocade.com |
5 | * | 5 | * |
@@ -19,12 +19,10 @@ | |||
19 | * bfad_im.c Linux driver IM module. | 19 | * bfad_im.c Linux driver IM module. |
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include <linux/slab.h> | ||
23 | #include "bfad_drv.h" | 22 | #include "bfad_drv.h" |
24 | #include "bfad_im.h" | 23 | #include "bfad_im.h" |
25 | #include "bfad_trcmod.h" | 24 | #include "bfa_cb_ioim.h" |
26 | #include "bfa_cb_ioim_macros.h" | 25 | #include "bfa_fcs.h" |
27 | #include <fcb/bfa_fcb_fcpim.h> | ||
28 | 26 | ||
29 | BFA_TRC_FILE(LDRV, IM); | 27 | BFA_TRC_FILE(LDRV, IM); |
30 | 28 | ||
@@ -33,8 +31,10 @@ struct scsi_transport_template *bfad_im_scsi_transport_template; | |||
33 | struct scsi_transport_template *bfad_im_scsi_vport_transport_template; | 31 | struct scsi_transport_template *bfad_im_scsi_vport_transport_template; |
34 | static void bfad_im_itnim_work_handler(struct work_struct *work); | 32 | static void bfad_im_itnim_work_handler(struct work_struct *work); |
35 | static int bfad_im_queuecommand(struct scsi_cmnd *cmnd, | 33 | static int bfad_im_queuecommand(struct scsi_cmnd *cmnd, |
36 | void (*done)(struct scsi_cmnd *)); | 34 | void (*done)(struct scsi_cmnd *)); |
37 | static int bfad_im_slave_alloc(struct scsi_device *sdev); | 35 | static int bfad_im_slave_alloc(struct scsi_device *sdev); |
36 | static void bfad_im_fc_rport_add(struct bfad_im_port_s *im_port, | ||
37 | struct bfad_itnim_s *itnim); | ||
38 | 38 | ||
39 | void | 39 | void |
40 | bfa_cb_ioim_done(void *drv, struct bfad_ioim_s *dio, | 40 | bfa_cb_ioim_done(void *drv, struct bfad_ioim_s *dio, |
@@ -58,6 +58,7 @@ bfa_cb_ioim_done(void *drv, struct bfad_ioim_s *dio, | |||
58 | sns_len = SCSI_SENSE_BUFFERSIZE; | 58 | sns_len = SCSI_SENSE_BUFFERSIZE; |
59 | memcpy(cmnd->sense_buffer, sns_info, sns_len); | 59 | memcpy(cmnd->sense_buffer, sns_info, sns_len); |
60 | } | 60 | } |
61 | |||
61 | if (residue > 0) { | 62 | if (residue > 0) { |
62 | bfa_trc(bfad, residue); | 63 | bfa_trc(bfad, residue); |
63 | scsi_set_resid(cmnd, residue); | 64 | scsi_set_resid(cmnd, residue); |
@@ -76,7 +77,8 @@ bfa_cb_ioim_done(void *drv, struct bfad_ioim_s *dio, | |||
76 | case BFI_IOIM_STS_TIMEDOUT: | 77 | case BFI_IOIM_STS_TIMEDOUT: |
77 | case BFI_IOIM_STS_PATHTOV: | 78 | case BFI_IOIM_STS_PATHTOV: |
78 | default: | 79 | default: |
79 | cmnd->result = ScsiResult(DID_ERROR, 0); | 80 | host_status = DID_ERROR; |
81 | cmnd->result = ScsiResult(host_status, 0); | ||
80 | } | 82 | } |
81 | 83 | ||
82 | /* Unmap DMA, if host is NULL, it means a scsi passthru cmd */ | 84 | /* Unmap DMA, if host is NULL, it means a scsi passthru cmd */ |
@@ -162,11 +164,6 @@ bfa_cb_tskim_done(void *bfad, struct bfad_tskim_s *dtsk, | |||
162 | wake_up(wq); | 164 | wake_up(wq); |
163 | } | 165 | } |
164 | 166 | ||
165 | void | ||
166 | bfa_cb_ioim_resfree(void *drv) | ||
167 | { | ||
168 | } | ||
169 | |||
170 | /** | 167 | /** |
171 | * Scsi_Host_template SCSI host template | 168 | * Scsi_Host_template SCSI host template |
172 | */ | 169 | */ |
@@ -179,15 +176,23 @@ bfad_im_info(struct Scsi_Host *shost) | |||
179 | static char bfa_buf[256]; | 176 | static char bfa_buf[256]; |
180 | struct bfad_im_port_s *im_port = | 177 | struct bfad_im_port_s *im_port = |
181 | (struct bfad_im_port_s *) shost->hostdata[0]; | 178 | (struct bfad_im_port_s *) shost->hostdata[0]; |
182 | struct bfad_s *bfad = im_port->bfad; | 179 | struct bfad_s *bfad = im_port->bfad; |
180 | struct bfa_s *bfa = &bfad->bfa; | ||
181 | struct bfa_ioc_s *ioc = &bfa->ioc; | ||
183 | char model[BFA_ADAPTER_MODEL_NAME_LEN]; | 182 | char model[BFA_ADAPTER_MODEL_NAME_LEN]; |
184 | 183 | ||
185 | bfa_get_adapter_model(&bfad->bfa, model); | 184 | bfa_get_adapter_model(bfa, model); |
186 | 185 | ||
187 | memset(bfa_buf, 0, sizeof(bfa_buf)); | 186 | memset(bfa_buf, 0, sizeof(bfa_buf)); |
188 | snprintf(bfa_buf, sizeof(bfa_buf), | 187 | if (ioc->ctdev) |
189 | "Brocade FC/FCOE Adapter, " "model: %s hwpath: %s driver: %s", | 188 | snprintf(bfa_buf, sizeof(bfa_buf), |
189 | "Brocade FCOE Adapter, " "model: %s hwpath: %s driver: %s", | ||
190 | model, bfad->pci_name, BFAD_DRIVER_VERSION); | ||
191 | else | ||
192 | snprintf(bfa_buf, sizeof(bfa_buf), | ||
193 | "Brocade FC Adapter, " "model: %s hwpath: %s driver: %s", | ||
190 | model, bfad->pci_name, BFAD_DRIVER_VERSION); | 194 | model, bfad->pci_name, BFAD_DRIVER_VERSION); |
195 | |||
191 | return bfa_buf; | 196 | return bfa_buf; |
192 | } | 197 | } |
193 | 198 | ||
@@ -221,9 +226,9 @@ bfad_im_abort_handler(struct scsi_cmnd *cmnd) | |||
221 | } | 226 | } |
222 | 227 | ||
223 | bfa_trc(bfad, hal_io->iotag); | 228 | bfa_trc(bfad, hal_io->iotag); |
224 | bfa_log(bfad->logmod, BFA_LOG_LINUX_SCSI_ABORT, | 229 | BFA_LOG(KERN_INFO, bfad, log_level, "scsi%d: abort cmnd %p iotag %x\n", |
225 | im_port->shost->host_no, cmnd, hal_io->iotag); | 230 | im_port->shost->host_no, cmnd, hal_io->iotag); |
226 | bfa_ioim_abort(hal_io); | 231 | (void) bfa_ioim_abort(hal_io); |
227 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | 232 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); |
228 | 233 | ||
229 | /* Need to wait until the command get aborted */ | 234 | /* Need to wait until the command get aborted */ |
@@ -237,7 +242,8 @@ bfad_im_abort_handler(struct scsi_cmnd *cmnd) | |||
237 | 242 | ||
238 | cmnd->scsi_done(cmnd); | 243 | cmnd->scsi_done(cmnd); |
239 | bfa_trc(bfad, hal_io->iotag); | 244 | bfa_trc(bfad, hal_io->iotag); |
240 | bfa_log(bfad->logmod, BFA_LOG_LINUX_SCSI_ABORT_COMP, | 245 | BFA_LOG(KERN_INFO, bfad, log_level, |
246 | "scsi%d: complete abort 0x%p iotag 0x%x\n", | ||
241 | im_port->shost->host_no, cmnd, hal_io->iotag); | 247 | im_port->shost->host_no, cmnd, hal_io->iotag); |
242 | return SUCCESS; | 248 | return SUCCESS; |
243 | out: | 249 | out: |
@@ -255,8 +261,8 @@ bfad_im_target_reset_send(struct bfad_s *bfad, struct scsi_cmnd *cmnd, | |||
255 | 261 | ||
256 | tskim = bfa_tskim_alloc(&bfad->bfa, (struct bfad_tskim_s *) cmnd); | 262 | tskim = bfa_tskim_alloc(&bfad->bfa, (struct bfad_tskim_s *) cmnd); |
257 | if (!tskim) { | 263 | if (!tskim) { |
258 | BFA_DEV_PRINTF(bfad, BFA_ERR, | 264 | BFA_LOG(KERN_ERR, bfad, log_level, |
259 | "target reset, fail to allocate tskim\n"); | 265 | "target reset, fail to allocate tskim\n"); |
260 | rc = BFA_STATUS_FAILED; | 266 | rc = BFA_STATUS_FAILED; |
261 | goto out; | 267 | goto out; |
262 | } | 268 | } |
@@ -306,7 +312,7 @@ bfad_im_reset_lun_handler(struct scsi_cmnd *cmnd) | |||
306 | 312 | ||
307 | tskim = bfa_tskim_alloc(&bfad->bfa, (struct bfad_tskim_s *) cmnd); | 313 | tskim = bfa_tskim_alloc(&bfad->bfa, (struct bfad_tskim_s *) cmnd); |
308 | if (!tskim) { | 314 | if (!tskim) { |
309 | BFA_DEV_PRINTF(bfad, BFA_ERR, | 315 | BFA_LOG(KERN_ERR, bfad, log_level, |
310 | "LUN reset, fail to allocate tskim"); | 316 | "LUN reset, fail to allocate tskim"); |
311 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | 317 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); |
312 | rc = FAILED; | 318 | rc = FAILED; |
@@ -331,8 +337,8 @@ bfad_im_reset_lun_handler(struct scsi_cmnd *cmnd) | |||
331 | 337 | ||
332 | task_status = cmnd->SCp.Status >> 1; | 338 | task_status = cmnd->SCp.Status >> 1; |
333 | if (task_status != BFI_TSKIM_STS_OK) { | 339 | if (task_status != BFI_TSKIM_STS_OK) { |
334 | BFA_DEV_PRINTF(bfad, BFA_ERR, "LUN reset failure, status: %d\n", | 340 | BFA_LOG(KERN_ERR, bfad, log_level, |
335 | task_status); | 341 | "LUN reset failure, status: %d\n", task_status); |
336 | rc = FAILED; | 342 | rc = FAILED; |
337 | } | 343 | } |
338 | 344 | ||
@@ -375,7 +381,7 @@ bfad_im_reset_bus_handler(struct scsi_cmnd *cmnd) | |||
375 | 381 | ||
376 | task_status = cmnd->SCp.Status >> 1; | 382 | task_status = cmnd->SCp.Status >> 1; |
377 | if (task_status != BFI_TSKIM_STS_OK) { | 383 | if (task_status != BFI_TSKIM_STS_OK) { |
378 | BFA_DEV_PRINTF(bfad, BFA_ERR, | 384 | BFA_LOG(KERN_ERR, bfad, log_level, |
379 | "target reset failure," | 385 | "target reset failure," |
380 | " status: %d\n", task_status); | 386 | " status: %d\n", task_status); |
381 | err_cnt++; | 387 | err_cnt++; |
@@ -438,6 +444,7 @@ bfa_fcb_itnim_free(struct bfad_s *bfad, struct bfad_itnim_s *itnim_drv) | |||
438 | wwn_t wwpn; | 444 | wwn_t wwpn; |
439 | u32 fcid; | 445 | u32 fcid; |
440 | char wwpn_str[32], fcid_str[16]; | 446 | char wwpn_str[32], fcid_str[16]; |
447 | struct bfad_im_s *im = itnim_drv->im; | ||
441 | 448 | ||
442 | /* online to free state transtion should not happen */ | 449 | /* online to free state transtion should not happen */ |
443 | bfa_assert(itnim_drv->state != ITNIM_STATE_ONLINE); | 450 | bfa_assert(itnim_drv->state != ITNIM_STATE_ONLINE); |
@@ -454,10 +461,14 @@ bfa_fcb_itnim_free(struct bfad_s *bfad, struct bfad_itnim_s *itnim_drv) | |||
454 | fcid = bfa_fcs_itnim_get_fcid(&itnim_drv->fcs_itnim); | 461 | fcid = bfa_fcs_itnim_get_fcid(&itnim_drv->fcs_itnim); |
455 | wwn2str(wwpn_str, wwpn); | 462 | wwn2str(wwpn_str, wwpn); |
456 | fcid2str(fcid_str, fcid); | 463 | fcid2str(fcid_str, fcid); |
457 | bfa_log(bfad->logmod, BFA_LOG_LINUX_ITNIM_FREE, | 464 | BFA_LOG(KERN_INFO, bfad, log_level, |
465 | "ITNIM FREE scsi%d: FCID: %s WWPN: %s\n", | ||
458 | port->im_port->shost->host_no, | 466 | port->im_port->shost->host_no, |
459 | fcid_str, wwpn_str); | 467 | fcid_str, wwpn_str); |
460 | bfad_os_itnim_process(itnim_drv); | 468 | |
469 | /* ITNIM processing */ | ||
470 | if (itnim_drv->queue_work) | ||
471 | queue_work(im->drv_workq, &itnim_drv->itnim_work); | ||
461 | } | 472 | } |
462 | 473 | ||
463 | /** | 474 | /** |
@@ -468,13 +479,17 @@ void | |||
468 | bfa_fcb_itnim_online(struct bfad_itnim_s *itnim_drv) | 479 | bfa_fcb_itnim_online(struct bfad_itnim_s *itnim_drv) |
469 | { | 480 | { |
470 | struct bfad_port_s *port; | 481 | struct bfad_port_s *port; |
482 | struct bfad_im_s *im = itnim_drv->im; | ||
471 | 483 | ||
472 | itnim_drv->bfa_itnim = bfa_fcs_itnim_get_halitn(&itnim_drv->fcs_itnim); | 484 | itnim_drv->bfa_itnim = bfa_fcs_itnim_get_halitn(&itnim_drv->fcs_itnim); |
473 | port = bfa_fcs_itnim_get_drvport(&itnim_drv->fcs_itnim); | 485 | port = bfa_fcs_itnim_get_drvport(&itnim_drv->fcs_itnim); |
474 | itnim_drv->state = ITNIM_STATE_ONLINE; | 486 | itnim_drv->state = ITNIM_STATE_ONLINE; |
475 | itnim_drv->queue_work = 1; | 487 | itnim_drv->queue_work = 1; |
476 | itnim_drv->im_port = port->im_port; | 488 | itnim_drv->im_port = port->im_port; |
477 | bfad_os_itnim_process(itnim_drv); | 489 | |
490 | /* ITNIM processing */ | ||
491 | if (itnim_drv->queue_work) | ||
492 | queue_work(im->drv_workq, &itnim_drv->itnim_work); | ||
478 | } | 493 | } |
479 | 494 | ||
480 | /** | 495 | /** |
@@ -486,6 +501,7 @@ bfa_fcb_itnim_offline(struct bfad_itnim_s *itnim_drv) | |||
486 | { | 501 | { |
487 | struct bfad_port_s *port; | 502 | struct bfad_port_s *port; |
488 | struct bfad_s *bfad; | 503 | struct bfad_s *bfad; |
504 | struct bfad_im_s *im = itnim_drv->im; | ||
489 | 505 | ||
490 | port = bfa_fcs_itnim_get_drvport(&itnim_drv->fcs_itnim); | 506 | port = bfa_fcs_itnim_get_drvport(&itnim_drv->fcs_itnim); |
491 | bfad = port->bfad; | 507 | bfad = port->bfad; |
@@ -497,16 +513,10 @@ bfa_fcb_itnim_offline(struct bfad_itnim_s *itnim_drv) | |||
497 | itnim_drv->im_port = port->im_port; | 513 | itnim_drv->im_port = port->im_port; |
498 | itnim_drv->state = ITNIM_STATE_OFFLINE_PENDING; | 514 | itnim_drv->state = ITNIM_STATE_OFFLINE_PENDING; |
499 | itnim_drv->queue_work = 1; | 515 | itnim_drv->queue_work = 1; |
500 | bfad_os_itnim_process(itnim_drv); | ||
501 | } | ||
502 | 516 | ||
503 | /** | 517 | /* ITNIM processing */ |
504 | * BFA FCS itnim timeout callback. | 518 | if (itnim_drv->queue_work) |
505 | * Context: Interrupt. bfad_lock is held | 519 | queue_work(im->drv_workq, &itnim_drv->itnim_work); |
506 | */ | ||
507 | void bfa_fcb_itnim_tov(struct bfad_itnim_s *itnim) | ||
508 | { | ||
509 | itnim->state = ITNIM_STATE_TIMEOUT; | ||
510 | } | 520 | } |
511 | 521 | ||
512 | /** | 522 | /** |
@@ -514,7 +524,7 @@ void bfa_fcb_itnim_tov(struct bfad_itnim_s *itnim) | |||
514 | */ | 524 | */ |
515 | int | 525 | int |
516 | bfad_im_scsi_host_alloc(struct bfad_s *bfad, struct bfad_im_port_s *im_port, | 526 | bfad_im_scsi_host_alloc(struct bfad_s *bfad, struct bfad_im_port_s *im_port, |
517 | struct device *dev) | 527 | struct device *dev) |
518 | { | 528 | { |
519 | int error = 1; | 529 | int error = 1; |
520 | 530 | ||
@@ -580,7 +590,7 @@ void | |||
580 | bfad_im_scsi_host_free(struct bfad_s *bfad, struct bfad_im_port_s *im_port) | 590 | bfad_im_scsi_host_free(struct bfad_s *bfad, struct bfad_im_port_s *im_port) |
581 | { | 591 | { |
582 | bfa_trc(bfad, bfad->inst_no); | 592 | bfa_trc(bfad, bfad->inst_no); |
583 | bfa_log(bfad->logmod, BFA_LOG_LINUX_SCSI_HOST_FREE, | 593 | BFA_LOG(KERN_INFO, bfad, log_level, "Free scsi%d\n", |
584 | im_port->shost->host_no); | 594 | im_port->shost->host_no); |
585 | 595 | ||
586 | fc_remove_host(im_port->shost); | 596 | fc_remove_host(im_port->shost); |
@@ -598,14 +608,11 @@ bfad_im_port_delete_handler(struct work_struct *work) | |||
598 | { | 608 | { |
599 | struct bfad_im_port_s *im_port = | 609 | struct bfad_im_port_s *im_port = |
600 | container_of(work, struct bfad_im_port_s, port_delete_work); | 610 | container_of(work, struct bfad_im_port_s, port_delete_work); |
601 | struct bfad_s *bfad = im_port->bfad; | ||
602 | 611 | ||
603 | if (im_port->port->pvb_type != BFAD_PORT_PHYS_BASE) { | 612 | if (im_port->port->pvb_type != BFAD_PORT_PHYS_BASE) { |
604 | im_port->flags |= BFAD_PORT_DELETE; | 613 | im_port->flags |= BFAD_PORT_DELETE; |
605 | fc_vport_terminate(im_port->fc_vport); | 614 | fc_vport_terminate(im_port->fc_vport); |
606 | atomic_dec(&bfad->wq_reqcnt); | ||
607 | } | 615 | } |
608 | |||
609 | } | 616 | } |
610 | 617 | ||
611 | bfa_status_t | 618 | bfa_status_t |
@@ -636,11 +643,8 @@ bfad_im_port_delete(struct bfad_s *bfad, struct bfad_port_s *port) | |||
636 | { | 643 | { |
637 | struct bfad_im_port_s *im_port = port->im_port; | 644 | struct bfad_im_port_s *im_port = port->im_port; |
638 | 645 | ||
639 | if (im_port->port->pvb_type != BFAD_PORT_PHYS_BASE) { | 646 | queue_work(bfad->im->drv_workq, |
640 | atomic_inc(&bfad->wq_reqcnt); | ||
641 | queue_work(bfad->im->drv_workq, | ||
642 | &im_port->port_delete_work); | 647 | &im_port->port_delete_work); |
643 | } | ||
644 | } | 648 | } |
645 | 649 | ||
646 | void | 650 | void |
@@ -663,16 +667,6 @@ bfad_im_port_clean(struct bfad_im_port_s *im_port) | |||
663 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | 667 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); |
664 | } | 668 | } |
665 | 669 | ||
666 | void | ||
667 | bfad_im_port_online(struct bfad_s *bfad, struct bfad_port_s *port) | ||
668 | { | ||
669 | } | ||
670 | |||
671 | void | ||
672 | bfad_im_port_offline(struct bfad_s *bfad, struct bfad_port_s *port) | ||
673 | { | ||
674 | } | ||
675 | |||
676 | bfa_status_t | 670 | bfa_status_t |
677 | bfad_im_probe(struct bfad_s *bfad) | 671 | bfad_im_probe(struct bfad_s *bfad) |
678 | { | 672 | { |
@@ -701,27 +695,12 @@ void | |||
701 | bfad_im_probe_undo(struct bfad_s *bfad) | 695 | bfad_im_probe_undo(struct bfad_s *bfad) |
702 | { | 696 | { |
703 | if (bfad->im) { | 697 | if (bfad->im) { |
704 | while (atomic_read(&bfad->wq_reqcnt)) { | ||
705 | printk(KERN_INFO "bfa %s: waiting workq processing," | ||
706 | " wq_reqcnt:%x\n", bfad->pci_name, | ||
707 | atomic_read(&bfad->wq_reqcnt)); | ||
708 | schedule_timeout_uninterruptible(HZ); | ||
709 | } | ||
710 | bfad_os_destroy_workq(bfad->im); | 698 | bfad_os_destroy_workq(bfad->im); |
711 | kfree(bfad->im); | 699 | kfree(bfad->im); |
712 | bfad->im = NULL; | 700 | bfad->im = NULL; |
713 | } | 701 | } |
714 | } | 702 | } |
715 | 703 | ||
716 | /** | ||
717 | * Call back function to handle IO redirection state change | ||
718 | */ | ||
719 | void | ||
720 | bfa_cb_ioredirect_state_change(void *hcb_bfad, bfa_boolean_t ioredirect) | ||
721 | { | ||
722 | /* Do nothing */ | ||
723 | } | ||
724 | |||
725 | struct Scsi_Host * | 704 | struct Scsi_Host * |
726 | bfad_os_scsi_host_alloc(struct bfad_im_port_s *im_port, struct bfad_s *bfad) | 705 | bfad_os_scsi_host_alloc(struct bfad_im_port_s *im_port, struct bfad_s *bfad) |
727 | { | 706 | { |
@@ -751,6 +730,7 @@ void | |||
751 | bfad_os_destroy_workq(struct bfad_im_s *im) | 730 | bfad_os_destroy_workq(struct bfad_im_s *im) |
752 | { | 731 | { |
753 | if (im && im->drv_workq) { | 732 | if (im && im->drv_workq) { |
733 | flush_workqueue(im->drv_workq); | ||
754 | destroy_workqueue(im->drv_workq); | 734 | destroy_workqueue(im->drv_workq); |
755 | im->drv_workq = NULL; | 735 | im->drv_workq = NULL; |
756 | } | 736 | } |
@@ -762,7 +742,7 @@ bfad_os_thread_workq(struct bfad_s *bfad) | |||
762 | struct bfad_im_s *im = bfad->im; | 742 | struct bfad_im_s *im = bfad->im; |
763 | 743 | ||
764 | bfa_trc(bfad, 0); | 744 | bfa_trc(bfad, 0); |
765 | snprintf(im->drv_workq_name, BFAD_KOBJ_NAME_LEN, "bfad_wq_%d", | 745 | snprintf(im->drv_workq_name, KOBJ_NAME_LEN, "bfad_wq_%d", |
766 | bfad->inst_no); | 746 | bfad->inst_no); |
767 | im->drv_workq = create_singlethread_workqueue(im->drv_workq_name); | 747 | im->drv_workq = create_singlethread_workqueue(im->drv_workq_name); |
768 | if (!im->drv_workq) | 748 | if (!im->drv_workq) |
@@ -832,12 +812,6 @@ struct scsi_host_template bfad_im_vport_template = { | |||
832 | .max_sectors = 0xFFFF, | 812 | .max_sectors = 0xFFFF, |
833 | }; | 813 | }; |
834 | 814 | ||
835 | void | ||
836 | bfad_im_probe_post(struct bfad_im_s *im) | ||
837 | { | ||
838 | flush_workqueue(im->drv_workq); | ||
839 | } | ||
840 | |||
841 | bfa_status_t | 815 | bfa_status_t |
842 | bfad_im_module_init(void) | 816 | bfad_im_module_init(void) |
843 | { | 817 | { |
@@ -861,20 +835,12 @@ bfad_im_module_exit(void) | |||
861 | { | 835 | { |
862 | if (bfad_im_scsi_transport_template) | 836 | if (bfad_im_scsi_transport_template) |
863 | fc_release_transport(bfad_im_scsi_transport_template); | 837 | fc_release_transport(bfad_im_scsi_transport_template); |
838 | |||
864 | if (bfad_im_scsi_vport_transport_template) | 839 | if (bfad_im_scsi_vport_transport_template) |
865 | fc_release_transport(bfad_im_scsi_vport_transport_template); | 840 | fc_release_transport(bfad_im_scsi_vport_transport_template); |
866 | } | 841 | } |
867 | 842 | ||
868 | void | 843 | void |
869 | bfad_os_itnim_process(struct bfad_itnim_s *itnim_drv) | ||
870 | { | ||
871 | struct bfad_im_s *im = itnim_drv->im; | ||
872 | |||
873 | if (itnim_drv->queue_work) | ||
874 | queue_work(im->drv_workq, &itnim_drv->itnim_work); | ||
875 | } | ||
876 | |||
877 | void | ||
878 | bfad_os_ramp_up_qdepth(struct bfad_itnim_s *itnim, struct scsi_device *sdev) | 844 | bfad_os_ramp_up_qdepth(struct bfad_itnim_s *itnim, struct scsi_device *sdev) |
879 | { | 845 | { |
880 | struct scsi_device *tmp_sdev; | 846 | struct scsi_device *tmp_sdev; |
@@ -916,9 +882,6 @@ bfad_os_handle_qfull(struct bfad_itnim_s *itnim, struct scsi_device *sdev) | |||
916 | } | 882 | } |
917 | } | 883 | } |
918 | 884 | ||
919 | |||
920 | |||
921 | |||
922 | struct bfad_itnim_s * | 885 | struct bfad_itnim_s * |
923 | bfad_os_get_itnim(struct bfad_im_port_s *im_port, int id) | 886 | bfad_os_get_itnim(struct bfad_im_port_s *im_port, int id) |
924 | { | 887 | { |
@@ -949,44 +912,64 @@ bfad_im_slave_alloc(struct scsi_device *sdev) | |||
949 | return 0; | 912 | return 0; |
950 | } | 913 | } |
951 | 914 | ||
915 | static u32 | ||
916 | bfad_im_supported_speeds(struct bfa_s *bfa) | ||
917 | { | ||
918 | struct bfa_ioc_attr_s ioc_attr; | ||
919 | u32 supported_speed = 0; | ||
920 | |||
921 | bfa_get_attr(bfa, &ioc_attr); | ||
922 | if (ioc_attr.adapter_attr.max_speed == BFA_PORT_SPEED_8GBPS) { | ||
923 | if (ioc_attr.adapter_attr.is_mezz) { | ||
924 | supported_speed |= FC_PORTSPEED_8GBIT | | ||
925 | FC_PORTSPEED_4GBIT | | ||
926 | FC_PORTSPEED_2GBIT | FC_PORTSPEED_1GBIT; | ||
927 | } else { | ||
928 | supported_speed |= FC_PORTSPEED_8GBIT | | ||
929 | FC_PORTSPEED_4GBIT | | ||
930 | FC_PORTSPEED_2GBIT; | ||
931 | } | ||
932 | } else if (ioc_attr.adapter_attr.max_speed == BFA_PORT_SPEED_4GBPS) { | ||
933 | supported_speed |= FC_PORTSPEED_4GBIT | FC_PORTSPEED_2GBIT | | ||
934 | FC_PORTSPEED_1GBIT; | ||
935 | } else if (ioc_attr.adapter_attr.max_speed == BFA_PORT_SPEED_10GBPS) { | ||
936 | supported_speed |= FC_PORTSPEED_10GBIT; | ||
937 | } | ||
938 | return supported_speed; | ||
939 | } | ||
940 | |||
952 | void | 941 | void |
953 | bfad_os_fc_host_init(struct bfad_im_port_s *im_port) | 942 | bfad_os_fc_host_init(struct bfad_im_port_s *im_port) |
954 | { | 943 | { |
955 | struct Scsi_Host *host = im_port->shost; | 944 | struct Scsi_Host *host = im_port->shost; |
956 | struct bfad_s *bfad = im_port->bfad; | 945 | struct bfad_s *bfad = im_port->bfad; |
957 | struct bfad_port_s *port = im_port->port; | 946 | struct bfad_port_s *port = im_port->port; |
958 | struct bfa_pport_attr_s pattr; | 947 | struct bfa_port_attr_s pattr; |
959 | char model[BFA_ADAPTER_MODEL_NAME_LEN]; | 948 | struct bfa_lport_attr_s port_attr; |
960 | char fw_ver[BFA_VERSION_LEN]; | 949 | char symname[BFA_SYMNAME_MAXLEN]; |
961 | 950 | ||
962 | fc_host_node_name(host) = | 951 | fc_host_node_name(host) = |
963 | bfa_os_htonll((bfa_fcs_port_get_nwwn(port->fcs_port))); | 952 | bfa_os_htonll((bfa_fcs_lport_get_nwwn(port->fcs_port))); |
964 | fc_host_port_name(host) = | 953 | fc_host_port_name(host) = |
965 | bfa_os_htonll((bfa_fcs_port_get_pwwn(port->fcs_port))); | 954 | bfa_os_htonll((bfa_fcs_lport_get_pwwn(port->fcs_port))); |
966 | fc_host_max_npiv_vports(host) = bfa_lps_get_max_vport(&bfad->bfa); | 955 | fc_host_max_npiv_vports(host) = bfa_lps_get_max_vport(&bfad->bfa); |
967 | 956 | ||
968 | fc_host_supported_classes(host) = FC_COS_CLASS3; | 957 | fc_host_supported_classes(host) = FC_COS_CLASS3; |
969 | 958 | ||
970 | memset(fc_host_supported_fc4s(host), 0, | 959 | memset(fc_host_supported_fc4s(host), 0, |
971 | sizeof(fc_host_supported_fc4s(host))); | 960 | sizeof(fc_host_supported_fc4s(host))); |
972 | if (bfad_supported_fc4s & (BFA_PORT_ROLE_FCP_IM | BFA_PORT_ROLE_FCP_TM)) | 961 | if (supported_fc4s & BFA_LPORT_ROLE_FCP_IM) |
973 | /* For FCP type 0x08 */ | 962 | /* For FCP type 0x08 */ |
974 | fc_host_supported_fc4s(host)[2] = 1; | 963 | fc_host_supported_fc4s(host)[2] = 1; |
975 | if (bfad_supported_fc4s & BFA_PORT_ROLE_FCP_IPFC) | ||
976 | /* For LLC/SNAP type 0x05 */ | ||
977 | fc_host_supported_fc4s(host)[3] = 0x20; | ||
978 | /* For fibre channel services type 0x20 */ | 964 | /* For fibre channel services type 0x20 */ |
979 | fc_host_supported_fc4s(host)[7] = 1; | 965 | fc_host_supported_fc4s(host)[7] = 1; |
980 | 966 | ||
981 | bfa_get_adapter_model(&bfad->bfa, model); | 967 | bfa_fcs_lport_get_attr(&bfad->bfa_fcs.fabric.bport, &port_attr); |
982 | bfa_get_adapter_fw_ver(&bfad->bfa, fw_ver); | 968 | strncpy(symname, port_attr.port_cfg.sym_name.symname, |
983 | sprintf(fc_host_symbolic_name(host), "Brocade %s FV%s DV%s", | 969 | BFA_SYMNAME_MAXLEN); |
984 | model, fw_ver, BFAD_DRIVER_VERSION); | 970 | sprintf(fc_host_symbolic_name(host), "%s", symname); |
985 | 971 | ||
986 | fc_host_supported_speeds(host) = 0; | 972 | fc_host_supported_speeds(host) = bfad_im_supported_speeds(&bfad->bfa); |
987 | fc_host_supported_speeds(host) |= | ||
988 | FC_PORTSPEED_8GBIT | FC_PORTSPEED_4GBIT | FC_PORTSPEED_2GBIT | | ||
989 | FC_PORTSPEED_1GBIT; | ||
990 | 973 | ||
991 | bfa_fcport_get_attr(&bfad->bfa, &pattr); | 974 | bfa_fcport_get_attr(&bfad->bfa, &pattr); |
992 | fc_host_maxframe_size(host) = pattr.pport_cfg.maxfrsize; | 975 | fc_host_maxframe_size(host) = pattr.pport_cfg.maxfrsize; |
@@ -1065,7 +1048,9 @@ bfad_im_itnim_work_handler(struct work_struct *work) | |||
1065 | fcid2str(fcid_str, fcid); | 1048 | fcid2str(fcid_str, fcid); |
1066 | list_add_tail(&itnim->list_entry, | 1049 | list_add_tail(&itnim->list_entry, |
1067 | &im_port->itnim_mapped_list); | 1050 | &im_port->itnim_mapped_list); |
1068 | bfa_log(bfad->logmod, BFA_LOG_LINUX_ITNIM_ONLINE, | 1051 | BFA_LOG(KERN_INFO, bfad, log_level, |
1052 | "ITNIM ONLINE Target: %d:0:%d " | ||
1053 | "FCID: %s WWPN: %s\n", | ||
1069 | im_port->shost->host_no, | 1054 | im_port->shost->host_no, |
1070 | itnim->scsi_tgt_id, | 1055 | itnim->scsi_tgt_id, |
1071 | fcid_str, wwpn_str); | 1056 | fcid_str, wwpn_str); |
@@ -1096,7 +1081,9 @@ bfad_im_itnim_work_handler(struct work_struct *work) | |||
1096 | wwn2str(wwpn_str, wwpn); | 1081 | wwn2str(wwpn_str, wwpn); |
1097 | fcid2str(fcid_str, fcid); | 1082 | fcid2str(fcid_str, fcid); |
1098 | list_del(&itnim->list_entry); | 1083 | list_del(&itnim->list_entry); |
1099 | bfa_log(bfad->logmod, BFA_LOG_LINUX_ITNIM_OFFLINE, | 1084 | BFA_LOG(KERN_INFO, bfad, log_level, |
1085 | "ITNIM OFFLINE Target: %d:0:%d " | ||
1086 | "FCID: %s WWPN: %s\n", | ||
1100 | im_port->shost->host_no, | 1087 | im_port->shost->host_no, |
1101 | itnim->scsi_tgt_id, | 1088 | itnim->scsi_tgt_id, |
1102 | fcid_str, wwpn_str); | 1089 | fcid_str, wwpn_str); |
@@ -1142,7 +1129,7 @@ bfad_im_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *)) | |||
1142 | struct bfa_ioim_s *hal_io; | 1129 | struct bfa_ioim_s *hal_io; |
1143 | unsigned long flags; | 1130 | unsigned long flags; |
1144 | int rc; | 1131 | int rc; |
1145 | s16 sg_cnt = 0; | 1132 | int sg_cnt = 0; |
1146 | struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device)); | 1133 | struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device)); |
1147 | 1134 | ||
1148 | rc = fc_remote_port_chkready(rport); | 1135 | rc = fc_remote_port_chkready(rport); |
@@ -1153,7 +1140,6 @@ bfad_im_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *)) | |||
1153 | } | 1140 | } |
1154 | 1141 | ||
1155 | sg_cnt = scsi_dma_map(cmnd); | 1142 | sg_cnt = scsi_dma_map(cmnd); |
1156 | |||
1157 | if (sg_cnt < 0) | 1143 | if (sg_cnt < 0) |
1158 | return SCSI_MLQUEUE_HOST_BUSY; | 1144 | return SCSI_MLQUEUE_HOST_BUSY; |
1159 | 1145 | ||
@@ -1168,6 +1154,7 @@ bfad_im_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *)) | |||
1168 | goto out_fail_cmd; | 1154 | goto out_fail_cmd; |
1169 | } | 1155 | } |
1170 | 1156 | ||
1157 | |||
1171 | itnim = itnim_data->itnim; | 1158 | itnim = itnim_data->itnim; |
1172 | if (!itnim) { | 1159 | if (!itnim) { |
1173 | cmnd->result = ScsiResult(DID_IMM_RETRY, 0); | 1160 | cmnd->result = ScsiResult(DID_IMM_RETRY, 0); |
@@ -1206,47 +1193,49 @@ bfad_os_rport_online_wait(struct bfad_s *bfad) | |||
1206 | int rport_delay = 10; | 1193 | int rport_delay = 10; |
1207 | 1194 | ||
1208 | for (i = 0; !(bfad->bfad_flags & BFAD_PORT_ONLINE) | 1195 | for (i = 0; !(bfad->bfad_flags & BFAD_PORT_ONLINE) |
1209 | && i < bfa_linkup_delay; i++) | 1196 | && i < bfa_linkup_delay; i++) { |
1210 | schedule_timeout_uninterruptible(HZ); | 1197 | set_current_state(TASK_UNINTERRUPTIBLE); |
1198 | schedule_timeout(HZ); | ||
1199 | } | ||
1211 | 1200 | ||
1212 | if (bfad->bfad_flags & BFAD_PORT_ONLINE) { | 1201 | if (bfad->bfad_flags & BFAD_PORT_ONLINE) { |
1213 | rport_delay = rport_delay < bfa_linkup_delay ? | 1202 | rport_delay = rport_delay < bfa_linkup_delay ? |
1214 | rport_delay : bfa_linkup_delay; | 1203 | rport_delay : bfa_linkup_delay; |
1215 | for (i = 0; !(bfad->bfad_flags & BFAD_RPORT_ONLINE) | 1204 | for (i = 0; !(bfad->bfad_flags & BFAD_RPORT_ONLINE) |
1216 | && i < rport_delay; i++) | 1205 | && i < rport_delay; i++) { |
1217 | schedule_timeout_uninterruptible(HZ); | 1206 | set_current_state(TASK_UNINTERRUPTIBLE); |
1207 | schedule_timeout(HZ); | ||
1208 | } | ||
1218 | 1209 | ||
1219 | if (rport_delay > 0 && (bfad->bfad_flags & BFAD_RPORT_ONLINE)) | 1210 | if (rport_delay > 0 && (bfad->bfad_flags & BFAD_RPORT_ONLINE)) { |
1220 | schedule_timeout_uninterruptible(rport_delay * HZ); | 1211 | set_current_state(TASK_UNINTERRUPTIBLE); |
1212 | schedule_timeout(rport_delay * HZ); | ||
1213 | } | ||
1221 | } | 1214 | } |
1222 | } | 1215 | } |
1223 | 1216 | ||
1224 | int | 1217 | int |
1225 | bfad_os_get_linkup_delay(struct bfad_s *bfad) | 1218 | bfad_os_get_linkup_delay(struct bfad_s *bfad) |
1226 | { | 1219 | { |
1227 | 1220 | u8 nwwns = 0; | |
1228 | u8 nwwns = 0; | 1221 | wwn_t wwns[BFA_PREBOOT_BOOTLUN_MAX]; |
1229 | wwn_t wwns[BFA_PREBOOT_BOOTLUN_MAX]; | 1222 | int linkup_delay; |
1230 | int ldelay; | ||
1231 | 1223 | ||
1232 | /* | 1224 | /* |
1233 | * Querying for the boot target port wwns | 1225 | * Querying for the boot target port wwns |
1234 | * -- read from boot information in flash. | 1226 | * -- read from boot information in flash. |
1235 | * If nwwns > 0 => boot over SAN and set bfa_linkup_delay = 30 | 1227 | * If nwwns > 0 => boot over SAN and set linkup_delay = 30 |
1236 | * else => local boot machine set bfa_linkup_delay = 10 | 1228 | * else => local boot machine set linkup_delay = 0 |
1237 | */ | 1229 | */ |
1238 | 1230 | ||
1239 | bfa_iocfc_get_bootwwns(&bfad->bfa, &nwwns, wwns); | 1231 | bfa_iocfc_get_bootwwns(&bfad->bfa, &nwwns, wwns); |
1240 | 1232 | ||
1241 | if (nwwns > 0) { | 1233 | if (nwwns > 0) |
1242 | /* If boot over SAN; linkup_delay = 30sec */ | 1234 | /* If Boot over SAN set linkup_delay = 30sec */ |
1243 | ldelay = 30; | 1235 | linkup_delay = 30; |
1244 | } else { | 1236 | else |
1245 | /* If local boot; linkup_delay = 10sec */ | 1237 | /* If local boot; no linkup_delay */ |
1246 | ldelay = 0; | 1238 | linkup_delay = 0; |
1247 | } | ||
1248 | 1239 | ||
1249 | return ldelay; | 1240 | return linkup_delay; |
1250 | } | 1241 | } |
1251 | |||
1252 | |||