Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | \ ========== Copyright Header Begin ========================================== |
2 | \ | |
3 | \ Hypervisor Software File: scsidisk.fth | |
4 | \ | |
5 | \ Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. | |
6 | \ | |
7 | \ - Do no alter or remove copyright notices | |
8 | \ | |
9 | \ - Redistribution and use of this software in source and binary forms, with | |
10 | \ or without modification, are permitted provided that the following | |
11 | \ conditions are met: | |
12 | \ | |
13 | \ - Redistribution of source code must retain the above copyright notice, | |
14 | \ this list of conditions and the following disclaimer. | |
15 | \ | |
16 | \ - Redistribution in binary form must reproduce the above copyright notice, | |
17 | \ this list of conditions and the following disclaimer in the | |
18 | \ documentation and/or other materials provided with the distribution. | |
19 | \ | |
20 | \ Neither the name of Sun Microsystems, Inc. or the names of contributors | |
21 | \ may be used to endorse or promote products derived from this software | |
22 | \ without specific prior written permission. | |
23 | \ | |
24 | \ This software is provided "AS IS," without a warranty of any kind. | |
25 | \ ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, | |
26 | \ INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A | |
27 | \ PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN | |
28 | \ MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR | |
29 | \ ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR | |
30 | \ DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN | |
31 | \ OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR | |
32 | \ FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE | |
33 | \ DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, | |
34 | \ ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF | |
35 | \ SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. | |
36 | \ | |
37 | \ You acknowledge that this software is not designed, licensed or | |
38 | \ intended for use in the design, construction, operation or maintenance of | |
39 | \ any nuclear facility. | |
40 | \ | |
41 | \ ========== Copyright Header End ============================================ | |
42 | id: @(#)scsidisk.fth 1.1 07/01/04 | |
43 | purpose: SCSI disk package implementing a "block" device-type interface. | |
44 | copyright: Copyright 2007 Sun Microsystems, Inc. All Rights Reserved | |
45 | \ See license at end of file | |
46 | ||
47 | hex | |
48 | ||
49 | " block" device-type | |
50 | " sd" encode-string \ SUN Note - ancient history, our disk driver is "sd" | |
51 | " disk" encode-string encode+ " compatible" property | |
52 | ||
53 | fload ${BP}/dev/usb2/device/storage/scsicom.fth \ Utility routines for SCSI commands | |
54 | ||
55 | hex | |
56 | ||
57 | \ 0 means no timeout | |
58 | : set-timeout ( msecs -- ) " set-timeout" $call-parent ; | |
59 | ||
60 | 0 instance value offset-low \ Offset to start of partition | |
61 | 0 instance value offset-high | |
62 | ||
63 | external | |
64 | 0 instance value label-package | |
65 | true value report-failure | |
66 | headers | |
67 | ||
68 | \ Sets offset-low and offset-high, reflecting the starting location of the | |
69 | \ partition specified by the "my-args" string. | |
70 | ||
71 | : init-label-package ( -- okay? ) | |
72 | 0 to offset-high 0 to offset-low | |
73 | my-args " disk-label" $open-package to label-package | |
74 | label-package dup if | |
75 | 0 0 " offset" label-package $call-method to offset-high to offset-low | |
76 | else | |
77 | report-failure if | |
78 | ." Can't open disk label package" cr | |
79 | then | |
80 | then | |
81 | ; | |
82 | ||
83 | ||
84 | \ Ensures that the disk is spinning, but doesn't wait forever | |
85 | ||
86 | create sstart-cmd h# 1b c, 0 c, 0 c, 0 c, 1 c, 0 c, | |
87 | ||
88 | : timed-spin ( -- error? ) | |
89 | \ Set timeout to 45 sec: some large (>1GB) drives take | |
90 | \ up to 30 secs to spin up. | |
91 | d# 45 d# 1000 * set-timeout | |
92 | ||
93 | 0 0 true sstart-cmd 6 -1 retry-command if ( true | sensebuf false ) | |
94 | \ true on top of the stack indicates a hardware error. | |
95 | \ We don't treat "illegal request" as an error because some drives | |
96 | \ don't support the start command. Everything else other than | |
97 | \ success is considered an error. | |
98 | if true else 2+ c@ 5 <> then ( error? ) | |
99 | else ( ) | |
100 | false ( false ) | |
101 | then ( error? ) | |
102 | ||
103 | 0 set-timeout | |
104 | ; | |
105 | ||
106 | 0 instance value /block \ Device native block size | |
107 | ||
108 | create mode-sense-bd h# 1a c, 0 c, 0 c, 0 c, d# 12 c, 0 c, | |
109 | create read-capacity-cmd h# 25 c, 0 c, 0 c, 0 c, 0 c, 0 c, 0 c, 0 c, 0 c, 0 c, | |
110 | ||
111 | : read-block-extent ( -- true | block-size #blocks false ) | |
112 | \ First try "read capacity" - data returned in bytes 4,5,6,7 | |
113 | \ The SCSI-2 standard requires disk devices to implement | |
114 | \ the "read capacity" command. | |
115 | ||
116 | 8 read-capacity-cmd 0a short-data-command 0= if | |
117 | dup 4 + 4c@ swap 4c@ 1+ false exit | |
118 | then | |
119 | ||
120 | \ Failing that, try "mode sense" with an allocation length big enough only | |
121 | \ for the header and the block descriptor, in case it's a SCSI-1 device | |
122 | ||
123 | d# 12 mode-sense-bd 6 short-data-command 0= if ( adr ) | |
124 | dup 9 + 3c@ swap 4 + 4c@ false exit | |
125 | then | |
126 | ||
127 | true | |
128 | ; | |
129 | : read-block-size ( -- n ) \ Ask device about its block size | |
130 | read-block-extent if d# 512 else drop then | |
131 | ; | |
132 | ||
133 | external | |
134 | ||
135 | [ifdef] report-geometry | |
136 | create mode-sense-geometry h# 1a c, 0 c, 4 c, 0 c, d# 36 c, 0 c, | |
137 | ||
138 | \ The sector/track value reported below is an average, because modern SCSI | |
139 | \ disks often have variable geometry - fewer sectors on the inner cylinders | |
140 | \ and spare sectors and tracks located at various places on the disk. | |
141 | \ If you multiply the sectors/track number obtained from the format info | |
142 | \ mode sense code page by the heads and cylinders obtained from the geometry | |
143 | \ page, the number of blocks thus calculated usually exceeds the number of | |
144 | \ logical blocks reported in the mode sense block descriptor, often by a | |
145 | \ factor of about 25%. | |
146 | ||
147 | \ Return true for error, otherwise disk geometry and false | |
148 | : geometry ( -- true | sectors/track #heads #cylinders false ) | |
149 | d# 36 mode-sense-geometry 6 short-data-command if true exit then >r | |
150 | r@ d# 17 + c@ r@ d# 14 + 3c@ ( heads cylinders ) | |
151 | 2dup * r> d# 4 + 4c@ ( heads cylinders heads*cylinders #blocks ) | |
152 | swap / -rot ( sectors/track heads cylinders ) | |
153 | false | |
154 | ; | |
155 | [then] | |
156 | ||
157 | : #blocks ( -- true | n false ) | |
158 | read-block-extent if true else nip then | |
159 | ; | |
160 | ||
161 | \ Return device block size; cache it the first time we find the information | |
162 | \ This method is called by the deblocker | |
163 | : block-size ( -- n ) | |
164 | /block if /block exit then \ Don't ask if we already know | |
165 | ||
166 | read-block-size dup to /block | |
167 | ; | |
168 | ||
169 | headers | |
170 | ||
171 | \ Read or write "#blks" blocks starting at "block#" into memory at "addr" | |
172 | \ Input? is true for reading or false for writing. | |
173 | \ command is 8 for reading or h# a for writing | |
174 | \ We use the 6-byte forms of the disk read and write commands where possible. | |
175 | ||
176 | : 2c! ( n addr -- ) >r lbsplit 2drop r> +c! c! ; | |
177 | : 4c! ( n addr -- ) >r lbsplit r> +c! +c! +c! c! ; | |
178 | ||
179 | : r/w-blocks ( addr block# #blks input? command -- actual# ) | |
180 | cmdbuf /cmdbuf erase | |
181 | [ifdef] use-short-form | |
182 | 2over h# 100 u> swap h# 20.0000 u>= or if ( addr block# #blks dir cmd ) | |
183 | [then] | |
184 | \ Use 10-byte form | |
185 | h# 20 or 0 cb! \ 28 (read) or 2a (write) ( addr block# #blks dir ) | |
186 | -rot swap ( addr dir #blks block# ) | |
187 | cmdbuf 2 + 4c! ( addr dir #blks ) | |
188 | dup cmdbuf 7 + 2c! ( addr dir #blks ) | |
189 | d# 10 ( addr dir #blks cmdlen ) | |
190 | [ifdef] use-short-form | |
191 | else ( addr block# #blks dir cmd ) | |
192 | \ Use 6-byte form | |
193 | 0 cb! ( addr block# #blks dir ) | |
194 | -rot swap ( addr dir #blks block# ) | |
195 | cmdbuf 1+ 3c! ( addr dir #blks ) | |
196 | dup 4 cb! ( addr dir #blks ) | |
197 | 6 ( addr dir #blks cmdlen ) | |
198 | then | |
199 | [then] | |
200 | swap ( addr dir cmdlen #blks ) | |
201 | dup >r ( addr input? cmdlen #blks ) | |
202 | /block * -rot cmdbuf swap -1 ( addr #bytes input? cmd cmdlen #retries ) | |
203 | retry-command if ( [ sensebuf ] hw? ) | |
204 | 0= if drop then r> drop 0 | |
205 | else | |
206 | r> | |
207 | then ( actual# ) | |
208 | ; | |
209 | ||
210 | external | |
211 | ||
212 | \ These three methods are called by the deblocker. | |
213 | ||
214 | : max-transfer ( -- n ) parent-max-transfer ; | |
215 | : read-blocks ( addr block# #blocks -- #read ) | |
216 | \ SUN Note - the following does not exist on SUN machines. Besides, | |
217 | \ sticking an "evaluate" in the middle of code is bad form. | |
218 | \ " show-progress" evaluate | |
219 | true d# 8 r/w-blocks | |
220 | ; | |
221 | : write-blocks ( addr block# #blocks -- #written ) false d# 10 r/w-blocks ; | |
222 | ||
223 | \ Methods used by external clients | |
224 | ||
225 | : open ( -- flag ) | |
226 | my-unit " set-address" $call-parent | |
227 | ||
228 | \ It might be a good idea to do an inquiry here to determine the | |
229 | \ device configuration, checking the result to see if the device | |
230 | \ really is a disk. | |
231 | ||
232 | \ Make sure the disk is spinning | |
233 | ||
234 | timed-spin if false exit then | |
235 | ||
236 | block-size to /block | |
237 | ||
238 | init-deblocker 0= if false exit then | |
239 | ||
240 | init-label-package 0= if | |
241 | deblocker close-package false exit | |
242 | then | |
243 | ||
244 | true | |
245 | ; | |
246 | ||
247 | : close ( -- ) | |
248 | label-package close-package | |
249 | deblocker close-package | |
250 | ; | |
251 | ||
252 | : seek ( offset.low offset.high -- okay? ) | |
253 | offset-low offset-high d+ " seek" deblocker $call-method | |
254 | ; | |
255 | ||
256 | : read ( addr len -- actual-len ) " read" deblocker $call-method ; | |
257 | : write ( addr len -- actual-len ) " write" deblocker $call-method ; | |
258 | : load ( addr -- size ) " load" label-package $call-method ; | |
259 | ||
260 | : size ( -- d.size ) " size" label-package $call-method ; | |
261 | headers | |
262 | ||
263 | \ LICENSE_BEGIN | |
264 | \ Copyright (c) 2006 FirmWorks | |
265 | \ | |
266 | \ Permission is hereby granted, free of charge, to any person obtaining | |
267 | \ a copy of this software and associated documentation files (the | |
268 | \ "Software"), to deal in the Software without restriction, including | |
269 | \ without limitation the rights to use, copy, modify, merge, publish, | |
270 | \ distribute, sublicense, and/or sell copies of the Software, and to | |
271 | \ permit persons to whom the Software is furnished to do so, subject to | |
272 | \ the following conditions: | |
273 | \ | |
274 | \ The above copyright notice and this permission notice shall be | |
275 | \ included in all copies or substantial portions of the Software. | |
276 | \ | |
277 | \ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
278 | \ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
279 | \ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |
280 | \ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | |
281 | \ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | |
282 | \ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | |
283 | \ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
284 | \ | |
285 | \ LICENSE_END |