Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

scsi: docs: convert libsas.txt to ReST

Link: https://lore.kernel.org/r/9022cb5551487f774cab16a828fe06b0b6b3add3.1583136624.git.mchehab+huawei@kernel.org
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>

authored by

Mauro Carvalho Chehab and committed by
Martin K. Petersen
a88dc3ec ac69461b

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