merge mainline into lazy
This commit is contained in:
commit
00542307eb
326 changed files with 18667 additions and 4092 deletions
|
@ -32,6 +32,12 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
|||
|
||||
static grub_scsi_dev_t grub_scsi_dev_list;
|
||||
|
||||
const char grub_scsi_names[GRUB_SCSI_NUM_SUBSYSTEMS][5] = {
|
||||
[GRUB_SCSI_SUBSYSTEM_USBMS] = "usb",
|
||||
[GRUB_SCSI_SUBSYSTEM_PATA] = "ata",
|
||||
[GRUB_SCSI_SUBSYSTEM_AHCI] = "ahci"
|
||||
};
|
||||
|
||||
void
|
||||
grub_scsi_dev_register (grub_scsi_dev_t dev)
|
||||
{
|
||||
|
@ -321,9 +327,9 @@ grub_scsi_iterate (int (*hook) (const char *name),
|
|||
{
|
||||
grub_scsi_dev_t p;
|
||||
|
||||
auto int scsi_iterate (int bus, int luns);
|
||||
auto int NESTED_FUNC_ATTR scsi_iterate (int id, int bus, int luns);
|
||||
|
||||
int scsi_iterate (int bus, int luns)
|
||||
int NESTED_FUNC_ATTR scsi_iterate (int id, int bus, int luns)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -332,7 +338,7 @@ grub_scsi_iterate (int (*hook) (const char *name),
|
|||
{
|
||||
char *sname;
|
||||
int ret;
|
||||
sname = grub_xasprintf ("%s%d", p->name, bus);
|
||||
sname = grub_xasprintf ("%s%d", grub_scsi_names[id], bus);
|
||||
if (!sname)
|
||||
return 1;
|
||||
ret = hook (sname);
|
||||
|
@ -346,7 +352,7 @@ grub_scsi_iterate (int (*hook) (const char *name),
|
|||
{
|
||||
char *sname;
|
||||
int ret;
|
||||
sname = grub_xasprintf ("%s%d%c", p->name, bus, 'a' + i);
|
||||
sname = grub_xasprintf ("%s%d%c", grub_scsi_names[id], bus, 'a' + i);
|
||||
if (!sname)
|
||||
return 1;
|
||||
ret = hook (sname);
|
||||
|
@ -357,11 +363,8 @@ grub_scsi_iterate (int (*hook) (const char *name),
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (pull != GRUB_DISK_PULL_NONE)
|
||||
return 0;
|
||||
|
||||
for (p = grub_scsi_dev_list; p; p = p->next)
|
||||
if (p->iterate && (p->iterate) (scsi_iterate))
|
||||
if (p->iterate && (p->iterate) (scsi_iterate, pull))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
|
@ -377,6 +380,7 @@ grub_scsi_open (const char *name, grub_disk_t disk,
|
|||
int lun, bus;
|
||||
grub_uint64_t maxtime;
|
||||
const char *nameend;
|
||||
unsigned id;
|
||||
|
||||
nameend = name + grub_strlen (name) - 1;
|
||||
/* Try to detect a LUN ('a'-'z'), otherwise just use the first
|
||||
|
@ -401,15 +405,25 @@ grub_scsi_open (const char *name, grub_disk_t disk,
|
|||
if (! scsi)
|
||||
return grub_errno;
|
||||
|
||||
for (id = 0; id < ARRAY_SIZE (grub_scsi_names); id++)
|
||||
if (grub_strncmp (grub_scsi_names[id], name, nameend - name) == 0)
|
||||
break;
|
||||
|
||||
if (id == ARRAY_SIZE (grub_scsi_names))
|
||||
{
|
||||
grub_free (scsi);
|
||||
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a SCSI disk");
|
||||
}
|
||||
|
||||
for (p = grub_scsi_dev_list; p; p = p->next)
|
||||
{
|
||||
if (grub_strncmp (p->name, name, nameend - name) != 0)
|
||||
continue;
|
||||
if (p->open (id, bus, scsi))
|
||||
{
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (p->open (bus, scsi))
|
||||
continue;
|
||||
|
||||
disk->id = grub_make_scsi_id (p->id, bus, lun);
|
||||
disk->id = grub_make_scsi_id (id, bus, lun);
|
||||
disk->data = scsi;
|
||||
scsi->dev = p;
|
||||
scsi->lun = lun;
|
||||
|
@ -470,22 +484,26 @@ grub_scsi_open (const char *name, grub_disk_t disk,
|
|||
return err;
|
||||
}
|
||||
|
||||
/* SCSI blocks can be something else than 512, although GRUB
|
||||
wants 512 byte blocks. */
|
||||
disk->total_sectors = ((grub_uint64_t)scsi->size
|
||||
* (grub_uint64_t)scsi->blocksize)
|
||||
>> GRUB_DISK_SECTOR_BITS;
|
||||
disk->total_sectors = scsi->size;
|
||||
if (scsi->blocksize & (scsi->blocksize - 1) || !scsi->blocksize)
|
||||
{
|
||||
grub_free (scsi);
|
||||
return grub_error (GRUB_ERR_IO, "invalid sector size %d",
|
||||
scsi->blocksize);
|
||||
}
|
||||
for (disk->log_sector_size = 0;
|
||||
(1 << disk->log_sector_size) < scsi->blocksize;
|
||||
disk->log_sector_size++);
|
||||
|
||||
grub_dprintf ("scsi", "blocks=%u, blocksize=%u\n",
|
||||
scsi->size, scsi->blocksize);
|
||||
grub_dprintf ("scsi", "Disk total 512 sectors = %llu\n",
|
||||
grub_dprintf ("scsi", "Disk total sectors = %llu\n",
|
||||
(unsigned long long) disk->total_sectors);
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
grub_free (scsi);
|
||||
|
||||
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a SCSI disk");
|
||||
}
|
||||
|
||||
|
@ -508,36 +526,36 @@ grub_scsi_read (grub_disk_t disk, grub_disk_addr_t sector,
|
|||
|
||||
scsi = disk->data;
|
||||
|
||||
/* SCSI sectors are variable in size. GRUB uses 512 byte
|
||||
sectors. */
|
||||
if (scsi->blocksize != GRUB_DISK_SECTOR_SIZE)
|
||||
while (size)
|
||||
{
|
||||
unsigned spb = scsi->blocksize >> GRUB_DISK_SECTOR_BITS;
|
||||
if (spb == 0 || (scsi->blocksize & (GRUB_DISK_SECTOR_SIZE - 1)) != 0)
|
||||
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
|
||||
"unsupported SCSI block size");
|
||||
/* PATA doesn't support more than 32K reads.
|
||||
Not sure about AHCI and USB. If it's confirmed that either of
|
||||
them can do bigger reads reliably this value can be moved to 'scsi'
|
||||
structure. */
|
||||
grub_size_t len = 32768 >> disk->log_sector_size;
|
||||
grub_err_t err;
|
||||
if (len > size)
|
||||
len = size;
|
||||
/* Depending on the type, select a read function. */
|
||||
switch (scsi->devtype)
|
||||
{
|
||||
case grub_scsi_devtype_direct:
|
||||
err = grub_scsi_read10 (disk, sector, len, buf);
|
||||
if (err)
|
||||
return err;
|
||||
break;
|
||||
|
||||
grub_uint32_t sector_mod = 0;
|
||||
sector = grub_divmod64 (sector, spb, §or_mod);
|
||||
|
||||
if (! (sector_mod == 0 && size % spb == 0))
|
||||
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
|
||||
"unaligned SCSI read not supported");
|
||||
|
||||
size /= spb;
|
||||
case grub_scsi_devtype_cdrom:
|
||||
err = grub_scsi_read12 (disk, sector, len, buf);
|
||||
if (err)
|
||||
return err;
|
||||
break;
|
||||
}
|
||||
size -= len;
|
||||
sector += len;
|
||||
buf += len << disk->log_sector_size;
|
||||
}
|
||||
|
||||
/* Depending on the type, select a read function. */
|
||||
switch (scsi->devtype)
|
||||
{
|
||||
case grub_scsi_devtype_direct:
|
||||
return grub_scsi_read10 (disk, sector, size, buf);
|
||||
|
||||
case grub_scsi_devtype_cdrom:
|
||||
return grub_scsi_read12 (disk, sector, size, buf);
|
||||
}
|
||||
|
||||
/* XXX: Never reached. */
|
||||
return GRUB_ERR_NONE;
|
||||
|
||||
#if 0 /* Workaround - it works - but very slowly, from some reason
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue