dm: scsi: Fix up code style
[oweals/u-boot.git] / cmd / scsi.c
1 /*
2  * (C) Copyright 2001
3  * Denis Peter, MPL AG Switzerland
4  *
5  * SPDX-License-Identifier:     GPL-2.0+
6  */
7
8 /*
9  * SCSI support.
10  */
11 #include <common.h>
12 #include <command.h>
13 #include <inttypes.h>
14 #include <asm/processor.h>
15 #include <scsi.h>
16 #include <image.h>
17 #include <pci.h>
18
19 #ifdef CONFIG_SCSI_DEV_LIST
20 #define SCSI_DEV_LIST CONFIG_SCSI_DEV_LIST
21 #else
22 #ifdef CONFIG_SCSI_SYM53C8XX
23 #define SCSI_VEND_ID    0x1000
24 #ifndef CONFIG_SCSI_DEV_ID
25 #define SCSI_DEV_ID             0x0001
26 #else
27 #define SCSI_DEV_ID             CONFIG_SCSI_DEV_ID
28 #endif
29 #elif defined CONFIG_SATA_ULI5288
30
31 #define SCSI_VEND_ID 0x10b9
32 #define SCSI_DEV_ID  0x5288
33
34 #elif !defined(CONFIG_SCSI_AHCI_PLAT)
35 #error no scsi device defined
36 #endif
37 #define SCSI_DEV_LIST {SCSI_VEND_ID, SCSI_DEV_ID}
38 #endif
39
40 #if defined(CONFIG_PCI) && !defined(CONFIG_SCSI_AHCI_PLAT)
41 const struct pci_device_id scsi_device_list[] = { SCSI_DEV_LIST };
42 #endif
43 static ccb tempccb;     /* temporary scsi command buffer */
44
45 static unsigned char tempbuff[512]; /* temporary data buffer */
46
47 static int scsi_max_devs; /* number of highest available scsi device */
48
49 static int scsi_curr_dev; /* current device */
50
51 static struct blk_desc scsi_dev_desc[CONFIG_SYS_SCSI_MAX_DEVICE];
52
53 /* almost the maximum amount of the scsi_ext command.. */
54 #define SCSI_MAX_READ_BLK 0xFFFF
55 #define SCSI_LBA48_READ 0xFFFFFFF
56
57 #ifdef CONFIG_SYS_64BIT_LBA
58 void scsi_setup_read16(ccb *pccb, lbaint_t start, unsigned long blocks)
59 {
60         pccb->cmd[0] = SCSI_READ16;
61         pccb->cmd[1] = pccb->lun << 5;
62         pccb->cmd[2] = (unsigned char)(start >> 56) & 0xff;
63         pccb->cmd[3] = (unsigned char)(start >> 48) & 0xff;
64         pccb->cmd[4] = (unsigned char)(start >> 40) & 0xff;
65         pccb->cmd[5] = (unsigned char)(start >> 32) & 0xff;
66         pccb->cmd[6] = (unsigned char)(start >> 24) & 0xff;
67         pccb->cmd[7] = (unsigned char)(start >> 16) & 0xff;
68         pccb->cmd[8] = (unsigned char)(start >> 8) & 0xff;
69         pccb->cmd[9] = (unsigned char)start & 0xff;
70         pccb->cmd[10] = 0;
71         pccb->cmd[11] = (unsigned char)(blocks >> 24) & 0xff;
72         pccb->cmd[12] = (unsigned char)(blocks >> 16) & 0xff;
73         pccb->cmd[13] = (unsigned char)(blocks >> 8) & 0xff;
74         pccb->cmd[14] = (unsigned char)blocks & 0xff;
75         pccb->cmd[15] = 0;
76         pccb->cmdlen = 16;
77         pccb->msgout[0] = SCSI_IDENTIFY; /* NOT USED */
78         debug("scsi_setup_read16: cmd: %02X %02X startblk %02X%02X%02X%02X%02X%02X%02X%02X blccnt %02X%02X%02X%02X\n",
79               pccb->cmd[0], pccb->cmd[1],
80               pccb->cmd[2], pccb->cmd[3], pccb->cmd[4], pccb->cmd[5],
81               pccb->cmd[6], pccb->cmd[7], pccb->cmd[8], pccb->cmd[9],
82               pccb->cmd[11], pccb->cmd[12], pccb->cmd[13], pccb->cmd[14]);
83 }
84 #endif
85
86 void scsi_setup_read_ext(ccb * pccb, lbaint_t start, unsigned short blocks)
87 {
88         pccb->cmd[0] = SCSI_READ10;
89         pccb->cmd[1] = pccb->lun << 5;
90         pccb->cmd[2] = (unsigned char)(start >> 24) & 0xff;
91         pccb->cmd[3] = (unsigned char)(start >> 16) & 0xff;
92         pccb->cmd[4] = (unsigned char)(start >> 8) & 0xff;
93         pccb->cmd[5] = (unsigned char)start & 0xff;
94         pccb->cmd[6] = 0;
95         pccb->cmd[7] = (unsigned char)(blocks >> 8) & 0xff;
96         pccb->cmd[8] = (unsigned char)blocks & 0xff;
97         pccb->cmd[6] = 0;
98         pccb->cmdlen=10;
99         pccb->msgout[0] = SCSI_IDENTIFY; /* NOT USED */
100         debug ("scsi_setup_read_ext: cmd: %02X %02X startblk %02X%02X%02X%02X blccnt %02X%02X\n",
101                 pccb->cmd[0],pccb->cmd[1],
102                 pccb->cmd[2],pccb->cmd[3],pccb->cmd[4],pccb->cmd[5],
103                 pccb->cmd[7],pccb->cmd[8]);
104 }
105
106 void scsi_setup_write_ext(ccb *pccb, lbaint_t start, unsigned short blocks)
107 {
108         pccb->cmd[0] = SCSI_WRITE10;
109         pccb->cmd[1] = pccb->lun << 5;
110         pccb->cmd[2] = (unsigned char)(start >> 24) & 0xff;
111         pccb->cmd[3] = (unsigned char)(start >> 16) & 0xff;
112         pccb->cmd[4] = (unsigned char)(start >> 8) & 0xff;
113         pccb->cmd[5] = (unsigned char)start & 0xff;
114         pccb->cmd[6] = 0;
115         pccb->cmd[7] = ((unsigned char)(blocks >> 8)) & 0xff;
116         pccb->cmd[8] = (unsigned char)blocks & 0xff;
117         pccb->cmd[9] = 0;
118         pccb->cmdlen = 10;
119         pccb->msgout[0] = SCSI_IDENTIFY;  /* NOT USED */
120         debug("%s: cmd: %02X %02X startblk %02X%02X%02X%02X blccnt %02X%02X\n",
121               __func__,
122               pccb->cmd[0], pccb->cmd[1],
123               pccb->cmd[2], pccb->cmd[3], pccb->cmd[4], pccb->cmd[5],
124               pccb->cmd[7], pccb->cmd[8]);
125 }
126
127 void scsi_setup_read6(ccb * pccb, lbaint_t start, unsigned short blocks)
128 {
129         pccb->cmd[0] = SCSI_READ6;
130         pccb->cmd[1] = pccb->lun << 5 | ((unsigned char)(start >> 16) & 0x1f);
131         pccb->cmd[2] = (unsigned char)(start >> 8) & 0xff;
132         pccb->cmd[3] = (unsigned char)start & 0xff;
133         pccb->cmd[4] = (unsigned char)blocks & 0xff;
134         pccb->cmd[5] = 0;
135         pccb->cmdlen=6;
136         pccb->msgout[0] = SCSI_IDENTIFY; /* NOT USED */
137         debug("scsi_setup_read6: cmd: %02X %02X startblk %02X%02X blccnt %02X\n",
138               pccb->cmd[0], pccb->cmd[1],
139               pccb->cmd[2], pccb->cmd[3], pccb->cmd[4]);
140 }
141
142
143 void scsi_setup_inquiry(ccb * pccb)
144 {
145         pccb->cmd[0] = SCSI_INQUIRY;
146         pccb->cmd[1] = pccb->lun << 5;
147         pccb->cmd[2] = 0;
148         pccb->cmd[3] = 0;
149         if (pccb->datalen > 255)
150                 pccb->cmd[4] = 255;
151         else
152                 pccb->cmd[4] = (unsigned char)pccb->datalen;
153         pccb->cmd[5] = 0;
154         pccb->cmdlen=6;
155         pccb->msgout[0] = SCSI_IDENTIFY; /* NOT USED */
156 }
157
158 static ulong scsi_read(struct blk_desc *block_dev, lbaint_t blknr,
159                        lbaint_t blkcnt, void *buffer)
160 {
161         int device = block_dev->devnum;
162         lbaint_t start, blks;
163         uintptr_t buf_addr;
164         unsigned short smallblks = 0;
165         ccb* pccb=(ccb *)&tempccb;
166         device&=0xff;
167
168         /* Setup device */
169         pccb->target = scsi_dev_desc[device].target;
170         pccb->lun = scsi_dev_desc[device].lun;
171         buf_addr = (unsigned long)buffer;
172         start = blknr;
173         blks = blkcnt;
174         debug("\nscsi_read: dev %d startblk " LBAF
175               ", blccnt " LBAF " buffer %lx\n",
176               device, start, blks, (unsigned long)buffer);
177         do {
178                 pccb->pdata = (unsigned char *)buf_addr;
179 #ifdef CONFIG_SYS_64BIT_LBA
180                 if (start > SCSI_LBA48_READ) {
181                         unsigned long blocks;
182                         blocks = min_t(lbaint_t, blks, SCSI_MAX_READ_BLK);
183                         pccb->datalen = scsi_dev_desc[device].blksz * blocks;
184                         scsi_setup_read16(pccb, start, blocks);
185                         start += blocks;
186                         blks -= blocks;
187                 } else
188 #endif
189                 if (blks > SCSI_MAX_READ_BLK) {
190                         pccb->datalen = scsi_dev_desc[device].blksz *
191                                 SCSI_MAX_READ_BLK;
192                         smallblks = SCSI_MAX_READ_BLK;
193                         scsi_setup_read_ext(pccb, start, smallblks);
194                         start += SCSI_MAX_READ_BLK;
195                         blks -= SCSI_MAX_READ_BLK;
196                 }
197                 else {
198                         pccb->datalen = scsi_dev_desc[device].blksz * blks;
199                         smallblks = (unsigned short)blks;
200                         scsi_setup_read_ext(pccb, start, smallblks);
201                         start += blks;
202                         blks=0;
203                 }
204                 debug("scsi_read_ext: startblk " LBAF
205                       ", blccnt %x buffer %" PRIXPTR "\n",
206                       start, smallblks, buf_addr);
207                 if (scsi_exec(pccb) != true) {
208                         scsi_print_error(pccb);
209                         blkcnt -= blks;
210                         break;
211                 }
212                 buf_addr+=pccb->datalen;
213         } while (blks != 0);
214         debug("scsi_read_ext: end startblk " LBAF
215               ", blccnt %x buffer %" PRIXPTR "\n", start, smallblks, buf_addr);
216         return blkcnt;
217 }
218
219 /*******************************************************************************
220  * scsi_write
221  */
222
223 /* Almost the maximum amount of the scsi_ext command.. */
224 #define SCSI_MAX_WRITE_BLK 0xFFFF
225
226 static ulong scsi_write(struct blk_desc *block_dev, lbaint_t blknr,
227                         lbaint_t blkcnt, const void *buffer)
228 {
229         int device = block_dev->devnum;
230         lbaint_t start, blks;
231         uintptr_t buf_addr;
232         unsigned short smallblks;
233         ccb* pccb = (ccb *)&tempccb;
234         device &= 0xff;
235         /* Setup  device
236          */
237         pccb->target = scsi_dev_desc[device].target;
238         pccb->lun = scsi_dev_desc[device].lun;
239         buf_addr = (unsigned long)buffer;
240         start = blknr;
241         blks = blkcnt;
242         debug("\n%s: dev %d startblk " LBAF ", blccnt " LBAF " buffer %lx\n",
243               __func__, device, start, blks, (unsigned long)buffer);
244         do {
245                 pccb->pdata = (unsigned char *)buf_addr;
246                 if (blks > SCSI_MAX_WRITE_BLK) {
247                         pccb->datalen = (scsi_dev_desc[device].blksz *
248                                          SCSI_MAX_WRITE_BLK);
249                         smallblks = SCSI_MAX_WRITE_BLK;
250                         scsi_setup_write_ext(pccb, start, smallblks);
251                         start += SCSI_MAX_WRITE_BLK;
252                         blks -= SCSI_MAX_WRITE_BLK;
253                 } else {
254                         pccb->datalen = scsi_dev_desc[device].blksz * blks;
255                         smallblks = (unsigned short)blks;
256                         scsi_setup_write_ext(pccb, start, smallblks);
257                         start += blks;
258                         blks = 0;
259                 }
260                 debug("%s: startblk " LBAF ", blccnt %x buffer %" PRIXPTR "\n",
261                       __func__, start, smallblks, buf_addr);
262                 if (scsi_exec(pccb) != true) {
263                         scsi_print_error(pccb);
264                         blkcnt -= blks;
265                         break;
266                 }
267                 buf_addr += pccb->datalen;
268         } while (blks != 0);
269         debug("%s: end startblk " LBAF ", blccnt %x buffer %" PRIXPTR "\n",
270               __func__, start, smallblks, buf_addr);
271         return blkcnt;
272 }
273
274 int scsi_get_disk_count(void)
275 {
276         return scsi_max_devs;
277 }
278
279 #if defined(CONFIG_PCI) && !defined(CONFIG_SCSI_AHCI_PLAT)
280 void scsi_init(void)
281 {
282         int busdevfunc = -1;
283         int i;
284         /*
285          * Find a device from the list, this driver will support a single
286          * controller.
287          */
288         for (i = 0; i < ARRAY_SIZE(scsi_device_list); i++) {
289                 /* get PCI Device ID */
290 #ifdef CONFIG_DM_PCI
291                 struct udevice *dev;
292                 int ret;
293
294                 ret = dm_pci_find_device(scsi_device_list[i].vendor,
295                                          scsi_device_list[i].device, 0, &dev);
296                 if (!ret) {
297                         busdevfunc = dm_pci_get_bdf(dev);
298                         break;
299                 }
300 #else
301                 busdevfunc = pci_find_device(scsi_device_list[i].vendor,
302                                              scsi_device_list[i].device,
303                                              0);
304 #endif
305                 if (busdevfunc != -1)
306                         break;
307         }
308
309         if (busdevfunc == -1) {
310                 printf("Error: SCSI Controller(s) ");
311                 for (i = 0; i < ARRAY_SIZE(scsi_device_list); i++) {
312                         printf("%04X:%04X ",
313                                scsi_device_list[i].vendor,
314                                scsi_device_list[i].device);
315                 }
316                 printf("not found\n");
317                 return;
318         }
319 #ifdef DEBUG
320         else {
321                 printf("SCSI Controller (%04X,%04X) found (%d:%d:%d)\n",
322                        scsi_device_list[i].vendor,
323                        scsi_device_list[i].device,
324                        (busdevfunc >> 16) & 0xFF,
325                        (busdevfunc >> 11) & 0x1F,
326                        (busdevfunc >> 8) & 0x7);
327         }
328 #endif
329         bootstage_start(BOOTSTAGE_ID_ACCUM_SCSI, "ahci");
330         scsi_low_level_init(busdevfunc);
331         scsi_scan(1);
332         bootstage_accum(BOOTSTAGE_ID_ACCUM_SCSI);
333 }
334 #endif
335
336 #ifdef CONFIG_PARTITIONS
337 struct blk_desc *scsi_get_dev(int dev)
338 {
339         return (dev < CONFIG_SYS_SCSI_MAX_DEVICE) ? &scsi_dev_desc[dev] : NULL;
340 }
341 #endif
342
343 #ifndef CONFIG_SPL_BUILD
344 /******************************************************************************
345  * scsi boot command intepreter. Derived from diskboot
346  */
347 int do_scsiboot (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
348 {
349         return common_diskboot(cmdtp, "scsi", argc, argv);
350 }
351
352 /*********************************************************************************
353  * scsi command intepreter
354  */
355 int do_scsi (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
356 {
357         switch (argc) {
358         case 0:
359         case 1:
360                 return CMD_RET_USAGE;
361
362         case 2:
363                 if (strncmp(argv[1], "res", 3) == 0) {
364                         printf("\nReset SCSI\n");
365                         scsi_bus_reset();
366                         scsi_scan(1);
367                         return 0;
368                 }
369                 if (strncmp(argv[1], "inf", 3) == 0) {
370                         int i;
371                         for (i = 0; i < CONFIG_SYS_SCSI_MAX_DEVICE; ++i) {
372                                 if (scsi_dev_desc[i].type == DEV_TYPE_UNKNOWN)
373                                         continue; /* list only known devices */
374                                 printf("SCSI dev. %d:  ", i);
375                                 dev_print(&scsi_dev_desc[i]);
376                         }
377                         return 0;
378                 }
379                 if (strncmp(argv[1], "dev", 3) == 0) {
380                         if (scsi_curr_dev < 0 ||
381                             scsi_curr_dev >= CONFIG_SYS_SCSI_MAX_DEVICE) {
382                                 printf("\nno SCSI devices available\n");
383                                 return 1;
384                         }
385                         printf("\n    Device %d: ", scsi_curr_dev);
386                         dev_print(&scsi_dev_desc[scsi_curr_dev]);
387                         return 0;
388                 }
389                 if (strncmp(argv[1], "scan", 4) == 0) {
390                         scsi_scan(1);
391                         return 0;
392                 }
393                 if (strncmp(argv[1], "part", 4) == 0) {
394                         int dev, ok;
395                         for (ok = 0, dev = 0;
396                              dev < CONFIG_SYS_SCSI_MAX_DEVICE; ++dev) {
397                                 if (scsi_dev_desc[dev].type !=
398                                     DEV_TYPE_UNKNOWN) {
399                                         ok++;
400                                         if (dev)
401                                                 printf("\n");
402                                         debug("print_part of %x\n", dev);
403                                         part_print(&scsi_dev_desc[dev]);
404                                 }
405                         }
406                         if (!ok)
407                                 printf("\nno SCSI devices available\n");
408                         return 1;
409                 }
410                 return CMD_RET_USAGE;
411         case 3:
412                 if (strncmp(argv[1], "dev", 3) == 0) {
413                         int dev = (int)simple_strtoul(argv[2], NULL, 10);
414                         printf("\nSCSI device %d: ", dev);
415                         if (dev >= CONFIG_SYS_SCSI_MAX_DEVICE) {
416                                 printf("unknown device\n");
417                                 return 1;
418                         }
419                         printf("\n    Device %d: ", dev);
420                         dev_print(&scsi_dev_desc[dev]);
421                         if (scsi_dev_desc[dev].type == DEV_TYPE_UNKNOWN)
422                                 return 1;
423                         scsi_curr_dev = dev;
424                         printf("... is now current device\n");
425                         return 0;
426                 }
427                 if (strncmp(argv[1], "part", 4) == 0) {
428                         int dev = (int)simple_strtoul(argv[2], NULL, 10);
429                         if (scsi_dev_desc[dev].type != DEV_TYPE_UNKNOWN)
430                                 part_print(&scsi_dev_desc[dev]);
431                         else
432                                 printf("\nSCSI device %d not available\n", dev);
433                         return 1;
434                 }
435                 return CMD_RET_USAGE;
436         default:
437                 /* at least 4 args */
438                 if (strcmp(argv[1], "read") == 0) {
439                         ulong addr = simple_strtoul(argv[2], NULL, 16);
440                         ulong blk  = simple_strtoul(argv[3], NULL, 16);
441                         ulong cnt  = simple_strtoul(argv[4], NULL, 16);
442                         ulong n;
443                         printf("\nSCSI read: device %d block # %ld, count %ld ... ",
444                                scsi_curr_dev, blk, cnt);
445                         n = scsi_read(&scsi_dev_desc[scsi_curr_dev],
446                                       blk, cnt, (ulong *)addr);
447                         printf("%ld blocks read: %s\n", n,
448                                n == cnt ? "OK" : "ERROR");
449                         return 0;
450                 } else if (strcmp(argv[1], "write") == 0) {
451                         ulong addr = simple_strtoul(argv[2], NULL, 16);
452                         ulong blk = simple_strtoul(argv[3], NULL, 16);
453                         ulong cnt = simple_strtoul(argv[4], NULL, 16);
454                         ulong n;
455                         printf("\nSCSI write: device %d block # %ld, count %ld ... ",
456                                scsi_curr_dev, blk, cnt);
457                         n = scsi_write(&scsi_dev_desc[scsi_curr_dev],
458                                        blk, cnt, (ulong *)addr);
459                         printf("%ld blocks written: %s\n", n,
460                                n == cnt ? "OK" : "ERROR");
461                         return 0;
462                 }
463         } /* switch */
464         return CMD_RET_USAGE;
465 }
466
467 U_BOOT_CMD(
468         scsi, 5, 1, do_scsi,
469         "SCSI sub-system",
470         "reset - reset SCSI controller\n"
471         "scsi info  - show available SCSI devices\n"
472         "scsi scan  - (re-)scan SCSI bus\n"
473         "scsi device [dev] - show or set current device\n"
474         "scsi part [dev] - print partition table of one or all SCSI devices\n"
475         "scsi read addr blk# cnt - read `cnt' blocks starting at block `blk#'\n"
476         "     to memory address `addr'\n"
477         "scsi write addr blk# cnt - write `cnt' blocks starting at block\n"
478         "     `blk#' from memory address `addr'"
479 );
480
481 U_BOOT_CMD(
482         scsiboot, 3, 1, do_scsiboot,
483         "boot from SCSI device",
484         "loadAddr dev:part"
485 );
486 #endif
487
488 /* copy src to dest, skipping leading and trailing blanks
489  * and null terminate the string
490  */
491 void scsi_ident_cpy(unsigned char *dest, unsigned char *src, unsigned int len)
492 {
493         int start,end;
494
495         start = 0;
496         while (start < len) {
497                 if (src[start] != ' ')
498                         break;
499                 start++;
500         }
501         end = len-1;
502         while (end > start) {
503                 if (src[end] != ' ')
504                         break;
505                 end--;
506         }
507         for (; start <= end; start++)
508                 *dest ++= src[start];
509         *dest='\0';
510 }
511
512
513 /* Trim trailing blanks, and NUL-terminate string
514  */
515 void scsi_trim_trail (unsigned char *str, unsigned int len)
516 {
517         unsigned char *p = str + len - 1;
518
519         while (len-- > 0) {
520                 *p-- = '\0';
521                 if (*p != ' ') {
522                         return;
523                 }
524         }
525 }
526
527 int scsi_read_capacity(ccb *pccb, lbaint_t *capacity, unsigned long *blksz)
528 {
529         *capacity = 0;
530
531         memset(pccb->cmd, '\0', sizeof(pccb->cmd));
532         pccb->cmd[0] = SCSI_RD_CAPAC10;
533         pccb->cmd[1] = pccb->lun << 5;
534         pccb->cmdlen = 10;
535         pccb->msgout[0] = SCSI_IDENTIFY; /* NOT USED */
536
537         pccb->datalen = 8;
538         if (scsi_exec(pccb) != true)
539                 return 1;
540
541         *capacity = ((lbaint_t)pccb->pdata[0] << 24) |
542                     ((lbaint_t)pccb->pdata[1] << 16) |
543                     ((lbaint_t)pccb->pdata[2] << 8)  |
544                     ((lbaint_t)pccb->pdata[3]);
545
546         if (*capacity != 0xffffffff) {
547                 /* Read capacity (10) was sufficient for this drive. */
548                 *blksz = ((unsigned long)pccb->pdata[4] << 24) |
549                          ((unsigned long)pccb->pdata[5] << 16) |
550                          ((unsigned long)pccb->pdata[6] << 8)  |
551                          ((unsigned long)pccb->pdata[7]);
552                 return 0;
553         }
554
555         /* Read capacity (10) was insufficient. Use read capacity (16). */
556         memset(pccb->cmd, '\0', sizeof(pccb->cmd));
557         pccb->cmd[0] = SCSI_RD_CAPAC16;
558         pccb->cmd[1] = 0x10;
559         pccb->cmdlen = 16;
560         pccb->msgout[0] = SCSI_IDENTIFY; /* NOT USED */
561
562         pccb->datalen = 16;
563         if (scsi_exec(pccb) != true)
564                 return 1;
565
566         *capacity = ((uint64_t)pccb->pdata[0] << 56) |
567                     ((uint64_t)pccb->pdata[1] << 48) |
568                     ((uint64_t)pccb->pdata[2] << 40) |
569                     ((uint64_t)pccb->pdata[3] << 32) |
570                     ((uint64_t)pccb->pdata[4] << 24) |
571                     ((uint64_t)pccb->pdata[5] << 16) |
572                     ((uint64_t)pccb->pdata[6] << 8)  |
573                     ((uint64_t)pccb->pdata[7]);
574
575         *blksz = ((uint64_t)pccb->pdata[8]  << 56) |
576                  ((uint64_t)pccb->pdata[9]  << 48) |
577                  ((uint64_t)pccb->pdata[10] << 40) |
578                  ((uint64_t)pccb->pdata[11] << 32) |
579                  ((uint64_t)pccb->pdata[12] << 24) |
580                  ((uint64_t)pccb->pdata[13] << 16) |
581                  ((uint64_t)pccb->pdata[14] << 8)  |
582                  ((uint64_t)pccb->pdata[15]);
583
584         return 0;
585 }
586
587
588 /************************************************************************************
589  * Some setup (fill-in) routines
590  */
591 void scsi_setup_test_unit_ready(ccb * pccb)
592 {
593         pccb->cmd[0] = SCSI_TST_U_RDY;
594         pccb->cmd[1] = pccb->lun << 5;
595         pccb->cmd[2] = 0;
596         pccb->cmd[3] = 0;
597         pccb->cmd[4] = 0;
598         pccb->cmd[5] = 0;
599         pccb->cmdlen = 6;
600         pccb->msgout[0] = SCSI_IDENTIFY; /* NOT USED */
601 }
602
603 /*********************************************************************************
604  * (re)-scan the scsi bus and reports scsi device info
605  * to the user if mode = 1
606  */
607 void scsi_scan(int mode)
608 {
609         unsigned char i,perq,modi,lun;
610         lbaint_t capacity;
611         unsigned long blksz;
612         ccb* pccb=(ccb *)&tempccb;
613
614         if (mode == 1)
615                 printf("scanning bus for devices...\n");
616         for (i = 0; i < CONFIG_SYS_SCSI_MAX_DEVICE; i++) {
617                 scsi_dev_desc[i].target = 0xff;
618                 scsi_dev_desc[i].lun = 0xff;
619                 scsi_dev_desc[i].lba = 0;
620                 scsi_dev_desc[i].blksz = 0;
621                 scsi_dev_desc[i].log2blksz  =
622                         LOG2_INVALID(typeof(scsi_dev_desc[i].log2blksz));
623                 scsi_dev_desc[i].type = DEV_TYPE_UNKNOWN;
624                 scsi_dev_desc[i].vendor[0] = 0;
625                 scsi_dev_desc[i].product[0] = 0;
626                 scsi_dev_desc[i].revision[0] = 0;
627                 scsi_dev_desc[i].removable = false;
628                 scsi_dev_desc[i].if_type = IF_TYPE_SCSI;
629                 scsi_dev_desc[i].devnum = i;
630                 scsi_dev_desc[i].part_type = PART_TYPE_UNKNOWN;
631                 scsi_dev_desc[i].block_read = scsi_read;
632                 scsi_dev_desc[i].block_write = scsi_write;
633         }
634         scsi_max_devs = 0;
635         for (i = 0; i < CONFIG_SYS_SCSI_MAX_SCSI_ID; i++) {
636                 pccb->target = i;
637                 for (lun = 0; lun < CONFIG_SYS_SCSI_MAX_LUN; lun++) {
638                         pccb->lun = lun;
639                         pccb->pdata = (unsigned char *)&tempbuff;
640                         pccb->datalen = 512;
641                         scsi_setup_inquiry(pccb);
642                         if (scsi_exec(pccb) != true) {
643                                 if(pccb->contr_stat==SCSI_SEL_TIME_OUT) {
644                                         debug("Selection timeout ID %d\n",
645                                               pccb->target);
646                                         continue; /* selection timeout => assuming no device present */
647                                 }
648                                 scsi_print_error(pccb);
649                                 continue;
650                         }
651                         perq = tempbuff[0];
652                         modi = tempbuff[1];
653                         if ((perq & 0x1f) == 0x1f)
654                                 continue; /* skip unknown devices */
655                         if ((modi & 0x80) == 0x80) /* drive is removable */
656                                 scsi_dev_desc[scsi_max_devs].removable = true;
657                         /* get info for this device */
658                         scsi_ident_cpy((unsigned char *)&scsi_dev_desc[scsi_max_devs].vendor[0],
659                                        &tempbuff[8], 8);
660                         scsi_ident_cpy((unsigned char *)&scsi_dev_desc[scsi_max_devs].product[0],
661                                        &tempbuff[16], 16);
662                         scsi_ident_cpy((unsigned char *)&scsi_dev_desc[scsi_max_devs].revision[0],
663                                        &tempbuff[32], 4);
664                         scsi_dev_desc[scsi_max_devs].target = pccb->target;
665                         scsi_dev_desc[scsi_max_devs].lun = pccb->lun;
666
667                         pccb->datalen = 0;
668                         scsi_setup_test_unit_ready(pccb);
669                         if (scsi_exec(pccb) != true) {
670                                 if (scsi_dev_desc[scsi_max_devs].removable) {
671                                         scsi_dev_desc[scsi_max_devs].type =
672                                                         perq;
673                                         goto removable;
674                                 }
675                                 scsi_print_error(pccb);
676                                 continue;
677                         }
678                         if (scsi_read_capacity(pccb, &capacity, &blksz)) {
679                                 scsi_print_error(pccb);
680                                 continue;
681                         }
682                         scsi_dev_desc[scsi_max_devs].lba = capacity;
683                         scsi_dev_desc[scsi_max_devs].blksz = blksz;
684                         scsi_dev_desc[scsi_max_devs].log2blksz =
685                                 LOG2(scsi_dev_desc[scsi_max_devs].blksz);
686                         scsi_dev_desc[scsi_max_devs].type = perq;
687                         part_init(&scsi_dev_desc[scsi_max_devs]);
688 removable:
689                         if(mode==1) {
690                                 printf ("  Device %d: ", scsi_max_devs);
691                                 dev_print(&scsi_dev_desc[scsi_max_devs]);
692                         } /* if mode */
693                         scsi_max_devs++;
694                 } /* next LUN */
695         }
696         if (scsi_max_devs > 0)
697                 scsi_curr_dev = 0;
698         else
699                 scsi_curr_dev = -1;
700
701         printf("Found %d device(s).\n", scsi_max_devs);
702 #ifndef CONFIG_SPL_BUILD
703         setenv_ulong("scsidevs", scsi_max_devs);
704 #endif
705 }