]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - common/cmd_sata.c
Merge with /home/hs/Atronic/u-boot
[karo-tx-uboot.git] / common / cmd_sata.c
1 /*
2  * Copyright (C) Procsys. All rights reserved.
3  * Author: Mushtaq Khan <mushtaq_k@procsys.com>
4  *                      <mushtaqk_921@yahoo.co.in>
5  *
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License as
9  * published by the Free Software Foundation; either version 2 of
10  * the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20  * MA 02111-1307 USA
21  *
22  * with the reference to libata in kernel 2.4.32
23  *
24  */
25
26 /*
27  * File contains SATA read-write and other utility functions.
28  */
29 #include <common.h>
30 #include <asm/io.h>
31 #include <pci.h>
32 #include <command.h>
33 #include <config.h>
34 #include <ide.h>
35 #include <ata.h>
36
37 #ifdef CFG_SATA_SUPPORTED
38 /*For debug prints set macro DEBUG_SATA to 1 */
39 #define DEBUG_SATA 0
40 /*Macro for SATA library specific declarations */
41 #define SATA_DECL
42 #include <sata.h>
43 #undef SATA_DECL
44
45 static u8 __inline__
46 sata_inb (unsigned long ioaddr)
47 {
48         return inb (ioaddr);
49 }
50
51 static void __inline__
52 sata_outb (unsigned char val, unsigned long ioaddr)
53 {
54         outb (val, ioaddr);
55 }
56
57 static void
58 output_data (struct sata_ioports *ioaddr, ulong * sect_buf, int words)
59 {
60         outsw (ioaddr->data_addr, sect_buf, words << 1);
61 }
62
63 static int
64 input_data (struct sata_ioports *ioaddr, ulong * sect_buf, int words)
65 {
66         insw (ioaddr->data_addr, sect_buf, words << 1);
67         return 0;
68 }
69
70 static void
71 sata_cpy (unsigned char *dst, unsigned char *src, unsigned int len)
72 {
73         unsigned char *end, *last;
74
75         last = dst;
76         end = src + len - 1;
77
78         /* reserve space for '\0' */
79         if (len < 2)
80                 goto OUT;
81
82         /* skip leading white space */
83         while ((*src) && (src < end) && (*src == ' '))
84                 ++src;
85
86         /* copy string, omitting trailing white space */
87         while ((*src) && (src < end)) {
88                 *dst++ = *src;
89                 if (*src++ != ' ')
90                         last = dst;
91         }
92       OUT:
93         *last = '\0';
94 }
95
96 int
97 sata_bus_softreset (int num)
98 {
99         u8 dev = 0, status = 0, i;
100
101         port[num].dev_mask = 0;
102
103         for (i = 0; i < CFG_SATA_DEVS_PER_BUS; i++) {
104                 if (!(sata_devchk (&port[num].ioaddr, i))) {
105                         PRINTF ("dev_chk failed for dev#%d\n", i);
106                 } else {
107                         port[num].dev_mask |= (1 << i);
108                         PRINTF ("dev_chk passed for dev#%d\n", i);
109                 }
110         }
111
112         if (!(port[num].dev_mask)) {
113                 printf ("no devices on port%d\n", num);
114                 return 1;
115         }
116
117         dev_select (&port[num].ioaddr, dev);
118
119         port[num].ctl_reg = 0x08;       /*Default value of control reg */
120         sata_outb (port[num].ctl_reg, port[num].ioaddr.ctl_addr);
121         udelay (10);
122         sata_outb (port[num].ctl_reg | ATA_SRST, port[num].ioaddr.ctl_addr);
123         udelay (10);
124         sata_outb (port[num].ctl_reg, port[num].ioaddr.ctl_addr);
125
126         /* spec mandates ">= 2ms" before checking status.
127          * We wait 150ms, because that was the magic delay used for
128          * ATAPI devices in Hale Landis's ATADRVR, for the period of time
129          * between when the ATA command register is written, and then
130          * status is checked.  Because waiting for "a while" before
131          * checking status is fine, post SRST, we perform this magic
132          * delay here as well.
133          */
134         msleep (150);
135         status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 300);
136         while ((status & ATA_BUSY)) {
137                 msleep (100);
138                 status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 3);
139         }
140
141         if (status & ATA_BUSY)
142                 printf ("ata%u is slow to respond,plz be patient\n", port);
143
144         while ((status & ATA_BUSY)) {
145                 msleep (100);
146                 status = sata_chk_status (&port[num].ioaddr);
147         }
148
149         if (status & ATA_BUSY) {
150                 printf ("ata%u failed to respond : ", port);
151                 printf ("bus reset failed\n");
152                 return 1;
153         }
154         return 0;
155 }
156
157 void
158 sata_identify (int num, int dev)
159 {
160         u8 cmd = 0, status = 0, devno = num * CFG_SATA_DEVS_PER_BUS + dev;
161         u16 iobuf[ATA_SECT_SIZE];
162         u64 n_sectors = 0;
163         u8 mask = 0;
164
165         memset (iobuf, 0, sizeof (iobuf));
166         hd_driveid_t *iop = (hd_driveid_t *) iobuf;
167
168         if (dev == 0)
169                 mask = 0x01;
170         else
171                 mask = 0x02;
172
173         if (!(port[num].dev_mask & mask)) {
174                 printf ("dev%d is not present on port#%d\n", dev, num);
175                 return;
176         }
177
178         printf ("port=%d dev=%d\n", num, dev);
179
180         dev_select (&port[num].ioaddr, dev);
181
182         status = 0;
183         cmd = ATA_CMD_IDENT;    /*Device Identify Command */
184         sata_outb (cmd, port[num].ioaddr.command_addr);
185         sata_inb (port[num].ioaddr.altstatus_addr);
186         udelay (10);
187
188         status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 1000);
189         if (status & ATA_ERR) {
190                 printf ("\ndevice not responding\n");
191                 port[num].dev_mask &= ~mask;
192                 return;
193         }
194
195         input_data (&port[num].ioaddr, (ulong *) iobuf, ATA_SECTORWORDS);
196
197         PRINTF ("\nata%u: dev %u cfg 49:%04x 82:%04x 83:%04x 84:%04x85:%04x"
198                 "86:%04x" "87:%04x 88:%04x\n", num, dev, iobuf[49],
199                 iobuf[82], iobuf[83], iobuf[84], iobuf[85], iobuf[86],
200                 iobuf[87], iobuf[88]);
201
202         /* we require LBA and DMA support (bits 8 & 9 of word 49) */
203         if (!ata_id_has_dma (iobuf) || !ata_id_has_lba (iobuf)) {
204                 PRINTF ("ata%u: no dma/lba\n", num);
205         }
206         ata_dump_id (iobuf);
207
208         if (ata_id_has_lba48 (iobuf)) {
209                 n_sectors = ata_id_u64 (iobuf, 100);
210         } else {
211                 n_sectors = ata_id_u32 (iobuf, 60);
212         }
213         PRINTF ("no. of sectors %u\n", ata_id_u64 (iobuf, 100));
214         PRINTF ("no. of sectors %u\n", ata_id_u32 (iobuf, 60));
215
216         if (n_sectors == 0) {
217                 port[num].dev_mask &= ~mask;
218                 return;
219         }
220
221         sata_cpy (sata_dev_desc[devno].revision, iop->fw_rev,
222                   sizeof (sata_dev_desc[devno].revision));
223         sata_cpy (sata_dev_desc[devno].vendor, iop->model,
224                   sizeof (sata_dev_desc[devno].vendor));
225         sata_cpy (sata_dev_desc[devno].product, iop->serial_no,
226                   sizeof (sata_dev_desc[devno].product));
227         strswab (sata_dev_desc[devno].revision);
228         strswab (sata_dev_desc[devno].vendor);
229
230         if ((iop->config & 0x0080) == 0x0080) {
231                 sata_dev_desc[devno].removable = 1;
232         } else {
233                 sata_dev_desc[devno].removable = 0;
234         }
235
236         sata_dev_desc[devno].lba = iop->lba_capacity;
237         PRINTF ("lba=0x%x", sata_dev_desc[devno].lba);
238
239 #ifdef CONFIG_LBA48
240         if (iop->command_set_2 & 0x0400) {
241                 sata_dev_desc[devno].lba48 = 1;
242                 lba = (unsigned long long) iop->lba48_capacity[0] |
243                     ((unsigned long long) iop->lba48_capacity[1] << 16) |
244                     ((unsigned long long) iop->lba48_capacity[2] << 32) |
245                     ((unsigned long long) iop->lba48_capacity[3] << 48);
246         } else {
247                 sata_dev_desc[devno].lba48 = 0;
248         }
249 #endif
250
251         /* assuming HD */
252         sata_dev_desc[devno].type = DEV_TYPE_HARDDISK;
253         sata_dev_desc[devno].blksz = ATA_BLOCKSIZE;
254         sata_dev_desc[devno].lun = 0;   /* just to fill something in... */
255 }
256
257 void
258 set_Feature_cmd (int num, int dev)
259 {
260         u8 mask = 0x00, status = 0;
261
262         if (dev == 0)
263                 mask = 0x01;
264         else
265                 mask = 0x02;
266
267         if (!(port[num].dev_mask & mask)) {
268                 PRINTF ("dev%d is not present on port#%d\n", dev, num);
269                 return;
270         }
271
272         dev_select (&port[num].ioaddr, dev);
273
274         sata_outb (SETFEATURES_XFER, port[num].ioaddr.feature_addr);
275         sata_outb (XFER_PIO_4, port[num].ioaddr.nsect_addr);
276         sata_outb (0, port[num].ioaddr.lbal_addr);
277         sata_outb (0, port[num].ioaddr.lbam_addr);
278         sata_outb (0, port[num].ioaddr.lbah_addr);
279
280         sata_outb (ATA_DEVICE_OBS, port[num].ioaddr.device_addr);
281         sata_outb (ATA_CMD_SETF, port[num].ioaddr.command_addr);
282
283         udelay (50);
284         msleep (150);
285
286         status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 5000);
287         if ((status & (ATA_STAT_BUSY | ATA_STAT_ERR))) {
288                 printf ("Error  : status 0x%02x\n", status);
289                 port[num].dev_mask &= ~mask;
290         }
291 }
292
293 void
294 sata_port (struct sata_ioports *ioport)
295 {
296         ioport->data_addr = ioport->cmd_addr + ATA_REG_DATA;
297         ioport->error_addr = ioport->cmd_addr + ATA_REG_ERR;
298         ioport->feature_addr = ioport->cmd_addr + ATA_REG_FEATURE;
299         ioport->nsect_addr = ioport->cmd_addr + ATA_REG_NSECT;
300         ioport->lbal_addr = ioport->cmd_addr + ATA_REG_LBAL;
301         ioport->lbam_addr = ioport->cmd_addr + ATA_REG_LBAM;
302         ioport->lbah_addr = ioport->cmd_addr + ATA_REG_LBAH;
303         ioport->device_addr = ioport->cmd_addr + ATA_REG_DEVICE;
304         ioport->status_addr = ioport->cmd_addr + ATA_REG_STATUS;
305         ioport->command_addr = ioport->cmd_addr + ATA_REG_CMD;
306 }
307
308 int
309 sata_devchk (struct sata_ioports *ioaddr, int dev)
310 {
311         u8 nsect, lbal;
312
313         dev_select (ioaddr, dev);
314
315         sata_outb (0x55, ioaddr->nsect_addr);
316         sata_outb (0xaa, ioaddr->lbal_addr);
317
318         sata_outb (0xaa, ioaddr->nsect_addr);
319         sata_outb (0x55, ioaddr->lbal_addr);
320
321         sata_outb (0x55, ioaddr->nsect_addr);
322         sata_outb (0xaa, ioaddr->lbal_addr);
323
324         nsect = sata_inb (ioaddr->nsect_addr);
325         lbal = sata_inb (ioaddr->lbal_addr);
326
327         if ((nsect == 0x55) && (lbal == 0xaa))
328                 return 1;       /* we found a device */
329         else
330                 return 0;       /* nothing found */
331 }
332
333 void
334 dev_select (struct sata_ioports *ioaddr, int dev)
335 {
336         u8 tmp = 0;
337
338         if (dev == 0)
339                 tmp = ATA_DEVICE_OBS;
340         else
341                 tmp = ATA_DEVICE_OBS | ATA_DEV1;
342
343         sata_outb (tmp, ioaddr->device_addr);
344         sata_inb (ioaddr->altstatus_addr);
345         udelay (5);
346 }
347
348 u8
349 sata_busy_wait (struct sata_ioports *ioaddr, int bits, unsigned int max)
350 {
351         u8 status;
352
353         do {
354                 udelay (1000);
355                 status = sata_chk_status (ioaddr);
356                 max--;
357         } while ((status & bits) && (max > 0));
358
359         return status;
360 }
361
362 u8
363 sata_chk_status (struct sata_ioports * ioaddr)
364 {
365         return sata_inb (ioaddr->status_addr);
366 }
367
368 void
369 msleep (int count)
370 {
371         int i;
372
373         for (i = 0; i < count; i++)
374                 udelay (1000);
375 }
376
377 ulong
378 sata_read (int device, ulong blknr,lbaint_t blkcnt, void * buff)
379 {
380         ulong n = 0, *buffer = (ulong *)buff;
381         u8 dev = 0, num = 0, mask = 0, status = 0;
382
383 #ifdef CONFIG_LBA48
384         unsigned char lba48 = 0;
385
386         if (blknr & 0x0000fffff0000000) {
387                 if (!sata_dev_desc[devno].lba48) {
388                         printf ("Drive doesn't support 48-bit addressing\n");
389                         return 0;
390                 }
391                 /* more than 28 bits used, use 48bit mode */
392                 lba48 = 1;
393         }
394 #endif
395         /*Port Number */
396         num = device / CFG_SATA_DEVS_PER_BUS;
397         /*dev on the port */
398         if (device >= CFG_SATA_DEVS_PER_BUS)
399                 dev = device - CFG_SATA_DEVS_PER_BUS;
400         else
401                 dev = device;
402
403         if (dev == 0)
404                 mask = 0x01;
405         else
406                 mask = 0x02;
407
408         if (!(port[num].dev_mask & mask)) {
409                 printf ("dev%d is not present on port#%d\n", dev, num);
410                 return 0;
411         }
412
413         /* Select device */
414         dev_select (&port[num].ioaddr, dev);
415
416         status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 500);
417         if (status & ATA_BUSY) {
418                 printf ("ata%u failed to respond\n", port[num].port_no);
419                 return n;
420         }
421         while (blkcnt-- > 0) {
422                 status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 500);
423                 if (status & ATA_BUSY) {
424                         printf ("ata%u failed to respond\n", 0);
425                         return n;
426                 }
427 #ifdef CONFIG_LBA48
428                 if (lba48) {
429                         /* write high bits */
430                         sata_outb (0, port[num].ioaddr.nsect_addr);
431                         sata_outb ((blknr >> 24) & 0xFF,
432                                    port[num].ioaddr.lbal_addr);
433                         sata_outb ((blknr >> 32) & 0xFF,
434                                    port[num].ioaddr.lbam_addr);
435                         sata_outb ((blknr >> 40) & 0xFF,
436                                    port[num].ioaddr.lbah_addr);
437                 }
438 #endif
439                 sata_outb (1, port[num].ioaddr.nsect_addr);
440                 sata_outb (((blknr) >> 0) & 0xFF,
441                            port[num].ioaddr.lbal_addr);
442                 sata_outb ((blknr >> 8) & 0xFF, port[num].ioaddr.lbam_addr);
443                 sata_outb ((blknr >> 16) & 0xFF, port[num].ioaddr.lbah_addr);
444
445 #ifdef CONFIG_LBA48
446                 if (lba48) {
447                         sata_outb (ATA_LBA, port[num].ioaddr.device_addr);
448                         sata_outb (ATA_CMD_READ_EXT,
449                                    port[num].ioaddr.command_addr);
450                 } else
451 #endif
452                 {
453                         sata_outb (ATA_LBA | ((blknr >> 24) & 0xF),
454                                    port[num].ioaddr.device_addr);
455                         sata_outb (ATA_CMD_READ,
456                                    port[num].ioaddr.command_addr);
457                 }
458
459                 msleep (50);
460                 /*may take up to 4 sec */
461                 status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 4000);
462
463                 if ((status & (ATA_STAT_DRQ | ATA_STAT_BUSY | ATA_STAT_ERR))
464                     != ATA_STAT_DRQ) {
465                         u8 err = 0;
466
467                         printf ("Error no DRQ dev %d blk %ld: sts 0x%02x\n",
468                                 device, (ulong) blknr, status);
469                         err = sata_inb (port[num].ioaddr.error_addr);
470                         printf ("Error reg = 0x%x\n", err);
471                         return (n);
472                 }
473                 input_data (&port[num].ioaddr, buffer, ATA_SECTORWORDS);
474                 sata_inb (port[num].ioaddr.altstatus_addr);
475                 udelay (50);
476
477                 ++n;
478                 ++blknr;
479                 buffer += ATA_SECTORWORDS;
480         }
481         return n;
482 }
483
484 ulong
485 sata_write (int device, ulong blknr,lbaint_t blkcnt, void * buff)
486 {
487         ulong n = 0, *buffer = (ulong *)buff;
488         unsigned char status = 0, num = 0, dev = 0, mask = 0;
489
490 #ifdef CONFIG_LBA48
491         unsigned char lba48 = 0;
492
493         if (blknr & 0x0000fffff0000000) {
494                 if (!sata_dev_desc[devno].lba48) {
495                         printf ("Drive doesn't support 48-bit addressing\n");
496                         return 0;
497                 }
498                 /* more than 28 bits used, use 48bit mode */
499                 lba48 = 1;
500         }
501 #endif
502         /*Port Number */
503         num = device / CFG_SATA_DEVS_PER_BUS;
504         /*dev on the Port */
505         if (device >= CFG_SATA_DEVS_PER_BUS)
506                 dev = device - CFG_SATA_DEVS_PER_BUS;
507         else
508                 dev = device;
509
510         if (dev == 0)
511                 mask = 0x01;
512         else
513                 mask = 0x02;
514
515         /* Select device */
516         dev_select (&port[num].ioaddr, dev);
517
518         status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 500);
519         if (status & ATA_BUSY) {
520                 printf ("ata%u failed to respond\n", port[num].port_no);
521                 return n;
522         }
523
524         while (blkcnt-- > 0) {
525                 status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 500);
526                 if (status & ATA_BUSY) {
527                         printf ("ata%u failed to respond\n",
528                                 port[num].port_no);
529                         return n;
530                 }
531 #ifdef CONFIG_LBA48
532                 if (lba48) {
533                         /* write high bits */
534                         sata_outb (0, port[num].ioaddr.nsect_addr);
535                         sata_outb ((blknr >> 24) & 0xFF,
536                                    port[num].ioaddr.lbal_addr);
537                         sata_outb ((blknr >> 32) & 0xFF,
538                                    port[num].ioaddr.lbam_addr);
539                         sata_outb ((blknr >> 40) & 0xFF,
540                                    port[num].ioaddr.lbah_addr);
541                 }
542 #endif
543                 sata_outb (1, port[num].ioaddr.nsect_addr);
544                 sata_outb ((blknr >> 0) & 0xFF, port[num].ioaddr.lbal_addr);
545                 sata_outb ((blknr >> 8) & 0xFF, port[num].ioaddr.lbam_addr);
546                 sata_outb ((blknr >> 16) & 0xFF, port[num].ioaddr.lbah_addr);
547 #ifdef CONFIG_LBA48
548                 if (lba48) {
549                         sata_outb (ATA_LBA, port[num].ioaddr.device_addr);
550                         sata_outb (ATA_CMD_WRITE_EXT,
551                                    port[num].ioaddr.command_addr);
552                 } else
553 #endif
554                 {
555                         sata_outb (ATA_LBA | ((blknr >> 24) & 0xF),
556                                    port[num].ioaddr.device_addr);
557                         sata_outb (ATA_CMD_WRITE,
558                                    port[num].ioaddr.command_addr);
559                 }
560
561                 msleep (50);
562                 /*may take up to 4 sec */
563                 status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 4000);
564                 if ((status & (ATA_STAT_DRQ | ATA_STAT_BUSY | ATA_STAT_ERR))
565                     != ATA_STAT_DRQ) {
566                         printf ("Error no DRQ dev %d blk %ld: sts 0x%02x\n",
567                                 device, (ulong) blknr, status);
568                         return (n);
569                 }
570
571                 output_data (&port[num].ioaddr, buffer, ATA_SECTORWORDS);
572                 sata_inb (port[num].ioaddr.altstatus_addr);
573                 udelay (50);
574
575                 ++n;
576                 ++blknr;
577                 buffer += ATA_SECTORWORDS;
578         }
579         return n;
580 }
581
582 block_dev_desc_t *sata_get_dev (int dev);
583
584 block_dev_desc_t *
585 sata_get_dev (int dev)
586 {
587         return ((block_dev_desc_t *) & sata_dev_desc[dev]);
588 }
589
590 int
591 do_sata (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
592 {
593
594         switch (argc) {
595         case 0:
596         case 1:
597                 printf ("Usage:\n%s\n", cmdtp->usage);
598                 return 1;
599         case 2:
600                 if (strncmp (argv[1], "init", 4) == 0) {
601                         int rcode = 0;
602
603                         rcode = init_sata ();
604                         if (rcode)
605                                 printf ("Sata initialization Failed\n");
606                         return rcode;
607                 } else if (strncmp (argv[1], "inf", 3) == 0) {
608                         int i;
609
610                         putc ('\n');
611                         for (i = 0; i < CFG_SATA_MAXDEVICES; ++i) {
612                                 /*List only known devices */
613                                 if (sata_dev_desc[i].type ==
614                                     DEV_TYPE_UNKNOWN)
615                                         continue;
616                                 printf ("sata dev %d: ", i);
617                                 dev_print (&sata_dev_desc[i]);
618                         }
619                         return 0;
620                 }
621                 printf ("Usage:\n%s\n", cmdtp->usage);
622                 return 1;
623         case 3:
624                 if (strcmp (argv[1], "dev") == 0) {
625                         int dev = (int) simple_strtoul (argv[2], NULL, 10);
626
627                         if (dev >= CFG_SATA_MAXDEVICES) {
628                                 printf ("\nSata dev %d not available\n",
629                                         dev);
630                                 return 1;
631                         }
632                         printf ("\nSATA dev %d: ", dev);
633                         dev_print (&sata_dev_desc[dev]);
634                         if (sata_dev_desc[dev].type == DEV_TYPE_UNKNOWN)
635                                 return 1;
636                         curr_dev = dev;
637                         return 0;
638                 } else if (strcmp (argv[1], "part") == 0) {
639                         int dev = (int) simple_strtoul (argv[2], NULL, 10);
640
641                         if (dev >= CFG_SATA_MAXDEVICES) {
642                                 printf ("\nSata dev %d not available\n",
643                                         dev);
644                                 return 1;
645                         }
646                         PRINTF ("\nSATA dev %d: ", dev);
647                         if (sata_dev_desc[dev].part_type !=
648                             PART_TYPE_UNKNOWN) {
649                                 print_part (&sata_dev_desc[dev]);
650                         } else {
651                                 printf ("\nSata dev %d partition type "
652                                         "unknown\n", dev);
653                                 return 1;
654                         }
655                         return 0;
656                 }
657                 printf ("Usage:\n%s\n", cmdtp->usage);
658                 return 1;
659         default:
660                 if (argc < 5) {
661                         printf ("Usage:\n%s\n", cmdtp->usage);
662                         return 1;
663                 }
664                 if (strcmp (argv[1], "read") == 0) {
665                         ulong addr = simple_strtoul (argv[2], NULL, 16);
666                         ulong cnt = simple_strtoul (argv[4], NULL, 16);
667                         ulong n;
668                         lbaint_t blk = simple_strtoul (argv[3], NULL, 16);
669
670                         memset ((int *) addr, 0, cnt * 512);
671                         printf ("\nSATA read: dev %d blk # %ld,"
672                                 "count %ld ... ", curr_dev, blk, cnt);
673                         n = sata_read (curr_dev, blk, cnt, (ulong *) addr);
674                         /* flush cache after read */
675                         flush_cache (addr, cnt * 512);
676                         printf ("%ld blocks read: %s\n", n,
677                                 (n == cnt) ? "OK" : "ERR");
678                         if (n == cnt)
679                                 return 1;
680                         else
681                                 return 0;
682                 } else if (strcmp (argv[1], "write") == 0) {
683                         ulong addr = simple_strtoul (argv[2], NULL, 16);
684                         ulong cnt = simple_strtoul (argv[4], NULL, 16);
685                         ulong n;
686                         lbaint_t blk = simple_strtoul (argv[3], NULL, 16);
687
688                         printf ("\nSata write: dev %d blk # %ld,"
689                                 "count %ld ... ", curr_dev, blk, cnt);
690                         n = sata_write (curr_dev, blk, cnt, (ulong *) addr);
691                         printf ("%ld blocks written: %s\n", n,
692                                 (n == cnt) ? "OK" : "ERR");
693                         if (n == cnt)
694                                 return 1;
695                         else
696                                 return 0;
697                 } else {
698                         printf ("Usage:\n%s\n", cmdtp->usage);
699                         return 1;
700                 }
701         }                       /*End OF SWITCH */
702 }
703
704 U_BOOT_CMD (sata, 5, 1, do_sata,
705             "sata init\n"
706             "sata info\n"
707             "sata part device\n"
708             "sata dev device\n"
709             "sata read  addr blk# cnt\n"
710             "sata write  addr blk# cnt\n", "cmd for init,rw and dev-info\n");
711
712 #endif