diff options
Diffstat (limited to 'drivers/scsi/ibmvscsi/ibmvfc.c')
-rw-r--r-- | drivers/scsi/ibmvscsi/ibmvfc.c | 91 |
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; | |||
50 | static unsigned int max_targets = IBMVFC_MAX_TARGETS; | 50 | static unsigned int max_targets = IBMVFC_MAX_TARGETS; |
51 | static unsigned int max_requests = IBMVFC_MAX_REQUESTS_DEFAULT; | 51 | static unsigned int max_requests = IBMVFC_MAX_REQUESTS_DEFAULT; |
52 | static unsigned int disc_threads = IBMVFC_MAX_DISC_THREADS; | 52 | static unsigned int disc_threads = IBMVFC_MAX_DISC_THREADS; |
53 | static unsigned int dev_loss_tmo = IBMVFC_DEV_LOSS_TMO; | ||
54 | static unsigned int ibmvfc_debug = IBMVFC_DEBUG; | 53 | static unsigned int ibmvfc_debug = IBMVFC_DEBUG; |
55 | static unsigned int log_level = IBMVFC_DEFAULT_LOG_LEVEL; | 54 | static unsigned int log_level = IBMVFC_DEFAULT_LOG_LEVEL; |
56 | static LIST_HEAD(ibmvfc_head); | 55 | static LIST_HEAD(ibmvfc_head); |
@@ -84,11 +83,6 @@ MODULE_PARM_DESC(disc_threads, "Number of device discovery threads to use. " | |||
84 | module_param_named(debug, ibmvfc_debug, uint, S_IRUGO | S_IWUSR); | 83 | module_param_named(debug, ibmvfc_debug, uint, S_IRUGO | S_IWUSR); |
85 | MODULE_PARM_DESC(debug, "Enable driver debug information. " | 84 | MODULE_PARM_DESC(debug, "Enable driver debug information. " |
86 | "[Default=" __stringify(IBMVFC_DEBUG) "]"); | 85 | "[Default=" __stringify(IBMVFC_DEBUG) "]"); |
87 | module_param_named(dev_loss_tmo, dev_loss_tmo, uint, S_IRUGO | S_IWUSR); | ||
88 | MODULE_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) "]"); | ||
92 | module_param_named(log_level, log_level, uint, 0); | 86 | module_param_named(log_level, log_level, uint, 0); |
93 | MODULE_PARM_DESC(log_level, "Set to 0 - 4 for increasing verbosity of device driver. " | 87 | MODULE_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 | ||
2499 | static const struct { | 2493 | static 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 | ||
2518 | static const char *unknown_ae = "Unknown async"; | 2509 | static 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 | **/ |
2525 | static const char *ibmvfc_get_ae_desc(u64 ae) | 2518 | static 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 | |||
2529 | static 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 | **/ | ||
2544 | static 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) | |||
2542 | static void ibmvfc_handle_async(struct ibmvfc_async_crq *crq, | 2561 | static 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) | |||
2788 | static int ibmvfc_slave_configure(struct scsi_device *sdev) | 2808 | static 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); |