diff options
Diffstat (limited to 'drivers/scsi/libsas/sas_init.c')
| -rw-r--r-- | drivers/scsi/libsas/sas_init.c | 33 |
1 files changed, 32 insertions, 1 deletions
diff --git a/drivers/scsi/libsas/sas_init.c b/drivers/scsi/libsas/sas_init.c index e04f6d6f5aff..22bfc025ae81 100644 --- a/drivers/scsi/libsas/sas_init.c +++ b/drivers/scsi/libsas/sas_init.c | |||
| @@ -123,6 +123,8 @@ int sas_register_ha(struct sas_ha_struct *sas_ha) | |||
| 123 | INIT_LIST_HEAD(&sas_ha->defer_q); | 123 | INIT_LIST_HEAD(&sas_ha->defer_q); |
| 124 | INIT_LIST_HEAD(&sas_ha->eh_dev_q); | 124 | INIT_LIST_HEAD(&sas_ha->eh_dev_q); |
| 125 | 125 | ||
| 126 | sas_ha->event_thres = SAS_PHY_SHUTDOWN_THRES; | ||
| 127 | |||
| 126 | error = sas_register_phys(sas_ha); | 128 | error = sas_register_phys(sas_ha); |
| 127 | if (error) { | 129 | if (error) { |
| 128 | printk(KERN_NOTICE "couldn't register sas phys:%d\n", error); | 130 | printk(KERN_NOTICE "couldn't register sas phys:%d\n", error); |
| @@ -557,14 +559,43 @@ EXPORT_SYMBOL_GPL(sas_domain_attach_transport); | |||
| 557 | 559 | ||
| 558 | struct asd_sas_event *sas_alloc_event(struct asd_sas_phy *phy) | 560 | struct asd_sas_event *sas_alloc_event(struct asd_sas_phy *phy) |
| 559 | { | 561 | { |
| 562 | struct asd_sas_event *event; | ||
| 560 | gfp_t flags = in_interrupt() ? GFP_ATOMIC : GFP_KERNEL; | 563 | gfp_t flags = in_interrupt() ? GFP_ATOMIC : GFP_KERNEL; |
| 564 | struct sas_ha_struct *sas_ha = phy->ha; | ||
| 565 | struct sas_internal *i = | ||
| 566 | to_sas_internal(sas_ha->core.shost->transportt); | ||
| 567 | |||
| 568 | event = kmem_cache_zalloc(sas_event_cache, flags); | ||
| 569 | if (!event) | ||
| 570 | return NULL; | ||
| 561 | 571 | ||
| 562 | return kmem_cache_zalloc(sas_event_cache, flags); | 572 | atomic_inc(&phy->event_nr); |
| 573 | |||
| 574 | if (atomic_read(&phy->event_nr) > phy->ha->event_thres) { | ||
| 575 | if (i->dft->lldd_control_phy) { | ||
| 576 | if (cmpxchg(&phy->in_shutdown, 0, 1) == 0) { | ||
| 577 | sas_printk("The phy%02d bursting events, shut it down.\n", | ||
| 578 | phy->id); | ||
| 579 | sas_notify_phy_event(phy, PHYE_SHUTDOWN); | ||
| 580 | } | ||
| 581 | } else { | ||
| 582 | /* Do not support PHY control, stop allocating events */ | ||
| 583 | WARN_ONCE(1, "PHY control not supported.\n"); | ||
| 584 | kmem_cache_free(sas_event_cache, event); | ||
| 585 | atomic_dec(&phy->event_nr); | ||
| 586 | event = NULL; | ||
| 587 | } | ||
| 588 | } | ||
| 589 | |||
| 590 | return event; | ||
| 563 | } | 591 | } |
| 564 | 592 | ||
| 565 | void sas_free_event(struct asd_sas_event *event) | 593 | void sas_free_event(struct asd_sas_event *event) |
| 566 | { | 594 | { |
| 595 | struct asd_sas_phy *phy = event->phy; | ||
| 596 | |||
| 567 | kmem_cache_free(sas_event_cache, event); | 597 | kmem_cache_free(sas_event_cache, event); |
| 598 | atomic_dec(&phy->event_nr); | ||
| 568 | } | 599 | } |
| 569 | 600 | ||
| 570 | /* ---------- SAS Class register/unregister ---------- */ | 601 | /* ---------- SAS Class register/unregister ---------- */ |
