root/drivers/scsi/libsas/sas_init.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. sas_alloc_task
  2. sas_alloc_slow_task
  3. sas_free_task
  4. sas_hash_addr
  5. sas_register_ha
  6. sas_disable_events
  7. sas_unregister_ha
  8. sas_get_linkerrors
  9. sas_try_ata_reset
  10. transport_sas_phy_reset
  11. sas_phy_enable
  12. sas_phy_reset
  13. sas_set_phy_speed
  14. sas_prep_resume_ha
  15. phys_suspended
  16. sas_resume_ha
  17. sas_suspend_ha
  18. sas_phy_release
  19. phy_reset_work
  20. phy_enable_work
  21. sas_phy_setup
  22. queue_phy_reset
  23. queue_phy_enable
  24. phy_event_threshold_show
  25. phy_event_threshold_store
  26. sas_domain_attach_transport
  27. sas_alloc_event
  28. sas_free_event
  29. sas_class_init
  30. sas_class_exit

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Serial Attached SCSI (SAS) Transport Layer initialization
   4  *
   5  * Copyright (C) 2005 Adaptec, Inc.  All rights reserved.
   6  * Copyright (C) 2005 Luben Tuikov <luben_tuikov@adaptec.com>
   7  */
   8 
   9 #include <linux/module.h>
  10 #include <linux/slab.h>
  11 #include <linux/init.h>
  12 #include <linux/device.h>
  13 #include <linux/spinlock.h>
  14 #include <scsi/sas_ata.h>
  15 #include <scsi/scsi_host.h>
  16 #include <scsi/scsi_device.h>
  17 #include <scsi/scsi_transport.h>
  18 #include <scsi/scsi_transport_sas.h>
  19 
  20 #include "sas_internal.h"
  21 
  22 #include "../scsi_sas_internal.h"
  23 
  24 static struct kmem_cache *sas_task_cache;
  25 static struct kmem_cache *sas_event_cache;
  26 
  27 struct sas_task *sas_alloc_task(gfp_t flags)
  28 {
  29         struct sas_task *task = kmem_cache_zalloc(sas_task_cache, flags);
  30 
  31         if (task) {
  32                 spin_lock_init(&task->task_state_lock);
  33                 task->task_state_flags = SAS_TASK_STATE_PENDING;
  34         }
  35 
  36         return task;
  37 }
  38 EXPORT_SYMBOL_GPL(sas_alloc_task);
  39 
  40 struct sas_task *sas_alloc_slow_task(gfp_t flags)
  41 {
  42         struct sas_task *task = sas_alloc_task(flags);
  43         struct sas_task_slow *slow = kmalloc(sizeof(*slow), flags);
  44 
  45         if (!task || !slow) {
  46                 if (task)
  47                         kmem_cache_free(sas_task_cache, task);
  48                 kfree(slow);
  49                 return NULL;
  50         }
  51 
  52         task->slow_task = slow;
  53         slow->task = task;
  54         timer_setup(&slow->timer, NULL, 0);
  55         init_completion(&slow->completion);
  56 
  57         return task;
  58 }
  59 EXPORT_SYMBOL_GPL(sas_alloc_slow_task);
  60 
  61 void sas_free_task(struct sas_task *task)
  62 {
  63         if (task) {
  64                 kfree(task->slow_task);
  65                 kmem_cache_free(sas_task_cache, task);
  66         }
  67 }
  68 EXPORT_SYMBOL_GPL(sas_free_task);
  69 
  70 /*------------ SAS addr hash -----------*/
  71 void sas_hash_addr(u8 *hashed, const u8 *sas_addr)
  72 {
  73         const u32 poly = 0x00DB2777;
  74         u32 r = 0;
  75         int i;
  76 
  77         for (i = 0; i < SAS_ADDR_SIZE; i++) {
  78                 int b;
  79 
  80                 for (b = (SAS_ADDR_SIZE - 1); b >= 0; b--) {
  81                         r <<= 1;
  82                         if ((1 << b) & sas_addr[i]) {
  83                                 if (!(r & 0x01000000))
  84                                         r ^= poly;
  85                         } else if (r & 0x01000000) {
  86                                 r ^= poly;
  87                         }
  88                 }
  89         }
  90 
  91         hashed[0] = (r >> 16) & 0xFF;
  92         hashed[1] = (r >> 8) & 0xFF;
  93         hashed[2] = r & 0xFF;
  94 }
  95 
  96 int sas_register_ha(struct sas_ha_struct *sas_ha)
  97 {
  98         char name[64];
  99         int error = 0;
 100 
 101         mutex_init(&sas_ha->disco_mutex);
 102         spin_lock_init(&sas_ha->phy_port_lock);
 103         sas_hash_addr(sas_ha->hashed_sas_addr, sas_ha->sas_addr);
 104 
 105         set_bit(SAS_HA_REGISTERED, &sas_ha->state);
 106         spin_lock_init(&sas_ha->lock);
 107         mutex_init(&sas_ha->drain_mutex);
 108         init_waitqueue_head(&sas_ha->eh_wait_q);
 109         INIT_LIST_HEAD(&sas_ha->defer_q);
 110         INIT_LIST_HEAD(&sas_ha->eh_dev_q);
 111 
 112         sas_ha->event_thres = SAS_PHY_SHUTDOWN_THRES;
 113 
 114         error = sas_register_phys(sas_ha);
 115         if (error) {
 116                 pr_notice("couldn't register sas phys:%d\n", error);
 117                 return error;
 118         }
 119 
 120         error = sas_register_ports(sas_ha);
 121         if (error) {
 122                 pr_notice("couldn't register sas ports:%d\n", error);
 123                 goto Undo_phys;
 124         }
 125 
 126         error = sas_init_events(sas_ha);
 127         if (error) {
 128                 pr_notice("couldn't start event thread:%d\n", error);
 129                 goto Undo_ports;
 130         }
 131 
 132         error = -ENOMEM;
 133         snprintf(name, sizeof(name), "%s_event_q", dev_name(sas_ha->dev));
 134         sas_ha->event_q = create_singlethread_workqueue(name);
 135         if (!sas_ha->event_q)
 136                 goto Undo_ports;
 137 
 138         snprintf(name, sizeof(name), "%s_disco_q", dev_name(sas_ha->dev));
 139         sas_ha->disco_q = create_singlethread_workqueue(name);
 140         if (!sas_ha->disco_q)
 141                 goto Undo_event_q;
 142 
 143         INIT_LIST_HEAD(&sas_ha->eh_done_q);
 144         INIT_LIST_HEAD(&sas_ha->eh_ata_q);
 145 
 146         return 0;
 147 
 148 Undo_event_q:
 149         destroy_workqueue(sas_ha->event_q);
 150 Undo_ports:
 151         sas_unregister_ports(sas_ha);
 152 Undo_phys:
 153 
 154         return error;
 155 }
 156 
 157 static void sas_disable_events(struct sas_ha_struct *sas_ha)
 158 {
 159         /* Set the state to unregistered to avoid further unchained
 160          * events to be queued, and flush any in-progress drainers
 161          */
 162         mutex_lock(&sas_ha->drain_mutex);
 163         spin_lock_irq(&sas_ha->lock);
 164         clear_bit(SAS_HA_REGISTERED, &sas_ha->state);
 165         spin_unlock_irq(&sas_ha->lock);
 166         __sas_drain_work(sas_ha);
 167         mutex_unlock(&sas_ha->drain_mutex);
 168 }
 169 
 170 int sas_unregister_ha(struct sas_ha_struct *sas_ha)
 171 {
 172         sas_disable_events(sas_ha);
 173         sas_unregister_ports(sas_ha);
 174 
 175         /* flush unregistration work */
 176         mutex_lock(&sas_ha->drain_mutex);
 177         __sas_drain_work(sas_ha);
 178         mutex_unlock(&sas_ha->drain_mutex);
 179 
 180         destroy_workqueue(sas_ha->disco_q);
 181         destroy_workqueue(sas_ha->event_q);
 182 
 183         return 0;
 184 }
 185 
 186 static int sas_get_linkerrors(struct sas_phy *phy)
 187 {
 188         if (scsi_is_sas_phy_local(phy)) {
 189                 struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
 190                 struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(shost);
 191                 struct asd_sas_phy *asd_phy = sas_ha->sas_phy[phy->number];
 192                 struct sas_internal *i =
 193                         to_sas_internal(sas_ha->core.shost->transportt);
 194 
 195                 return i->dft->lldd_control_phy(asd_phy, PHY_FUNC_GET_EVENTS, NULL);
 196         }
 197 
 198         return sas_smp_get_phy_events(phy);
 199 }
 200 
 201 int sas_try_ata_reset(struct asd_sas_phy *asd_phy)
 202 {
 203         struct domain_device *dev = NULL;
 204 
 205         /* try to route user requested link resets through libata */
 206         if (asd_phy->port)
 207                 dev = asd_phy->port->port_dev;
 208 
 209         /* validate that dev has been probed */
 210         if (dev)
 211                 dev = sas_find_dev_by_rphy(dev->rphy);
 212 
 213         if (dev && dev_is_sata(dev)) {
 214                 sas_ata_schedule_reset(dev);
 215                 sas_ata_wait_eh(dev);
 216                 return 0;
 217         }
 218 
 219         return -ENODEV;
 220 }
 221 
 222 /*
 223  * transport_sas_phy_reset - reset a phy and permit libata to manage the link
 224  *
 225  * phy reset request via sysfs in host workqueue context so we know we
 226  * can block on eh and safely traverse the domain_device topology
 227  */
 228 static int transport_sas_phy_reset(struct sas_phy *phy, int hard_reset)
 229 {
 230         enum phy_func reset_type;
 231 
 232         if (hard_reset)
 233                 reset_type = PHY_FUNC_HARD_RESET;
 234         else
 235                 reset_type = PHY_FUNC_LINK_RESET;
 236 
 237         if (scsi_is_sas_phy_local(phy)) {
 238                 struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
 239                 struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(shost);
 240                 struct asd_sas_phy *asd_phy = sas_ha->sas_phy[phy->number];
 241                 struct sas_internal *i =
 242                         to_sas_internal(sas_ha->core.shost->transportt);
 243 
 244                 if (!hard_reset && sas_try_ata_reset(asd_phy) == 0)
 245                         return 0;
 246                 return i->dft->lldd_control_phy(asd_phy, reset_type, NULL);
 247         } else {
 248                 struct sas_rphy *rphy = dev_to_rphy(phy->dev.parent);
 249                 struct domain_device *ddev = sas_find_dev_by_rphy(rphy);
 250                 struct domain_device *ata_dev = sas_ex_to_ata(ddev, phy->number);
 251 
 252                 if (ata_dev && !hard_reset) {
 253                         sas_ata_schedule_reset(ata_dev);
 254                         sas_ata_wait_eh(ata_dev);
 255                         return 0;
 256                 } else
 257                         return sas_smp_phy_control(ddev, phy->number, reset_type, NULL);
 258         }
 259 }
 260 
 261 static int sas_phy_enable(struct sas_phy *phy, int enable)
 262 {
 263         int ret;
 264         enum phy_func cmd;
 265 
 266         if (enable)
 267                 cmd = PHY_FUNC_LINK_RESET;
 268         else
 269                 cmd = PHY_FUNC_DISABLE;
 270 
 271         if (scsi_is_sas_phy_local(phy)) {
 272                 struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
 273                 struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(shost);
 274                 struct asd_sas_phy *asd_phy = sas_ha->sas_phy[phy->number];
 275                 struct sas_internal *i =
 276                         to_sas_internal(sas_ha->core.shost->transportt);
 277 
 278                 if (enable)
 279                         ret = transport_sas_phy_reset(phy, 0);
 280                 else
 281                         ret = i->dft->lldd_control_phy(asd_phy, cmd, NULL);
 282         } else {
 283                 struct sas_rphy *rphy = dev_to_rphy(phy->dev.parent);
 284                 struct domain_device *ddev = sas_find_dev_by_rphy(rphy);
 285 
 286                 if (enable)
 287                         ret = transport_sas_phy_reset(phy, 0);
 288                 else
 289                         ret = sas_smp_phy_control(ddev, phy->number, cmd, NULL);
 290         }
 291         return ret;
 292 }
 293 
 294 int sas_phy_reset(struct sas_phy *phy, int hard_reset)
 295 {
 296         int ret;
 297         enum phy_func reset_type;
 298 
 299         if (!phy->enabled)
 300                 return -ENODEV;
 301 
 302         if (hard_reset)
 303                 reset_type = PHY_FUNC_HARD_RESET;
 304         else
 305                 reset_type = PHY_FUNC_LINK_RESET;
 306 
 307         if (scsi_is_sas_phy_local(phy)) {
 308                 struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
 309                 struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(shost);
 310                 struct asd_sas_phy *asd_phy = sas_ha->sas_phy[phy->number];
 311                 struct sas_internal *i =
 312                         to_sas_internal(sas_ha->core.shost->transportt);
 313 
 314                 ret = i->dft->lldd_control_phy(asd_phy, reset_type, NULL);
 315         } else {
 316                 struct sas_rphy *rphy = dev_to_rphy(phy->dev.parent);
 317                 struct domain_device *ddev = sas_find_dev_by_rphy(rphy);
 318                 ret = sas_smp_phy_control(ddev, phy->number, reset_type, NULL);
 319         }
 320         return ret;
 321 }
 322 
 323 int sas_set_phy_speed(struct sas_phy *phy,
 324                       struct sas_phy_linkrates *rates)
 325 {
 326         int ret;
 327 
 328         if ((rates->minimum_linkrate &&
 329              rates->minimum_linkrate > phy->maximum_linkrate) ||
 330             (rates->maximum_linkrate &&
 331              rates->maximum_linkrate < phy->minimum_linkrate))
 332                 return -EINVAL;
 333 
 334         if (rates->minimum_linkrate &&
 335             rates->minimum_linkrate < phy->minimum_linkrate_hw)
 336                 rates->minimum_linkrate = phy->minimum_linkrate_hw;
 337 
 338         if (rates->maximum_linkrate &&
 339             rates->maximum_linkrate > phy->maximum_linkrate_hw)
 340                 rates->maximum_linkrate = phy->maximum_linkrate_hw;
 341 
 342         if (scsi_is_sas_phy_local(phy)) {
 343                 struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
 344                 struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(shost);
 345                 struct asd_sas_phy *asd_phy = sas_ha->sas_phy[phy->number];
 346                 struct sas_internal *i =
 347                         to_sas_internal(sas_ha->core.shost->transportt);
 348 
 349                 ret = i->dft->lldd_control_phy(asd_phy, PHY_FUNC_SET_LINK_RATE,
 350                                                rates);
 351         } else {
 352                 struct sas_rphy *rphy = dev_to_rphy(phy->dev.parent);
 353                 struct domain_device *ddev = sas_find_dev_by_rphy(rphy);
 354                 ret = sas_smp_phy_control(ddev, phy->number,
 355                                           PHY_FUNC_LINK_RESET, rates);
 356 
 357         }
 358 
 359         return ret;
 360 }
 361 
 362 void sas_prep_resume_ha(struct sas_ha_struct *ha)
 363 {
 364         int i;
 365 
 366         set_bit(SAS_HA_REGISTERED, &ha->state);
 367 
 368         /* clear out any stale link events/data from the suspension path */
 369         for (i = 0; i < ha->num_phys; i++) {
 370                 struct asd_sas_phy *phy = ha->sas_phy[i];
 371 
 372                 memset(phy->attached_sas_addr, 0, SAS_ADDR_SIZE);
 373                 phy->frame_rcvd_size = 0;
 374         }
 375 }
 376 EXPORT_SYMBOL(sas_prep_resume_ha);
 377 
 378 static int phys_suspended(struct sas_ha_struct *ha)
 379 {
 380         int i, rc = 0;
 381 
 382         for (i = 0; i < ha->num_phys; i++) {
 383                 struct asd_sas_phy *phy = ha->sas_phy[i];
 384 
 385                 if (phy->suspended)
 386                         rc++;
 387         }
 388 
 389         return rc;
 390 }
 391 
 392 void sas_resume_ha(struct sas_ha_struct *ha)
 393 {
 394         const unsigned long tmo = msecs_to_jiffies(25000);
 395         int i;
 396 
 397         /* deform ports on phys that did not resume
 398          * at this point we may be racing the phy coming back (as posted
 399          * by the lldd).  So we post the event and once we are in the
 400          * libsas context check that the phy remains suspended before
 401          * tearing it down.
 402          */
 403         i = phys_suspended(ha);
 404         if (i)
 405                 dev_info(ha->dev, "waiting up to 25 seconds for %d phy%s to resume\n",
 406                          i, i > 1 ? "s" : "");
 407         wait_event_timeout(ha->eh_wait_q, phys_suspended(ha) == 0, tmo);
 408         for (i = 0; i < ha->num_phys; i++) {
 409                 struct asd_sas_phy *phy = ha->sas_phy[i];
 410 
 411                 if (phy->suspended) {
 412                         dev_warn(&phy->phy->dev, "resume timeout\n");
 413                         sas_notify_phy_event(phy, PHYE_RESUME_TIMEOUT);
 414                 }
 415         }
 416 
 417         /* all phys are back up or timed out, turn on i/o so we can
 418          * flush out disks that did not return
 419          */
 420         scsi_unblock_requests(ha->core.shost);
 421         sas_drain_work(ha);
 422 }
 423 EXPORT_SYMBOL(sas_resume_ha);
 424 
 425 void sas_suspend_ha(struct sas_ha_struct *ha)
 426 {
 427         int i;
 428 
 429         sas_disable_events(ha);
 430         scsi_block_requests(ha->core.shost);
 431         for (i = 0; i < ha->num_phys; i++) {
 432                 struct asd_sas_port *port = ha->sas_port[i];
 433 
 434                 sas_discover_event(port, DISCE_SUSPEND);
 435         }
 436 
 437         /* flush suspend events while unregistered */
 438         mutex_lock(&ha->drain_mutex);
 439         __sas_drain_work(ha);
 440         mutex_unlock(&ha->drain_mutex);
 441 }
 442 EXPORT_SYMBOL(sas_suspend_ha);
 443 
 444 static void sas_phy_release(struct sas_phy *phy)
 445 {
 446         kfree(phy->hostdata);
 447         phy->hostdata = NULL;
 448 }
 449 
 450 static void phy_reset_work(struct work_struct *work)
 451 {
 452         struct sas_phy_data *d = container_of(work, typeof(*d), reset_work.work);
 453 
 454         d->reset_result = transport_sas_phy_reset(d->phy, d->hard_reset);
 455 }
 456 
 457 static void phy_enable_work(struct work_struct *work)
 458 {
 459         struct sas_phy_data *d = container_of(work, typeof(*d), enable_work.work);
 460 
 461         d->enable_result = sas_phy_enable(d->phy, d->enable);
 462 }
 463 
 464 static int sas_phy_setup(struct sas_phy *phy)
 465 {
 466         struct sas_phy_data *d = kzalloc(sizeof(*d), GFP_KERNEL);
 467 
 468         if (!d)
 469                 return -ENOMEM;
 470 
 471         mutex_init(&d->event_lock);
 472         INIT_SAS_WORK(&d->reset_work, phy_reset_work);
 473         INIT_SAS_WORK(&d->enable_work, phy_enable_work);
 474         d->phy = phy;
 475         phy->hostdata = d;
 476 
 477         return 0;
 478 }
 479 
 480 static int queue_phy_reset(struct sas_phy *phy, int hard_reset)
 481 {
 482         struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
 483         struct sas_ha_struct *ha = SHOST_TO_SAS_HA(shost);
 484         struct sas_phy_data *d = phy->hostdata;
 485         int rc;
 486 
 487         if (!d)
 488                 return -ENOMEM;
 489 
 490         /* libsas workqueue coordinates ata-eh reset with discovery */
 491         mutex_lock(&d->event_lock);
 492         d->reset_result = 0;
 493         d->hard_reset = hard_reset;
 494 
 495         spin_lock_irq(&ha->lock);
 496         sas_queue_work(ha, &d->reset_work);
 497         spin_unlock_irq(&ha->lock);
 498 
 499         rc = sas_drain_work(ha);
 500         if (rc == 0)
 501                 rc = d->reset_result;
 502         mutex_unlock(&d->event_lock);
 503 
 504         return rc;
 505 }
 506 
 507 static int queue_phy_enable(struct sas_phy *phy, int enable)
 508 {
 509         struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
 510         struct sas_ha_struct *ha = SHOST_TO_SAS_HA(shost);
 511         struct sas_phy_data *d = phy->hostdata;
 512         int rc;
 513 
 514         if (!d)
 515                 return -ENOMEM;
 516 
 517         /* libsas workqueue coordinates ata-eh reset with discovery */
 518         mutex_lock(&d->event_lock);
 519         d->enable_result = 0;
 520         d->enable = enable;
 521 
 522         spin_lock_irq(&ha->lock);
 523         sas_queue_work(ha, &d->enable_work);
 524         spin_unlock_irq(&ha->lock);
 525 
 526         rc = sas_drain_work(ha);
 527         if (rc == 0)
 528                 rc = d->enable_result;
 529         mutex_unlock(&d->event_lock);
 530 
 531         return rc;
 532 }
 533 
 534 static struct sas_function_template sft = {
 535         .phy_enable = queue_phy_enable,
 536         .phy_reset = queue_phy_reset,
 537         .phy_setup = sas_phy_setup,
 538         .phy_release = sas_phy_release,
 539         .set_phy_speed = sas_set_phy_speed,
 540         .get_linkerrors = sas_get_linkerrors,
 541         .smp_handler = sas_smp_handler,
 542 };
 543 
 544 static inline ssize_t phy_event_threshold_show(struct device *dev,
 545                         struct device_attribute *attr, char *buf)
 546 {
 547         struct Scsi_Host *shost = class_to_shost(dev);
 548         struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
 549 
 550         return scnprintf(buf, PAGE_SIZE, "%u\n", sha->event_thres);
 551 }
 552 
 553 static inline ssize_t phy_event_threshold_store(struct device *dev,
 554                         struct device_attribute *attr,
 555                         const char *buf, size_t count)
 556 {
 557         struct Scsi_Host *shost = class_to_shost(dev);
 558         struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
 559 
 560         sha->event_thres = simple_strtol(buf, NULL, 10);
 561 
 562         /* threshold cannot be set too small */
 563         if (sha->event_thres < 32)
 564                 sha->event_thres = 32;
 565 
 566         return count;
 567 }
 568 
 569 DEVICE_ATTR(phy_event_threshold,
 570         S_IRUGO|S_IWUSR,
 571         phy_event_threshold_show,
 572         phy_event_threshold_store);
 573 EXPORT_SYMBOL_GPL(dev_attr_phy_event_threshold);
 574 
 575 struct scsi_transport_template *
 576 sas_domain_attach_transport(struct sas_domain_function_template *dft)
 577 {
 578         struct scsi_transport_template *stt = sas_attach_transport(&sft);
 579         struct sas_internal *i;
 580 
 581         if (!stt)
 582                 return stt;
 583 
 584         i = to_sas_internal(stt);
 585         i->dft = dft;
 586         stt->create_work_queue = 1;
 587         stt->eh_strategy_handler = sas_scsi_recover_host;
 588 
 589         return stt;
 590 }
 591 EXPORT_SYMBOL_GPL(sas_domain_attach_transport);
 592 
 593 
 594 struct asd_sas_event *sas_alloc_event(struct asd_sas_phy *phy)
 595 {
 596         struct asd_sas_event *event;
 597         gfp_t flags = in_interrupt() ? GFP_ATOMIC : GFP_KERNEL;
 598         struct sas_ha_struct *sas_ha = phy->ha;
 599         struct sas_internal *i =
 600                 to_sas_internal(sas_ha->core.shost->transportt);
 601 
 602         event = kmem_cache_zalloc(sas_event_cache, flags);
 603         if (!event)
 604                 return NULL;
 605 
 606         atomic_inc(&phy->event_nr);
 607 
 608         if (atomic_read(&phy->event_nr) > phy->ha->event_thres) {
 609                 if (i->dft->lldd_control_phy) {
 610                         if (cmpxchg(&phy->in_shutdown, 0, 1) == 0) {
 611                                 pr_notice("The phy%d bursting events, shut it down.\n",
 612                                           phy->id);
 613                                 sas_notify_phy_event(phy, PHYE_SHUTDOWN);
 614                         }
 615                 } else {
 616                         /* Do not support PHY control, stop allocating events */
 617                         WARN_ONCE(1, "PHY control not supported.\n");
 618                         kmem_cache_free(sas_event_cache, event);
 619                         atomic_dec(&phy->event_nr);
 620                         event = NULL;
 621                 }
 622         }
 623 
 624         return event;
 625 }
 626 
 627 void sas_free_event(struct asd_sas_event *event)
 628 {
 629         struct asd_sas_phy *phy = event->phy;
 630 
 631         kmem_cache_free(sas_event_cache, event);
 632         atomic_dec(&phy->event_nr);
 633 }
 634 
 635 /* ---------- SAS Class register/unregister ---------- */
 636 
 637 static int __init sas_class_init(void)
 638 {
 639         sas_task_cache = KMEM_CACHE(sas_task, SLAB_HWCACHE_ALIGN);
 640         if (!sas_task_cache)
 641                 goto out;
 642 
 643         sas_event_cache = KMEM_CACHE(asd_sas_event, SLAB_HWCACHE_ALIGN);
 644         if (!sas_event_cache)
 645                 goto free_task_kmem;
 646 
 647         return 0;
 648 free_task_kmem:
 649         kmem_cache_destroy(sas_task_cache);
 650 out:
 651         return -ENOMEM;
 652 }
 653 
 654 static void __exit sas_class_exit(void)
 655 {
 656         kmem_cache_destroy(sas_task_cache);
 657         kmem_cache_destroy(sas_event_cache);
 658 }
 659 
 660 MODULE_AUTHOR("Luben Tuikov <luben_tuikov@adaptec.com>");
 661 MODULE_DESCRIPTION("SAS Transport Layer");
 662 MODULE_LICENSE("GPL v2");
 663 
 664 module_init(sas_class_init);
 665 module_exit(sas_class_exit);
 666 
 667 EXPORT_SYMBOL_GPL(sas_register_ha);
 668 EXPORT_SYMBOL_GPL(sas_unregister_ha);

/* [<][>][^][v][top][bottom][index][help] */