Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

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