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