aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/ibmvscsi/ibmvfc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/ibmvscsi/ibmvfc.c')
-rw-r--r--drivers/scsi/ibmvscsi/ibmvfc.c91
1 files changed, 56 insertions, 35 deletions
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
index 9f75a6d519a2..00d08b25425f 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc.c
+++ b/drivers/scsi/ibmvscsi/ibmvfc.c
@@ -50,7 +50,6 @@ static unsigned int max_lun = IBMVFC_MAX_LUN;
50static unsigned int max_targets = IBMVFC_MAX_TARGETS; 50static unsigned int max_targets = IBMVFC_MAX_TARGETS;
51static unsigned int max_requests = IBMVFC_MAX_REQUESTS_DEFAULT; 51static unsigned int max_requests = IBMVFC_MAX_REQUESTS_DEFAULT;
52static unsigned int disc_threads = IBMVFC_MAX_DISC_THREADS; 52static unsigned int disc_threads = IBMVFC_MAX_DISC_THREADS;
53static unsigned int dev_loss_tmo = IBMVFC_DEV_LOSS_TMO;
54static unsigned int ibmvfc_debug = IBMVFC_DEBUG; 53static unsigned int ibmvfc_debug = IBMVFC_DEBUG;
55static unsigned int log_level = IBMVFC_DEFAULT_LOG_LEVEL; 54static unsigned int log_level = IBMVFC_DEFAULT_LOG_LEVEL;
56static LIST_HEAD(ibmvfc_head); 55static LIST_HEAD(ibmvfc_head);
@@ -84,11 +83,6 @@ MODULE_PARM_DESC(disc_threads, "Number of device discovery threads to use. "
84module_param_named(debug, ibmvfc_debug, uint, S_IRUGO | S_IWUSR); 83module_param_named(debug, ibmvfc_debug, uint, S_IRUGO | S_IWUSR);
85MODULE_PARM_DESC(debug, "Enable driver debug information. " 84MODULE_PARM_DESC(debug, "Enable driver debug information. "
86 "[Default=" __stringify(IBMVFC_DEBUG) "]"); 85 "[Default=" __stringify(IBMVFC_DEBUG) "]");
87module_param_named(dev_loss_tmo, dev_loss_tmo, uint, S_IRUGO | S_IWUSR);
88MODULE_PARM_DESC(dev_loss_tmo, "Maximum number of seconds that the FC "
89 "transport should insulate the loss of a remote port. Once this "
90 "value is exceeded, the scsi target is removed. "
91 "[Default=" __stringify(IBMVFC_DEV_LOSS_TMO) "]");
92module_param_named(log_level, log_level, uint, 0); 86module_param_named(log_level, log_level, uint, 0);
93MODULE_PARM_DESC(log_level, "Set to 0 - 4 for increasing verbosity of device driver. " 87MODULE_PARM_DESC(log_level, "Set to 0 - 4 for increasing verbosity of device driver. "
94 "[Default=" __stringify(IBMVFC_DEFAULT_LOG_LEVEL) "]"); 88 "[Default=" __stringify(IBMVFC_DEFAULT_LOG_LEVEL) "]");
@@ -2496,41 +2490,66 @@ static void ibmvfc_terminate_rport_io(struct fc_rport *rport)
2496 LEAVE; 2490 LEAVE;
2497} 2491}
2498 2492
2499static const struct { 2493static const struct ibmvfc_async_desc ae_desc [] = {
2500 enum ibmvfc_async_event ae; 2494 { IBMVFC_AE_ELS_PLOGI, "PLOGI", IBMVFC_DEFAULT_LOG_LEVEL + 1 },
2501 const char *desc; 2495 { IBMVFC_AE_ELS_LOGO, "LOGO", IBMVFC_DEFAULT_LOG_LEVEL + 1 },
2502} ae_desc [] = { 2496 { IBMVFC_AE_ELS_PRLO, "PRLO", IBMVFC_DEFAULT_LOG_LEVEL + 1 },
2503 { IBMVFC_AE_ELS_PLOGI, "PLOGI" }, 2497 { IBMVFC_AE_SCN_NPORT, "N-Port SCN", IBMVFC_DEFAULT_LOG_LEVEL + 1 },
2504 { IBMVFC_AE_ELS_LOGO, "LOGO" }, 2498 { IBMVFC_AE_SCN_GROUP, "Group SCN", IBMVFC_DEFAULT_LOG_LEVEL + 1 },
2505 { IBMVFC_AE_ELS_PRLO, "PRLO" }, 2499 { IBMVFC_AE_SCN_DOMAIN, "Domain SCN", IBMVFC_DEFAULT_LOG_LEVEL },
2506 { IBMVFC_AE_SCN_NPORT, "N-Port SCN" }, 2500 { IBMVFC_AE_SCN_FABRIC, "Fabric SCN", IBMVFC_DEFAULT_LOG_LEVEL },
2507 { IBMVFC_AE_SCN_GROUP, "Group SCN" }, 2501 { IBMVFC_AE_LINK_UP, "Link Up", IBMVFC_DEFAULT_LOG_LEVEL },
2508 { IBMVFC_AE_SCN_DOMAIN, "Domain SCN" }, 2502 { IBMVFC_AE_LINK_DOWN, "Link Down", IBMVFC_DEFAULT_LOG_LEVEL },
2509 { IBMVFC_AE_SCN_FABRIC, "Fabric SCN" }, 2503 { IBMVFC_AE_LINK_DEAD, "Link Dead", IBMVFC_DEFAULT_LOG_LEVEL },
2510 { IBMVFC_AE_LINK_UP, "Link Up" }, 2504 { IBMVFC_AE_HALT, "Halt", IBMVFC_DEFAULT_LOG_LEVEL },
2511 { IBMVFC_AE_LINK_DOWN, "Link Down" }, 2505 { IBMVFC_AE_RESUME, "Resume", IBMVFC_DEFAULT_LOG_LEVEL },
2512 { IBMVFC_AE_LINK_DEAD, "Link Dead" }, 2506 { IBMVFC_AE_ADAPTER_FAILED, "Adapter Failed", IBMVFC_DEFAULT_LOG_LEVEL },
2513 { IBMVFC_AE_HALT, "Halt" },
2514 { IBMVFC_AE_RESUME, "Resume" },
2515 { IBMVFC_AE_ADAPTER_FAILED, "Adapter Failed" },
2516}; 2507};
2517 2508
2518static const char *unknown_ae = "Unknown async"; 2509static const struct ibmvfc_async_desc unknown_ae = {
2510 0, "Unknown async", IBMVFC_DEFAULT_LOG_LEVEL
2511};
2519 2512
2520/** 2513/**
2521 * ibmvfc_get_ae_desc - Get text description for async event 2514 * ibmvfc_get_ae_desc - Get text description for async event
2522 * @ae: async event 2515 * @ae: async event
2523 * 2516 *
2524 **/ 2517 **/
2525static const char *ibmvfc_get_ae_desc(u64 ae) 2518static const struct ibmvfc_async_desc *ibmvfc_get_ae_desc(u64 ae)
2526{ 2519{
2527 int i; 2520 int i;
2528 2521
2529 for (i = 0; i < ARRAY_SIZE(ae_desc); i++) 2522 for (i = 0; i < ARRAY_SIZE(ae_desc); i++)
2530 if (ae_desc[i].ae == ae) 2523 if (ae_desc[i].ae == ae)
2531 return ae_desc[i].desc; 2524 return &ae_desc[i];
2525
2526 return &unknown_ae;
2527}
2528
2529static const struct {
2530 enum ibmvfc_ae_link_state state;
2531 const char *desc;
2532} link_desc [] = {
2533 { IBMVFC_AE_LS_LINK_UP, " link up" },
2534 { IBMVFC_AE_LS_LINK_BOUNCED, " link bounced" },
2535 { IBMVFC_AE_LS_LINK_DOWN, " link down" },
2536 { IBMVFC_AE_LS_LINK_DEAD, " link dead" },
2537};
2532 2538
2533 return unknown_ae; 2539/**
2540 * ibmvfc_get_link_state - Get text description for link state
2541 * @state: link state
2542 *
2543 **/
2544static const char *ibmvfc_get_link_state(enum ibmvfc_ae_link_state state)
2545{
2546 int i;
2547
2548 for (i = 0; i < ARRAY_SIZE(link_desc); i++)
2549 if (link_desc[i].state == state)
2550 return link_desc[i].desc;
2551
2552 return "";
2534} 2553}
2535 2554
2536/** 2555/**
@@ -2542,11 +2561,12 @@ static const char *ibmvfc_get_ae_desc(u64 ae)
2542static void ibmvfc_handle_async(struct ibmvfc_async_crq *crq, 2561static void ibmvfc_handle_async(struct ibmvfc_async_crq *crq,
2543 struct ibmvfc_host *vhost) 2562 struct ibmvfc_host *vhost)
2544{ 2563{
2545 const char *desc = ibmvfc_get_ae_desc(crq->event); 2564 const struct ibmvfc_async_desc *desc = ibmvfc_get_ae_desc(crq->event);
2546 struct ibmvfc_target *tgt; 2565 struct ibmvfc_target *tgt;
2547 2566
2548 ibmvfc_log(vhost, 3, "%s event received. scsi_id: %llx, wwpn: %llx," 2567 ibmvfc_log(vhost, desc->log_level, "%s event received. scsi_id: %llx, wwpn: %llx,"
2549 " node_name: %llx\n", desc, crq->scsi_id, crq->wwpn, crq->node_name); 2568 " node_name: %llx%s\n", desc->desc, crq->scsi_id, crq->wwpn, crq->node_name,
2569 ibmvfc_get_link_state(crq->link_state));
2550 2570
2551 switch (crq->event) { 2571 switch (crq->event) {
2552 case IBMVFC_AE_RESUME: 2572 case IBMVFC_AE_RESUME:
@@ -2788,7 +2808,6 @@ static int ibmvfc_target_alloc(struct scsi_target *starget)
2788static int ibmvfc_slave_configure(struct scsi_device *sdev) 2808static int ibmvfc_slave_configure(struct scsi_device *sdev)
2789{ 2809{
2790 struct Scsi_Host *shost = sdev->host; 2810 struct Scsi_Host *shost = sdev->host;
2791 struct fc_rport *rport = starget_to_rport(sdev->sdev_target);
2792 unsigned long flags = 0; 2811 unsigned long flags = 0;
2793 2812
2794 spin_lock_irqsave(shost->host_lock, flags); 2813 spin_lock_irqsave(shost->host_lock, flags);
@@ -2800,8 +2819,6 @@ static int ibmvfc_slave_configure(struct scsi_device *sdev)
2800 scsi_activate_tcq(sdev, sdev->queue_depth); 2819 scsi_activate_tcq(sdev, sdev->queue_depth);
2801 } else 2820 } else
2802 scsi_deactivate_tcq(sdev, sdev->queue_depth); 2821 scsi_deactivate_tcq(sdev, sdev->queue_depth);
2803
2804 rport->dev_loss_tmo = dev_loss_tmo;
2805 spin_unlock_irqrestore(shost->host_lock, flags); 2822 spin_unlock_irqrestore(shost->host_lock, flags);
2806 return 0; 2823 return 0;
2807} 2824}
@@ -4285,8 +4302,10 @@ static void ibmvfc_do_work(struct ibmvfc_host *vhost)
4285 spin_unlock_irqrestore(vhost->host->host_lock, flags); 4302 spin_unlock_irqrestore(vhost->host->host_lock, flags);
4286 rc = ibmvfc_reset_crq(vhost); 4303 rc = ibmvfc_reset_crq(vhost);
4287 spin_lock_irqsave(vhost->host->host_lock, flags); 4304 spin_lock_irqsave(vhost->host->host_lock, flags);
4288 if (rc || (rc = ibmvfc_send_crq_init(vhost)) || 4305 if (rc == H_CLOSED)
4289 (rc = vio_enable_interrupts(to_vio_dev(vhost->dev)))) { 4306 vio_enable_interrupts(to_vio_dev(vhost->dev));
4307 else if (rc || (rc = ibmvfc_send_crq_init(vhost)) ||
4308 (rc = vio_enable_interrupts(to_vio_dev(vhost->dev)))) {
4290 ibmvfc_link_down(vhost, IBMVFC_LINK_DEAD); 4309 ibmvfc_link_down(vhost, IBMVFC_LINK_DEAD);
4291 dev_err(vhost->dev, "Error after reset (rc=%d)\n", rc); 4310 dev_err(vhost->dev, "Error after reset (rc=%d)\n", rc);
4292 } 4311 }
@@ -4744,6 +4763,8 @@ static int ibmvfc_probe(struct vio_dev *vdev, const struct vio_device_id *id)
4744 if ((rc = scsi_add_host(shost, dev))) 4763 if ((rc = scsi_add_host(shost, dev)))
4745 goto release_event_pool; 4764 goto release_event_pool;
4746 4765
4766 fc_host_dev_loss_tmo(shost) = IBMVFC_DEV_LOSS_TMO;
4767
4747 if ((rc = ibmvfc_create_trace_file(&shost->shost_dev.kobj, 4768 if ((rc = ibmvfc_create_trace_file(&shost->shost_dev.kobj,
4748 &ibmvfc_trace_attr))) { 4769 &ibmvfc_trace_attr))) {
4749 dev_err(dev, "Failed to create trace file. rc=%d\n", rc); 4770 dev_err(dev, "Failed to create trace file. rc=%d\n", rc);