VirtualBox

Changeset 43672 in vbox for trunk/src/VBox/Devices/PC


Ignore:
Timestamp:
Oct 17, 2012 2:53:01 PM (12 years ago)
Author:
vboxsync
Message:

BIOS: Fixed trouble with El Torito reading incomplete CD sectors over SCSI.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/PC/BIOS/scsi.c

    r43660 r43672  
    253253{
    254254    bio_dsk_t __far *bios_dsk = read_word(0x0040, 0x000E) :> &EbdaData->bdisk;
     255    uint32_t        read_len;
    255256    uint8_t         status, sizes;
    256257    uint16_t        i;
     
    273274             bios_dsk->drqp.nsect, bios_dsk->drqp.sect_sz);
    274275
    275     //@todo: why do we need to do this?
    276     cmdlen -= 2; // ATAPI uses 12 bytes for a READ 10 CDB??
     276    cmdlen -= 2; /* ATAPI uses 12-byte command packets for a READ 10. */
    277277
    278278    io_base   = bios_dsk->scsidev[device_id].io_base;
     
    284284    while (status & VBSCSI_BUSY);
    285285
    286     sizes = (((length + before) >> 12) & 0xF0) | cmdlen;
     286    /* On the SCSI level, we have to transfer whole sectors. */
     287    /* NB: With proper residual length support, this should not be necessary; we should
     288     * be able to avoid transferring the 'after' part of the sector.
     289     */
     290    read_len = length + before + bios_dsk->drqp.skip_a;
     291
     292    sizes = (((read_len) >> 12) & 0xF0) | cmdlen;
    287293    outb(io_base + VBSCSI_REGISTER_COMMAND, target_id);                 /* Write the target ID. */
    288294    outb(io_base + VBSCSI_REGISTER_COMMAND, SCSI_TXDIR_FROM_DEVICE);    /* Write the transfer direction. */
    289295    outb(io_base + VBSCSI_REGISTER_COMMAND, sizes);                     /* Write the CDB size. */
    290     outb(io_base + VBSCSI_REGISTER_COMMAND, length + before);           /* Write the buffer size. */
    291     outb(io_base + VBSCSI_REGISTER_COMMAND, (length + before) >> 8);
     296    outb(io_base + VBSCSI_REGISTER_COMMAND, read_len);                  /* Write the buffer size. */
     297    outb(io_base + VBSCSI_REGISTER_COMMAND, (read_len) >> 8);
    292298    for (i = 0; i < cmdlen; i++)                                        /* Write the CDB. */
    293299        outb(io_base + VBSCSI_REGISTER_COMMAND, cmdbuf[i]);
     
    323329        buffer = (FP_SEG(buffer) + (32768 >> 4)) :> FP_OFF(buffer);
    324330    }
     331
    325332    DBG_SCSI("%s: reading %ld bytes to %X:%X\n", __func__, length, FP_SEG(buffer), FP_OFF(buffer));
    326333    rep_insb(buffer, length, io_base + VBSCSI_REGISTER_DATA_IN);
     334
     335    if (bios_dsk->drqp.skip_a)  /* If necessary, throw away more data. */
     336        insb_discard(bios_dsk->drqp.skip_a, io_base + VBSCSI_REGISTER_DATA_IN);
    327337
    328338    return 0;
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette