Merge mainline into yeeloongfw
This commit is contained in:
commit
b7e79e8a6a
155 changed files with 5949 additions and 2562 deletions
|
@ -120,7 +120,8 @@ grub_biosdisk_open (const char *name, grub_disk_t disk)
|
|||
{
|
||||
data->flags = GRUB_BIOSDISK_FLAG_LBA | GRUB_BIOSDISK_FLAG_CDROM;
|
||||
data->sectors = 32;
|
||||
total_sectors = GRUB_ULONG_MAX; /* TODO: get the correct size. */
|
||||
/* TODO: get the correct size. */
|
||||
total_sectors = GRUB_DISK_SIZE_UNKNOWN;
|
||||
}
|
||||
else if (drive & 0x80)
|
||||
{
|
||||
|
|
|
@ -204,7 +204,7 @@ grub_ofdisk_open (const char *name, grub_disk_t disk)
|
|||
/* XXX: There is no property to read the number of blocks. There
|
||||
should be a property `#blocks', but it is not there. Perhaps it
|
||||
is possible to use seek for this. */
|
||||
disk->total_sectors = 0xFFFFFFFFUL;
|
||||
disk->total_sectors = GRUB_DISK_SIZE_UNKNOWN;
|
||||
|
||||
disk->id = (unsigned long) op;
|
||||
|
||||
|
|
35
disk/scsi.c
35
disk/scsi.c
|
@ -421,7 +421,7 @@ grub_scsi_open (const char *name, grub_disk_t disk)
|
|||
|
||||
/* According to USB MS tests specification, issue Test Unit Ready
|
||||
* until OK */
|
||||
maxtime = grub_get_time_ms () + 1000;
|
||||
maxtime = grub_get_time_ms () + 5000; /* It is safer value */
|
||||
do
|
||||
{
|
||||
/* Timeout is necessary - for example in case when we have
|
||||
|
@ -460,7 +460,7 @@ grub_scsi_open (const char *name, grub_disk_t disk)
|
|||
grub_dprintf ("scsi", "blocks=%u, blocksize=%u\n",
|
||||
scsi->size, scsi->blocksize);
|
||||
grub_dprintf ("scsi", "Disk total 512 sectors = %llu\n",
|
||||
disk->total_sectors);
|
||||
(unsigned long long) disk->total_sectors);
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
@ -519,6 +519,37 @@ grub_scsi_read (grub_disk_t disk, grub_disk_addr_t sector,
|
|||
|
||||
/* XXX: Never reached. */
|
||||
return GRUB_ERR_NONE;
|
||||
|
||||
#if 0 /* Workaround - it works - but very slowly, from some reason
|
||||
* unknown to me (specially on OHCI). Do not use it. */
|
||||
/* Split transfer requests to device sector size because */
|
||||
/* some devices are not able to transfer more than 512-1024 bytes */
|
||||
grub_err_t err = GRUB_ERR_NONE;
|
||||
|
||||
for ( ; size; size--)
|
||||
{
|
||||
/* Depending on the type, select a read function. */
|
||||
switch (scsi->devtype)
|
||||
{
|
||||
case grub_scsi_devtype_direct:
|
||||
err = grub_scsi_read10 (disk, sector, 1, buf);
|
||||
break;
|
||||
|
||||
case grub_scsi_devtype_cdrom:
|
||||
err = grub_scsi_read12 (disk, sector, 1, buf);
|
||||
break;
|
||||
|
||||
default: /* This should not happen */
|
||||
return GRUB_ERR_READ_ERROR;
|
||||
}
|
||||
if (err)
|
||||
return err;
|
||||
sector++;
|
||||
buf += scsi->blocksize;
|
||||
}
|
||||
|
||||
return err;
|
||||
#endif
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
|
|
40
disk/usbms.c
40
disk/usbms.c
|
@ -253,6 +253,7 @@ grub_usbms_transfer (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd,
|
|||
struct grub_usbms_csw status;
|
||||
static grub_uint32_t tag = 0;
|
||||
grub_usb_err_t err = GRUB_USB_ERR_NONE;
|
||||
grub_usb_err_t errCSW = GRUB_USB_ERR_NONE;
|
||||
int retrycnt = 3 + 1;
|
||||
grub_size_t i;
|
||||
|
||||
|
@ -290,9 +291,8 @@ grub_usbms_transfer (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd,
|
|||
{
|
||||
if (err == GRUB_USB_ERR_STALL)
|
||||
{
|
||||
grub_usb_clear_halt (dev->dev, dev->in->endp_addr);
|
||||
grub_usb_clear_halt (dev->dev, dev->out->endp_addr);
|
||||
goto retry;
|
||||
goto CheckCSW;
|
||||
}
|
||||
return grub_error (GRUB_ERR_IO, "USB Mass Storage request failed");
|
||||
}
|
||||
|
@ -302,7 +302,12 @@ grub_usbms_transfer (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd,
|
|||
{
|
||||
err = grub_usb_bulk_read (dev->dev, dev->in->endp_addr, size, buf);
|
||||
grub_dprintf ("usb", "read: %d %d\n", err, GRUB_USB_ERR_STALL);
|
||||
if (err) goto CheckCSW;
|
||||
if (err)
|
||||
{
|
||||
if (err == GRUB_USB_ERR_STALL)
|
||||
grub_usb_clear_halt (dev->dev, dev->in->endp_addr);
|
||||
goto CheckCSW;
|
||||
}
|
||||
/* Debug print of received data. */
|
||||
grub_dprintf ("usb", "buf:\n");
|
||||
if (size <= 64)
|
||||
|
@ -316,6 +321,12 @@ grub_usbms_transfer (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd,
|
|||
err = grub_usb_bulk_write (dev->dev, dev->out->endp_addr, size, buf);
|
||||
grub_dprintf ("usb", "write: %d %d\n", err, GRUB_USB_ERR_STALL);
|
||||
grub_dprintf ("usb", "buf:\n");
|
||||
if (err)
|
||||
{
|
||||
if (err == GRUB_USB_ERR_STALL)
|
||||
grub_usb_clear_halt (dev->dev, dev->out->endp_addr);
|
||||
goto CheckCSW;
|
||||
}
|
||||
/* Debug print of sent data. */
|
||||
if (size <= 256)
|
||||
for (i=0; i<size; i++)
|
||||
|
@ -326,15 +337,16 @@ grub_usbms_transfer (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd,
|
|||
|
||||
/* Read the status - (maybe) according to specification. */
|
||||
CheckCSW:
|
||||
err = grub_usb_bulk_read (dev->dev, dev->in->endp_addr,
|
||||
errCSW = grub_usb_bulk_read (dev->dev, dev->in->endp_addr,
|
||||
sizeof (status), (char *) &status);
|
||||
if (err)
|
||||
if (errCSW)
|
||||
{
|
||||
grub_usb_clear_halt (dev->dev, dev->in->endp_addr);
|
||||
err = grub_usb_bulk_read (dev->dev, dev->in->endp_addr,
|
||||
errCSW = grub_usb_bulk_read (dev->dev, dev->in->endp_addr,
|
||||
sizeof (status), (char *) &status);
|
||||
if (err)
|
||||
if (errCSW)
|
||||
{ /* Bulk-only reset device. */
|
||||
grub_dprintf ("usb", "Bulk-only reset device - errCSW\n");
|
||||
grub_usbms_reset (dev->dev, dev->interface);
|
||||
grub_usb_clear_halt (dev->dev, dev->in->endp_addr);
|
||||
grub_usb_clear_halt (dev->dev, dev->out->endp_addr);
|
||||
|
@ -347,9 +359,11 @@ CheckCSW:
|
|||
status.signature, status.tag, status.residue);
|
||||
grub_dprintf ("usb", "CSW: status=0x%02x\n", status.status);
|
||||
|
||||
/* If phase error, do bulk-only reset device. */
|
||||
if (status.status == 2)
|
||||
{
|
||||
/* If phase error or not valid signature, do bulk-only reset device. */
|
||||
if ((status.status == 2) ||
|
||||
(status.signature != grub_cpu_to_le32(0x53425355)))
|
||||
{ /* Bulk-only reset device. */
|
||||
grub_dprintf ("usb", "Bulk-only reset device - bad status\n");
|
||||
grub_usbms_reset (dev->dev, dev->interface);
|
||||
grub_usb_clear_halt (dev->dev, dev->in->endp_addr);
|
||||
grub_usb_clear_halt (dev->dev, dev->out->endp_addr);
|
||||
|
@ -357,9 +371,13 @@ CheckCSW:
|
|||
goto retry;
|
||||
}
|
||||
|
||||
if (status.status)
|
||||
/* If "command failed" status or data transfer failed -> error */
|
||||
if ((status.status || err) && !read_write)
|
||||
return grub_error (GRUB_ERR_READ_ERROR,
|
||||
"error communication with USB Mass Storage device");
|
||||
else if ((status.status || err) && read_write)
|
||||
return grub_error (GRUB_ERR_WRITE_ERROR,
|
||||
"error communication with USB Mass Storage device");
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue