linux/include/scsi/libsas.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0-only */
   2/*
   3 * SAS host prototypes and structures header file
   4 *
   5 * Copyright (C) 2005 Adaptec, Inc.  All rights reserved.
   6 * Copyright (C) 2005 Luben Tuikov <luben_tuikov@adaptec.com>
   7 */
   8
   9#ifndef _LIBSAS_H_
  10#define _LIBSAS_H_
  11
  12
  13#include <linux/timer.h>
  14#include <linux/pci.h>
  15#include <scsi/sas.h>
  16#include <linux/libata.h>
  17#include <linux/list.h>
  18#include <scsi/scsi_device.h>
  19#include <scsi/scsi_cmnd.h>
  20#include <scsi/scsi_transport_sas.h>
  21#include <linux/scatterlist.h>
  22#include <linux/slab.h>
  23
  24struct block_device;
  25
  26enum sas_class {
  27        SAS,
  28        EXPANDER
  29};
  30
  31enum sas_phy_role {
  32        PHY_ROLE_NONE = 0,
  33        PHY_ROLE_TARGET = 0x40,
  34        PHY_ROLE_INITIATOR = 0x80,
  35};
  36
  37enum sas_phy_type {
  38        PHY_TYPE_PHYSICAL,
  39        PHY_TYPE_VIRTUAL
  40};
  41
  42/* The events are mnemonically described in sas_dump.c
  43 * so when updating/adding events here, please also
  44 * update the other file too.
  45 */
  46enum port_event {
  47        PORTE_BYTES_DMAED     = 0U,
  48        PORTE_BROADCAST_RCVD,
  49        PORTE_LINK_RESET_ERR,
  50        PORTE_TIMER_EVENT,
  51        PORTE_HARD_RESET,
  52        PORT_NUM_EVENTS,
  53};
  54
  55enum phy_event {
  56        PHYE_LOSS_OF_SIGNAL   = 0U,
  57        PHYE_OOB_DONE,
  58        PHYE_OOB_ERROR,
  59        PHYE_SPINUP_HOLD,             /* hot plug SATA, no COMWAKE sent */
  60        PHYE_RESUME_TIMEOUT,
  61        PHYE_SHUTDOWN,
  62        PHY_NUM_EVENTS,
  63};
  64
  65enum discover_event {
  66        DISCE_DISCOVER_DOMAIN   = 0U,
  67        DISCE_REVALIDATE_DOMAIN,
  68        DISCE_SUSPEND,
  69        DISCE_RESUME,
  70        DISC_NUM_EVENTS,
  71};
  72
  73/* ---------- Expander Devices ---------- */
  74
  75#define to_dom_device(_obj) container_of(_obj, struct domain_device, dev_obj)
  76#define to_dev_attr(_attr)  container_of(_attr, struct domain_dev_attribute,\
  77                                         attr)
  78
  79enum routing_attribute {
  80        DIRECT_ROUTING,
  81        SUBTRACTIVE_ROUTING,
  82        TABLE_ROUTING,
  83};
  84
  85enum ex_phy_state {
  86        PHY_EMPTY,
  87        PHY_VACANT,
  88        PHY_NOT_PRESENT,
  89        PHY_DEVICE_DISCOVERED
  90};
  91
  92struct ex_phy {
  93        int    phy_id;
  94
  95        enum ex_phy_state phy_state;
  96
  97        enum sas_device_type attached_dev_type;
  98        enum sas_linkrate linkrate;
  99
 100        u8   attached_sata_host:1;
 101        u8   attached_sata_dev:1;
 102        u8   attached_sata_ps:1;
 103
 104        enum sas_protocol attached_tproto;
 105        enum sas_protocol attached_iproto;
 106
 107        u8   attached_sas_addr[SAS_ADDR_SIZE];
 108        u8   attached_phy_id;
 109
 110        int phy_change_count;
 111        enum routing_attribute routing_attr;
 112        u8   virtual:1;
 113
 114        int  last_da_index;
 115
 116        struct sas_phy *phy;
 117        struct sas_port *port;
 118};
 119
 120struct expander_device {
 121        struct list_head children;
 122
 123        int    ex_change_count;
 124        u16    max_route_indexes;
 125        u8     num_phys;
 126
 127        u8     t2t_supp:1;
 128        u8     configuring:1;
 129        u8     conf_route_table:1;
 130
 131        u8     enclosure_logical_id[8];
 132
 133        struct ex_phy *ex_phy;
 134        struct sas_port *parent_port;
 135
 136        struct mutex cmd_mutex;
 137};
 138
 139/* ---------- SATA device ---------- */
 140#define ATA_RESP_FIS_SIZE 24
 141
 142struct sata_device {
 143        unsigned int class;
 144        u8     port_no;        /* port number, if this is a PM (Port) */
 145
 146        struct ata_port *ap;
 147        struct ata_host *ata_host;
 148        struct smp_resp rps_resp ____cacheline_aligned; /* report_phy_sata_resp */
 149        u8     fis[ATA_RESP_FIS_SIZE];
 150};
 151
 152struct ssp_device {
 153        struct list_head eh_list_node; /* pending a user requested eh action */
 154        struct scsi_lun reset_lun;
 155};
 156
 157enum {
 158        SAS_DEV_GONE,
 159        SAS_DEV_FOUND, /* device notified to lldd */
 160        SAS_DEV_DESTROY,
 161        SAS_DEV_EH_PENDING,
 162        SAS_DEV_LU_RESET,
 163        SAS_DEV_RESET,
 164};
 165
 166struct domain_device {
 167        spinlock_t done_lock;
 168        enum sas_device_type dev_type;
 169
 170        enum sas_linkrate linkrate;
 171        enum sas_linkrate min_linkrate;
 172        enum sas_linkrate max_linkrate;
 173
 174        int  pathways;
 175
 176        struct domain_device *parent;
 177        struct list_head siblings; /* devices on the same level */
 178        struct asd_sas_port *port;        /* shortcut to root of the tree */
 179        struct sas_phy *phy;
 180
 181        struct list_head dev_list_node;
 182        struct list_head disco_list_node; /* awaiting probe or destruct */
 183
 184        enum sas_protocol    iproto;
 185        enum sas_protocol    tproto;
 186
 187        struct sas_rphy *rphy;
 188
 189        u8  sas_addr[SAS_ADDR_SIZE];
 190        u8  hashed_sas_addr[HASHED_SAS_ADDR_SIZE];
 191
 192        u8  frame_rcvd[32];
 193
 194        union {
 195                struct expander_device ex_dev;
 196                struct sata_device     sata_dev; /* STP & directly attached */
 197                struct ssp_device      ssp_dev;
 198        };
 199
 200        void *lldd_dev;
 201        unsigned long state;
 202        struct kref kref;
 203};
 204
 205struct sas_work {
 206        struct list_head drain_node;
 207        struct work_struct work;
 208};
 209
 210static inline bool dev_is_expander(enum sas_device_type type)
 211{
 212        return type == SAS_EDGE_EXPANDER_DEVICE ||
 213               type == SAS_FANOUT_EXPANDER_DEVICE;
 214}
 215
 216static inline void INIT_SAS_WORK(struct sas_work *sw, void (*fn)(struct work_struct *))
 217{
 218        INIT_WORK(&sw->work, fn);
 219        INIT_LIST_HEAD(&sw->drain_node);
 220}
 221
 222struct sas_discovery_event {
 223        struct sas_work work;
 224        struct asd_sas_port *port;
 225};
 226
 227static inline struct sas_discovery_event *to_sas_discovery_event(struct work_struct *work)
 228{
 229        struct sas_discovery_event *ev = container_of(work, typeof(*ev), work.work);
 230
 231        return ev;
 232}
 233
 234struct sas_discovery {
 235        struct sas_discovery_event disc_work[DISC_NUM_EVENTS];
 236        unsigned long    pending;
 237        u8     fanout_sas_addr[SAS_ADDR_SIZE];
 238        u8     eeds_a[SAS_ADDR_SIZE];
 239        u8     eeds_b[SAS_ADDR_SIZE];
 240        int    max_level;
 241};
 242
 243/* The port struct is Class:RW, driver:RO */
 244struct asd_sas_port {
 245/* private: */
 246        struct sas_discovery disc;
 247        struct domain_device *port_dev;
 248        spinlock_t dev_list_lock;
 249        struct list_head dev_list;
 250        struct list_head disco_list;
 251        struct list_head destroy_list;
 252        struct list_head sas_port_del_list;
 253        enum   sas_linkrate linkrate;
 254
 255        struct sas_work work;
 256        int suspended;
 257
 258/* public: */
 259        int id;
 260
 261        enum sas_class   class;
 262        u8               sas_addr[SAS_ADDR_SIZE];
 263        u8               attached_sas_addr[SAS_ADDR_SIZE];
 264        enum sas_protocol   iproto;
 265        enum sas_protocol   tproto;
 266
 267        enum sas_oob_mode oob_mode;
 268
 269        spinlock_t       phy_list_lock;
 270        struct list_head phy_list;
 271        int              num_phys;
 272        u32              phy_mask;
 273
 274        struct sas_ha_struct *ha;
 275
 276        struct sas_port *port;
 277
 278        void *lldd_port;          /* not touched by the sas class code */
 279};
 280
 281struct asd_sas_event {
 282        struct sas_work work;
 283        struct asd_sas_phy *phy;
 284        int event;
 285};
 286
 287static inline struct asd_sas_event *to_asd_sas_event(struct work_struct *work)
 288{
 289        struct asd_sas_event *ev = container_of(work, typeof(*ev), work.work);
 290
 291        return ev;
 292}
 293
 294static inline void INIT_SAS_EVENT(struct asd_sas_event *ev,
 295                void (*fn)(struct work_struct *),
 296                struct asd_sas_phy *phy, int event)
 297{
 298        INIT_SAS_WORK(&ev->work, fn);
 299        ev->phy = phy;
 300        ev->event = event;
 301}
 302
 303#define SAS_PHY_SHUTDOWN_THRES   1024
 304
 305/* The phy pretty much is controlled by the LLDD.
 306 * The class only reads those fields.
 307 */
 308struct asd_sas_phy {
 309/* private: */
 310        atomic_t event_nr;
 311        int in_shutdown;
 312        int error;
 313        int suspended;
 314
 315        struct sas_phy *phy;
 316
 317/* public: */
 318        /* The following are class:RO, driver:R/W */
 319        int            enabled;   /* must be set */
 320
 321        int            id;        /* must be set */
 322        enum sas_class class;
 323        enum sas_protocol iproto;
 324        enum sas_protocol tproto;
 325
 326        enum sas_phy_type  type;
 327        enum sas_phy_role  role;
 328        enum sas_oob_mode  oob_mode;
 329        enum sas_linkrate linkrate;
 330
 331        u8   *sas_addr;           /* must be set */
 332        u8   attached_sas_addr[SAS_ADDR_SIZE]; /* class:RO, driver: R/W */
 333
 334        spinlock_t     frame_rcvd_lock;
 335        u8             *frame_rcvd; /* must be set */
 336        int            frame_rcvd_size;
 337
 338        spinlock_t     sas_prim_lock;
 339        u32            sas_prim;
 340
 341        struct list_head port_phy_el; /* driver:RO */
 342        struct asd_sas_port      *port; /* Class:RW, driver: RO */
 343
 344        struct sas_ha_struct *ha; /* may be set; the class sets it anyway */
 345
 346        void *lldd_phy;           /* not touched by the sas_class_code */
 347};
 348
 349struct scsi_core {
 350        struct Scsi_Host *shost;
 351
 352};
 353
 354enum sas_ha_state {
 355        SAS_HA_REGISTERED,
 356        SAS_HA_DRAINING,
 357        SAS_HA_ATA_EH_ACTIVE,
 358        SAS_HA_FROZEN,
 359};
 360
 361struct sas_ha_struct {
 362/* private: */
 363        struct list_head  defer_q; /* work queued while draining */
 364        struct mutex      drain_mutex;
 365        unsigned long     state;
 366        spinlock_t        lock;
 367        int               eh_active;
 368        wait_queue_head_t eh_wait_q;
 369        struct list_head  eh_dev_q;
 370
 371        struct mutex disco_mutex;
 372
 373        struct scsi_core core;
 374
 375/* public: */
 376        char *sas_ha_name;
 377        struct device *dev;       /* should be set */
 378        struct module *lldd_module; /* should be set */
 379
 380        struct workqueue_struct *event_q;
 381        struct workqueue_struct *disco_q;
 382
 383        u8 *sas_addr;             /* must be set */
 384        u8 hashed_sas_addr[HASHED_SAS_ADDR_SIZE];
 385
 386        spinlock_t      phy_port_lock;
 387        struct asd_sas_phy  **sas_phy; /* array of valid pointers, must be set */
 388        struct asd_sas_port **sas_port; /* array of valid pointers, must be set */
 389        int             num_phys; /* must be set, gt 0, static */
 390
 391        int strict_wide_ports; /* both sas_addr and attached_sas_addr must match
 392                                * their siblings when forming wide ports */
 393
 394        void *lldd_ha;            /* not touched by sas class code */
 395
 396        struct list_head eh_done_q;  /* complete via scsi_eh_flush_done_q */
 397        struct list_head eh_ata_q; /* scmds to promote from sas to ata eh */
 398
 399        int event_thres;
 400};
 401
 402#define SHOST_TO_SAS_HA(_shost) (*(struct sas_ha_struct **)(_shost)->hostdata)
 403
 404static inline struct domain_device *
 405starget_to_domain_dev(struct scsi_target *starget) {
 406        return starget->hostdata;
 407}
 408
 409static inline struct domain_device *
 410sdev_to_domain_dev(struct scsi_device *sdev) {
 411        return starget_to_domain_dev(sdev->sdev_target);
 412}
 413
 414static inline struct ata_device *sas_to_ata_dev(struct domain_device *dev)
 415{
 416        return &dev->sata_dev.ap->link.device[0];
 417}
 418
 419static inline struct domain_device *
 420cmd_to_domain_dev(struct scsi_cmnd *cmd)
 421{
 422        return sdev_to_domain_dev(cmd->device);
 423}
 424
 425void sas_hash_addr(u8 *hashed, const u8 *sas_addr);
 426
 427/* Before calling a notify event, LLDD should use this function
 428 * when the link is severed (possibly from its tasklet).
 429 * The idea is that the Class only reads those, while the LLDD,
 430 * can R/W these (thus avoiding a race).
 431 */
 432static inline void sas_phy_disconnected(struct asd_sas_phy *phy)
 433{
 434        phy->oob_mode = OOB_NOT_CONNECTED;
 435        phy->linkrate = SAS_LINK_RATE_UNKNOWN;
 436}
 437
 438static inline unsigned int to_sas_gpio_od(int device, int bit)
 439{
 440        return 3 * device + bit;
 441}
 442
 443static inline void sas_put_local_phy(struct sas_phy *phy)
 444{
 445        put_device(&phy->dev);
 446}
 447
 448#ifdef CONFIG_SCSI_SAS_HOST_SMP
 449int try_test_sas_gpio_gp_bit(unsigned int od, u8 *data, u8 index, u8 count);
 450#else
 451static inline int try_test_sas_gpio_gp_bit(unsigned int od, u8 *data, u8 index, u8 count)
 452{
 453        return -1;
 454}
 455#endif
 456
 457/* ---------- Tasks ---------- */
 458/*
 459      service_response |  SAS_TASK_COMPLETE  |  SAS_TASK_UNDELIVERED |
 460  exec_status          |                     |                       |
 461  ---------------------+---------------------+-----------------------+
 462       SAM_...         |         X           |                       |
 463       DEV_NO_RESPONSE |         X           |           X           |
 464       INTERRUPTED     |         X           |                       |
 465       QUEUE_FULL      |                     |           X           |
 466       DEVICE_UNKNOWN  |                     |           X           |
 467       SG_ERR          |                     |           X           |
 468  ---------------------+---------------------+-----------------------+
 469 */
 470
 471enum service_response {
 472        SAS_TASK_COMPLETE,
 473        SAS_TASK_UNDELIVERED = -1,
 474};
 475
 476enum exec_status {
 477        /*
 478         * Values 0..0x7f are used to return the SAM_STAT_* codes.  To avoid
 479         * 'case value not in enumerated type' compiler warnings every value
 480         * returned through the exec_status enum needs an alias with the SAS_
 481         * prefix here.
 482         */
 483        SAS_SAM_STAT_GOOD = SAM_STAT_GOOD,
 484        SAS_SAM_STAT_BUSY = SAM_STAT_BUSY,
 485        SAS_SAM_STAT_TASK_ABORTED = SAM_STAT_TASK_ABORTED,
 486        SAS_SAM_STAT_CHECK_CONDITION = SAM_STAT_CHECK_CONDITION,
 487
 488        SAS_DEV_NO_RESPONSE = 0x80,
 489        SAS_DATA_UNDERRUN,
 490        SAS_DATA_OVERRUN,
 491        SAS_INTERRUPTED,
 492        SAS_QUEUE_FULL,
 493        SAS_DEVICE_UNKNOWN,
 494        SAS_SG_ERR,
 495        SAS_OPEN_REJECT,
 496        SAS_OPEN_TO,
 497        SAS_PROTO_RESPONSE,
 498        SAS_PHY_DOWN,
 499        SAS_NAK_R_ERR,
 500        SAS_PENDING,
 501        SAS_ABORTED_TASK,
 502};
 503
 504/* When a task finishes with a response, the LLDD examines the
 505 * response:
 506 *      - For an ATA task task_status_struct::stat is set to
 507 * SAS_PROTO_RESPONSE, and the task_status_struct::buf is set to the
 508 * contents of struct ata_task_resp.
 509 *      - For SSP tasks, if no data is present or status/TMF response
 510 * is valid, task_status_struct::stat is set.  If data is present
 511 * (SENSE data), the LLDD copies up to SAS_STATUS_BUF_SIZE, sets
 512 * task_status_struct::buf_valid_size, and task_status_struct::stat is
 513 * set to SAM_CHECK_COND.
 514 *
 515 * "buf" has format SCSI Sense for SSP task, or struct ata_task_resp
 516 * for ATA task.
 517 *
 518 * "frame_len" is the total frame length, which could be more or less
 519 * than actually copied.
 520 *
 521 * Tasks ending with response, always set the residual field.
 522 */
 523struct ata_task_resp {
 524        u16  frame_len;
 525        u8   ending_fis[ATA_RESP_FIS_SIZE];       /* dev to host or data-in */
 526};
 527
 528#define SAS_STATUS_BUF_SIZE 96
 529
 530struct task_status_struct {
 531        enum service_response resp;
 532        enum exec_status      stat;
 533        int  buf_valid_size;
 534
 535        u8   buf[SAS_STATUS_BUF_SIZE];
 536
 537        u32  residual;
 538        enum sas_open_rej_reason open_rej_reason;
 539};
 540
 541/* ATA and ATAPI task queuable to a SAS LLDD.
 542 */
 543struct sas_ata_task {
 544        struct host_to_dev_fis fis;
 545        u8     atapi_packet[16];  /* 0 if not ATAPI task */
 546
 547        u8     retry_count;       /* hardware retry, should be > 0 */
 548
 549        u8     dma_xfer:1;        /* PIO:0 or DMA:1 */
 550        u8     use_ncq:1;
 551        u8     set_affil_pol:1;
 552        u8     stp_affil_pol:1;
 553
 554        u8     device_control_reg_update:1;
 555};
 556
 557struct sas_smp_task {
 558        struct scatterlist smp_req;
 559        struct scatterlist smp_resp;
 560};
 561
 562enum task_attribute {
 563        TASK_ATTR_SIMPLE = 0,
 564        TASK_ATTR_HOQ    = 1,
 565        TASK_ATTR_ORDERED= 2,
 566        TASK_ATTR_ACA    = 4,
 567};
 568
 569struct sas_ssp_task {
 570        u8     retry_count;       /* hardware retry, should be > 0 */
 571
 572        u8     LUN[8];
 573        u8     enable_first_burst:1;
 574        enum   task_attribute task_attr;
 575        u8     task_prio;
 576        struct scsi_cmnd *cmd;
 577};
 578
 579struct sas_task {
 580        struct domain_device *dev;
 581
 582        spinlock_t   task_state_lock;
 583        unsigned     task_state_flags;
 584
 585        enum   sas_protocol      task_proto;
 586
 587        union {
 588                struct sas_ata_task ata_task;
 589                struct sas_smp_task smp_task;
 590                struct sas_ssp_task ssp_task;
 591        };
 592
 593        struct scatterlist *scatter;
 594        int    num_scatter;
 595        u32    total_xfer_len;
 596        u8     data_dir:2;        /* Use PCI_DMA_... */
 597
 598        struct task_status_struct task_status;
 599        void   (*task_done)(struct sas_task *);
 600
 601        void   *lldd_task;        /* for use by LLDDs */
 602        void   *uldd_task;
 603        struct sas_task_slow *slow_task;
 604};
 605
 606struct sas_task_slow {
 607        /* standard/extra infrastructure for slow path commands (SMP and
 608         * internal lldd commands
 609         */
 610        struct timer_list     timer;
 611        struct completion     completion;
 612        struct sas_task       *task;
 613};
 614
 615#define SAS_TASK_STATE_PENDING      1
 616#define SAS_TASK_STATE_DONE         2
 617#define SAS_TASK_STATE_ABORTED      4
 618#define SAS_TASK_NEED_DEV_RESET     8
 619#define SAS_TASK_AT_INITIATOR       16
 620
 621extern struct sas_task *sas_alloc_task(gfp_t flags);
 622extern struct sas_task *sas_alloc_slow_task(gfp_t flags);
 623extern void sas_free_task(struct sas_task *task);
 624
 625struct sas_domain_function_template {
 626        /* The class calls these to notify the LLDD of an event. */
 627        void (*lldd_port_formed)(struct asd_sas_phy *);
 628        void (*lldd_port_deformed)(struct asd_sas_phy *);
 629
 630        /* The class calls these when a device is found or gone. */
 631        int  (*lldd_dev_found)(struct domain_device *);
 632        void (*lldd_dev_gone)(struct domain_device *);
 633
 634        int (*lldd_execute_task)(struct sas_task *, gfp_t gfp_flags);
 635
 636        /* Task Management Functions. Must be called from process context. */
 637        int (*lldd_abort_task)(struct sas_task *);
 638        int (*lldd_abort_task_set)(struct domain_device *, u8 *lun);
 639        int (*lldd_clear_aca)(struct domain_device *, u8 *lun);
 640        int (*lldd_clear_task_set)(struct domain_device *, u8 *lun);
 641        int (*lldd_I_T_nexus_reset)(struct domain_device *);
 642        int (*lldd_ata_check_ready)(struct domain_device *);
 643        void (*lldd_ata_set_dmamode)(struct domain_device *);
 644        int (*lldd_lu_reset)(struct domain_device *, u8 *lun);
 645        int (*lldd_query_task)(struct sas_task *);
 646
 647        /* Port and Adapter management */
 648        int (*lldd_clear_nexus_port)(struct asd_sas_port *);
 649        int (*lldd_clear_nexus_ha)(struct sas_ha_struct *);
 650
 651        /* Phy management */
 652        int (*lldd_control_phy)(struct asd_sas_phy *, enum phy_func, void *);
 653
 654        /* GPIO support */
 655        int (*lldd_write_gpio)(struct sas_ha_struct *, u8 reg_type,
 656                               u8 reg_index, u8 reg_count, u8 *write_data);
 657};
 658
 659extern int sas_register_ha(struct sas_ha_struct *);
 660extern int sas_unregister_ha(struct sas_ha_struct *);
 661extern void sas_prep_resume_ha(struct sas_ha_struct *sas_ha);
 662extern void sas_resume_ha(struct sas_ha_struct *sas_ha);
 663extern void sas_suspend_ha(struct sas_ha_struct *sas_ha);
 664
 665int sas_set_phy_speed(struct sas_phy *phy, struct sas_phy_linkrates *rates);
 666int sas_phy_reset(struct sas_phy *phy, int hard_reset);
 667extern int sas_queuecommand(struct Scsi_Host *, struct scsi_cmnd *);
 668extern int sas_target_alloc(struct scsi_target *);
 669extern int sas_slave_configure(struct scsi_device *);
 670extern int sas_change_queue_depth(struct scsi_device *, int new_depth);
 671extern int sas_bios_param(struct scsi_device *, struct block_device *,
 672                          sector_t capacity, int *hsc);
 673extern struct scsi_transport_template *
 674sas_domain_attach_transport(struct sas_domain_function_template *);
 675extern struct device_attribute dev_attr_phy_event_threshold;
 676
 677int  sas_discover_root_expander(struct domain_device *);
 678
 679void sas_init_ex_attr(void);
 680
 681int  sas_ex_revalidate_domain(struct domain_device *);
 682
 683void sas_unregister_domain_devices(struct asd_sas_port *port, int gone);
 684void sas_init_disc(struct sas_discovery *disc, struct asd_sas_port *);
 685int  sas_discover_event(struct asd_sas_port *, enum discover_event ev);
 686
 687int  sas_discover_sata(struct domain_device *);
 688int  sas_discover_end_dev(struct domain_device *);
 689
 690void sas_unregister_dev(struct asd_sas_port *port, struct domain_device *);
 691
 692void sas_init_dev(struct domain_device *);
 693
 694void sas_task_abort(struct sas_task *);
 695int sas_eh_abort_handler(struct scsi_cmnd *cmd);
 696int sas_eh_device_reset_handler(struct scsi_cmnd *cmd);
 697int sas_eh_target_reset_handler(struct scsi_cmnd *cmd);
 698
 699extern void sas_target_destroy(struct scsi_target *);
 700extern int sas_slave_alloc(struct scsi_device *);
 701extern int sas_ioctl(struct scsi_device *sdev, unsigned int cmd,
 702                     void __user *arg);
 703extern int sas_drain_work(struct sas_ha_struct *ha);
 704
 705extern void sas_ssp_task_response(struct device *dev, struct sas_task *task,
 706                                  struct ssp_response_iu *iu);
 707struct sas_phy *sas_get_local_phy(struct domain_device *dev);
 708
 709int sas_request_addr(struct Scsi_Host *shost, u8 *addr);
 710
 711int sas_notify_port_event(struct asd_sas_phy *phy, enum port_event event,
 712                          gfp_t gfp_flags);
 713int sas_notify_phy_event(struct asd_sas_phy *phy, enum phy_event event,
 714                         gfp_t gfp_flags);
 715
 716#endif /* _SASLIB_H_ */
 717