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
  40struct block_device;
  41
  42enum sas_class {
  43        SAS,
  44        EXPANDER
  45};
  46
  47enum sas_phy_role {
  48        PHY_ROLE_NONE = 0,
  49        PHY_ROLE_TARGET = 0x40,
  50        PHY_ROLE_INITIATOR = 0x80,
  51};
  52
  53enum sas_phy_type {
  54        PHY_TYPE_PHYSICAL,
  55        PHY_TYPE_VIRTUAL
  56};
  57
  58/* The events are mnemonically described in sas_dump.c
  59 * so when updating/adding events here, please also
  60 * update the other file too.
  61 */
  62enum ha_event {
  63        HAE_RESET             = 0U,
  64        HA_NUM_EVENTS         = 1,
  65};
  66
  67enum port_event {
  68        PORTE_BYTES_DMAED     = 0U,
  69        PORTE_BROADCAST_RCVD  = 1,
  70        PORTE_LINK_RESET_ERR  = 2,
  71        PORTE_TIMER_EVENT     = 3,
  72        PORTE_HARD_RESET      = 4,
  73        PORT_NUM_EVENTS       = 5,
  74};
  75
  76enum phy_event {
  77        PHYE_LOSS_OF_SIGNAL   = 0U,
  78        PHYE_OOB_DONE         = 1,
  79        PHYE_OOB_ERROR        = 2,
  80        PHYE_SPINUP_HOLD      = 3, /* hot plug SATA, no COMWAKE sent */
  81        PHY_NUM_EVENTS        = 4,
  82};
  83
  84enum discover_event {
  85        DISCE_DISCOVER_DOMAIN   = 0U,
  86        DISCE_REVALIDATE_DOMAIN = 1,
  87        DISCE_PORT_GONE         = 2,
  88        DISC_NUM_EVENTS         = 3,
  89};
  90
  91/* ---------- Expander Devices ---------- */
  92
  93#define to_dom_device(_obj) container_of(_obj, struct domain_device, dev_obj)
  94#define to_dev_attr(_attr)  container_of(_attr, struct domain_dev_attribute,\
  95                                         attr)
  96
  97enum routing_attribute {
  98        DIRECT_ROUTING,
  99        SUBTRACTIVE_ROUTING,
 100        TABLE_ROUTING,
 101};
 102
 103enum ex_phy_state {
 104        PHY_EMPTY,
 105        PHY_VACANT,
 106        PHY_NOT_PRESENT,
 107        PHY_DEVICE_DISCOVERED
 108};
 109
 110struct ex_phy {
 111        int    phy_id;
 112
 113        enum ex_phy_state phy_state;
 114
 115        enum sas_dev_type attached_dev_type;
 116        enum sas_linkrate linkrate;
 117
 118        u8   attached_sata_host:1;
 119        u8   attached_sata_dev:1;
 120        u8   attached_sata_ps:1;
 121
 122        enum sas_protocol attached_tproto;
 123        enum sas_protocol attached_iproto;
 124
 125        u8   attached_sas_addr[SAS_ADDR_SIZE];
 126        u8   attached_phy_id;
 127
 128        u8   phy_change_count;
 129        enum routing_attribute routing_attr;
 130        u8   virtual:1;
 131
 132        int  last_da_index;
 133
 134        struct sas_phy *phy;
 135        struct sas_port *port;
 136};
 137
 138struct expander_device {
 139        struct list_head children;
 140
 141        u16    ex_change_count;
 142        u16    max_route_indexes;
 143        u8     num_phys;
 144        u8     configuring:1;
 145        u8     conf_route_table:1;
 146        u8     enclosure_logical_id[8];
 147
 148        struct ex_phy *ex_phy;
 149        struct sas_port *parent_port;
 150};
 151
 152/* ---------- SATA device ---------- */
 153enum ata_command_set {
 154        ATA_COMMAND_SET   = 0,
 155        ATAPI_COMMAND_SET = 1,
 156};
 157
 158struct sata_device {
 159        enum   ata_command_set command_set;
 160        struct smp_resp        rps_resp; /* report_phy_sata_resp */
 161        __le16 *identify_device;
 162        __le16 *identify_packet_device;
 163
 164        u8     port_no;        /* port number, if this is a PM (Port) */
 165        struct list_head children; /* PM Ports if this is a PM */
 166
 167        struct ata_port *ap;
 168        struct ata_host ata_host;
 169        struct ata_taskfile tf;
 170        u32 sstatus;
 171        u32 serror;
 172        u32 scontrol;
 173};
 174
 175/* ---------- Domain device ---------- */
 176struct domain_device {
 177        enum sas_dev_type dev_type;
 178
 179        enum sas_linkrate linkrate;
 180        enum sas_linkrate min_linkrate;
 181        enum sas_linkrate max_linkrate;
 182
 183        int  pathways;
 184
 185        struct domain_device *parent;
 186        struct list_head siblings; /* devices on the same level */
 187        struct asd_sas_port *port;        /* shortcut to root of the tree */
 188
 189        struct list_head dev_list_node;
 190
 191        enum sas_protocol    iproto;
 192        enum sas_protocol    tproto;
 193
 194        struct sas_rphy *rphy;
 195
 196        u8  sas_addr[SAS_ADDR_SIZE];
 197        u8  hashed_sas_addr[HASHED_SAS_ADDR_SIZE];
 198
 199        u8  frame_rcvd[32];
 200
 201        union {
 202                struct expander_device ex_dev;
 203                struct sata_device     sata_dev; /* STP & directly attached */
 204        };
 205
 206        void *lldd_dev;
 207};
 208
 209struct sas_discovery_event {
 210        struct work_struct work;
 211        struct asd_sas_port *port;
 212};
 213
 214struct sas_discovery {
 215        spinlock_t disc_event_lock;
 216        struct sas_discovery_event disc_work[DISC_NUM_EVENTS];
 217        unsigned long    pending;
 218        u8     fanout_sas_addr[8];
 219        u8     eeds_a[8];
 220        u8     eeds_b[8];
 221        int    max_level;
 222};
 223
 224
 225/* The port struct is Class:RW, driver:RO */
 226struct asd_sas_port {
 227/* private: */
 228        struct completion port_gone_completion;
 229
 230        struct sas_discovery disc;
 231        struct domain_device *port_dev;
 232        spinlock_t dev_list_lock;
 233        struct list_head dev_list;
 234        enum   sas_linkrate linkrate;
 235
 236        struct sas_phy *phy;
 237        struct work_struct work;
 238
 239/* public: */
 240        int id;
 241
 242        enum sas_class   class;
 243        u8               sas_addr[SAS_ADDR_SIZE];
 244        u8               attached_sas_addr[SAS_ADDR_SIZE];
 245        enum sas_protocol   iproto;
 246        enum sas_protocol   tproto;
 247
 248        enum sas_oob_mode oob_mode;
 249
 250        spinlock_t       phy_list_lock;
 251        struct list_head phy_list;
 252        int              num_phys;
 253        u32              phy_mask;
 254
 255        struct sas_ha_struct *ha;
 256
 257        struct sas_port *port;
 258
 259        void *lldd_port;          /* not touched by the sas class code */
 260};
 261
 262struct asd_sas_event {
 263        struct work_struct work;
 264        struct asd_sas_phy *phy;
 265};
 266
 267/* The phy pretty much is controlled by the LLDD.
 268 * The class only reads those fields.
 269 */
 270struct asd_sas_phy {
 271/* private: */
 272        /* protected by ha->event_lock */
 273        struct asd_sas_event   port_events[PORT_NUM_EVENTS];
 274        struct asd_sas_event   phy_events[PHY_NUM_EVENTS];
 275
 276        unsigned long port_events_pending;
 277        unsigned long phy_events_pending;
 278
 279        int error;
 280
 281        struct sas_phy *phy;
 282
 283/* public: */
 284        /* The following are class:RO, driver:R/W */
 285        int            enabled;   /* must be set */
 286
 287        int            id;        /* must be set */
 288        enum sas_class class;
 289        enum sas_protocol iproto;
 290        enum sas_protocol tproto;
 291
 292        enum sas_phy_type  type;
 293        enum sas_phy_role  role;
 294        enum sas_oob_mode  oob_mode;
 295        enum sas_linkrate linkrate;
 296
 297        u8   *sas_addr;           /* must be set */
 298        u8   attached_sas_addr[SAS_ADDR_SIZE]; /* class:RO, driver: R/W */
 299
 300        spinlock_t     frame_rcvd_lock;
 301        u8             *frame_rcvd; /* must be set */
 302        int            frame_rcvd_size;
 303
 304        spinlock_t     sas_prim_lock;
 305        u32            sas_prim;
 306
 307        struct list_head port_phy_el; /* driver:RO */
 308        struct asd_sas_port      *port; /* Class:RW, driver: RO */
 309
 310        struct sas_ha_struct *ha; /* may be set; the class sets it anyway */
 311
 312        void *lldd_phy;           /* not touched by the sas_class_code */
 313};
 314
 315struct scsi_core {
 316        struct Scsi_Host *shost;
 317
 318        spinlock_t        task_queue_lock;
 319        struct list_head  task_queue;
 320        int               task_queue_size;
 321
 322        struct task_struct *queue_thread;
 323};
 324
 325struct sas_ha_event {
 326        struct work_struct work;
 327        struct sas_ha_struct *ha;
 328};
 329
 330enum sas_ha_state {
 331        SAS_HA_REGISTERED,
 332        SAS_HA_UNREGISTERED
 333};
 334
 335struct sas_ha_struct {
 336/* private: */
 337        spinlock_t       event_lock;
 338        struct sas_ha_event ha_events[HA_NUM_EVENTS];
 339        unsigned long    pending;
 340
 341        enum sas_ha_state state;
 342        spinlock_t        state_lock;
 343
 344        struct scsi_core core;
 345
 346/* public: */
 347        char *sas_ha_name;
 348        struct device *dev;       /* should be set */
 349        struct module *lldd_module; /* should be set */
 350
 351        u8 *sas_addr;             /* must be set */
 352        u8 hashed_sas_addr[HASHED_SAS_ADDR_SIZE];
 353
 354        spinlock_t      phy_port_lock;
 355        struct asd_sas_phy  **sas_phy; /* array of valid pointers, must be set */
 356        struct asd_sas_port **sas_port; /* array of valid pointers, must be set */
 357        int             num_phys; /* must be set, gt 0, static */
 358
 359        /* The class calls this to send a task for execution. */
 360        int lldd_max_execute_num;
 361        int lldd_queue_size;
 362
 363        /* LLDD calls these to notify the class of an event. */
 364        void (*notify_ha_event)(struct sas_ha_struct *, enum ha_event);
 365        void (*notify_port_event)(struct asd_sas_phy *, enum port_event);
 366        void (*notify_phy_event)(struct asd_sas_phy *, enum phy_event);
 367
 368        void *lldd_ha;            /* not touched by sas class code */
 369
 370        struct list_head eh_done_q;
 371};
 372
 373#define SHOST_TO_SAS_HA(_shost) (*(struct sas_ha_struct **)(_shost)->hostdata)
 374
 375static inline struct domain_device *
 376starget_to_domain_dev(struct scsi_target *starget) {
 377        return starget->hostdata;
 378}
 379
 380static inline struct domain_device *
 381sdev_to_domain_dev(struct scsi_device *sdev) {
 382        return starget_to_domain_dev(sdev->sdev_target);
 383}
 384
 385static inline struct domain_device *
 386cmd_to_domain_dev(struct scsi_cmnd *cmd)
 387{
 388        return sdev_to_domain_dev(cmd->device);
 389}
 390
 391void sas_hash_addr(u8 *hashed, const u8 *sas_addr);
 392
 393/* Before calling a notify event, LLDD should use this function
 394 * when the link is severed (possibly from its tasklet).
 395 * The idea is that the Class only reads those, while the LLDD,
 396 * can R/W these (thus avoiding a race).
 397 */
 398static inline void sas_phy_disconnected(struct asd_sas_phy *phy)
 399{
 400        phy->oob_mode = OOB_NOT_CONNECTED;
 401        phy->linkrate = SAS_LINK_RATE_UNKNOWN;
 402}
 403
 404/* ---------- Tasks ---------- */
 405/*
 406      service_response |  SAS_TASK_COMPLETE  |  SAS_TASK_UNDELIVERED |
 407  exec_status          |                     |                       |
 408  ---------------------+---------------------+-----------------------+
 409       SAM_...         |         X           |                       |
 410       DEV_NO_RESPONSE |         X           |           X           |
 411       INTERRUPTED     |         X           |                       |
 412       QUEUE_FULL      |                     |           X           |
 413       DEVICE_UNKNOWN  |                     |           X           |
 414       SG_ERR          |                     |           X           |
 415  ---------------------+---------------------+-----------------------+
 416 */
 417
 418enum service_response {
 419        SAS_TASK_COMPLETE,
 420        SAS_TASK_UNDELIVERED = -1,
 421};
 422
 423enum exec_status {
 424        SAM_GOOD         = 0,
 425        SAM_CHECK_COND   = 2,
 426        SAM_COND_MET     = 4,
 427        SAM_BUSY         = 8,
 428        SAM_INTERMEDIATE = 0x10,
 429        SAM_IM_COND_MET  = 0x12,
 430        SAM_RESV_CONFLICT= 0x14,
 431        SAM_TASK_SET_FULL= 0x28,
 432        SAM_ACA_ACTIVE   = 0x30,
 433        SAM_TASK_ABORTED = 0x40,
 434
 435        SAS_DEV_NO_RESPONSE = 0x80,
 436        SAS_DATA_UNDERRUN,
 437        SAS_DATA_OVERRUN,
 438        SAS_INTERRUPTED,
 439        SAS_QUEUE_FULL,
 440        SAS_DEVICE_UNKNOWN,
 441        SAS_SG_ERR,
 442        SAS_OPEN_REJECT,
 443        SAS_OPEN_TO,
 444        SAS_PROTO_RESPONSE,
 445        SAS_PHY_DOWN,
 446        SAS_NAK_R_ERR,
 447        SAS_PENDING,
 448        SAS_ABORTED_TASK,
 449};
 450
 451/* When a task finishes with a response, the LLDD examines the
 452 * response:
 453 *      - For an ATA task task_status_struct::stat is set to
 454 * SAS_PROTO_RESPONSE, and the task_status_struct::buf is set to the
 455 * contents of struct ata_task_resp.
 456 *      - For SSP tasks, if no data is present or status/TMF response
 457 * is valid, task_status_struct::stat is set.  If data is present
 458 * (SENSE data), the LLDD copies up to SAS_STATUS_BUF_SIZE, sets
 459 * task_status_struct::buf_valid_size, and task_status_struct::stat is
 460 * set to SAM_CHECK_COND.
 461 *
 462 * "buf" has format SCSI Sense for SSP task, or struct ata_task_resp
 463 * for ATA task.
 464 *
 465 * "frame_len" is the total frame length, which could be more or less
 466 * than actually copied.
 467 *
 468 * Tasks ending with response, always set the residual field.
 469 */
 470struct ata_task_resp {
 471        u16  frame_len;
 472        u8   ending_fis[24];      /* dev to host or data-in */
 473        u32  sstatus;
 474        u32  serror;
 475        u32  scontrol;
 476        u32  sactive;
 477};
 478
 479#define SAS_STATUS_BUF_SIZE 96
 480
 481struct task_status_struct {
 482        enum service_response resp;
 483        enum exec_status      stat;
 484        int  buf_valid_size;
 485
 486        u8   buf[SAS_STATUS_BUF_SIZE];
 487
 488        u32  residual;
 489        enum sas_open_rej_reason open_rej_reason;
 490};
 491
 492/* ATA and ATAPI task queuable to a SAS LLDD.
 493 */
 494struct sas_ata_task {
 495        struct host_to_dev_fis fis;
 496        u8     atapi_packet[16];  /* 0 if not ATAPI task */
 497
 498        u8     retry_count;       /* hardware retry, should be > 0 */
 499
 500        u8     dma_xfer:1;        /* PIO:0 or DMA:1 */
 501        u8     use_ncq:1;
 502        u8     set_affil_pol:1;
 503        u8     stp_affil_pol:1;
 504
 505        u8     device_control_reg_update:1;
 506};
 507
 508struct sas_smp_task {
 509        struct scatterlist smp_req;
 510        struct scatterlist smp_resp;
 511};
 512
 513enum task_attribute {
 514        TASK_ATTR_SIMPLE = 0,
 515        TASK_ATTR_HOQ    = 1,
 516        TASK_ATTR_ORDERED= 2,
 517        TASK_ATTR_ACA    = 4,
 518};
 519
 520struct sas_ssp_task {
 521        u8     retry_count;       /* hardware retry, should be > 0 */
 522
 523        u8     LUN[8];
 524        u8     enable_first_burst:1;
 525        enum   task_attribute task_attr;
 526        u8     task_prio;
 527        u8     cdb[16];
 528};
 529
 530struct sas_task {
 531        struct domain_device *dev;
 532        struct list_head      list;
 533
 534        spinlock_t   task_state_lock;
 535        unsigned     task_state_flags;
 536
 537        enum   sas_protocol      task_proto;
 538
 539        /* Used by the discovery code. */
 540        struct timer_list     timer;
 541        struct completion     completion;
 542
 543        union {
 544                struct sas_ata_task ata_task;
 545                struct sas_smp_task smp_task;
 546                struct sas_ssp_task ssp_task;
 547        };
 548
 549        struct scatterlist *scatter;
 550        int    num_scatter;
 551        u32    total_xfer_len;
 552        u8     data_dir:2;        /* Use PCI_DMA_... */
 553
 554        struct task_status_struct task_status;
 555        void   (*task_done)(struct sas_task *);
 556
 557        void   *lldd_task;        /* for use by LLDDs */
 558        void   *uldd_task;
 559
 560        struct work_struct abort_work;
 561};
 562
 563extern struct kmem_cache *sas_task_cache;
 564
 565#define SAS_TASK_STATE_PENDING      1
 566#define SAS_TASK_STATE_DONE         2
 567#define SAS_TASK_STATE_ABORTED      4
 568#define SAS_TASK_NEED_DEV_RESET     8
 569#define SAS_TASK_AT_INITIATOR       16
 570
 571static inline struct sas_task *sas_alloc_task(gfp_t flags)
 572{
 573        struct sas_task *task = kmem_cache_zalloc(sas_task_cache, flags);
 574
 575        if (task) {
 576                INIT_LIST_HEAD(&task->list);
 577                spin_lock_init(&task->task_state_lock);
 578                task->task_state_flags = SAS_TASK_STATE_PENDING;
 579                init_timer(&task->timer);
 580                init_completion(&task->completion);
 581        }
 582
 583        return task;
 584}
 585
 586static inline void sas_free_task(struct sas_task *task)
 587{
 588        if (task) {
 589                BUG_ON(!list_empty(&task->list));
 590                kmem_cache_free(sas_task_cache, task);
 591        }
 592}
 593
 594struct sas_domain_function_template {
 595        /* The class calls these to notify the LLDD of an event. */
 596        void (*lldd_port_formed)(struct asd_sas_phy *);
 597        void (*lldd_port_deformed)(struct asd_sas_phy *);
 598
 599        /* The class calls these when a device is found or gone. */
 600        int  (*lldd_dev_found)(struct domain_device *);
 601        void (*lldd_dev_gone)(struct domain_device *);
 602
 603        int (*lldd_execute_task)(struct sas_task *, int num,
 604                                 gfp_t gfp_flags);
 605
 606        /* Task Management Functions. Must be called from process context. */
 607        int (*lldd_abort_task)(struct sas_task *);
 608        int (*lldd_abort_task_set)(struct domain_device *, u8 *lun);
 609        int (*lldd_clear_aca)(struct domain_device *, u8 *lun);
 610        int (*lldd_clear_task_set)(struct domain_device *, u8 *lun);
 611        int (*lldd_I_T_nexus_reset)(struct domain_device *);
 612        int (*lldd_lu_reset)(struct domain_device *, u8 *lun);
 613        int (*lldd_query_task)(struct sas_task *);
 614
 615        /* Port and Adapter management */
 616        int (*lldd_clear_nexus_port)(struct asd_sas_port *);
 617        int (*lldd_clear_nexus_ha)(struct sas_ha_struct *);
 618
 619        /* Phy management */
 620        int (*lldd_control_phy)(struct asd_sas_phy *, enum phy_func, void *);
 621};
 622
 623extern int sas_register_ha(struct sas_ha_struct *);
 624extern int sas_unregister_ha(struct sas_ha_struct *);
 625
 626int sas_set_phy_speed(struct sas_phy *phy,
 627                      struct sas_phy_linkrates *rates);
 628int sas_phy_enable(struct sas_phy *phy, int enabled);
 629int sas_phy_reset(struct sas_phy *phy, int hard_reset);
 630int sas_queue_up(struct sas_task *task);
 631extern int sas_queuecommand(struct scsi_cmnd *,
 632                     void (*scsi_done)(struct scsi_cmnd *));
 633extern int sas_target_alloc(struct scsi_target *);
 634extern int sas_slave_alloc(struct scsi_device *);
 635extern int sas_slave_configure(struct scsi_device *);
 636extern void sas_slave_destroy(struct scsi_device *);
 637extern int sas_change_queue_depth(struct scsi_device *, int new_depth);
 638extern int sas_change_queue_type(struct scsi_device *, int qt);
 639extern int sas_bios_param(struct scsi_device *,
 640                          struct block_device *,
 641                          sector_t capacity, int *hsc);
 642extern struct scsi_transport_template *
 643sas_domain_attach_transport(struct sas_domain_function_template *);
 644extern void sas_domain_release_transport(struct scsi_transport_template *);
 645
 646int  sas_discover_root_expander(struct domain_device *);
 647
 648void sas_init_ex_attr(void);
 649
 650int  sas_ex_revalidate_domain(struct domain_device *);
 651
 652void sas_unregister_domain_devices(struct asd_sas_port *port);
 653void sas_init_disc(struct sas_discovery *disc, struct asd_sas_port *);
 654int  sas_discover_event(struct asd_sas_port *, enum discover_event ev);
 655
 656int  sas_discover_sata(struct domain_device *);
 657int  sas_discover_end_dev(struct domain_device *);
 658
 659void sas_unregister_dev(struct domain_device *);
 660
 661void sas_init_dev(struct domain_device *);
 662
 663void sas_task_abort(struct sas_task *);
 664int __sas_task_abort(struct sas_task *);
 665int sas_eh_device_reset_handler(struct scsi_cmnd *cmd);
 666int sas_eh_bus_reset_handler(struct scsi_cmnd *cmd);
 667
 668extern void sas_target_destroy(struct scsi_target *);
 669extern int sas_slave_alloc(struct scsi_device *);
 670extern int sas_ioctl(struct scsi_device *sdev, int cmd, void __user *arg);
 671
 672extern int sas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
 673                           struct request *req);
 674
 675extern void sas_ssp_task_response(struct device *dev, struct sas_task *task,
 676                                  struct ssp_response_iu *iu);
 677struct sas_phy *sas_find_local_phy(struct domain_device *dev);
 678
 679int sas_request_addr(struct Scsi_Host *shost, u8 *addr);
 680
 681#endif /* _SASLIB_H_ */
 682