Merge git://git.denx.de/u-boot-mpc85xx
[oweals/u-boot.git] / common / scsi.c
1 /*
2  * (C) Copyright 2001
3  * Denis Peter, MPL AG Switzerland
4  *
5  * SPDX-License-Identifier:     GPL-2.0+
6  */
7
8 #include <common.h>
9 #include <dm.h>
10 #include <inttypes.h>
11 #include <pci.h>
12 #include <scsi.h>
13
14 #ifdef CONFIG_SCSI_DEV_LIST
15 #define SCSI_DEV_LIST CONFIG_SCSI_DEV_LIST
16 #else
17 #ifdef CONFIG_SCSI_SYM53C8XX
18 #define SCSI_VEND_ID    0x1000
19 #ifndef CONFIG_SCSI_DEV_ID
20 #define SCSI_DEV_ID             0x0001
21 #else
22 #define SCSI_DEV_ID             CONFIG_SCSI_DEV_ID
23 #endif
24 #elif defined CONFIG_SATA_ULI5288
25
26 #define SCSI_VEND_ID 0x10b9
27 #define SCSI_DEV_ID  0x5288
28
29 #elif !defined(CONFIG_SCSI_AHCI_PLAT)
30 #error no scsi device defined
31 #endif
32 #define SCSI_DEV_LIST {SCSI_VEND_ID, SCSI_DEV_ID}
33 #endif
34
35 #if defined(CONFIG_PCI) && !defined(CONFIG_SCSI_AHCI_PLAT)
36 const struct pci_device_id scsi_device_list[] = { SCSI_DEV_LIST };
37 #endif
38 static ccb tempccb;     /* temporary scsi command buffer */
39
40 static unsigned char tempbuff[512]; /* temporary data buffer */
41
42 static int scsi_max_devs; /* number of highest available scsi device */
43
44 static int scsi_curr_dev; /* current device */
45
46 static struct blk_desc scsi_dev_desc[CONFIG_SYS_SCSI_MAX_DEVICE];
47
48 /* almost the maximum amount of the scsi_ext command.. */
49 #define SCSI_MAX_READ_BLK 0xFFFF
50 #define SCSI_LBA48_READ 0xFFFFFFF
51
52 #ifdef CONFIG_SYS_64BIT_LBA
53 void scsi_setup_read16(ccb *pccb, lbaint_t start, unsigned long blocks)
54 {
55         pccb->cmd[0] = SCSI_READ16;
56         pccb->cmd[1] = pccb->lun << 5;
57         pccb->cmd[2] = (unsigned char)(start >> 56) & 0xff;
58         pccb->cmd[3] = (unsigned char)(start >> 48) & 0xff;
59         pccb->cmd[4] = (unsigned char)(start >> 40) & 0xff;
60         pccb->cmd[5] = (unsigned char)(start >> 32) & 0xff;
61         pccb->cmd[6] = (unsigned char)(start >> 24) & 0xff;
62         pccb->cmd[7] = (unsigned char)(start >> 16) & 0xff;
63         pccb->cmd[8] = (unsigned char)(start >> 8) & 0xff;
64         pccb->cmd[9] = (unsigned char)start & 0xff;
65         pccb->cmd[10] = 0;
66         pccb->cmd[11] = (unsigned char)(blocks >> 24) & 0xff;
67         pccb->cmd[12] = (unsigned char)(blocks >> 16) & 0xff;
68         pccb->cmd[13] = (unsigned char)(blocks >> 8) & 0xff;
69         pccb->cmd[14] = (unsigned char)blocks & 0xff;
70         pccb->cmd[15] = 0;
71         pccb->cmdlen = 16;
72         pccb->msgout[0] = SCSI_IDENTIFY; /* NOT USED */
73         debug("scsi_setup_read16: cmd: %02X %02X startblk %02X%02X%02X%02X%02X%02X%02X%02X blccnt %02X%02X%02X%02X\n",
74               pccb->cmd[0], pccb->cmd[1],
75               pccb->cmd[2], pccb->cmd[3], pccb->cmd[4], pccb->cmd[5],
76               pccb->cmd[6], pccb->cmd[7], pccb->cmd[8], pccb->cmd[9],
77               pccb->cmd[11], pccb->cmd[12], pccb->cmd[13], pccb->cmd[14]);
78 }
79 #endif
80
81 static void scsi_setup_read_ext(ccb *pccb, lbaint_t start,
82                                 unsigned short blocks)
83 {
84         pccb->cmd[0] = SCSI_READ10;
85         pccb->cmd[1] = pccb->lun << 5;
86         pccb->cmd[2] = (unsigned char)(start >> 24) & 0xff;
87         pccb->cmd[3] = (unsigned char)(start >> 16) & 0xff;
88         pccb->cmd[4] = (unsigned char)(start >> 8) & 0xff;
89         pccb->cmd[5] = (unsigned char)start & 0xff;
90         pccb->cmd[6] = 0;
91         pccb->cmd[7] = (unsigned char)(blocks >> 8) & 0xff;
92         pccb->cmd[8] = (unsigned char)blocks & 0xff;
93         pccb->cmd[6] = 0;
94         pccb->cmdlen = 10;
95         pccb->msgout[0] = SCSI_IDENTIFY; /* NOT USED */
96         debug("scsi_setup_read_ext: cmd: %02X %02X startblk %02X%02X%02X%02X blccnt %02X%02X\n",
97               pccb->cmd[0], pccb->cmd[1],
98               pccb->cmd[2], pccb->cmd[3], pccb->cmd[4], pccb->cmd[5],
99               pccb->cmd[7], pccb->cmd[8]);
100 }
101
102 static void scsi_setup_write_ext(ccb *pccb, lbaint_t start,
103                                  unsigned short blocks)
104 {
105         pccb->cmd[0] = SCSI_WRITE10;
106         pccb->cmd[1] = pccb->lun << 5;
107         pccb->cmd[2] = (unsigned char)(start >> 24) & 0xff;
108         pccb->cmd[3] = (unsigned char)(start >> 16) & 0xff;
109         pccb->cmd[4] = (unsigned char)(start >> 8) & 0xff;
110         pccb->cmd[5] = (unsigned char)start & 0xff;
111         pccb->cmd[6] = 0;
112         pccb->cmd[7] = ((unsigned char)(blocks >> 8)) & 0xff;
113         pccb->cmd[8] = (unsigned char)blocks & 0xff;
114         pccb->cmd[9] = 0;
115         pccb->cmdlen = 10;
116         pccb->msgout[0] = SCSI_IDENTIFY;  /* NOT USED */
117         debug("%s: cmd: %02X %02X startblk %02X%02X%02X%02X blccnt %02X%02X\n",
118               __func__,
119               pccb->cmd[0], pccb->cmd[1],
120               pccb->cmd[2], pccb->cmd[3], pccb->cmd[4], pccb->cmd[5],
121               pccb->cmd[7], pccb->cmd[8]);
122 }
123
124 static void scsi_setup_inquiry(ccb *pccb)
125 {
126         pccb->cmd[0] = SCSI_INQUIRY;
127         pccb->cmd[1] = pccb->lun << 5;
128         pccb->cmd[2] = 0;
129         pccb->cmd[3] = 0;
130         if (pccb->datalen > 255)
131                 pccb->cmd[4] = 255;
132         else
133                 pccb->cmd[4] = (unsigned char)pccb->datalen;
134         pccb->cmd[5] = 0;
135         pccb->cmdlen = 6;
136         pccb->msgout[0] = SCSI_IDENTIFY; /* NOT USED */
137 }
138
139 #ifdef CONFIG_BLK
140 static ulong scsi_read(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
141                        void *buffer)
142 #else
143 static ulong scsi_read(struct blk_desc *block_dev, lbaint_t blknr,
144                        lbaint_t blkcnt, void *buffer)
145 #endif
146 {
147 #ifdef CONFIG_BLK
148         struct blk_desc *block_dev = dev_get_uclass_platdata(dev);
149 #endif
150         lbaint_t start, blks;
151         uintptr_t buf_addr;
152         unsigned short smallblks = 0;
153         ccb *pccb = (ccb *)&tempccb;
154
155         /* Setup device */
156         pccb->target = block_dev->target;
157         pccb->lun = block_dev->lun;
158         buf_addr = (unsigned long)buffer;
159         start = blknr;
160         blks = blkcnt;
161         debug("\nscsi_read: dev %d startblk " LBAF
162               ", blccnt " LBAF " buffer %lx\n",
163               block_dev->devnum, start, blks, (unsigned long)buffer);
164         do {
165                 pccb->pdata = (unsigned char *)buf_addr;
166 #ifdef CONFIG_SYS_64BIT_LBA
167                 if (start > SCSI_LBA48_READ) {
168                         unsigned long blocks;
169                         blocks = min_t(lbaint_t, blks, SCSI_MAX_READ_BLK);
170                         pccb->datalen = block_dev->blksz * blocks;
171                         scsi_setup_read16(pccb, start, blocks);
172                         start += blocks;
173                         blks -= blocks;
174                 } else
175 #endif
176                 if (blks > SCSI_MAX_READ_BLK) {
177                         pccb->datalen = block_dev->blksz *
178                                 SCSI_MAX_READ_BLK;
179                         smallblks = SCSI_MAX_READ_BLK;
180                         scsi_setup_read_ext(pccb, start, smallblks);
181                         start += SCSI_MAX_READ_BLK;
182                         blks -= SCSI_MAX_READ_BLK;
183                 } else {
184                         pccb->datalen = block_dev->blksz * blks;
185                         smallblks = (unsigned short)blks;
186                         scsi_setup_read_ext(pccb, start, smallblks);
187                         start += blks;
188                         blks = 0;
189                 }
190                 debug("scsi_read_ext: startblk " LBAF
191                       ", blccnt %x buffer %" PRIXPTR "\n",
192                       start, smallblks, buf_addr);
193                 if (scsi_exec(pccb) != true) {
194                         scsi_print_error(pccb);
195                         blkcnt -= blks;
196                         break;
197                 }
198                 buf_addr += pccb->datalen;
199         } while (blks != 0);
200         debug("scsi_read_ext: end startblk " LBAF
201               ", blccnt %x buffer %" PRIXPTR "\n", start, smallblks, buf_addr);
202         return blkcnt;
203 }
204
205 /*******************************************************************************
206  * scsi_write
207  */
208
209 /* Almost the maximum amount of the scsi_ext command.. */
210 #define SCSI_MAX_WRITE_BLK 0xFFFF
211
212 #ifdef CONFIG_BLK
213 static ulong scsi_write(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
214                         const void *buffer)
215 #else
216 static ulong scsi_write(struct blk_desc *block_dev, lbaint_t blknr,
217                         lbaint_t blkcnt, const void *buffer)
218 #endif
219 {
220 #ifdef CONFIG_BLK
221         struct blk_desc *block_dev = dev_get_uclass_platdata(dev);
222 #endif
223         lbaint_t start, blks;
224         uintptr_t buf_addr;
225         unsigned short smallblks;
226         ccb *pccb = (ccb *)&tempccb;
227
228         /* Setup device */
229         pccb->target = block_dev->target;
230         pccb->lun = block_dev->lun;
231         buf_addr = (unsigned long)buffer;
232         start = blknr;
233         blks = blkcnt;
234         debug("\n%s: dev %d startblk " LBAF ", blccnt " LBAF " buffer %lx\n",
235               __func__, block_dev->devnum, start, blks, (unsigned long)buffer);
236         do {
237                 pccb->pdata = (unsigned char *)buf_addr;
238                 if (blks > SCSI_MAX_WRITE_BLK) {
239                         pccb->datalen = (block_dev->blksz *
240                                          SCSI_MAX_WRITE_BLK);
241                         smallblks = SCSI_MAX_WRITE_BLK;
242                         scsi_setup_write_ext(pccb, start, smallblks);
243                         start += SCSI_MAX_WRITE_BLK;
244                         blks -= SCSI_MAX_WRITE_BLK;
245                 } else {
246                         pccb->datalen = block_dev->blksz * blks;
247                         smallblks = (unsigned short)blks;
248                         scsi_setup_write_ext(pccb, start, smallblks);
249                         start += blks;
250                         blks = 0;
251                 }
252                 debug("%s: startblk " LBAF ", blccnt %x buffer %" PRIXPTR "\n",
253                       __func__, start, smallblks, buf_addr);
254                 if (scsi_exec(pccb) != true) {
255                         scsi_print_error(pccb);
256                         blkcnt -= blks;
257                         break;
258                 }
259                 buf_addr += pccb->datalen;
260         } while (blks != 0);
261         debug("%s: end startblk " LBAF ", blccnt %x buffer %" PRIXPTR "\n",
262               __func__, start, smallblks, buf_addr);
263         return blkcnt;
264 }
265
266 #if defined(CONFIG_PCI) && !defined(CONFIG_SCSI_AHCI_PLAT)
267 void scsi_init(void)
268 {
269         int busdevfunc = -1;
270         int i;
271         /*
272          * Find a device from the list, this driver will support a single
273          * controller.
274          */
275         for (i = 0; i < ARRAY_SIZE(scsi_device_list); i++) {
276                 /* get PCI Device ID */
277 #ifdef CONFIG_DM_PCI
278                 struct udevice *dev;
279                 int ret;
280
281                 ret = dm_pci_find_device(scsi_device_list[i].vendor,
282                                          scsi_device_list[i].device, 0, &dev);
283                 if (!ret) {
284                         busdevfunc = dm_pci_get_bdf(dev);
285                         break;
286                 }
287 #else
288                 busdevfunc = pci_find_device(scsi_device_list[i].vendor,
289                                              scsi_device_list[i].device,
290                                              0);
291 #endif
292                 if (busdevfunc != -1)
293                         break;
294         }
295
296         if (busdevfunc == -1) {
297                 printf("Error: SCSI Controller(s) ");
298                 for (i = 0; i < ARRAY_SIZE(scsi_device_list); i++) {
299                         printf("%04X:%04X ",
300                                scsi_device_list[i].vendor,
301                                scsi_device_list[i].device);
302                 }
303                 printf("not found\n");
304                 return;
305         }
306 #ifdef DEBUG
307         else {
308                 printf("SCSI Controller (%04X,%04X) found (%d:%d:%d)\n",
309                        scsi_device_list[i].vendor,
310                        scsi_device_list[i].device,
311                        (busdevfunc >> 16) & 0xFF,
312                        (busdevfunc >> 11) & 0x1F,
313                        (busdevfunc >> 8) & 0x7);
314         }
315 #endif
316         bootstage_start(BOOTSTAGE_ID_ACCUM_SCSI, "ahci");
317         scsi_low_level_init(busdevfunc);
318         scsi_scan(1);
319         bootstage_accum(BOOTSTAGE_ID_ACCUM_SCSI);
320 }
321 #endif
322
323 /* copy src to dest, skipping leading and trailing blanks
324  * and null terminate the string
325  */
326 static void scsi_ident_cpy(unsigned char *dest, unsigned char *src,
327                            unsigned int len)
328 {
329         int start, end;
330
331         start = 0;
332         while (start < len) {
333                 if (src[start] != ' ')
334                         break;
335                 start++;
336         }
337         end = len-1;
338         while (end > start) {
339                 if (src[end] != ' ')
340                         break;
341                 end--;
342         }
343         for (; start <= end; start++)
344                 *dest ++= src[start];
345         *dest = '\0';
346 }
347
348 static int scsi_read_capacity(ccb *pccb, lbaint_t *capacity,
349                               unsigned long *blksz)
350 {
351         *capacity = 0;
352
353         memset(pccb->cmd, '\0', sizeof(pccb->cmd));
354         pccb->cmd[0] = SCSI_RD_CAPAC10;
355         pccb->cmd[1] = pccb->lun << 5;
356         pccb->cmdlen = 10;
357         pccb->msgout[0] = SCSI_IDENTIFY; /* NOT USED */
358
359         pccb->datalen = 8;
360         if (scsi_exec(pccb) != true)
361                 return 1;
362
363         *capacity = ((lbaint_t)pccb->pdata[0] << 24) |
364                     ((lbaint_t)pccb->pdata[1] << 16) |
365                     ((lbaint_t)pccb->pdata[2] << 8)  |
366                     ((lbaint_t)pccb->pdata[3]);
367
368         if (*capacity != 0xffffffff) {
369                 /* Read capacity (10) was sufficient for this drive. */
370                 *blksz = ((unsigned long)pccb->pdata[4] << 24) |
371                          ((unsigned long)pccb->pdata[5] << 16) |
372                          ((unsigned long)pccb->pdata[6] << 8)  |
373                          ((unsigned long)pccb->pdata[7]);
374                 return 0;
375         }
376
377         /* Read capacity (10) was insufficient. Use read capacity (16). */
378         memset(pccb->cmd, '\0', sizeof(pccb->cmd));
379         pccb->cmd[0] = SCSI_RD_CAPAC16;
380         pccb->cmd[1] = 0x10;
381         pccb->cmdlen = 16;
382         pccb->msgout[0] = SCSI_IDENTIFY; /* NOT USED */
383
384         pccb->datalen = 16;
385         if (scsi_exec(pccb) != true)
386                 return 1;
387
388         *capacity = ((uint64_t)pccb->pdata[0] << 56) |
389                     ((uint64_t)pccb->pdata[1] << 48) |
390                     ((uint64_t)pccb->pdata[2] << 40) |
391                     ((uint64_t)pccb->pdata[3] << 32) |
392                     ((uint64_t)pccb->pdata[4] << 24) |
393                     ((uint64_t)pccb->pdata[5] << 16) |
394                     ((uint64_t)pccb->pdata[6] << 8)  |
395                     ((uint64_t)pccb->pdata[7]);
396
397         *blksz = ((uint64_t)pccb->pdata[8]  << 56) |
398                  ((uint64_t)pccb->pdata[9]  << 48) |
399                  ((uint64_t)pccb->pdata[10] << 40) |
400                  ((uint64_t)pccb->pdata[11] << 32) |
401                  ((uint64_t)pccb->pdata[12] << 24) |
402                  ((uint64_t)pccb->pdata[13] << 16) |
403                  ((uint64_t)pccb->pdata[14] << 8)  |
404                  ((uint64_t)pccb->pdata[15]);
405
406         return 0;
407 }
408
409
410 /*
411  * Some setup (fill-in) routines
412  */
413 static void scsi_setup_test_unit_ready(ccb *pccb)
414 {
415         pccb->cmd[0] = SCSI_TST_U_RDY;
416         pccb->cmd[1] = pccb->lun << 5;
417         pccb->cmd[2] = 0;
418         pccb->cmd[3] = 0;
419         pccb->cmd[4] = 0;
420         pccb->cmd[5] = 0;
421         pccb->cmdlen = 6;
422         pccb->msgout[0] = SCSI_IDENTIFY; /* NOT USED */
423 }
424
425 /**
426  * scsi_init_dev_desc_priv - initialize only SCSI specific blk_desc properties
427  *
428  * @dev_desc: Block device description pointer
429  */
430 static void scsi_init_dev_desc_priv(struct blk_desc *dev_desc)
431 {
432         dev_desc->target = 0xff;
433         dev_desc->lun = 0xff;
434         dev_desc->log2blksz =
435                 LOG2_INVALID(typeof(dev_desc->log2blksz));
436         dev_desc->type = DEV_TYPE_UNKNOWN;
437         dev_desc->vendor[0] = 0;
438         dev_desc->product[0] = 0;
439         dev_desc->revision[0] = 0;
440         dev_desc->removable = false;
441 #ifndef CONFIG_BLK
442         dev_desc->block_read = scsi_read;
443         dev_desc->block_write = scsi_write;
444 #endif
445 }
446
447 /**
448  * scsi_init_dev_desc - initialize all SCSI specific blk_desc properties
449  *
450  * @dev_desc: Block device description pointer
451  * @devnum: Device number
452  */
453 static void scsi_init_dev_desc(struct blk_desc *dev_desc, int devnum)
454 {
455         dev_desc->lba = 0;
456         dev_desc->blksz = 0;
457         dev_desc->if_type = IF_TYPE_SCSI;
458         dev_desc->devnum = devnum;
459         dev_desc->part_type = PART_TYPE_UNKNOWN;
460
461         scsi_init_dev_desc_priv(dev_desc);
462 }
463
464 /**
465  * scsi_detect_dev - Detect scsi device
466  *
467  * @target: target id
468  * @dev_desc: block device description
469  *
470  * The scsi_detect_dev detects and fills a dev_desc structure when the device is
471  * detected. The LUN number is taken from the struct blk_desc *dev_desc.
472  *
473  * Return: 0 on success, error value otherwise
474  */
475 static int scsi_detect_dev(int target, struct blk_desc *dev_desc)
476 {
477         unsigned char perq, modi;
478         lbaint_t capacity;
479         unsigned long blksz;
480         ccb *pccb = (ccb *)&tempccb;
481
482         pccb->target = target;
483         pccb->lun = dev_desc->lun;
484         pccb->pdata = (unsigned char *)&tempbuff;
485         pccb->datalen = 512;
486         scsi_setup_inquiry(pccb);
487         if (scsi_exec(pccb) != true) {
488                 if (pccb->contr_stat == SCSI_SEL_TIME_OUT) {
489                         /*
490                           * selection timeout => assuming no
491                           * device present
492                           */
493                         debug("Selection timeout ID %d\n",
494                               pccb->target);
495                         return -ETIMEDOUT;
496                 }
497                 scsi_print_error(pccb);
498                 return -ENODEV;
499         }
500         perq = tempbuff[0];
501         modi = tempbuff[1];
502         if ((perq & 0x1f) == 0x1f)
503                 return -ENODEV; /* skip unknown devices */
504         if ((modi & 0x80) == 0x80) /* drive is removable */
505                 dev_desc->removable = true;
506         /* get info for this device */
507         scsi_ident_cpy((unsigned char *)dev_desc->vendor,
508                        &tempbuff[8], 8);
509         scsi_ident_cpy((unsigned char *)dev_desc->product,
510                        &tempbuff[16], 16);
511         scsi_ident_cpy((unsigned char *)dev_desc->revision,
512                        &tempbuff[32], 4);
513         dev_desc->target = pccb->target;
514         dev_desc->lun = pccb->lun;
515
516         pccb->datalen = 0;
517         scsi_setup_test_unit_ready(pccb);
518         if (scsi_exec(pccb) != true) {
519                 if (dev_desc->removable) {
520                         dev_desc->type = perq;
521                         goto removable;
522                 }
523                 scsi_print_error(pccb);
524                 return -EINVAL;
525         }
526         if (scsi_read_capacity(pccb, &capacity, &blksz)) {
527                 scsi_print_error(pccb);
528                 return -EINVAL;
529         }
530         dev_desc->lba = capacity;
531         dev_desc->blksz = blksz;
532         dev_desc->log2blksz = LOG2(dev_desc->blksz);
533         dev_desc->type = perq;
534         part_init(&dev_desc[0]);
535 removable:
536         return 0;
537 }
538
539 /*
540  * (re)-scan the scsi bus and reports scsi device info
541  * to the user if mode = 1
542  */
543 int scsi_scan(int mode)
544 {
545         unsigned char i, lun;
546         int ret;
547
548         if (mode == 1)
549                 printf("scanning bus for devices...\n");
550         for (i = 0; i < CONFIG_SYS_SCSI_MAX_DEVICE; i++)
551                 scsi_init_dev_desc(&scsi_dev_desc[i], i);
552
553         scsi_max_devs = 0;
554         for (i = 0; i < CONFIG_SYS_SCSI_MAX_SCSI_ID; i++) {
555                 for (lun = 0; lun < CONFIG_SYS_SCSI_MAX_LUN; lun++) {
556                         scsi_dev_desc[scsi_max_devs].lun = lun;
557                         ret = scsi_detect_dev(i, &scsi_dev_desc[scsi_max_devs]);
558                         if (ret)
559                                 continue;
560
561                         if (mode == 1) {
562                                 printf("  Device %d: ", 0);
563                                 dev_print(&scsi_dev_desc[scsi_max_devs]);
564                         } /* if mode */
565                         scsi_max_devs++;
566                 } /* next LUN */
567         }
568         if (scsi_max_devs > 0)
569                 scsi_curr_dev = 0;
570         else
571                 scsi_curr_dev = -1;
572
573         printf("Found %d device(s).\n", scsi_max_devs);
574 #ifndef CONFIG_SPL_BUILD
575         setenv_ulong("scsidevs", scsi_max_devs);
576 #endif
577         return 0;
578 }
579
580 #ifdef CONFIG_BLK
581 static const struct blk_ops scsi_blk_ops = {
582         .read   = scsi_read,
583         .write  = scsi_write,
584 };
585
586 U_BOOT_DRIVER(scsi_blk) = {
587         .name           = "scsi_blk",
588         .id             = UCLASS_BLK,
589         .ops            = &scsi_blk_ops,
590 };
591 #else
592 U_BOOT_LEGACY_BLK(scsi) = {
593         .if_typename    = "scsi",
594         .if_type        = IF_TYPE_SCSI,
595         .max_devs       = CONFIG_SYS_SCSI_MAX_DEVICE,
596         .desc           = scsi_dev_desc,
597 };
598 #endif