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 } 706