aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libsas/sas_init.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/libsas/sas_init.c')
-rw-r--r--drivers/scsi/libsas/sas_init.c33
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
558struct asd_sas_event *sas_alloc_event(struct asd_sas_phy *phy) 560struct 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
565void sas_free_event(struct asd_sas_event *event) 593void 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 ---------- */