X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;ds=sidebyside;f=common%2Fcmd_scsi.c;h=86954089fe78aa234434306e37aba9bee9ec1d91;hb=774da4b9aadeea4d6973a16debc02a6801ff9344;hp=13b3d996f649b2b443fddcf6b5c531527d2e5ed2;hpb=18122019972ca639ee3b581257e3a63ff7c8efeb;p=oweals%2Fu-boot.git diff --git a/common/cmd_scsi.c b/common/cmd_scsi.c index 13b3d996f6..86954089fe 100644 --- a/common/cmd_scsi.c +++ b/common/cmd_scsi.c @@ -2,26 +2,7 @@ * (C) Copyright 2001 * Denis Peter, MPL AG Switzerland * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - * - * + * SPDX-License-Identifier: GPL-2.0+ */ /* @@ -29,6 +10,7 @@ */ #include #include +#include #include #include #include @@ -55,7 +37,7 @@ #define SCSI_DEV_LIST {SCSI_VEND_ID, SCSI_DEV_ID} #endif -#ifdef CONFIG_PCI +#if defined(CONFIG_PCI) && !defined(CONFIG_SCSI_AHCI_PLAT) const struct pci_device_id scsi_device_list[] = { SCSI_DEV_LIST }; #endif static ccb tempccb; /* temporary scsi command buffer */ @@ -72,18 +54,21 @@ static block_dev_desc_t scsi_dev_desc[CONFIG_SYS_SCSI_MAX_DEVICE]; * forward declerations of some Setup Routines */ void scsi_setup_test_unit_ready(ccb * pccb); -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); -static void scsi_setup_write_ext(ccb *pccb, unsigned long start, - unsigned short blocks); +void scsi_setup_read6(ccb * pccb, lbaint_t start, unsigned short blocks); +void scsi_setup_read_ext(ccb * pccb, lbaint_t start, unsigned short blocks); +void scsi_setup_read16(ccb * pccb, lbaint_t start, unsigned long blocks); + +static void scsi_setup_write_ext(ccb *pccb, lbaint_t start, + unsigned short blocks); void scsi_setup_inquiry(ccb * pccb); void scsi_ident_cpy (unsigned char *dest, unsigned char *src, unsigned int len); static int scsi_read_capacity(ccb *pccb, lbaint_t *capacity, unsigned long *blksz); -static ulong scsi_read(int device, ulong blknr, lbaint_t blkcnt, void *buffer); -static ulong scsi_write(int device, ulong blknr, +static ulong scsi_read(int device, lbaint_t blknr, lbaint_t blkcnt, + void *buffer); +static ulong scsi_write(int device, lbaint_t blknr, lbaint_t blkcnt, const void *buffer); @@ -106,6 +91,8 @@ void scsi_scan(int mode) scsi_dev_desc[i].lun=0xff; scsi_dev_desc[i].lba=0; scsi_dev_desc[i].blksz=0; + scsi_dev_desc[i].log2blksz = + LOG2_INVALID(typeof(scsi_dev_desc[i].log2blksz)); scsi_dev_desc[i].type=DEV_TYPE_UNKNOWN; scsi_dev_desc[i].vendor[0]=0; scsi_dev_desc[i].product[0]=0; @@ -166,6 +153,8 @@ void scsi_scan(int mode) } scsi_dev_desc[scsi_max_devs].lba=capacity; scsi_dev_desc[scsi_max_devs].blksz=blksz; + scsi_dev_desc[scsi_max_devs].log2blksz = + LOG2(scsi_dev_desc[scsi_max_devs].blksz); scsi_dev_desc[scsi_max_devs].type=perq; init_part(&scsi_dev_desc[scsi_max_devs]); removable: @@ -182,7 +171,9 @@ removable: scsi_curr_dev = -1; printf("Found %d device(s).\n", scsi_max_devs); +#ifndef CONFIG_SPL_BUILD setenv_ulong("scsidevs", scsi_max_devs); +#endif } int scsi_get_disk_count(void) @@ -190,10 +181,10 @@ int scsi_get_disk_count(void) return scsi_max_devs; } -#ifdef CONFIG_PCI +#if defined(CONFIG_PCI) && !defined(CONFIG_SCSI_AHCI_PLAT) void scsi_init(void) { - int busdevfunc; + int busdevfunc = -1; int i; /* * Find a device from the list, this driver will support a single @@ -201,9 +192,21 @@ void scsi_init(void) */ for (i = 0; i < ARRAY_SIZE(scsi_device_list); i++) { /* get PCI Device ID */ +#ifdef CONFIG_DM_PCI + struct udevice *dev; + int ret; + + ret = dm_pci_find_device(scsi_device_list[i].vendor, + scsi_device_list[i].device, 0, &dev); + if (!ret) { + busdevfunc = dm_pci_get_bdf(dev); + break; + } +#else busdevfunc = pci_find_device(scsi_device_list[i].vendor, scsi_device_list[i].device, 0); +#endif if (busdevfunc != -1) break; } @@ -228,8 +231,10 @@ void scsi_init(void) (busdevfunc >> 8) & 0x7); } #endif + bootstage_start(BOOTSTAGE_ID_ACCUM_SCSI, "ahci"); scsi_low_level_init(busdevfunc); scsi_scan(1); + bootstage_accum(BOOTSTAGE_ID_ACCUM_SCSI); } #endif @@ -366,13 +371,16 @@ int do_scsi (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) * scsi_read */ -#define SCSI_MAX_READ_BLK 0xFFFF /* almost the maximum amount of the scsi_ext command.. */ +/* almost the maximum amount of the scsi_ext command.. */ +#define SCSI_MAX_READ_BLK 0xFFFF +#define SCSI_LBA48_READ 0xFFFFFFF -static ulong scsi_read(int device, ulong blknr, lbaint_t blkcnt, void *buffer) +static ulong scsi_read(int device, lbaint_t blknr, lbaint_t blkcnt, + void *buffer) { lbaint_t start, blks; uintptr_t buf_addr; - unsigned short smallblks; + unsigned short smallblks = 0; ccb* pccb=(ccb *)&tempccb; device&=0xff; /* Setup device @@ -387,7 +395,17 @@ static ulong scsi_read(int device, ulong blknr, lbaint_t blkcnt, void *buffer) device, start, blks, (unsigned long)buffer); do { pccb->pdata=(unsigned char *)buf_addr; - if(blks>SCSI_MAX_READ_BLK) { +#ifdef CONFIG_SYS_64BIT_LBA + if (start > SCSI_LBA48_READ) { + unsigned long blocks; + blocks = min_t(lbaint_t, blks, SCSI_MAX_READ_BLK); + pccb->datalen = scsi_dev_desc[device].blksz * blocks; + scsi_setup_read16(pccb, start, blocks); + start += blocks; + blks -= blocks; + } else +#endif + 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); @@ -402,7 +420,7 @@ static ulong scsi_read(int device, ulong blknr, lbaint_t blkcnt, void *buffer) blks=0; } debug("scsi_read_ext: startblk " LBAF - ", blccnt %x buffer %lx\n", + ", blccnt %x buffer %" PRIXPTR "\n", start, smallblks, buf_addr); if (scsi_exec(pccb) != true) { scsi_print_error(pccb); @@ -412,7 +430,7 @@ static ulong scsi_read(int device, ulong blknr, lbaint_t blkcnt, void *buffer) buf_addr+=pccb->datalen; } while(blks!=0); debug("scsi_read_ext: end startblk " LBAF - ", blccnt %x buffer %lx\n", start, smallblks, buf_addr); + ", blccnt %x buffer %" PRIXPTR "\n", start, smallblks, buf_addr); return(blkcnt); } @@ -423,7 +441,7 @@ static ulong scsi_read(int device, ulong blknr, lbaint_t blkcnt, void *buffer) /* Almost the maximum amount of the scsi_ext command.. */ #define SCSI_MAX_WRITE_BLK 0xFFFF -static ulong scsi_write(int device, ulong blknr, +static ulong scsi_write(int device, lbaint_t blknr, lbaint_t blkcnt, const void *buffer) { lbaint_t start, blks; @@ -456,7 +474,7 @@ static ulong scsi_write(int device, ulong blknr, start += blks; blks = 0; } - debug("%s: startblk " LBAF ", blccnt %x buffer %lx\n", + debug("%s: startblk " LBAF ", blccnt %x buffer %" PRIXPTR "\n", __func__, start, smallblks, buf_addr); if (scsi_exec(pccb) != true) { scsi_print_error(pccb); @@ -465,7 +483,7 @@ static ulong scsi_write(int device, ulong blknr, } buf_addr += pccb->datalen; } while (blks != 0); - debug("%s: end startblk " LBAF ", blccnt %x buffer %lx\n", + debug("%s: end startblk " LBAF ", blccnt %x buffer %" PRIXPTR "\n", __func__, start, smallblks, buf_addr); return blkcnt; } @@ -587,7 +605,38 @@ void scsi_setup_test_unit_ready(ccb * pccb) pccb->msgout[0]=SCSI_IDENTIFY; /* NOT USED */ } -void scsi_setup_read_ext(ccb * pccb, unsigned long start, unsigned short blocks) +#ifdef CONFIG_SYS_64BIT_LBA +void scsi_setup_read16(ccb * pccb, lbaint_t start, unsigned long blocks) +{ + pccb->cmd[0] = SCSI_READ16; + pccb->cmd[1] = pccb->lun<<5; + pccb->cmd[2] = ((unsigned char) (start >> 56)) & 0xff; + pccb->cmd[3] = ((unsigned char) (start >> 48)) & 0xff; + pccb->cmd[4] = ((unsigned char) (start >> 40)) & 0xff; + pccb->cmd[5] = ((unsigned char) (start >> 32)) & 0xff; + pccb->cmd[6] = ((unsigned char) (start >> 24)) & 0xff; + pccb->cmd[7] = ((unsigned char) (start >> 16)) & 0xff; + pccb->cmd[8] = ((unsigned char) (start >> 8)) & 0xff; + pccb->cmd[9] = ((unsigned char) (start)) & 0xff; + pccb->cmd[10] = 0; + pccb->cmd[11] = ((unsigned char) (blocks >> 24)) & 0xff; + pccb->cmd[12] = ((unsigned char) (blocks >> 16)) & 0xff; + pccb->cmd[13] = ((unsigned char) (blocks >> 8)) & 0xff; + pccb->cmd[14] = (unsigned char) blocks & 0xff; + pccb->cmd[15] = 0; + pccb->cmdlen = 16; + pccb->msgout[0] = SCSI_IDENTIFY; /* NOT USED */ + debug ("scsi_setup_read16: cmd: %02X %02X " + "startblk %02X%02X%02X%02X%02X%02X%02X%02X " + "blccnt %02X%02X%02X%02X\n", + pccb->cmd[0], pccb->cmd[1], + pccb->cmd[2], pccb->cmd[3], pccb->cmd[4], pccb->cmd[5], + pccb->cmd[6], pccb->cmd[7], pccb->cmd[8], pccb->cmd[9], + pccb->cmd[11], pccb->cmd[12], pccb->cmd[13], pccb->cmd[14]); +} +#endif + +void scsi_setup_read_ext(ccb * pccb, lbaint_t start, unsigned short blocks) { pccb->cmd[0]=SCSI_READ10; pccb->cmd[1]=pccb->lun<<5; @@ -607,7 +656,7 @@ void scsi_setup_read_ext(ccb * pccb, unsigned long start, unsigned short blocks) pccb->cmd[7],pccb->cmd[8]); } -void scsi_setup_write_ext(ccb *pccb, unsigned long start, unsigned short blocks) +void scsi_setup_write_ext(ccb *pccb, lbaint_t start, unsigned short blocks) { pccb->cmd[0] = SCSI_WRITE10; pccb->cmd[1] = pccb->lun << 5; @@ -628,7 +677,7 @@ void scsi_setup_write_ext(ccb *pccb, unsigned long start, unsigned short blocks) pccb->cmd[7], pccb->cmd[8]); } -void scsi_setup_read6(ccb * pccb, unsigned long start, unsigned short blocks) +void scsi_setup_read6(ccb * pccb, lbaint_t start, unsigned short blocks) { pccb->cmd[0]=SCSI_READ6; pccb->cmd[1]=pccb->lun<<5 | (((unsigned char)(start>>16))&0x1f);