linux/include/scsi/libsas.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0-or-later */
   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
 210/* Lots of code duplicates this in the SCSI tree, which can be factored out */
 211static inline bool sas_dev_type_is_expander(enum sas_device_type type)
 212{
 213        return type == SAS_EDGE_EXPANDER_DEVICE ||
 214               type == SAS_FANOUT_EXPANDER_DEVICE;
 215}
 216
 217static inline void INIT_SAS_WORK(struct sas_work *sw, void (*fn)(struct work_struct *))
 218{
 219        INIT_WORK(&sw->work, fn);
 220        INIT_LIST_HEAD(&sw->drain_node);
 221}
 222
 223struct sas_discovery_event {
 224        struct sas_work work;
 225        struct asd_sas_port *port;
 226};
 227
 228static inline struct sas_discovery_event *to_sas_discovery_event(struct work_struct *work)
 229{
 230        struct sas_discovery_event *ev = container_of(work, typeof(*ev), work.work);
 231
 232        return ev;
 233}
 234
 235struct sas_discovery {
 236        struct sas_discovery_event disc_work[DISC_NUM_EVENTS];
 237        unsigned long    pending;
 238        u8     fanout_sas_addr[SAS_ADDR_SIZE];
 239        u8     eeds_a[SAS_ADDR_SIZE];
 240        u8     eeds_b[SAS_ADDR_SIZE];
 241        int    max_level;
 242};
 243
 244/* The port struct is Class:RW, driver:RO */
 245struct asd_sas_port {
 246/* private: */
 247        struct sas_discovery disc;
 248        struct domain_device *port_dev;
 249        spinlock_t dev_list_lock;
 250        struct list_head dev_list;
 251        struct list_head disco_list;
 252        struct list_head destroy_list;
 253        struct list_head sas_port_del_list;
 254        enum   sas_linkrate linkrate;
 255
 256        struct sas_work work;
 257        int suspended;
 258
 259/* public: */
 260        int id;
 261
 262        enum sas_class   class;
 263        u8               sas_addr[SAS_ADDR_SIZE];
 264        u8               attached_sas_addr[SAS_ADDR_SIZE];
 265        enum sas_protocol   iproto;
 266        enum sas_protocol   tproto;
 267
 268        enum sas_oob_mode oob_mode;
 269
 270        spinlock_t       phy_list_lock;
 271        struct list_head phy_list;
 272        int              num_phys;
 273        u32              phy_mask;
 274
 275        struct sas_ha_struct *ha;
 276
 277        struct sas_port *port;
 278
 279        void *lldd_port;          /* not touched by the sas class code */
 280};
 281
 282struct asd_sas_event {
 283        struct sas_work work;
 284        struct asd_sas_phy *phy;
 285        int event;
 286};
 287
 288static inline struct asd_sas_event *to_asd_sas_event(struct work_struct *work)
 289{
 290        struct asd_sas_event *ev = container_of(work, typeof(*ev), work.work);
 291
 292        return ev;
 293}
 294
 295static inline void INIT_SAS_EVENT(struct asd_sas_event *ev,
 296                void (*fn)(struct work_struct *),
 297                struct asd_sas_phy *phy, int event)
 298{
 299        INIT_SAS_WORK(&ev->work, fn);
 300        ev->phy = phy;
 301        ev->event = event;
 302}
 303
 304#define SAS_PHY_SHUTDOWN_THRES   1024
 305
 306/* The phy pretty much is controlled by the LLDD.
 307 * The class only reads those fields.
 308 */
 309struct asd_sas_phy {
 310/* private: */
 311        atomic_t event_nr;
 312        int in_shutdown;
 313        int error;
 314        int suspended;
 315
 316        struct sas_phy *phy;
 317
 318/* public: */
 319        /* The following are class:RO, driver:R/W */
 320        int            enabled;   /* must be set */
 321
 322        int            id;        /* must be set */
 323        enum sas_class class;
 324        enum sas_protocol iproto;
 325        enum sas_protocol tproto;
 326
 327        enum sas_phy_type  type;
 328        enum sas_phy_role  role;
 329        enum sas_oob_mode  oob_mode;
 330        enum sas_linkrate linkrate;
 331
 332        u8   *sas_addr;           /* must be set */
 333        u8   attached_sas_addr[SAS_ADDR_SIZE]; /* class:RO, driver: R/W */
 334
 335        spinlock_t     frame_rcvd_lock;
 336        u8             *frame_rcvd; /* must be set */
 337        int            frame_rcvd_size;
 338
 339        spinlock_t     sas_prim_lock;
 340        u32            sas_prim;
 341
 342        struct list_head port_phy_el; /* driver:RO */
 343        struct asd_sas_port      *port; /* Class:RW, driver: RO */
 344
 345        struct sas_ha_struct *ha; /* may be set; the class sets it anyway */
 346
 347        void *lldd_phy;           /* not touched by the sas_class_code */
 348};
 349
 350struct scsi_core {
 351        struct Scsi_Host *shost;
 352
 353};
 354
 355enum sas_ha_state {
 356        SAS_HA_REGISTERED,
 357        SAS_HA_DRAINING,
 358        SAS_HA_ATA_EH_ACTIVE,
 359        SAS_HA_FROZEN,
 360};
 361
 362struct sas_ha_struct {
 363/* private: */
 364        struct list_head  defer_q; /* work queued while draining */
 365        struct mutex      drain_mutex;
 366        unsigned long     state;
 367        spinlock_t        lock;
 368        int               eh_active;
 369        wait_queue_head_t eh_wait_q;
 370        struct list_head  eh_dev_q;
 371
 372        struct mutex disco_mutex;
 373
 374        struct scsi_core core;
 375
 376/* public: */
 377        char *sas_ha_name;
 378        struct device *dev;       /* should be set */
 379        struct module *lldd_module; /* should be set */
 380
 381        struct workqueue_struct *event_q;
 382        struct workqueue_struct *disco_q;
 383
 384        u8 *sas_addr;             /* must be set */
 385        u8 hashed_sas_addr[HASHED_SAS_ADDR_SIZE];
 386
 387        spinlock_t      phy_port_lock;
 388        struct asd_sas_phy  **sas_phy; /* array of valid pointers, must be set */
 389        struct asd_sas_port **sas_port; /* array of valid pointers, must be set */
 390        int             num_phys; /* must be set, gt 0, static */
 391
 392        int strict_wide_ports; /* both sas_addr and attached_sas_addr must match
 393                                * their siblings when forming wide ports */
 394
 395        /* LLDD calls these to notify the class of an event. */
 396        int (*notify_port_event)(struct asd_sas_phy *, enum port_event);
 397        int (*notify_phy_event)(struct asd_sas_phy *, enum phy_event);
 398
 399        void *lldd_ha;            /* not touched by sas class code */
 400
 401        struct list_head eh_done_q;  /* complete via scsi_eh_flush_done_q */
 402        struct list_head eh_ata_q; /* scmds to promote from sas to ata eh */
 403
 404        int event_thres;
 405};
 406
 407#define SHOST_TO_SAS_HA(_shost) (*(struct sas_ha_struct **)(_shost)->hostdata)
 408
 409static inline struct domain_device *
 410starget_to_domain_dev(struct scsi_target *starget) {
 411        return starget->hostdata;
 412}
 413
 414static inline struct domain_device *
 415sdev_to_domain_dev(struct scsi_device *sdev) {
 416        return starget_to_domain_dev(sdev->sdev_target);
 417}
 418
 419static inline struct ata_device *sas_to_ata_dev(struct domain_device *dev)
 420{
 421        return &dev->sata_dev.ap->link.device[0];
 422}
 423
 424static inline struct domain_device *
 425cmd_to_domain_dev(struct scsi_cmnd *cmd)
 426{
 427        return sdev_to_domain_dev(cmd->device);
 428}
 429
 430void sas_hash_addr(u8 *hashed, const u8 *sas_addr);
 431
 432/* Before calling a notify event, LLDD should use this function
 433 * when the link is severed (possibly from its tasklet).
 434 * The idea is that the Class only reads those, while the LLDD,
 435 * can R/W these (thus avoiding a race).
 436 */
 437static inline void sas_phy_disconnected(struct asd_sas_phy *phy)
 438{
 439        phy->oob_mode = OOB_NOT_CONNECTED;
 440        phy->linkrate = SAS_LINK_RATE_UNKNOWN;
 441}
 442
 443static inline unsigned int to_sas_gpio_od(int device, int bit)
 444{
 445        return 3 * device + bit;
 446}
 447
 448static inline void sas_put_local_phy(struct sas_phy *phy)
 449{
 450        put_device(&phy->dev);
 451}
 452
 453#ifdef CONFIG_SCSI_SAS_HOST_SMP
 454int try_test_sas_gpio_gp_bit(unsigned int od, u8 *data, u8 index, u8 count);
 455#else
 456static inline int try_test_sas_gpio_gp_bit(unsigned int od, u8 *data, u8 index, u8 count)
 457{
 458        return -1;
 459}
 460#endif
 461
 462/* ---------- Tasks ---------- */
 463/*
 464      service_response |  SAS_TASK_COMPLETE  |  SAS_TASK_UNDELIVERED |
 465  exec_status          |                     |                       |
 466  ---------------------+---------------------+-----------------------+
 467       SAM_...         |         X           |                       |
 468       DEV_NO_RESPONSE |         X           |           X           |
 469       INTERRUPTED     |         X           |                       |
 470       QUEUE_FULL      |                     |           X           |
 471       DEVICE_UNKNOWN  |                     |           X           |
 472       SG_ERR          |                     |           X           |
 473  ---------------------+---------------------+-----------------------+
 474 */
 475
 476enum service_response {
 477        SAS_TASK_COMPLETE,
 478        SAS_TASK_UNDELIVERED = -1,
 479};
 480
 481enum exec_status {
 482        /* The SAM_STAT_.. codes fit in the lower 6 bits, alias some of
 483         * them here to silence 'case value not in enumerated type' warnings
 484         */
 485        __SAM_STAT_CHECK_CONDITION = SAM_STAT_CHECK_CONDITION,
 486
 487        SAS_DEV_NO_RESPONSE = 0x80,
 488        SAS_DATA_UNDERRUN,
 489        SAS_DATA_OVERRUN,
 490        SAS_INTERRUPTED,
 491        SAS_QUEUE_FULL,
 492        SAS_DEVICE_UNKNOWN,
 493        SAS_SG_ERR,
 494        SAS_OPEN_REJECT,
 495        SAS_OPEN_TO,
 496        SAS_PROTO_RESPONSE,
 497        SAS_PHY_DOWN,
 498        SAS_NAK_R_ERR,
 499        SAS_PENDING,
 500        SAS_ABORTED_TASK,
 501};
 502
 503/* When a task finishes with a response, the LLDD examines the
 504 * response:
 505 *      - For an ATA task task_status_struct::stat is set to
 506 * SAS_PROTO_RESPONSE, and the task_status_struct::buf is set to the
 507 * contents of struct ata_task_resp.
 508 *      - For SSP tasks, if no data is present or status/TMF response
 509 * is valid, task_status_struct::stat is set.  If data is present
 510 * (SENSE data), the LLDD copies up to SAS_STATUS_BUF_SIZE, sets
 511 * task_status_struct::buf_valid_size, and task_status_struct::stat is
 512 * set to SAM_CHECK_COND.
 513 *
 514 * "buf" has format SCSI Sense for SSP task, or struct ata_task_resp
 515 * for ATA task.
 516 *
 517 * "frame_len" is the total frame length, which could be more or less
 518 * than actually copied.
 519 *
 520 * Tasks ending with response, always set the residual field.
 521 */
 522struct ata_task_resp {
 523        u16  frame_len;
 524        u8   ending_fis[ATA_RESP_FIS_SIZE];       /* dev to host or data-in */
 525};
 526
 527#define SAS_STATUS_BUF_SIZE 96
 528
 529struct task_status_struct {
 530        enum service_response resp;
 531        enum exec_status      stat;
 532        int  buf_valid_size;
 533
 534        u8   buf[SAS_STATUS_BUF_SIZE];
 535
 536        u32  residual;
 537        enum sas_open_rej_reason open_rej_reason;
 538};
 539
 540/* ATA and ATAPI task queuable to a SAS LLDD.
 541 */
 542struct sas_ata_task {
 543        struct host_to_dev_fis fis;
 544        u8     atapi_packet[16];  /* 0 if not ATAPI task */
 545
 546        u8     retry_count;       /* hardware retry, should be > 0 */
 547
 548        u8     dma_xfer:1;        /* PIO:0 or DMA:1 */
 549        u8     use_ncq:1;
 550        u8     set_affil_pol:1;
 551        u8     stp_affil_pol:1;
 552
 553        u8     device_control_reg_update:1;
 554};
 555
 556struct sas_smp_task {
 557        struct scatterlist smp_req;
 558        struct scatterlist smp_resp;
 559};
 560
 561enum task_attribute {
 562        TASK_ATTR_SIMPLE = 0,
 563        TASK_ATTR_HOQ    = 1,
 564        TASK_ATTR_ORDERED= 2,
 565        TASK_ATTR_ACA    = 4,
 566};
 567
 568struct sas_ssp_task {
 569        u8     retry_count;       /* hardware retry, should be > 0 */
 570
 571        u8     LUN[8];
 572        u8     enable_first_burst:1;
 573        enum   task_attribute task_attr;
 574        u8     task_prio;
 575        struct scsi_cmnd *cmd;
 576};
 577
 578struct sas_task {
 579        struct domain_device *dev;
 580
 581        spinlock_t   task_state_lock;
 582        unsigned     task_state_flags;
 583
 584        enum   sas_protocol      task_proto;
 585
 586        union {
 587                struct sas_ata_task ata_task;
 588                struct sas_smp_task smp_task;
 589                struct sas_ssp_task ssp_task;
 590        };
 591
 592        struct scatterlist *scatter;
 593        int    num_scatter;
 594        u32    total_xfer_len;
 595        u8     data_dir:2;        /* Use PCI_DMA_... */
 596
 597        struct task_status_struct task_status;
 598        void   (*task_done)(struct sas_task *);
 599
 600        void   *lldd_task;        /* for use by LLDDs */
 601        void   *uldd_task;
 602        struct sas_task_slow *slow_task;
 603};
 604
 605struct sas_task_slow {
 606        /* standard/extra infrastructure for slow path commands (SMP and
 607         * internal lldd commands
 608         */
 609        struct timer_list     timer;
 610        struct completion     completion;
 611        struct sas_task       *task;
 612};
 613
 614#define SAS_TASK_STATE_PENDING      1
 615#define SAS_TASK_STATE_DONE         2
 616#define SAS_TASK_STATE_ABORTED      4
 617#define SAS_TASK_NEED_DEV_RESET     8
 618#define SAS_TASK_AT_INITIATOR       16
 619
 620extern struct sas_task *sas_alloc_task(gfp_t flags);
 621extern struct sas_task *sas_alloc_slow_task(gfp_t flags);
 622extern void sas_free_task(struct sas_task *task);
 623
 624struct sas_domain_function_template {
 625        /* The class calls these to notify the LLDD of an event. */
 626        void (*lldd_port_formed)(struct asd_sas_phy *);
 627        void (*lldd_port_deformed)(struct asd_sas_phy *);
 628
 629        /* The class calls these when a device is found or gone. */
 630        int  (*lldd_dev_found)(struct domain_device *);
 631        void (*lldd_dev_gone)(struct domain_device *);
 632
 633        int (*lldd_execute_task)(struct sas_task *, gfp_t gfp_flags);
 634
 635        /* Task Management Functions. Must be called from process context. */
 636        int (*lldd_abort_task)(struct sas_task *);
 637        int (*lldd_abort_task_set)(struct domain_device *, u8 *lun);
 638        int (*lldd_clear_aca)(struct domain_device *, u8 *lun);
 639        int (*lldd_clear_task_set)(struct domain_device *, u8 *lun);
 640        int (*lldd_I_T_nexus_reset)(struct domain_device *);
 641        int (*lldd_ata_check_ready)(struct domain_device *);
 642        void (*lldd_ata_set_dmamode)(struct domain_device *);
 643        int (*lldd_lu_reset)(struct domain_device *, u8 *lun);
 644        int (*lldd_query_task)(struct sas_task *);
 645
 646        /* Port and Adapter management */
 647        int (*lldd_clear_nexus_port)(struct asd_sas_port *);
 648        int (*lldd_clear_nexus_ha)(struct sas_ha_struct *);
 649
 650        /* Phy management */
 651        int (*lldd_control_phy)(struct asd_sas_phy *, enum phy_func, void *);
 652
 653        /* GPIO support */
 654        int (*lldd_write_gpio)(struct sas_ha_struct *, u8 reg_type,
 655                               u8 reg_index, u8 reg_count, u8 *write_data);
 656};
 657
 658extern int sas_register_ha(struct sas_ha_struct *);
 659extern int sas_unregister_ha(struct sas_ha_struct *);
 660extern void sas_prep_resume_ha(struct sas_ha_struct *sas_ha);
 661extern void sas_resume_ha(struct sas_ha_struct *sas_ha);
 662extern void sas_suspend_ha(struct sas_ha_struct *sas_ha);
 663
 664int sas_set_phy_speed(struct sas_phy *phy, struct sas_phy_linkrates *rates);
 665int sas_phy_reset(struct sas_phy *phy, int hard_reset);
 666extern int sas_queuecommand(struct Scsi_Host *, struct scsi_cmnd *);
 667extern int sas_target_alloc(struct scsi_target *);
 668extern int sas_slave_configure(struct scsi_device *);
 669extern int sas_change_queue_depth(struct scsi_device *, int new_depth);
 670extern int sas_bios_param(struct scsi_device *, struct block_device *,
 671                          sector_t capacity, int *hsc);
 672extern struct scsi_transport_template *
 673sas_domain_attach_transport(struct sas_domain_function_template *);
 674extern struct device_attribute dev_attr_phy_event_threshold;
 675
 676int  sas_discover_root_expander(struct domain_device *);
 677
 678void sas_init_ex_attr(void);
 679
 680int  sas_ex_revalidate_domain(struct domain_device *);
 681
 682void sas_unregister_domain_devices(struct asd_sas_port *port, int gone);
 683void sas_init_disc(struct sas_discovery *disc, struct asd_sas_port *);
 684int  sas_discover_event(struct asd_sas_port *, enum discover_event ev);
 685
 686int  sas_discover_sata(struct domain_device *);
 687int  sas_discover_end_dev(struct domain_device *);
 688
 689void sas_unregister_dev(struct asd_sas_port *port, struct domain_device *);
 690
 691void sas_init_dev(struct domain_device *);
 692
 693void sas_task_abort(struct sas_task *);
 694int sas_eh_abort_handler(struct scsi_cmnd *cmd);
 695int sas_eh_device_reset_handler(struct scsi_cmnd *cmd);
 696int sas_eh_target_reset_handler(struct scsi_cmnd *cmd);
 697
 698extern void sas_target_destroy(struct scsi_target *);
 699extern int sas_slave_alloc(struct scsi_device *);
 700extern int sas_ioctl(struct scsi_device *sdev, unsigned int cmd,
 701                     void __user *arg);
 702extern int sas_drain_work(struct sas_ha_struct *ha);
 703
 704extern void sas_ssp_task_response(struct device *dev, struct sas_task *task,
 705                                  struct ssp_response_iu *iu);
 706struct sas_phy *sas_get_local_phy(struct domain_device *dev);
 707
 708int sas_request_addr(struct Scsi_Host *shost, u8 *addr);
 709
 710#endif /* _SASLIB_H_ */
 711