Add the files.
[platform/kernel/u-boot.git] / drivers / at45.c
1 /* Driver for ATMEL DataFlash support
2  * Author : Hamid Ikdoumi (Atmel)
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of
7  * the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
17  * MA 02111-1307 USA
18  *
19  */
20
21 #include <config.h>
22 #include <common.h>
23
24 #ifdef CONFIG_HAS_DATAFLASH
25 #include <dataflash.h>
26
27
28 #define AT91C_TIMEOUT_WRDY                      200000
29
30
31 /*----------------------------------------------------------------------*/
32 /* \fn    AT91F_DataFlashSendCommand                                    */
33 /* \brief Generic function to send a command to the dataflash           */
34 /*----------------------------------------------------------------------*/ 
35 AT91S_DataFlashStatus AT91F_DataFlashSendCommand(
36         AT91PS_DataFlash pDataFlash,
37         unsigned char OpCode,
38         unsigned int CmdSize,
39         unsigned int DataflashAddress)
40 {
41         unsigned int adr;
42
43         if ( (pDataFlash->pDataFlashDesc->state) != IDLE)
44                 return DATAFLASH_BUSY;
45
46         /* process the address to obtain page address and byte address */
47         adr = ((DataflashAddress / (pDataFlash->pDevice->pages_size)) << 
48                 pDataFlash->pDevice->page_offset) + (DataflashAddress % 
49                 (pDataFlash->pDevice->pages_size));
50
51         /* fill the  command  buffer */
52         pDataFlash->pDataFlashDesc->command[0] = OpCode;
53         if (pDataFlash->pDevice->pages_number >= 16384) {
54                 pDataFlash->pDataFlashDesc->command[1] = 
55                         (unsigned char)((adr & 0x0F000000) >> 24);
56                 pDataFlash->pDataFlashDesc->command[2] = 
57                         (unsigned char)((adr & 0x00FF0000) >> 16);
58                 pDataFlash->pDataFlashDesc->command[3] = 
59                         (unsigned char)((adr & 0x0000FF00) >> 8);
60                 pDataFlash->pDataFlashDesc->command[4] = 
61                         (unsigned char)(adr & 0x000000FF);
62         } else {
63                 pDataFlash->pDataFlashDesc->command[1] = 
64                         (unsigned char)((adr & 0x00FF0000) >> 16);
65                 pDataFlash->pDataFlashDesc->command[2] = 
66                         (unsigned char)((adr & 0x0000FF00) >> 8);
67                 pDataFlash->pDataFlashDesc->command[3] = 
68                         (unsigned char)(adr & 0x000000FF);
69                 pDataFlash->pDataFlashDesc->command[4] = 0;
70         }
71         pDataFlash->pDataFlashDesc->command[5] = 0;
72         pDataFlash->pDataFlashDesc->command[6] = 0;
73         pDataFlash->pDataFlashDesc->command[7] = 0;
74
75         /* Initialize the SpiData structure for the spi write fuction */
76         pDataFlash->pDataFlashDesc->tx_cmd_pt   =  
77                 pDataFlash->pDataFlashDesc->command;
78         pDataFlash->pDataFlashDesc->tx_cmd_size =  CmdSize;
79         pDataFlash->pDataFlashDesc->rx_cmd_pt   =  
80                 pDataFlash->pDataFlashDesc->command;
81         pDataFlash->pDataFlashDesc->rx_cmd_size =  CmdSize;
82
83         /* send the command and read the data */
84         return AT91F_SpiWrite (pDataFlash->pDataFlashDesc); }
85
86
87 /*----------------------------------------------------------------------*/
88 /* \fn    AT91F_DataFlashGetStatus                                      */
89 /* \brief Read the status register of the dataflash                     */
90 /*----------------------------------------------------------------------*/ 
91 AT91S_DataFlashStatus AT91F_DataFlashGetStatus(AT91PS_DataflashDesc pDesc) 
92 {
93         AT91S_DataFlashStatus status;
94
95         /* if a transfert is in progress ==> return 0 */
96         if( (pDesc->state) != IDLE)
97                 return DATAFLASH_BUSY;
98
99         /* first send the read status command (D7H) */
100         pDesc->command[0] = DB_STATUS;
101         pDesc->command[1] = 0;
102
103         pDesc->DataFlash_state  = GET_STATUS;
104         pDesc->tx_data_size     = 0;    /* Transmit the command */
105                                         /* and receive response */
106         pDesc->tx_cmd_pt                = pDesc->command;
107         pDesc->rx_cmd_pt                = pDesc->command;
108         pDesc->rx_cmd_size              = 2;
109         pDesc->tx_cmd_size              = 2;
110         status = AT91F_SpiWrite (pDesc);
111
112         pDesc->DataFlash_state = *( (unsigned char *) (pDesc->rx_cmd_pt) +1);
113
114         return status;
115 }
116
117
118 /*----------------------------------------------------------------------*/
119 /* \fn    AT91F_DataFlashWaitReady                                      */
120 /* \brief wait for dataflash ready (bit7 of the status register == 1)   */
121 /*----------------------------------------------------------------------*/ 
122 AT91S_DataFlashStatus AT91F_DataFlashWaitReady(AT91PS_DataflashDesc 
123 pDataFlashDesc, unsigned int timeout) 
124 {
125         pDataFlashDesc->DataFlash_state = IDLE;
126
127         do {
128                 AT91F_DataFlashGetStatus(pDataFlashDesc);
129                 timeout--;
130         } while( ((pDataFlashDesc->DataFlash_state & 0x80) != 0x80) && 
131                         (timeout > 0) );
132
133         if((pDataFlashDesc->DataFlash_state & 0x80) != 0x80)
134                 return DATAFLASH_ERROR;
135
136         return DATAFLASH_OK;
137 }
138
139
140 /*--------------------------------------------------------------------------*/
141 /* Function Name       : AT91F_DataFlashContinuousRead                      */
142 /* Object              : Continuous stream Read                             */
143 /* Input Parameters    : DataFlash Service                                  */
144 /*                                              : <src> = dataflash address */
145 /*                     : <*dataBuffer> = data buffer pointer                */
146 /*                     : <sizeToRead> = data buffer size                    */
147 /* Return value         : State of the dataflash                            */
148 /*--------------------------------------------------------------------------*/ 
149 AT91S_DataFlashStatus AT91F_DataFlashContinuousRead (
150         AT91PS_DataFlash pDataFlash,
151         int src,
152         unsigned char *dataBuffer,
153         int sizeToRead )
154 {
155         AT91S_DataFlashStatus status;
156         /* Test the size to read in the device */
157         if ( (src + sizeToRead) > 
158                 (pDataFlash->pDevice->pages_size * 
159                 (pDataFlash->pDevice->pages_number)))
160                 return DATAFLASH_MEMORY_OVERFLOW;
161
162         pDataFlash->pDataFlashDesc->rx_data_pt = dataBuffer;
163         pDataFlash->pDataFlashDesc->rx_data_size = sizeToRead;
164         pDataFlash->pDataFlashDesc->tx_data_pt = dataBuffer;
165         pDataFlash->pDataFlashDesc->tx_data_size = sizeToRead;
166
167         status = AT91F_DataFlashSendCommand 
168                         (pDataFlash, DB_CONTINUOUS_ARRAY_READ, 8, src);
169         /* Send the command to the dataflash */
170         return(status);
171 }
172
173
174 /*---------------------------------------------------------------------------*/
175 /* Function Name       : AT91F_DataFlashPagePgmBuf                           */
176 /* Object              : Main memory page program thru buffer 1 or buffer 2  */
177 /* Input Parameters    : DataFlash Service                                   */
178 /*                                              : <*src> = Source buffer     */
179 /*                     : <dest> = dataflash destination address              */
180 /*                     : <SizeToWrite> = data buffer size                    */
181 /* Return value         : State of the dataflash                             */
182 /*---------------------------------------------------------------------------*/ 
183 AT91S_DataFlashStatus AT91F_DataFlashPagePgmBuf(
184         AT91PS_DataFlash pDataFlash,
185         unsigned char *src,
186         unsigned int dest,
187         unsigned int SizeToWrite)
188 {
189         int cmdsize;
190         pDataFlash->pDataFlashDesc->tx_data_pt = src;
191         pDataFlash->pDataFlashDesc->tx_data_size = SizeToWrite;
192         pDataFlash->pDataFlashDesc->rx_data_pt = src;
193         pDataFlash->pDataFlashDesc->rx_data_size = SizeToWrite;
194
195         cmdsize = 4;
196         /* Send the command to the dataflash */
197         if (pDataFlash->pDevice->pages_number >= 16384)
198                 cmdsize = 5;
199         return(AT91F_DataFlashSendCommand (pDataFlash, DB_PAGE_PGM_BUF1, 
200 cmdsize, dest)); }
201
202
203 /*---------------------------------------------------------------------------*/
204 /* Function Name       : AT91F_MainMemoryToBufferTransfert                   */
205 /* Object              : Read a page in the SRAM Buffer 1 or 2               */
206 /* Input Parameters    : DataFlash Service                                   */
207 /*                     : Page concerned                                      */
208 /*                     :                                                     */
209 /* Return value         : State of the dataflash                             */
210 /*---------------------------------------------------------------------------*/ 
211 AT91S_DataFlashStatus AT91F_MainMemoryToBufferTransfert(
212         AT91PS_DataFlash pDataFlash,
213         unsigned char BufferCommand,
214         unsigned int page)
215 {
216         int cmdsize;
217         /* Test if the buffer command is legal */
218         if ((BufferCommand != DB_PAGE_2_BUF1_TRF) 
219                 && (BufferCommand != DB_PAGE_2_BUF2_TRF))
220                 return DATAFLASH_BAD_COMMAND;
221
222         /* no data to transmit or receive */
223         pDataFlash->pDataFlashDesc->tx_data_size = 0;
224         cmdsize = 4;
225         if (pDataFlash->pDevice->pages_number >= 16384)
226                 cmdsize = 5;
227         return(AT91F_DataFlashSendCommand (pDataFlash, BufferCommand, cmdsize, 
228 page*pDataFlash->pDevice->pages_size));
229 }
230
231
232 /*-------------------------------------------------------------------------- */
233 /* Function Name       : AT91F_DataFlashWriteBuffer                          */
234 /* Object              : Write data to the internal sram buffer 1 or 2       */
235 /* Input Parameters    : DataFlash Service                                   */
236 /*                      : <BufferCommand> = command to write buffer1 or 2    */
237 /*                     : <*dataBuffer> = data buffer to write                */
238 /*                     : <bufferAddress> = address in the internal buffer    */
239 /*                     : <SizeToWrite> = data buffer size                    */
240 /* Return value         : State of the dataflash                             */
241 /*---------------------------------------------------------------------------*/
242 AT91S_DataFlashStatus AT91F_DataFlashWriteBuffer (
243         AT91PS_DataFlash pDataFlash,
244         unsigned char BufferCommand,
245         unsigned char *dataBuffer,
246         unsigned int bufferAddress,
247         int SizeToWrite )
248 {
249         int cmdsize;
250         /* Test if the buffer command is legal */
251         if ((BufferCommand != DB_BUF1_WRITE) 
252                 && (BufferCommand != DB_BUF2_WRITE))
253                 return DATAFLASH_BAD_COMMAND;
254
255         /* buffer address must be lower than page size */
256         if (bufferAddress > pDataFlash->pDevice->pages_size)
257                 return DATAFLASH_BAD_ADDRESS;
258
259         if ( (pDataFlash->pDataFlashDesc->state)  != IDLE)
260                 return DATAFLASH_BUSY;
261
262         /* Send first Write Command */
263         pDataFlash->pDataFlashDesc->command[0] = BufferCommand;
264         pDataFlash->pDataFlashDesc->command[1] = 0;
265         if (pDataFlash->pDevice->pages_number >= 16384) {
266                 pDataFlash->pDataFlashDesc->command[2] = 0;
267                 pDataFlash->pDataFlashDesc->command[3] = 
268                         (unsigned char)(((unsigned int)(bufferAddress &  
269                                 pDataFlash->pDevice->byte_mask)) >> 8);
270                 pDataFlash->pDataFlashDesc->command[4] = 
271                         (unsigned char)((unsigned int)bufferAddress  & 0x00FF);
272                 cmdsize = 5;
273         } else {
274                 pDataFlash->pDataFlashDesc->command[2] = 
275                         (unsigned char)(((unsigned int)(bufferAddress & 
276                                 pDataFlash->pDevice->byte_mask)) >> 8);
277                 pDataFlash->pDataFlashDesc->command[3] = 
278                         (unsigned char)((unsigned int)bufferAddress  & 0x00FF);
279                 pDataFlash->pDataFlashDesc->command[4] = 0;
280                 cmdsize = 4;
281         }
282
283         pDataFlash->pDataFlashDesc->tx_cmd_pt    = 
284                 pDataFlash->pDataFlashDesc->command;
285         pDataFlash->pDataFlashDesc->tx_cmd_size = cmdsize;
286         pDataFlash->pDataFlashDesc->rx_cmd_pt    = 
287                 pDataFlash->pDataFlashDesc->command;
288         pDataFlash->pDataFlashDesc->rx_cmd_size = cmdsize;
289
290         pDataFlash->pDataFlashDesc->rx_data_pt  = dataBuffer;
291         pDataFlash->pDataFlashDesc->tx_data_pt  = dataBuffer;
292         pDataFlash->pDataFlashDesc->rx_data_size        = SizeToWrite;
293         pDataFlash->pDataFlashDesc->tx_data_size        = SizeToWrite;
294
295         return AT91F_SpiWrite(pDataFlash->pDataFlashDesc);
296 }
297
298 /*---------------------------------------------------------------------------*/
299 /* Function Name       : AT91F_PageErase                                     */
300 /* Object              : Erase a page                                        */
301 /* Input Parameters    : DataFlash Service                                   */
302 /*                     : Page concerned                                      */
303 /*                     :                                                     */
304 /* Return value         : State of the dataflash                             */
305 /*---------------------------------------------------------------------------*/
306 AT91S_DataFlashStatus AT91F_PageErase(
307         AT91PS_DataFlash pDataFlash,
308         unsigned int page)
309 {
310         int cmdsize;
311         /* Test if the buffer command is legal */
312         /* no data to transmit or receive */
313         pDataFlash->pDataFlashDesc->tx_data_size = 0;
314
315         cmdsize = 4;
316         if (pDataFlash->pDevice->pages_number >= 16384)
317                 cmdsize = 5;
318         return(AT91F_DataFlashSendCommand (pDataFlash, DB_PAGE_ERASE, cmdsize, 
319 page*pDataFlash->pDevice->pages_size));
320 }
321
322
323 /*---------------------------------------------------------------------------*/
324 /* Function Name       : AT91F_BlockErase                                    */
325 /* Object              : Erase a Block                                       */
326 /* Input Parameters    : DataFlash Service                                   */
327 /*                     : Page concerned                                      */
328 /*                     :                                                     */
329 /* Return value         : State of the dataflash                             */
330 /*---------------------------------------------------------------------------*/ 
331 AT91S_DataFlashStatus AT91F_BlockErase(
332         AT91PS_DataFlash pDataFlash,
333         unsigned int block)
334 {
335         int cmdsize;
336         /* Test if the buffer command is legal */
337         /* no data to transmit or receive */
338         pDataFlash->pDataFlashDesc->tx_data_size = 0;
339         cmdsize = 4;
340         if (pDataFlash->pDevice->pages_number >= 16384)
341                 cmdsize = 5;
342         return(AT91F_DataFlashSendCommand (pDataFlash, DB_BLOCK_ERASE,cmdsize, 
343 block*8*pDataFlash->pDevice->pages_size));
344 }
345
346 /*---------------------------------------------------------------------------*/
347 /* Function Name       : AT91F_WriteBufferToMain                             */
348 /* Object              : Write buffer to the main memory                     */
349 /* Input Parameters    : DataFlash Service                                   */
350 /*              : <BufferCommand> = command to send to buffer1 or buffer2    */
351 /*                     : <dest> = main memory address                        */
352 /* Return value         : State of the dataflash                             */
353 /*---------------------------------------------------------------------------*/ 
354 AT91S_DataFlashStatus AT91F_WriteBufferToMain (
355         AT91PS_DataFlash pDataFlash,
356         unsigned char BufferCommand,
357         unsigned int dest )
358 {
359         int cmdsize;
360         /* Test if the buffer command is correct */
361         if ((BufferCommand != DB_BUF1_PAGE_PGM) &&
362             (BufferCommand != DB_BUF1_PAGE_ERASE_PGM) &&
363             (BufferCommand != DB_BUF2_PAGE_PGM) &&
364             (BufferCommand != DB_BUF2_PAGE_ERASE_PGM) )
365                 return DATAFLASH_BAD_COMMAND;
366
367         /* no data to transmit or receive */
368         pDataFlash->pDataFlashDesc->tx_data_size = 0;
369
370         cmdsize = 4;
371         if (pDataFlash->pDevice->pages_number >= 16384)
372                 cmdsize = 5;
373         /* Send the command to the dataflash */
374         return(AT91F_DataFlashSendCommand (pDataFlash, BufferCommand, cmdsize,
375                                                 dest)); }
376
377
378 /*---------------------------------------------------------------------------*/
379 /* Function Name       : AT91F_PartialPageWrite                              */
380 /* Object              : Erase partielly a page                              */
381 /* Input Parameters    : <page> = page number                                */
382 /*                      : <AdrInpage> = adr to begin the fading              */
383 /*                     : <length> = Number of bytes to erase                 */
384 /*---------------------------------------------------------------------------*/ 
385 AT91S_DataFlashStatus AT91F_PartialPageWrite (
386         AT91PS_DataFlash pDataFlash,
387         unsigned char *src,
388         unsigned int dest,
389         unsigned int size)
390 {
391         unsigned int page;
392         unsigned int AdrInPage;
393
394         page = dest / (pDataFlash->pDevice->pages_size);
395         AdrInPage = dest % (pDataFlash->pDevice->pages_size);
396
397         /* Read the contents of the page in the Sram Buffer */
398         AT91F_MainMemoryToBufferTransfert(pDataFlash, 
399                                                 DB_PAGE_2_BUF1_TRF, page);
400         AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 
401                                                 AT91C_TIMEOUT_WRDY);
402         /*Update the SRAM buffer */
403         AT91F_DataFlashWriteBuffer(pDataFlash, DB_BUF1_WRITE, src, 
404                                         AdrInPage, size);
405
406         AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 
407                                         AT91C_TIMEOUT_WRDY);
408
409         /* Erase page if a 128 Mbits device */
410         if (pDataFlash->pDevice->pages_number >= 16384) {
411                 AT91F_PageErase(pDataFlash, page);
412                 /* Rewrite the modified Sram Buffer in the main memory */
413                 AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 
414                                                 AT91C_TIMEOUT_WRDY);
415         }
416
417         /* Rewrite the modified Sram Buffer in the main memory */
418         return(AT91F_WriteBufferToMain(pDataFlash, DB_BUF1_PAGE_ERASE_PGM, 
419                                 (page*pDataFlash->pDevice->pages_size)));
420 }
421
422 /*---------------------------------------------------------------------------*/
423 /* Function Name       : AT91F_DataFlashWrite                                */
424 /* Object              :                                                     */
425 /* Input Parameters    : <*src> = Source buffer                              */
426 /*                     : <dest> = dataflash adress                           */
427 /*                     : <size> = data buffer size                           */
428 /*---------------------------------------------------------------------------*/ 
429 AT91S_DataFlashStatus AT91F_DataFlashWrite(
430         AT91PS_DataFlash pDataFlash,
431         unsigned char *src,
432         int dest,
433         int size )
434 {
435         unsigned int length;
436         unsigned int page;
437         unsigned int status;
438
439         AT91F_SpiEnable(pDataFlash->pDevice->cs);
440
441         if ( (dest + size) > (pDataFlash->pDevice->pages_size * 
442                                         (pDataFlash->pDevice->pages_number)))
443                 return DATAFLASH_MEMORY_OVERFLOW;
444
445         /* If destination does not fit a page start address */
446         if ((dest % ((unsigned int)(pDataFlash->pDevice->pages_size)))  != 0 ) 
447         {
448                 length = pDataFlash->pDevice->pages_size - 
449                                 (dest % 
450                                 ((unsigned int)
451                                 (pDataFlash->pDevice->pages_size)));
452
453                 if (size < length)
454                         length = size;
455
456                 if(!AT91F_PartialPageWrite(pDataFlash,src, dest, length))
457                         return DATAFLASH_ERROR;
458
459                 AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 
460                         AT91C_TIMEOUT_WRDY);
461
462                 /* Update size, source and destination pointers */
463                 size -= length;
464                 dest += length;
465                 src += length;
466         }
467
468         while (( size - pDataFlash->pDevice->pages_size ) >= 0 ) {
469                 /* program dataflash page */
470                 page = (unsigned int)dest / (pDataFlash->pDevice->pages_size);
471
472                 status = AT91F_DataFlashWriteBuffer(pDataFlash, 
473                                 DB_BUF1_WRITE, src, 0, 
474                                 pDataFlash->pDevice->pages_size);
475                 AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 
476                                                 AT91C_TIMEOUT_WRDY);
477
478                 status = AT91F_PageErase(pDataFlash, page);
479                 AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 
480                                                 AT91C_TIMEOUT_WRDY);
481                 if (!status)
482                         return DATAFLASH_ERROR;
483
484                 status = AT91F_WriteBufferToMain (pDataFlash, 
485                                                 DB_BUF1_PAGE_PGM, dest);
486                 if(!status)
487                         return DATAFLASH_ERROR;
488
489                 AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 
490                                                 AT91C_TIMEOUT_WRDY);
491
492                 /* Update size, source and destination pointers */
493                 size -= pDataFlash->pDevice->pages_size;
494                 dest += pDataFlash->pDevice->pages_size;
495                 src  += pDataFlash->pDevice->pages_size;
496         }
497
498         /* If still some bytes to read */
499         if ( size > 0 ) {
500                 /* program dataflash page */
501                 if(!AT91F_PartialPageWrite(pDataFlash, src, dest, size) )
502                         return DATAFLASH_ERROR;
503
504                 AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 
505                                                 AT91C_TIMEOUT_WRDY);
506         }
507         return DATAFLASH_OK;
508 }
509
510
511 /*---------------------------------------------------------------------------*/
512 /* Function Name       : AT91F_DataFlashRead                                 */
513 /* Object              : Read a block in dataflash                           */
514 /* Input Parameters    :                                                     */
515 /* Return value         :                                                    */
516 /*---------------------------------------------------------------------------*/
517 int AT91F_DataFlashRead(
518         AT91PS_DataFlash pDataFlash,
519         unsigned long addr,
520         unsigned long size,
521         char *buffer)
522 {
523         unsigned long SizeToRead;
524
525         AT91F_SpiEnable(pDataFlash->pDevice->cs);
526
527         if(AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 
528                                         AT91C_TIMEOUT_WRDY) != DATAFLASH_OK)
529                 return -1;
530
531         while (size) {
532                 SizeToRead = (size < 0x8000)? size:0x8000;
533
534                 if (AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 
535                                         AT91C_TIMEOUT_WRDY) != DATAFLASH_OK)
536                         return -1;
537
538                 if (AT91F_DataFlashContinuousRead (pDataFlash, addr, 
539                                 (uchar *) buffer, SizeToRead) != DATAFLASH_OK)
540                         return -1;
541
542                 size -= SizeToRead;
543                 addr += SizeToRead;
544                 buffer += SizeToRead;
545         }
546
547         return DATAFLASH_OK;
548 }
549
550