]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/atazz/atazz.ms
merge
[plan9front.git] / sys / src / cmd / atazz / atazz.ms
1 .FP lucidasans
2 .TL
3 ATA au Naturel
4 .AU
5 Erik Quanstrom
6 quanstro@quanstro.net
7 .AB
8 The Plan 9
9 .I sd (3)
10 interface allows raw commands to be sent.  Traditionally,
11 only SCSI CDBs could be sent in this manner.  For devices
12 that respond to ATA/ATAPI commands, a small set of SCSI CDBs
13 have been translated into an ATA equivalent.  This approach
14 works very well.  However, there are ATA commands such as
15 SMART which do not have direct translations.  I describe how
16 ATA/ATAPI commands were supported without disturbing
17 existing functionality.
18 .AE
19 .SH
20 Introduction
21 .PP
22 In writing new
23 .I sd (3)
24 drivers for plan 9, it has been necessary to copy laundry
25 list of special commands that were needed with previous
26 drivers.  The set of commands supported by each device
27 driver varies, and they are typically executed by writing a
28 magic string into the driver's
29 .CW ctl
30 file.  This requires code duplicated for each driver, and
31 covers few commands.  Coverage depends on the driver.  It is
32 not possible for the control interface to return output,
33 making some commands impossible to implement.  While a
34 work around has been to change the contents of the control
35 file, this solution is extremely unwieldy even for simple
36 commands such as
37 .CW "IDENTIFY DEVICE" .
38 .SH
39 Considerations
40 .PP
41 Currently, all 
42 .I sd
43 devices respond to a small subset of SCSI commands
44 through the raw interface and the normal read/write interface uses
45 SCSI command blocks.  SCSI devices, of course, respond natively
46 while ATA devices emulate these commands with the help
47 .I sd .
48 This means that
49 .I scuzz (8)
50 can get surprisingly far with ATA devices, and ATAPI 
51 .I \fP(\fPsic. )
52 devices
53 work quite well.  Although a new implementation might not
54 use this approach, replacing the interface did not appear
55 cost effective and would lead to maximum incompatibilities,
56 while this interface is experimental.  This means that the raw interface will need
57 a method of signaling an ATA command rather than a SCSI CDB.
58 .PP
59 An unattractive wart of the ATA command set is there are seven
60 protocols and two command sizes.  While each command has a
61 specific size (either 28-bit LBA or 48-bit LLBA) and is
62 associated with a particular protocol (PIO, DMA, PACKET,
63 etc.), this information is available only by table lookup.
64 While this information may not always be necessary for simple
65 SATA-based controllers, for the IDE controllers, it is required.
66 PIO commands are required and use a different set of registers
67 than DMA commands.  Queued DMA commands and ATAPI
68 commands are submitted differently still.  Finally,
69 the data direction is implied by the command.  Having these
70 three extra pieces of information in addition to the command
71 seems necessary.
72 .PP
73 A final bit of extra-command information that may be useful
74 is a timeout.  While
75 .I alarm (2)
76 timeouts work with many drivers, it would be an added
77 convenience to be able to specify a timeout along with the
78 command.  This seems a good idea in principle, since some
79 ATA commands should return within milli- or microseconds,
80 others may take hours to complete.  On the other hand, the
81 existing SCSI interface does not support it and changing its
82 kernel-to-user space format would be quite invasive.  Timeouts
83 were left for a later date.
84 .SH
85 Protocol and Data Format
86 .PP
87 The existing protocol for SCSI commands suits ATA as well.
88 We simply write the command block to the raw device.  Then
89 we either write or read the data.  Finally the status block
90 is read.  What remains is choosing a data format for ATA
91 commands.
92 .PP
93 The T10 Committee has defined a SCSI-to-ATA translation
94 scheme called SAT[4].  This provides a standard set of
95 translations between common SCSI commands and ATA commands.
96 It specifies the ATA protocol and some other sideband
97 information.  It is particularly useful for common commands
98 such as
99 .CW "READ\ (12)"
100 or
101 .CW "READ CAPACITY\ (12)" .
102 Unfortunately, our purpose is to address the uncommon commands.
103 For those, special commands
104 .CW "ATA PASSTHROUGH\ (12)"
105 and
106 .CW "(16)"
107 exist.  Unfortunately several commands we are interested in,
108 such as those that set transfer modes are not allowed by the
109 standard.  This is not a major obstacle.  We could simply
110 ignore the standard.  But this goes against the general
111 reasons for using an established standard: interoperability.
112 Finally, it should be mentioned that SAT format adds yet
113 another intermediate format of variable size which would
114 require translation to a usable format for all the existing
115 Plan 9 drivers.  If we're not hewing to a standard, we should
116 build or choose for convenience.
117 .PP
118 ATA-8 and ACS-2 also specify an abstract register layout.
119 The size of the command block varies based on the “size”
120 (either 28- or 48-bits) of the command and only context
121 differentiates a command from a response.  The SATA
122 specification defines host-to-drive communications.  The
123 formats of transactions are called Frame Information
124 Structures (FISes).  Typically drivers fill out the command
125 FISes directly and have direct access to the Device-to-Host
126 Register (D2H) FISes that return the resulting ATA register
127 settings.  The command FISes are also called Host-to-Device
128 (H2D) Register FISes.  Using this structure has several advantages.  It
129 is directly usable by many of the existing SATA drivers.
130 All SATA commands are the same size and are tagged as
131 commands.  Normal responses are also all of the same size
132 and are tagged as responses.  Unfortunately, the ATA
133 protocol is not specified.  Nevertheless, SATA FISes seem to
134 handle most of our needs and are quite convenient; they can
135 be used directly by two of the three current SATA drivers.
136 .SH
137 Implementation
138 .PP
139 Raw ATA commands are formatted as a ATA escape byte, an
140 encoded ATA protocol
141 .CW proto
142 and the FIS.  Typically this would be a
143 H2D FIS, but this is not a requirement.  The escape byte
144 .R 0xff ,
145 which is not and, according to the current specification,
146 will never be a valid SCSI command, was chosen.  The
147 protocol encoding
148 .CW proto
149 and other FIS construction details are specified in
150 .CW "/sys/include/fis.h" .
151 The
152 .CW proto
153 encodes the ATA protocol, the command “size” and data
154 direction.  The “atazz” command format is pictured in \*(Fn.
155 .F1
156 .PS
157 scale=10
158 w=8
159 h=2
160 define hdr |
161 [
162         box $1          ht h wid w
163 ] |
164 define fis |
165 [
166         box $1          ht h wid w
167 ] |
168
169 F: [
170 A:      hdr("0xff")
171         hdr("proto")
172         hdr("0x27")
173         hdr("flags")
174
175 B:      hdr("cmd")              at A+(0, -h)
176         hdr("feat")
177         hdr("lba0")
178         hdr("lba8")
179
180 C:      hdr("lba16")            at B+(0, -h)
181         hdr("dev")
182         hdr("lba24")
183         hdr("lba32")
184
185 D:      hdr("lba40")            at C+(0, -h)
186         hdr("feat8")
187         hdr("cnt")
188         hdr("cnt8")
189
190 E:      hdr("rsvd")             at D+(0, -h)
191         hdr("ctl")
192 ]
193 G: [
194         fis("sdXX/raw")
195 ]                               at F.se +(w*2, -h)
196 arrow from F.e to G.w
197 H: [
198         fis("data")
199 ]                               at G.sw +(-w*2, -h)
200 HH: [
201         fis("sdXX/raw")
202 ]                               at H.se +(w*2, -h)
203
204 arrow from H.e to HH.w
205
206 Q: [
207         fis("sdXX/raw")
208 ]                               at HH +(0, -2*h)
209
210 I: [
211 K:      hdr("0xff")
212         hdr("proto")
213         hdr("0x34")
214         hdr("port");
215
216 L:      hdr("stat")             at K+(0, -h)
217         hdr("err")
218         hdr("lba0")
219         hdr("lba8")
220
221 M:      hdr("lba16")            at L+(0, -h)
222         hdr("dev")
223         hdr("lba24")
224         hdr("lba32")
225
226 O:      hdr("lba40")            at M+(0, -h)
227         hdr("feat8")
228         hdr("cnt")
229         hdr("cnt8")
230
231 P:      hdr("rsvd")             at O+(0, -h)
232         hdr("ctl")
233 ]                               at Q.sw +(-w*3.5, -3*h)
234 arrow from Q.w to I.e
235
236 .PE
237 .F2
238 .F3
239 .PP
240 Raw ATA replies are formatted as a one-byte
241 .R  sd
242 status code followed by the reply FIS.
243 The usual read/write register substitutions are
244 applied; ioport replaces flags, status replaces cmd, error
245 replaces feature.
246 .PP
247 Important commands such as
248 .CW "SMART RETURN STATUS"
249 return no data.  In this case, the protocol is run as usual.
250 The client performs a 0-byte read to fulfill data transfer
251 step.  The status is in the D2H FIS returned as the status.
252 The vendor ATA command
253 .R 0xf0
254 is used to return the device signature FIS as there is no
255 universal in-band way to do this without side effects.
256 When talking only to ATA drives, it is possible to first
257 issue a
258 .CW "IDENTIFY PACKET DEVICE"
259 and then a
260 .CW "IDENTIFY DEVICE"
261 command, inferring the device type from the successful
262 command.  However, it would not be possible to enumerate the
263 devices behind a port multiplier using this technique.
264 .SH
265 Kernel changes and Libfis
266 .PP
267 Very few changes were made to devsd to accommodate ATA
268 commands.  the
269 .CW SDreq
270 structure adds
271 .CW proto
272 and
273 .CW ataproto
274 fields.  To avoid disturbing existing SCSI functionality and
275 to allow drivers which support SCSI and ATA commands in
276 parallel, an additional
277 .CW ataio
278 callback was added to
279 .CW SDifc
280 with the same signature as
281 the existing
282 .CW rio
283 callback.  About twenty lines of code were
284 added to
285 .CW port/devsd.c 
286 to recognize raw ATA commands and call the
287 driver's
288 .CW ataio
289 function.
290 .PP
291 To assist in generating the FISes to communicate with devices,
292 .CW libfis
293 was written.  It contains functions to identify and
294 enumerate the important features of a drive, to format
295 H2D FISes And finally, functions for
296 .I sd
297 and
298 .I sd
299 -devices to build D2H FISes to
300 capture the device signature.
301 .PP
302 All ATA device drivers for the 386 architecture have been
303 modified to accept raw ATA commands.  Due to consolidation
304 of FIS handling, the AHCI driver lost
305 175 lines of code, additional non-atazz-related functionality
306 notwithstanding.  The IDE driver remained exactly the same
307 size.  Quite a bit more code could be removed if the driver
308 were reorganized.  The mv50xx driver gained 153 lines of
309 code.  Development versions of the Marvell Orion driver
310 lost over 500 lines while
311 .CW libfis
312 is only about the same line count.
313 .PP
314 Since FIS formats were used to convey
315 commands from user space,
316 .CW libfis
317 has been equally useful for user space applications.  This is
318 because the
319 .I atazz
320 interface can be thought of as an idealized HBA.  Conversely,
321 the hardware driver does not need to know anything about
322 the command it is issuing beyond the ATA protocol.
323 .SH
324 Atazz
325 .PP
326 As an example and debugging tool, the
327 .I atazz (8)
328 command was written.
329 .I Atazz
330 is an analog to
331 .I scuzz (8);
332 they can be thought of as a driver for a virtual interface provided
333 by
334 .I sd
335 combined with a disk console.
336 ATA commands are spelled out verbosely as in ACS-2.  Arbitrary ATA
337 commands may be submitted, but the controller or driver may
338 not support all of them.  Here is a sample transcript:
339 .P1
340 az> probe
341 /dev/sda0       976773168; 512  50000f001b206489
342 /dev/sdC1       0; 0    0
343 /dev/sdD0       1023120; 512    0
344 /dev/sdE0       976773168; 512  50014ee2014f5b5a
345 /dev/sdF7       976773168; 512  5000cca214c3a6d3
346 az> open /dev/sdF0
347 az> smart enable operations
348 az> smart return status
349 normal
350 az> rfis
351 00
352 34405000004fc2a00000000000000000
353 .P2
354 .PP
355 In the example, the
356 .CW probe
357 command is a special command that uses
358 .CW #S/sdctl
359 to enumerate the controllers in the system.
360 For each controller, the 
361 .CW sd
362 vendor command
363 .CW 0xf0
364 .CW \fP(\fPGET
365 .CW SIGNATURE )
366 is issued.  If this command is successful, the
367 number of sectors, sector size and WWN are gathered
368 and and listed.  The
369 .CW /dev/sdC1
370 device reports 0 sectors and 0 sector size because it is
371 a DVD-RW with no media.  The
372 .CW open
373 command is another special command that issues the
374 same commands a SATA driver would issue to gather
375 the information about the drive.  The final two commands
376 enable SMART
377 and return the SMART status.  The smart status is
378 returned in a D2H FIS.  This result is parsed the result
379 is printed as either “normal,” or “threshold exceeded”
380 (the drive predicts imminent failure).
381 .PP
382 As a further real-world example, a drive from my file server
383 failed after a power outage.  The simple diagnostic
384 .CW "SMART RETURN STATUS"
385 returned an uninformative “threshold exceeded.”
386 We can run some more in-depth tests.  In this case we
387 will need to make up for the fact that
388 .I atazz
389 does not know every option to every command.  We
390 will set the
391 .CW lba0
392 register by hand:
393 .P1
394 az> smart lba0 1 execute off-line immediate     # short data collection
395 az> smart read data
396 col status: 00 never started
397 exe status: 89 failed: shipping damage, 90% left
398 time left: 10507s
399 shrt poll: 176m
400 ext poll: 19m
401 az> 
402 .P2
403 .PP
404 Here we see that the drive claims that it was damaged in
405 shipping and the damage occurred in the first 10% of the
406 drive.  Since we know the drive had been working before
407 the power outage, and the original symptom was excessive
408 UREs (Unrecoverable Read Errors) followed by write
409 failures, and finally a threshold exceeded condition, it is
410 reasonable to assume that the head may have crashed.
411 .SH
412 Stand Alone Applications
413 .PP
414 There are several obvious stand-alone applications for
415 this functionality: a drive firmware upgrade utility,
416 a drive scrubber that bypasses the drive cache and a
417 SMART monitor.
418 .PP
419 Since SCSI also supports a basic SMART-like
420 interface through the
421 .CW "SEND DIAGNOSTIC"
422 and
423 .CW "RECEIVE DIAGNOSTIC RESULTS"
424 commands,
425 .I disk/smart (8)
426 gives a chance to test both raw ATA and SCSI
427 commands in the same application.
428 .PP
429 .I Disk/smart
430 uses the usual techniques for gathering a list of
431 devices or uses the devices given.  Then it issues a raw ATA request for
432 the device signature.  If that fails, it is assumed
433 that the drive is SCSI, and a raw SCSI request is issued.
434 In both cases,
435 .I disk/smart
436 is able to reliably determine if SMART is supported
437 and can be enabled.
438 .PP
439 If successful, each device is probed every 5 minutes
440 and failures are logged.  A one shot mode is also
441 available:
442 .P1
443 chula# disk/smart -atv
444 sda0: normal
445 sda1: normal
446 sda2: normal
447 sda3: threshold exceeded
448 sdE1: normal
449 sdF7: normal
450 .P2
451 .PP
452 Drives
453 .CW sda0 ,
454 .CW sda1
455 are SCSI
456 and the remainder are ATA.  Note that other drives
457 on the same controller are ATA.
458 Recalling that
459 .CW sdC0
460 was previously listed, we can check to see why no
461 results were reported by
462 .CW sdC0 :
463 .P1
464 chula# for(i in a3 C0)
465         echo identify device | 
466                 atazz /dev/sd$i >[2]/dev/null |
467                 grep '^flags'
468 flags   lba llba smart power nop sct 
469 flags   lba 
470 .P2
471 So we see that
472 .CW sdC0
473 simply does not support the SMART feature set.
474 .SH
475 Further Work
476 .PP
477 While the raw ATA interface has been used extensively
478 from user space and has allowed the removal of quirky
479 functionality, device setup has not yet been addressed.
480 For example, both the Orion and AHCI drivers have
481 an initialization routine similar to the following
482 .P1
483 newdrive(Drive *d)
484 {
485         setfissig(d, getsig(d));
486         if(identify(d) != 0)
487                 return SDeio;
488         setpowermode(d);
489         if(settxmode(d, d->udma) != 0)
490                 return SDeio;
491         return SDok;
492 }
493 .P2
494 However in preparing this document, it was discovered
495 that one sets the power mode before setting the
496 transfer mode and the other does the opposite.  It is
497 not clear that this particular difference is a problem,
498 but over time, such differences will be the source of bugs.
499 Neither the IDE nor the Marvell 50xx drivers sets the
500 power mode at all.  Worse,
501 none is capable of properly addressing drives with
502 features such as PUIS (Power Up In Standby) enabled.
503 To addresses this problem all four of the ATA drivers would
504 need to be changed.
505 .PP
506 Rather than maintaining a number of mutually out-of-date
507 drivers, it would be advantageous to build an ATA analog
508 of
509 .CW pc/sdscsi.c
510 using the raw ATA interface to submit ATA commands.
511 There are some difficulties that make such a change a bit
512 more than trivial.  Since current model for hot-pluggable
513 devices is not compatible with the top-down
514 approach currently taken by
515 .I sd 
516 this would need to be addressed.  It does not seem that
517 this would be difficult.  Interface resets after failed commands
518 should also be addressed.
519 .SH
520 Source
521 .PP
522 The current source including all the pc drivers and applications
523 are available
524 in the following
525 .I contrib (1)
526 packages on
527 .I sources :
528 .br
529 .CW "quanstro/fis" ,
530 .br
531 .CW "quanstro/sd" ,
532 .br
533 .CW "quanstro/atazz" ,
534 and
535 .br
536 .CW "quanstro/smart" .
537 .PP
538 The following manual pages are included:
539 .br
540 .I fis (2),
541 .I sd (3),
542 .I sdahci (3),
543 .I sdaoe (3),
544 .I sdloop (3),
545 .I sdorion (3),
546 .I atazz (8),
547 and
548 .I smart (8).
549 .SH
550 Abbreviated References
551 .nr PI 5n
552 .IP [1]
553 .I sd (1),
554 published online at
555 .br
556 .CW "http://plan9.bell-labs.com/magic/man2html/3/sd" .
557 .IP [2]
558 .I scuzz (8),
559 published online at
560 .br
561 .CW "http://plan9.bell-labs.com/magic/man2html/8/scuzz" .
562 .IP [3]
563 T13
564 .I "ATA/ATAPI Command Set\ \-\ 2" ,
565 revision 1, January 21, 2009,
566 formerly published online at 
567 .CW "http://www.t13.org" .
568 .IP [4]
569 T10
570 .I "SCSI/ATA Translation\ \-\ 2 (SAT\-2)" ,
571 revision 7, February 18, 2007,
572 formerly published online at
573 .CW "http://www.t10.org" .