VirtualBox

Ignore:
Timestamp:
Sep 3, 2023 11:07:46 AM (17 months ago)
Author:
vboxsync
Message:

BIOS: Added proper VDS S/G support to the LSI Logic driver.

File:
1 edited

Legend:

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

    r98103 r101004  
    3535#include "scsi.h"
    3636
     37#define USE_VDS
     38
    3739//#define DEBUG_LSILOGIC 1
    3840#if DEBUG_LSILOGIC
     
    4345
    4446#define RT_BIT(bit) (1L << (bit))
     47
     48
     49#ifdef USE_VDS
     50#define NUM_SG_BUFFERS      34
     51#endif
     52
    4553
    4654/**
     
    292300{
    293301    /** The SCSI I/O request structure. */
    294     MptSCSIIORequest   ScsiIoReq;
     302    MptSCSIIORequest    ScsiIoReq;
    295303    /** S/G elements being used, must come after the I/O request structure. */
    296     MptSGEntrySimple32 Sge;
     304    MptSGEntrySimple32  Sge[NUM_SG_BUFFERS];
    297305    /** The reply frame used for address replies. */
    298     uint8_t            abReply[128];
     306    uint8_t             abReply[128];
    299307    /** I/O base of device. */
    300     uint16_t           u16IoBase;
     308    uint16_t            u16IoBase;
     309#ifdef USE_VDS
     310    /** VDS EDDS structure for the I/O request structure. */
     311    vds_edds            edds_req;
     312    /** VDS EDDS DMA buffer descriptor structure. */
     313    vds_edds            edds;
     314    vds_sg              edds_more_sg[NUM_SG_BUFFERS - 1];
     315#endif
    301316} lsilogic_t;
    302317
     
    366381static int lsilogic_scsi_cmd_exec(lsilogic_t __far *lsilogic)
    367382{
    368     uint32_t u32Reply = 0;
    369     uint32_t u32ReplyDummy = 0;
    370 
     383    uint32_t    u32Reply = 0;
     384    uint32_t    u32ReplyDummy = 0;
     385
     386#ifdef USE_VDS
     387    /* Lock request memory. */
     388    lsilogic->edds_req.num_avail = 1;
     389    vds_build_sg_list(&lsilogic->edds_req, &lsilogic->ScsiIoReq, sizeof(lsilogic->ScsiIoReq));
     390
     391    /* Send it off. */
     392    outpd(lsilogic->u16IoBase + LSILOGIC_REG_REQUEST_QUEUE, lsilogic->edds_req.u.sg[0].phys_addr);
     393#else
    371394    /* Send it off. */
    372395    outpd(lsilogic->u16IoBase + LSILOGIC_REG_REQUEST_QUEUE, lsilogic_addr_to_phys(&lsilogic->ScsiIoReq));
     396#endif
    373397
    374398    /* Wait for it to finish. */
     
    377401    outpd(lsilogic->u16IoBase + LSILOGIC_REG_HOST_INTR_STATUS, 1);
    378402
     403#ifdef USE_VDS
     404    /* Unlock the request again. */
     405    vds_free_sg_list(&lsilogic->edds_req);
     406#endif
    379407    /* Read the reply queue. */
    380408    u32Reply = inpd(lsilogic->u16IoBase + LSILOGIC_REG_REPLY_QUEUE);
     
    401429
    402430int lsilogic_scsi_cmd_data_out(void __far *pvHba, uint8_t idTgt, uint8_t __far *aCDB,
    403                                uint8_t cbCDB, uint8_t __far *buffer, uint32_t length)
    404 {
    405     lsilogic_t __far *lsilogic = (lsilogic_t __far *)pvHba;
    406     int i;
     431                               uint8_t cbCDB, unsigned char __far *buffer, uint32_t length)
     432{
     433    lsilogic_t __far    *lsilogic = (lsilogic_t __far *)pvHba;
     434    int                 i;
     435    int                 rc;
    407436
    408437    _fmemset(&lsilogic->ScsiIoReq, 0, sizeof(lsilogic->ScsiIoReq));
     438
     439#ifdef USE_VDS
     440    lsilogic->edds.num_avail = NUM_SG_BUFFERS;
     441    vds_build_sg_list(&lsilogic->edds, buffer, length);
     442#endif
    409443
    410444    lsilogic->ScsiIoReq.u8TargetID          = idTgt;
     
    420454        lsilogic->ScsiIoReq.au8CDB[i] = aCDB[i];
    421455
    422     lsilogic->Sge.u24Length               = length;
    423     lsilogic->Sge.fEndOfList              = 1;
    424     lsilogic->Sge.f64BitAddress           = 0;
    425     lsilogic->Sge.fBufferContainsData     = 0;
    426     lsilogic->Sge.fLocalAddress           = 0;
    427     lsilogic->Sge.u2ElementType           = 0x01; /* Simple type */
    428     lsilogic->Sge.fEndOfBuffer            = 1;
    429     lsilogic->Sge.fLastElement            = 1;
    430     lsilogic->Sge.u32DataBufferAddressLow = lsilogic_addr_to_phys(buffer);
    431 
    432     return lsilogic_scsi_cmd_exec(lsilogic);
     456#ifdef USE_VDS
     457    for (i = 0; i < lsilogic->edds.num_used; ++i)
     458    {
     459        lsilogic->Sge[i].u24Length                  = lsilogic->edds.u.sg[i].size;
     460        lsilogic->Sge[i].fEndOfList                 = 0;
     461        lsilogic->Sge[i].f64BitAddress              = 0;
     462        lsilogic->Sge[i].fBufferContainsData        = 0;
     463        lsilogic->Sge[i].fLocalAddress              = 0;
     464        lsilogic->Sge[i].u2ElementType              = 0x01; /* Simple type */
     465        lsilogic->Sge[i].fEndOfBuffer               = 0;
     466        lsilogic->Sge[i].fLastElement               = 0;
     467        lsilogic->Sge[i].u32DataBufferAddressLow    = lsilogic->edds.u.sg[i].phys_addr;
     468    }
     469    --i;
     470    lsilogic->Sge[i].fEndOfList = lsilogic->Sge[i].fEndOfBuffer = lsilogic->Sge[i].fLastElement = 1;
     471#else
     472    lsilogic->Sge[0].u24Length               = length;
     473    lsilogic->Sge[0].fEndOfList              = 1;
     474    lsilogic->Sge[0].f64BitAddress           = 0;
     475    lsilogic->Sge[0].fBufferContainsData     = 0;
     476    lsilogic->Sge[0].fLocalAddress           = 0;
     477    lsilogic->Sge[0].u2ElementType           = 0x01; /* Simple type */
     478    lsilogic->Sge[0].fEndOfBuffer            = 1;
     479    lsilogic->Sge[0].fLastElement            = 1;
     480    lsilogic->Sge[0].u32DataBufferAddressLow = phys_buf;
     481#endif
     482
     483    rc = lsilogic_scsi_cmd_exec(lsilogic);
     484
     485#ifdef USE_VDS
     486    /* Unlock the buffer again. */
     487    vds_free_sg_list(&lsilogic->edds);
     488#endif
     489
     490    return rc;
    433491}
    434492
    435493int lsilogic_scsi_cmd_data_in(void __far *pvHba, uint8_t idTgt, uint8_t __far *aCDB,
    436                               uint8_t cbCDB, uint8_t __far *buffer, uint32_t length)
    437 {
    438     lsilogic_t __far *lsilogic = (lsilogic_t __far *)pvHba;
    439     int i;
     494                              uint8_t cbCDB, unsigned char __far *buffer, uint32_t length)
     495{
     496    lsilogic_t __far    *lsilogic = (lsilogic_t __far *)pvHba;
     497    int                 i;
     498    int                 rc;
    440499
    441500    _fmemset(&lsilogic->ScsiIoReq, 0, sizeof(lsilogic->ScsiIoReq));
     501
     502#ifdef USE_VDS
     503    lsilogic->edds.num_avail = NUM_SG_BUFFERS;
     504    vds_build_sg_list(&lsilogic->edds, buffer, length);
     505#endif
    442506
    443507    lsilogic->ScsiIoReq.u8TargetID          = idTgt;
     
    453517        lsilogic->ScsiIoReq.au8CDB[i] = aCDB[i];
    454518
    455     lsilogic->Sge.u24Length                 = length;
    456     lsilogic->Sge.fEndOfList                = 1;
    457     lsilogic->Sge.f64BitAddress             = 0;
    458     lsilogic->Sge.fBufferContainsData       = 0;
    459     lsilogic->Sge.fLocalAddress             = 0;
    460     lsilogic->Sge.u2ElementType             = 0x01; /* Simple type */
    461     lsilogic->Sge.fEndOfBuffer              = 1;
    462     lsilogic->Sge.fLastElement              = 1;
    463     lsilogic->Sge.u32DataBufferAddressLow   = lsilogic_addr_to_phys(buffer);
    464 
    465     return lsilogic_scsi_cmd_exec(lsilogic);
     519#ifdef USE_VDS
     520    for (i = 0; i < lsilogic->edds.num_used; ++i)
     521    {
     522        lsilogic->Sge[i].u24Length                  = lsilogic->edds.u.sg[i].size;
     523        lsilogic->Sge[i].fEndOfList                 = 0;
     524        lsilogic->Sge[i].f64BitAddress              = 0;
     525        lsilogic->Sge[i].fBufferContainsData        = 0;
     526        lsilogic->Sge[i].fLocalAddress              = 0;
     527        lsilogic->Sge[i].u2ElementType              = 0x01; /* Simple type */
     528        lsilogic->Sge[i].fEndOfBuffer               = 0;
     529        lsilogic->Sge[i].fLastElement               = 0;
     530        lsilogic->Sge[i].u32DataBufferAddressLow    = lsilogic->edds.u.sg[i].phys_addr;
     531    }
     532    --i;
     533    lsilogic->Sge[i].fEndOfList = lsilogic->Sge[i].fEndOfBuffer = lsilogic->Sge[i].fLastElement = 1;
     534
     535#else
     536    lsilogic->Sge[0].u24Length                 = length;
     537    lsilogic->Sge[0].fEndOfList                = 1;
     538    lsilogic->Sge[0].f64BitAddress             = 0;
     539    lsilogic->Sge[0].fBufferContainsData       = 0;
     540    lsilogic->Sge[0].fLocalAddress             = 0;
     541    lsilogic->Sge[0].u2ElementType             = 0x01; /* Simple type */
     542    lsilogic->Sge[0].fEndOfBuffer              = 1;
     543    lsilogic->Sge[0].fLastElement              = 1;
     544    lsilogic->Sge[0].u32DataBufferAddressLow   = lsilogic_addr_to_phys(buffer);
     545#endif
     546
     547    rc = lsilogic_scsi_cmd_exec(lsilogic);
     548
     549#ifdef USE_VDS
     550    /* Unlock the buffer again. */
     551    vds_free_sg_list(&lsilogic->edds);
     552#endif
     553
     554    return rc;
    466555}
    467556
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