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