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