VirtualBox

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


Ignore:
Timestamp:
May 21, 2021 8:18:45 AM (4 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
144552
Message:

Devices/PC/BIOS: Fix CD/DVD access with the new BusLogic and LsiLogic drivers, bugref:4841

Location:
trunk/src/VBox/Devices/PC/BIOS
Files:
5 edited

Legend:

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

    r89168 r89211  
    3232#endif
    3333
    34 #define BUSLOGICCOMMAND_EXECUTE_MAILBOX_COMMAND     0x02
    35 #define BUSLOGICCOMMAND_INITIALIZE_EXTENDED_MAILBOX 0x81
     34#define BUSLOGICCOMMAND_EXECUTE_MAILBOX_COMMAND        0x02
     35#define BUSLOGICCOMMAND_INITIALIZE_EXTENDED_MAILBOX    0x81
     36#define BUSLOGICCOMMAND_DISABLE_HOST_ADAPTER_INTERRUPT 0x25
     37
    3638
    3739#define RT_BIT(bit) (1 << (bit))
     
    275277    /** I/O base of device. */
    276278    uint16_t         u16IoBase;
     279    /** The sink buf. */
     280    void __far       *pvSinkBuf;
    277281} buslogic_t;
    278282
     
    355359
    356360int buslogic_scsi_cmd_data_in(void __far *pvHba, uint8_t idTgt, uint8_t __far *aCDB,
    357                             uint8_t cbCDB, uint8_t __far *buffer, uint32_t length, uint16_t skip_a,
    358                             uint16_t skip_b)
     361                            uint8_t cbCDB, uint8_t __far *buffer, uint32_t length, uint16_t skip_b,
     362                            uint16_t skip_a)
    359363{
    360364    buslogic_t __far *buslogic = (buslogic_t __far *)pvHba;
     
    379383    {
    380384        buslogic->aSge[idxSge].cbSegment = skip_b;
    381         buslogic->aSge[idxSge].u32PhysAddrSegmentBase = 0; /* See ahci.c:sink_buf_phys */
     385        buslogic->aSge[idxSge].u32PhysAddrSegmentBase = buslogic_addr_to_phys(buslogic->pvSinkBuf);
    382386        idxSge++;
    383387    }
     
    391395    {
    392396        buslogic->aSge[idxSge].cbSegment = skip_a;
    393         buslogic->aSge[idxSge].u32PhysAddrSegmentBase = 0; /* See ahci.c:sink_buf_phys */
     397        buslogic->aSge[idxSge].u32PhysAddrSegmentBase = buslogic_addr_to_phys(buslogic->pvSinkBuf);
    394398        idxSge++;
    395399    }
     
    420424static int buslogic_scsi_hba_init(buslogic_t __far *buslogic)
    421425{
     426    int rc;
     427    uint8_t bIrqOff = 0;
    422428    ReqInitExtMbx       ReqInitMbx;
    423429
     
    426432    while (!(inb(buslogic->u16IoBase + BUSLOGIC_REGISTER_STATUS) & BL_STAT_HARDY));
    427433
    428     /* Initialize mailbox. */
    429     ReqInitMbx.cMailbox = 1;
    430     ReqInitMbx.uMailboxBaseAddress = buslogic_addr_to_phys(&buslogic->MbxOut32);
    431     return buslogic_cmd(buslogic, BUSLOGICCOMMAND_INITIALIZE_EXTENDED_MAILBOX,
    432                         (unsigned char __far *)&ReqInitMbx, sizeof(ReqInitMbx),
    433                         NULL, 0);
     434    /* Disable interrupts. */
     435    rc = buslogic_cmd(buslogic, BUSLOGICCOMMAND_DISABLE_HOST_ADAPTER_INTERRUPT,
     436                      (unsigned char __far *)&bIrqOff, sizeof(bIrqOff),
     437                      NULL, 0);
     438    if (!rc)
     439    {
     440        /* Initialize mailbox. */
     441        ReqInitMbx.cMailbox = 1;
     442        ReqInitMbx.uMailboxBaseAddress = buslogic_addr_to_phys(&buslogic->MbxOut32);
     443        rc = buslogic_cmd(buslogic, BUSLOGICCOMMAND_INITIALIZE_EXTENDED_MAILBOX,
     444                          (unsigned char __far *)&ReqInitMbx, sizeof(ReqInitMbx),
     445                          NULL, 0);
     446    }
     447
     448    return rc;
    434449}
    435450
     
    437452 * Init the BusLogic SCSI driver and detect attached disks.
    438453 */
    439 int buslogic_scsi_init(void __far *pvHba, uint8_t u8Bus, uint8_t u8DevFn)
     454int buslogic_scsi_init(void __far *pvHba, void __far *pvSinkBuf, uint8_t u8Bus, uint8_t u8DevFn)
    440455{
    441456    buslogic_t __far *buslogic = (buslogic_t __far *)pvHba;
     
    457472        DBG_BUSLOGIC("I/O base: 0x%x\n", u16IoBase);
    458473        buslogic->u16IoBase = u16IoBase;
     474        buslogic->pvSinkBuf = pvSinkBuf;
    459475        return buslogic_scsi_hba_init(buslogic);
    460476    }
  • trunk/src/VBox/Devices/PC/BIOS/lsilogic.c

    r89168 r89211  
    289289    /** I/O base of device. */
    290290    uint16_t           u16IoBase;
    291     /** Saved high bits of EAX. */
    292     uint16_t           saved_eax_hi;
     291    /** The sink buf. */
     292    void __far         *pvSinkBuf;
    293293} lsilogic_t;
    294294
     
    426426
    427427int lsilogic_scsi_cmd_data_in(void __far *pvHba, uint8_t idTgt, uint8_t __far *aCDB,
    428                               uint8_t cbCDB, uint8_t __far *buffer, uint32_t length, uint16_t skip_a,
    429                               uint16_t skip_b)
     428                              uint8_t cbCDB, uint8_t __far *buffer, uint32_t length, uint16_t skip_b,
     429                              uint16_t skip_a)
    430430{
    431431    lsilogic_t __far *lsilogic = (lsilogic_t __far *)pvHba;
     
    459459        lsilogic->aSge[idxSge].fEndOfBuffer            = 0;
    460460        lsilogic->aSge[idxSge].fLastElement            = 0;
    461         lsilogic->aSge[idxSge].u32DataBufferAddressLow = 0; /* See ahci.c:sink_buf_phys */
     461        lsilogic->aSge[idxSge].u32DataBufferAddressLow = lsilogic_addr_to_phys(lsilogic->pvSinkBuf);
    462462
    463463        idxSge++;
     
    479479    if (skip_a)
    480480    {
    481         lsilogic->aSge[idxSge].u24Length               = length;
     481        lsilogic->aSge[idxSge].u24Length               = skip_a;
    482482        lsilogic->aSge[idxSge].fEndOfList              = 1;
    483483        lsilogic->aSge[idxSge].f64BitAddress           = 0;
     
    487487        lsilogic->aSge[idxSge].fEndOfBuffer            = 1;
    488488        lsilogic->aSge[idxSge].fLastElement            = 1;
    489         lsilogic->aSge[idxSge].u32DataBufferAddressLow = 0; /* See ahci.c:sink_buf_phys */
     489        lsilogic->aSge[idxSge].u32DataBufferAddressLow = lsilogic_addr_to_phys(lsilogic->pvSinkBuf);
    490490        idxSge++;
    491491    }
     
    536536 * Init the LsiLogic SCSI driver and detect attached disks.
    537537 */
    538 int lsilogic_scsi_init(void __far *pvHba, uint8_t u8Bus, uint8_t u8DevFn)
     538int lsilogic_scsi_init(void __far *pvHba, void __far *pvSinkBuf, uint8_t u8Bus, uint8_t u8DevFn)
    539539{
    540540    lsilogic_t __far *lsilogic = (lsilogic_t __far *)pvHba;
     
    556556        DBG_LSILOGIC("I/O base: 0x%x\n", u16IoBase);
    557557        lsilogic->u16IoBase = u16IoBase;
     558        lsilogic->pvSinkBuf = pvSinkBuf;
    558559        return lsilogic_scsi_hba_init(lsilogic);
    559560    }
  • trunk/src/VBox/Devices/PC/BIOS/scsi.c

    r89169 r89211  
    3535#define VBOX_SCSI_NO_HBA 0xffff
    3636
    37 typedef int (* scsi_hba_init)(void __far *pvHba, uint8_t u8Bus, uint8_t u8DevFn);
     37typedef int (* scsi_hba_init)(void __far *pvHba, void __far *pvSinkBuf, uint8_t u8Bus, uint8_t u8DevFn);
    3838typedef int (* scsi_hba_cmd_data_out)(void __far *pvHba, uint8_t idTgt, uint8_t __far *aCDB,
    3939                                      uint8_t cbCDB, uint8_t __far *buffer, uint32_t length);
     
    112112
    113113    return hba_seg;
     114}
     115
     116/**
     117 * Allocates 1K of conventional memory.
     118 */
     119static uint16_t scsi_sink_buf_alloc(void)
     120{
     121    uint16_t    base_mem_kb;
     122    uint16_t    sink_seg;
     123
     124    base_mem_kb = read_word(0x00, 0x0413);
     125
     126    DBG_SCSI("SCSI: %dK of base mem\n", base_mem_kb);
     127
     128    if (base_mem_kb == 0)
     129        return 0;
     130
     131    base_mem_kb -= 2; /* Allocate 2K block. */
     132    sink_seg = (((uint32_t)base_mem_kb * 1024) >> 4); /* Calculate start segment. */
     133
     134    write_word(0x00, 0x0413, base_mem_kb);
     135
     136    return sink_seg;
    114137}
    115138
     
    521544{
    522545    int i;
     546    uint16_t sink_seg = 0;
    523547    bio_dsk_t __far     *bios_dsk;
    524548
     
    538562                break;
    539563
     564            if (!sink_seg) /* Allocate a sink buffer for throwing away data when accessing CD/DVD drives. */
     565            {
     566                sink_seg = scsi_sink_buf_alloc();
     567                if (!sink_seg)
     568                    break;
     569            }
     570
    540571            u8Bus = (busdevfn & 0xff00) >> 8;
    541572            u8DevFn = busdevfn & 0x00ff;
    542573
    543574            DBG_SCSI("SCSI HBA at Bus %u DevFn 0x%x (raw 0x%x)\n", u8Bus, u8DevFn, busdevfn);
    544             rc = hbaacc[i].init(hba_seg :> 0, u8Bus, u8DevFn);
     575            rc = hbaacc[i].init(hba_seg :> 0, sink_seg :> 0, u8Bus, u8DevFn);
    545576            if (!rc)
    546577                scsi_enumerate_attached_devices(hba_seg, i);
  • trunk/src/VBox/Devices/PC/BIOS/scsi.h

    r89168 r89211  
    5757ct_assert(sizeof(cdb_rw16) == 16);
    5858
    59 extern int lsilogic_scsi_init(void __far *pvHba, uint8_t u8Bus, uint8_t u8DevFn);
     59extern int lsilogic_scsi_init(void __far *pvHba, void __far *pvSinkBuf, uint8_t u8Bus, uint8_t u8DevFn);
    6060extern int lsilogic_scsi_cmd_data_out(void __far *pvHba, uint8_t idTgt, uint8_t __far *aCDB,
    6161                                      uint8_t cbCDB, uint8_t __far *buffer, uint32_t length);
    6262extern int lsilogic_scsi_cmd_data_in(void __far *pvHba, uint8_t idTgt, uint8_t __far *aCDB,
    63                                      uint8_t cbCDB, uint8_t __far *buffer, uint32_t length, uint16_t skip_a,
    64                                      uint16_t skip_b);
     63                                     uint8_t cbCDB, uint8_t __far *buffer, uint32_t length, uint16_t skip_b,
     64                                     uint16_t skip_a);
    6565
    66 extern int buslogic_scsi_init(void __far *pvHba, uint8_t u8Bus, uint8_t u8DevFn);
     66extern int buslogic_scsi_init(void __far *pvHba, void __far *pvSinkBuf, uint8_t u8Bus, uint8_t u8DevFn);
    6767extern int buslogic_scsi_cmd_data_out(void __far *pvHba, uint8_t idTgt, uint8_t __far *aCDB,
    6868                                      uint8_t cbCDB, uint8_t __far *buffer, uint32_t length);
    6969extern int buslogic_scsi_cmd_data_in(void __far *pvHba, uint8_t idTgt, uint8_t __far *aCDB,
    70                                      uint8_t cbCDB, uint8_t __far *buffer, uint32_t length, uint16_t skip_a,
    71                                      uint16_t skip_b);
     70                                     uint8_t cbCDB, uint8_t __far *buffer, uint32_t length, uint16_t skip_b,
     71                                     uint16_t skip_a);
    7272
    73 extern int virtio_scsi_init(void __far *pvHba, uint8_t u8Bus, uint8_t u8DevFn);
     73extern int virtio_scsi_init(void __far *pvHba, void __far *pvSinkBuf, uint8_t u8Bus, uint8_t u8DevFn);
    7474extern int virtio_scsi_cmd_data_out(void __far *pvHba, uint8_t idTgt, uint8_t __far *aCDB,
    7575                                    uint8_t cbCDB, uint8_t __far *buffer, uint32_t length);
    7676extern int virtio_scsi_cmd_data_in(void __far *pvHba, uint8_t idTgt, uint8_t __far *aCDB,
    77                                    uint8_t cbCDB, uint8_t __far *buffer, uint32_t length, uint16_t skip_a,
    78                                    uint16_t skip_b);
     77                                   uint8_t cbCDB, uint8_t __far *buffer, uint32_t length, uint16_t skip_b,
     78                                   uint16_t skip_a);
    7979
    8080#endif /* !VBOX_INCLUDED_SRC_PC_BIOS_scsi_h */
  • trunk/src/VBox/Devices/PC/BIOS/virtio.c

    r89168 r89211  
    209209    /** Device/Function number. */
    210210    uint8_t          u8DevFn;
    211     /** Saved high bits of EAX. */
    212     uint16_t         saved_eax_hi;
     211    /** The sink buf. */
     212    void __far       *pvSinkBuf;
    213213    /** The current executed command structure. */
    214214    virtio_scsi_req_hdr_t ScsiReqHdr;
     
    435435
    436436int virtio_scsi_cmd_data_in(void __far *pvHba, uint8_t idTgt, uint8_t __far *aCDB,
    437                             uint8_t cbCDB, uint8_t __far *buffer, uint32_t length, uint16_t skip_a,
    438                             uint16_t skip_b)
     437                            uint8_t cbCDB, uint8_t __far *buffer, uint32_t length, uint16_t skip_b,
     438                            uint16_t skip_a)
    439439{
    440440    virtio_t __far *virtio = (virtio_t __far *)pvHba;
     
    470470    if (skip_b)
    471471    {
    472         virtio->Queue.aDescTbl[idxDesc].GCPhysBufLow  = 0; /* See ahci.c:sink_buf_phys */
     472        virtio->Queue.aDescTbl[idxDesc].GCPhysBufLow  = virtio_addr_to_phys(virtio->pvSinkBuf);
    473473        virtio->Queue.aDescTbl[idxDesc].GCPhysBufHigh = 0;
    474474        virtio->Queue.aDescTbl[idxDesc].cbBuf         = skip_b;
     
    491491        virtio->Queue.aDescTbl[idxDesc - 1].idxNext = idxDesc;
    492492
    493         virtio->Queue.aDescTbl[idxDesc].GCPhysBufLow  = 0; /* See ahci.c:sink_buf_phys */
     493        virtio->Queue.aDescTbl[idxDesc].GCPhysBufLow  = virtio_addr_to_phys(virtio->pvSinkBuf);
    494494        virtio->Queue.aDescTbl[idxDesc].GCPhysBufHigh = 0;
    495495        virtio->Queue.aDescTbl[idxDesc].cbBuf         = skip_a;
     
    662662 * Init the VirtIO SCSI driver and detect attached disks.
    663663 */
    664 int virtio_scsi_init(void __far *pvHba, uint8_t u8Bus, uint8_t u8DevFn)
     664int virtio_scsi_init(void __far *pvHba, void __far *pvSinkBuf, uint8_t u8Bus, uint8_t u8DevFn)
    665665{
    666666    virtio_t __far *virtio = (virtio_t __far *)pvHba;
     
    715715        pci_write_config_word(u8Bus, u8DevFn, 4, 0x7);
    716716
     717        virtio->pvSinkBuf = pvSinkBuf;
    717718        return virtio_scsi_hba_init(virtio, u8Bus, u8DevFn, u8PciCapOffVirtIo);
    718719    }
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