linux/Documentation/scsi/libsas.rst
<<
>>
Prefs
   1.. SPDX-License-Identifier: GPL-2.0
   2
   3=========
   4SAS Layer
   5=========
   6
   7The SAS Layer is a management infrastructure which manages
   8SAS LLDDs.  It sits between SCSI Core and SAS LLDDs.  The
   9layout is as follows: while SCSI Core is concerned with
  10SAM/SPC issues, and a SAS LLDD+sequencer is concerned with
  11phy/OOB/link management, the SAS layer is concerned with:
  12
  13      * SAS Phy/Port/HA event management (LLDD generates,
  14        SAS Layer processes),
  15      * SAS Port management (creation/destruction),
  16      * SAS Domain discovery and revalidation,
  17      * SAS Domain device management,
  18      * SCSI Host registration/unregistration,
  19      * Device registration with SCSI Core (SAS) or libata
  20        (SATA), and
  21      * Expander management and exporting expander control
  22        to user space.
  23
  24A SAS LLDD is a PCI device driver.  It is concerned with
  25phy/OOB management, and vendor specific tasks and generates
  26events to the SAS layer.
  27
  28The SAS Layer does most SAS tasks as outlined in the SAS 1.1
  29spec.
  30
  31The sas_ha_struct describes the SAS LLDD to the SAS layer.
  32Most of it is used by the SAS Layer but a few fields need to
  33be initialized by the LLDDs.
  34
  35After initializing your hardware, from the probe() function
  36you call sas_register_ha(). It will register your LLDD with
  37the SCSI subsystem, creating a SCSI host and it will
  38register your SAS driver with the sysfs SAS tree it creates.
  39It will then return.  Then you enable your phys to actually
  40start OOB (at which point your driver will start calling the
  41notify_* event callbacks).
  42
  43Structure descriptions
  44======================
  45
  46``struct sas_phy``
  47------------------
  48
  49Normally this is statically embedded to your driver's
  50phy structure::
  51
  52    struct my_phy {
  53            blah;
  54            struct sas_phy sas_phy;
  55            bleh;
  56    };
  57
  58And then all the phys are an array of my_phy in your HA
  59struct (shown below).
  60
  61Then as you go along and initialize your phys you also
  62initialize the sas_phy struct, along with your own
  63phy structure.
  64
  65In general, the phys are managed by the LLDD and the ports
  66are managed by the SAS layer.  So the phys are initialized
  67and updated by the LLDD and the ports are initialized and
  68updated by the SAS layer.
  69
  70There is a scheme where the LLDD can RW certain fields,
  71and the SAS layer can only read such ones, and vice versa.
  72The idea is to avoid unnecessary locking.
  73
  74enabled
  75    - must be set (0/1)
  76
  77id
  78    - must be set [0,MAX_PHYS)]
  79
  80class, proto, type, role, oob_mode, linkrate
  81    - must be set
  82
  83oob_mode
  84    - you set this when OOB has finished and then notify
  85      the SAS Layer.
  86
  87sas_addr
  88    - this normally points to an array holding the sas
  89      address of the phy, possibly somewhere in your my_phy
  90      struct.
  91
  92attached_sas_addr
  93    - set this when you (LLDD) receive an
  94      IDENTIFY frame or a FIS frame, _before_ notifying the SAS
  95      layer.  The idea is that sometimes the LLDD may want to fake
  96      or provide a different SAS address on that phy/port and this
  97      allows it to do this.  At best you should copy the sas
  98      address from the IDENTIFY frame or maybe generate a SAS
  99      address for SATA directly attached devices.  The Discover
 100      process may later change this.
 101
 102frame_rcvd
 103    - this is where you copy the IDENTIFY/FIS frame
 104      when you get it; you lock, copy, set frame_rcvd_size and
 105      unlock the lock, and then call the event.  It is a pointer
 106      since there's no way to know your hw frame size _exactly_,
 107      so you define the actual array in your phy struct and let
 108      this pointer point to it.  You copy the frame from your
 109      DMAable memory to that area holding the lock.
 110
 111sas_prim
 112    - this is where primitives go when they're
 113      received.  See sas.h. Grab the lock, set the primitive,
 114      release the lock, notify.
 115
 116port
 117    - this points to the sas_port if the phy belongs
 118      to a port -- the LLDD only reads this. It points to the
 119      sas_port this phy is part of.  Set by the SAS Layer.
 120
 121ha
 122    - may be set; the SAS layer sets it anyway.
 123
 124lldd_phy
 125    - you should set this to point to your phy so you
 126      can find your way around faster when the SAS layer calls one
 127      of your callbacks and passes you a phy.  If the sas_phy is
 128      embedded you can also use container_of -- whatever you
 129      prefer.
 130
 131
 132``struct sas_port``
 133-------------------
 134
 135The LLDD doesn't set any fields of this struct -- it only
 136reads them.  They should be self explanatory.
 137
 138phy_mask is 32 bit, this should be enough for now, as I
 139haven't heard of a HA having more than 8 phys.
 140
 141lldd_port
 142    - I haven't found use for that -- maybe other
 143      LLDD who wish to have internal port representation can make
 144      use of this.
 145
 146``struct sas_ha_struct``
 147------------------------
 148
 149It normally is statically declared in your own LLDD
 150structure describing your adapter::
 151
 152    struct my_sas_ha {
 153        blah;
 154        struct sas_ha_struct sas_ha;
 155        struct my_phy phys[MAX_PHYS];
 156        struct sas_port sas_ports[MAX_PHYS]; /* (1) */
 157        bleh;
 158    };
 159
 160    (1) If your LLDD doesn't have its own port representation.
 161
 162What needs to be initialized (sample function given below).
 163
 164pcidev
 165^^^^^^
 166
 167sas_addr
 168       - since the SAS layer doesn't want to mess with
 169         memory allocation, etc, this points to statically
 170         allocated array somewhere (say in your host adapter
 171         structure) and holds the SAS address of the host
 172         adapter as given by you or the manufacturer, etc.
 173
 174sas_port
 175^^^^^^^^
 176
 177sas_phy
 178      - an array of pointers to structures. (see
 179        note above on sas_addr).
 180        These must be set.  See more notes below.
 181
 182num_phys
 183       - the number of phys present in the sas_phy array,
 184         and the number of ports present in the sas_port
 185         array.  There can be a maximum num_phys ports (one per
 186         port) so we drop the num_ports, and only use
 187         num_phys.
 188
 189The event interface::
 190
 191        /* LLDD calls these to notify the class of an event. */
 192        void sas_notify_port_event(struct sas_phy *, enum port_event, gfp_t);
 193        void sas_notify_phy_event(struct sas_phy *, enum phy_event, gfp_t);
 194
 195The port notification::
 196
 197        /* The class calls these to notify the LLDD of an event. */
 198        void (*lldd_port_formed)(struct sas_phy *);
 199        void (*lldd_port_deformed)(struct sas_phy *);
 200
 201If the LLDD wants notification when a port has been formed
 202or deformed it sets those to a function satisfying the type.
 203
 204A SAS LLDD should also implement at least one of the Task
 205Management Functions (TMFs) described in SAM::
 206
 207        /* Task Management Functions. Must be called from process context. */
 208        int (*lldd_abort_task)(struct sas_task *);
 209        int (*lldd_abort_task_set)(struct domain_device *, u8 *lun);
 210        int (*lldd_clear_aca)(struct domain_device *, u8 *lun);
 211        int (*lldd_clear_task_set)(struct domain_device *, u8 *lun);
 212        int (*lldd_I_T_nexus_reset)(struct domain_device *);
 213        int (*lldd_lu_reset)(struct domain_device *, u8 *lun);
 214        int (*lldd_query_task)(struct sas_task *);
 215
 216For more information please read SAM from T10.org.
 217
 218Port and Adapter management::
 219
 220        /* Port and Adapter management */
 221        int (*lldd_clear_nexus_port)(struct sas_port *);
 222        int (*lldd_clear_nexus_ha)(struct sas_ha_struct *);
 223
 224A SAS LLDD should implement at least one of those.
 225
 226Phy management::
 227
 228        /* Phy management */
 229        int (*lldd_control_phy)(struct sas_phy *, enum phy_func);
 230
 231lldd_ha
 232    - set this to point to your HA struct. You can also
 233      use container_of if you embedded it as shown above.
 234
 235A sample initialization and registration function
 236can look like this (called last thing from probe())
 237*but* before you enable the phys to do OOB::
 238
 239    static int register_sas_ha(struct my_sas_ha *my_ha)
 240    {
 241            int i;
 242            static struct sas_phy   *sas_phys[MAX_PHYS];
 243            static struct sas_port  *sas_ports[MAX_PHYS];
 244
 245            my_ha->sas_ha.sas_addr = &my_ha->sas_addr[0];
 246
 247            for (i = 0; i < MAX_PHYS; i++) {
 248                    sas_phys[i] = &my_ha->phys[i].sas_phy;
 249                    sas_ports[i] = &my_ha->sas_ports[i];
 250            }
 251
 252            my_ha->sas_ha.sas_phy  = sas_phys;
 253            my_ha->sas_ha.sas_port = sas_ports;
 254            my_ha->sas_ha.num_phys = MAX_PHYS;
 255
 256            my_ha->sas_ha.lldd_port_formed = my_port_formed;
 257
 258            my_ha->sas_ha.lldd_dev_found = my_dev_found;
 259            my_ha->sas_ha.lldd_dev_gone = my_dev_gone;
 260
 261            my_ha->sas_ha.lldd_execute_task = my_execute_task;
 262
 263            my_ha->sas_ha.lldd_abort_task     = my_abort_task;
 264            my_ha->sas_ha.lldd_abort_task_set = my_abort_task_set;
 265            my_ha->sas_ha.lldd_clear_aca      = my_clear_aca;
 266            my_ha->sas_ha.lldd_clear_task_set = my_clear_task_set;
 267            my_ha->sas_ha.lldd_I_T_nexus_reset= NULL; (2)
 268            my_ha->sas_ha.lldd_lu_reset       = my_lu_reset;
 269            my_ha->sas_ha.lldd_query_task     = my_query_task;
 270
 271            my_ha->sas_ha.lldd_clear_nexus_port = my_clear_nexus_port;
 272            my_ha->sas_ha.lldd_clear_nexus_ha = my_clear_nexus_ha;
 273
 274            my_ha->sas_ha.lldd_control_phy = my_control_phy;
 275
 276            return sas_register_ha(&my_ha->sas_ha);
 277    }
 278
 279(2) SAS 1.1 does not define I_T Nexus Reset TMF.
 280
 281Events
 282======
 283
 284Events are **the only way** a SAS LLDD notifies the SAS layer
 285of anything.  There is no other method or way a LLDD to tell
 286the SAS layer of anything happening internally or in the SAS
 287domain.
 288
 289Phy events::
 290
 291        PHYE_LOSS_OF_SIGNAL, (C)
 292        PHYE_OOB_DONE,
 293        PHYE_OOB_ERROR,      (C)
 294        PHYE_SPINUP_HOLD.
 295
 296Port events, passed on a _phy_::
 297
 298        PORTE_BYTES_DMAED,      (M)
 299        PORTE_BROADCAST_RCVD,   (E)
 300        PORTE_LINK_RESET_ERR,   (C)
 301        PORTE_TIMER_EVENT,      (C)
 302        PORTE_HARD_RESET.
 303
 304Host Adapter event:
 305        HAE_RESET
 306
 307A SAS LLDD should be able to generate
 308
 309        - at least one event from group C (choice),
 310        - events marked M (mandatory) are mandatory (only one),
 311        - events marked E (expander) if it wants the SAS layer
 312          to handle domain revalidation (only one such).
 313        - Unmarked events are optional.
 314
 315Meaning:
 316
 317HAE_RESET
 318    - when your HA got internal error and was reset.
 319
 320PORTE_BYTES_DMAED
 321    - on receiving an IDENTIFY/FIS frame
 322
 323PORTE_BROADCAST_RCVD
 324    - on receiving a primitive
 325
 326PORTE_LINK_RESET_ERR
 327    - timer expired, loss of signal, loss of DWS, etc. [1]_
 328
 329PORTE_TIMER_EVENT
 330    - DWS reset timeout timer expired [1]_
 331
 332PORTE_HARD_RESET
 333    - Hard Reset primitive received.
 334
 335PHYE_LOSS_OF_SIGNAL
 336    - the device is gone [1]_
 337
 338PHYE_OOB_DONE
 339    - OOB went fine and oob_mode is valid
 340
 341PHYE_OOB_ERROR
 342    - Error while doing OOB, the device probably
 343      got disconnected. [1]_
 344
 345PHYE_SPINUP_HOLD
 346    - SATA is present, COMWAKE not sent.
 347
 348.. [1] should set/clear the appropriate fields in the phy,
 349       or alternatively call the inlined sas_phy_disconnected()
 350       which is just a helper, from their tasklet.
 351
 352The Execute Command SCSI RPC::
 353
 354        int (*lldd_execute_task)(struct sas_task *, gfp_t gfp_flags);
 355
 356Used to queue a task to the SAS LLDD.  @task is the task to be executed.
 357@gfp_mask is the gfp_mask defining the context of the caller.
 358
 359This function should implement the Execute Command SCSI RPC,
 360
 361That is, when lldd_execute_task() is called, the command
 362go out on the transport *immediately*.  There is *no*
 363queuing of any sort and at any level in a SAS LLDD.
 364
 365Returns:
 366
 367   * -SAS_QUEUE_FULL, -ENOMEM, nothing was queued;
 368   * 0, the task(s) were queued.
 369
 370::
 371
 372    struct sas_task {
 373            dev -- the device this task is destined to
 374            task_proto -- _one_ of enum sas_proto
 375            scatter -- pointer to scatter gather list array
 376            num_scatter -- number of elements in scatter
 377            total_xfer_len -- total number of bytes expected to be transferred
 378            data_dir -- PCI_DMA_...
 379            task_done -- callback when the task has finished execution
 380    };
 381
 382Discovery
 383=========
 384
 385The sysfs tree has the following purposes:
 386
 387    a) It shows you the physical layout of the SAS domain at
 388       the current time, i.e. how the domain looks in the
 389       physical world right now.
 390    b) Shows some device parameters _at_discovery_time_.
 391
 392This is a link to the tree(1) program, very useful in
 393viewing the SAS domain:
 394ftp://mama.indstate.edu/linux/tree/
 395
 396I expect user space applications to actually create a
 397graphical interface of this.
 398
 399That is, the sysfs domain tree doesn't show or keep state if
 400you e.g., change the meaning of the READY LED MEANING
 401setting, but it does show you the current connection status
 402of the domain device.
 403
 404Keeping internal device state changes is responsibility of
 405upper layers (Command set drivers) and user space.
 406
 407When a device or devices are unplugged from the domain, this
 408is reflected in the sysfs tree immediately, and the device(s)
 409removed from the system.
 410
 411The structure domain_device describes any device in the SAS
 412domain.  It is completely managed by the SAS layer.  A task
 413points to a domain device, this is how the SAS LLDD knows
 414where to send the task(s) to.  A SAS LLDD only reads the
 415contents of the domain_device structure, but it never creates
 416or destroys one.
 417
 418Expander management from User Space
 419===================================
 420
 421In each expander directory in sysfs, there is a file called
 422"smp_portal".  It is a binary sysfs attribute file, which
 423implements an SMP portal (Note: this is *NOT* an SMP port),
 424to which user space applications can send SMP requests and
 425receive SMP responses.
 426
 427Functionality is deceptively simple:
 428
 4291. Build the SMP frame you want to send. The format and layout
 430   is described in the SAS spec.  Leave the CRC field equal 0.
 431
 432open(2)
 433
 4342. Open the expander's SMP portal sysfs file in RW mode.
 435
 436write(2)
 437
 4383. Write the frame you built in 1.
 439
 440read(2)
 441
 4424. Read the amount of data you expect to receive for the frame you built.
 443   If you receive different amount of data you expected to receive,
 444   then there was some kind of error.
 445
 446close(2)
 447
 448All this process is shown in detail in the function do_smp_func()
 449and its callers, in the file "expander_conf.c".
 450
 451The kernel functionality is implemented in the file
 452"sas_expander.c".
 453
 454The program "expander_conf.c" implements this. It takes one
 455argument, the sysfs file name of the SMP portal to the
 456expander, and gives expander information, including routing
 457tables.
 458
 459The SMP portal gives you complete control of the expander,
 460so please be careful.
 461