VirtualBox

Changeset 38530 in vbox


Ignore:
Timestamp:
Aug 25, 2011 2:26:49 PM (14 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
73677
Message:

VSCSI: Implement REQUEST SENSE command

Location:
trunk/src/VBox/Devices/Storage/VSCSI
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Storage/VSCSI/VSCSIDevice.cpp

    r32983 r38530  
    6767                ScsiInquiryReply.u3PeripheralQualifier = SCSI_INQUIRY_DATA_PERIPHERAL_QUALIFIER_NOT_CONNECTED_NOT_SUPPORTED;
    6868                cbData = vscsiCopyToIoMemCtx(&pVScsiReq->IoMemCtx, (uint8_t *)&ScsiInquiryReply, sizeof(SCSIINQUIRYDATA));
    69                 *prcReq = vscsiReqSenseOkSet(pVScsiReq);
     69                *prcReq = vscsiReqSenseOkSet(&pVScsiDevice->VScsiSense, pVScsiReq);
    7070            }
    7171            else
     
    8181             */
    8282            if (vscsiBE2HU32(&pVScsiReq->pbCDB[6]) < 16)
    83                 *prcReq = vscsiReqSenseErrorSet(pVScsiReq, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INV_FIELD_IN_CMD_PACKET);
     83                *prcReq = vscsiReqSenseErrorSet(&pVScsiDevice->VScsiSense, pVScsiReq, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INV_FIELD_IN_CMD_PACKET);
    8484            else
    8585            {
     
    9191                cbData = vscsiCopyToIoMemCtx(&pVScsiReq->IoMemCtx, aReply, sizeof(aReply));
    9292                if (cbData < 16)
    93                     *prcReq = vscsiReqSenseErrorSet(pVScsiReq, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INV_FIELD_IN_CMD_PACKET);
     93                    *prcReq = vscsiReqSenseErrorSet(&pVScsiDevice->VScsiSense, pVScsiReq, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INV_FIELD_IN_CMD_PACKET);
    9494                else
    95                     *prcReq = vscsiReqSenseOkSet(pVScsiReq);
     95                    *prcReq = vscsiReqSenseOkSet(&pVScsiDevice->VScsiSense, pVScsiReq);
    9696            }
    9797            break;
     
    9999        case SCSI_TEST_UNIT_READY:
    100100        {
    101             *prcReq = vscsiReqSenseOkSet(pVScsiReq);
     101            *prcReq = vscsiReqSenseOkSet(&pVScsiDevice->VScsiSense, pVScsiReq);
    102102            break;
     103        }
     104        case SCSI_REQUEST_SENSE:
     105        {
     106            /* Descriptor format sense data is not supported and results in an error. */
     107            if ((pVScsiReq->pbCDB[1] & 0x1) != 0)
     108                *prcReq = vscsiReqSenseErrorSet(&pVScsiDevice->VScsiSense, pVScsiReq, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INV_FIELD_IN_CMD_PACKET);
     109            else
     110                *prcReq = vscsiReqSenseCmd(&pVScsiDevice->VScsiSense, pVScsiReq);
    103111        }
    104112        default:
     
    140148    pVScsiDevice->cLunsMax             = 0;
    141149    pVScsiDevice->papVScsiLun          = NULL;
     150    vscsiSenseInit(&pVScsiDevice->VScsiSense);
    142151
    143152    rc = RTMemCacheCreate(&pVScsiDevice->hCacheReq, sizeof(VSCSIREQINT), 0, UINT32_MAX,
     
    282291        {
    283292            /* LUN not present, report error. */
    284             vscsiReqSenseErrorSet(pVScsiReq,
     293            vscsiReqSenseErrorSet(&pVScsiDevice->VScsiSense, pVScsiReq,
    285294                                  SCSI_SENSE_ILLEGAL_REQUEST,
    286295                                  SCSI_ASC_LOGICAL_UNIT_DOES_NOT_RESPOND_TO_SELECTION);
  • trunk/src/VBox/Devices/Storage/VSCSI/VSCSIInternal.h

    r33540 r38530  
    3636/** Pointer to a virtual SCSI I/O request. */
    3737typedef VSCSIIOREQINT         *PVSCSIIOREQINT;
     38/** Pointer to virtual SCSI sense data state. */
     39typedef struct VSCSISENSE     *PVSCSISENSE;
     40
     41/**
     42 * Virtual SCSI sense data handling.
     43 */
     44typedef struct VSCSISENSE
     45{
     46    /** Buffer holding the sense data. */
     47    uint8_t              abSenseBuf[32];
     48} VSCSISENSE;
    3849
    3950/**
     
    5263    /** Request cache */
    5364    RTMEMCACHE           hCacheReq;
     65    /** Sense data handling. */
     66    VSCSISENSE           VScsiSense;
    5467    /** Pointer to the array of LUN handles.
    5568     *  The index is the LUN id. */
     
    241254
    242255/**
     256 * Init the sense data state.
     257 *
     258 * @returns nothing.
     259 * @param   pVScsiSense  The SCSI sense data state to init.
     260 */
     261void vscsiSenseInit(PVSCSISENSE pVScsiSense);
     262
     263/**
    243264 * Sets a ok sense code.
    244265 *
    245266 * @returns SCSI status code.
     267 * @param   pVScsiSense  The SCSI sense state to use.
    246268 * @param   pVScsiReq    The SCSI request.
    247269 */
    248 int vscsiReqSenseOkSet(PVSCSIREQINT pVScsiReq);
     270int vscsiReqSenseOkSet(PVSCSISENSE pVScsiSense, PVSCSIREQINT pVScsiReq);
    249271
    250272/**
     
    252274 *
    253275 * @returns SCSI status code.
     276 * @param   pVScsiSense   The SCSI sense state to use.
    254277 * @param   pVScsiReq     The SCSI request.
    255  * @param   uSCSISenseKey The SCSi sense key to set.
     278 * @param   uSCSISenseKey The SCSI sense key to set.
    256279 * @param   uSCSIASC      The ASC value.
    257280 */
    258 int vscsiReqSenseErrorSet(PVSCSIREQINT pVScsiReq, uint8_t uSCSISenseKey, uint8_t uSCSIASC);
     281int vscsiReqSenseErrorSet(PVSCSISENSE pVScsiSense, PVSCSIREQINT pVScsiReq, uint8_t uSCSISenseKey, uint8_t uSCSIASC);
     282
     283/**
     284 * Process a request sense command.
     285 *
     286 * @returns SCSI status code.
     287 * @param   pVScsiSense   The SCSI sense state to use.
     288 * @param   pVScsiReq     The SCSI request.
     289 */
     290int vscsiReqSenseCmd(PVSCSISENSE pVScsiSense, PVSCSIREQINT pVScsiReq);
    259291
    260292/**
     
    289321uint32_t vscsiIoReqOutstandingCountGet(PVSCSILUNINT pVScsiLun);
    290322
     323/**
     324 * Wrapper for the get medium size I/O callback.
     325 *
     326 * @returns VBox status code.
     327 * @param   pVScsiLun   The LUN.
     328 * @param   pcbSize     Where to store the size on success.
     329 */
    291330DECLINLINE(int) vscsiLunMediumGetSize(PVSCSILUNINT pVScsiLun, uint64_t *pcbSize)
    292331{
     
    296335}
    297336
     337/**
     338 * Wrapper for the I/O request enqueue I/O callback.
     339 *
     340 * @returns VBox status code.
     341 * @param   pVScsiLun   The LUN.
     342 * @param   pVScsiIoReq The I/O request to enqueue.
     343 */
    298344DECLINLINE(int) vscsiLunReqTransferEnqueue(PVSCSILUNINT pVScsiLun, PVSCSIIOREQINT pVScsiIoReq)
    299345{
     
    303349}
    304350
     351/**
     352 * Wrapper around vscsiReqSenseOkSet()
     353 */
     354DECLINLINE(int) vscsiLunReqSenseOkSet(PVSCSILUNINT pVScsiLun, PVSCSIREQINT pVScsiReq)
     355{
     356    return vscsiReqSenseOkSet(&pVScsiLun->pVScsiDevice->VScsiSense, pVScsiReq);
     357}
     358
     359/**
     360 * Wrapper around vscsiReqSenseErrorSet()
     361 */
     362DECLINLINE(int) vscsiLunReqSenseErrorSet(PVSCSILUNINT pVScsiLun, PVSCSIREQINT pVScsiReq, uint8_t uSCSISenseKey, uint8_t uSCSIASC)
     363{
     364    return vscsiReqSenseErrorSet(&pVScsiLun->pVScsiDevice->VScsiSense, pVScsiReq, uSCSISenseKey, uSCSIASC);
     365}
     366
     367
    305368#endif /* ___VSCSIInternal_h */
    306369
  • trunk/src/VBox/Devices/Storage/VSCSI/VSCSIIoReq.cpp

    r32983 r38530  
    114114    /** @todo error reporting */
    115115    if (RT_SUCCESS(rcIoReq))
    116         rcReq = vscsiReqSenseOkSet(pVScsiReq);
     116        rcReq = vscsiLunReqSenseOkSet(pVScsiLun, pVScsiReq);
    117117    else if (!fRedoPossible)
    118118    {
    119119        /** @todo Not 100% correct for the write case as the 0x00 ASCQ for write errors
    120120         * is not used for SBC devices. */
    121         rcReq = vscsiReqSenseErrorSet(pVScsiReq, SCSI_SENSE_MEDIUM_ERROR,
    122                                       pVScsiIoReq->enmTxDir == VSCSIIOREQTXDIR_READ
    123                                       ? SCSI_ASC_READ_ERROR
    124                                       : SCSI_ASC_WRITE_ERROR);
     121        rcReq = vscsiLunReqSenseErrorSet(pVScsiLun, pVScsiReq, SCSI_SENSE_MEDIUM_ERROR,
     122                                         pVScsiIoReq->enmTxDir == VSCSIIOREQTXDIR_READ
     123                                         ? SCSI_ASC_READ_ERROR
     124                                         : SCSI_ASC_WRITE_ERROR);
    125125    }
    126126    else
  • trunk/src/VBox/Devices/Storage/VSCSI/VSCSILunSbc.cpp

    r32983 r38530  
    9191
    9292            vscsiCopyToIoMemCtx(&pVScsiReq->IoMemCtx, (uint8_t *)&ScsiInquiryReply, sizeof(SCSIINQUIRYDATA));
    93             rcReq = vscsiReqSenseOkSet(pVScsiReq);
     93            rcReq = vscsiLunReqSenseOkSet(pVScsiLun, pVScsiReq);
    9494            break;
    9595        }
     
    109109            vscsiH2BEU32(&aReply[4], 512);
    110110            vscsiCopyToIoMemCtx(&pVScsiReq->IoMemCtx, aReply, sizeof(aReply));
    111             rcReq = vscsiReqSenseOkSet(pVScsiReq);
     111            rcReq = vscsiLunReqSenseOkSet(pVScsiLun, pVScsiReq);
    112112            break;
    113113        }
     
    135135
    136136            vscsiCopyToIoMemCtx(&pVScsiReq->IoMemCtx, aReply, sizeof(aReply));
    137             rcReq = vscsiReqSenseOkSet(pVScsiReq);
     137            rcReq = vscsiLunReqSenseOkSet(pVScsiLun, pVScsiReq);
    138138            break;
    139139        }
     
    222222
    223223                    vscsiCopyToIoMemCtx(&pVScsiReq->IoMemCtx, aReply, sizeof(aReply));
    224                     rcReq =  vscsiReqSenseOkSet(pVScsiReq);
     224                    rcReq =  vscsiLunReqSenseOkSet(pVScsiLun, pVScsiReq);
    225225                    break;
    226226                }
     
    236236        case SCSI_START_STOP_UNIT:
    237237        {
    238             rcReq = vscsiReqSenseOkSet(pVScsiReq);
     238            rcReq = vscsiLunReqSenseOkSet(pVScsiLun, pVScsiReq);
    239239            break;
    240240        }
     
    258258                        aReply[3] = 0;
    259259                        vscsiCopyToIoMemCtx(&pVScsiReq->IoMemCtx, aReply, sizeof(aReply));
    260                         rcReq = vscsiReqSenseOkSet(pVScsiReq);
     260                        rcReq = vscsiLunReqSenseOkSet(pVScsiLun, pVScsiReq);
    261261                        break;
    262262                    }
    263263                }
    264264                default:
    265                     rcReq = vscsiReqSenseErrorSet(pVScsiReq, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INV_FIELD_IN_CMD_PACKET);
     265                    rcReq = vscsiLunReqSenseErrorSet(pVScsiLun, pVScsiReq, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INV_FIELD_IN_CMD_PACKET);
    266266            }
    267267            break;
     
    281281
    282282                    vscsiCopyToIoMemCtx(&pVScsiReq->IoMemCtx, aReply, sizeof(aReply));
    283                     rcReq = vscsiReqSenseOkSet(pVScsiReq);
     283                    rcReq = vscsiLunReqSenseOkSet(pVScsiLun, pVScsiReq);
    284284                    break;
    285285                }
    286286                default:
    287                     rcReq = vscsiReqSenseErrorSet(pVScsiReq, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INV_FIELD_IN_CMD_PACKET); /* Don't know if this is correct */
     287                    rcReq = vscsiLunReqSenseErrorSet(pVScsiLun, pVScsiReq, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INV_FIELD_IN_CMD_PACKET); /* Don't know if this is correct */
    288288            }
    289289            break;
     
    291291        default:
    292292            //AssertMsgFailed(("Command %#x [%s] not implemented\n", pRequest->pbCDB[0], SCSICmdText(pRequest->pbCDB[0])));
    293             rcReq = vscsiReqSenseErrorSet(pVScsiReq, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_ILLEGAL_OPCODE);
     293            rcReq = vscsiLunReqSenseErrorSet(pVScsiLun, pVScsiReq, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_ILLEGAL_OPCODE);
    294294    }
    295295
     
    301301        if (RT_UNLIKELY(uLbaStart + cSectorTransfer > pVScsiLunSbc->cSectors))
    302302        {
    303             rcReq = vscsiReqSenseErrorSet(pVScsiReq, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_LOGICAL_BLOCK_OOR);
     303            rcReq = vscsiLunReqSenseErrorSet(pVScsiLun, pVScsiReq, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_LOGICAL_BLOCK_OOR);
    304304            vscsiDeviceReqComplete(pVScsiLun->pVScsiDevice, pVScsiReq, rcReq, false, VINF_SUCCESS);
    305305        }
  • trunk/src/VBox/Devices/Storage/VSCSI/VSCSISense.cpp

    r28800 r38530  
    2222#include "VSCSIInternal.h"
    2323
    24 int vscsiReqSenseOkSet(PVSCSIREQINT pVScsiReq)
     24void vscsiSenseInit(PVSCSISENSE pVScsiSense)
    2525{
    26     if (pVScsiReq->cbSense < 14)
    27         return SCSI_STATUS_OK;
     26    memset(pVScsiSense->abSenseBuf, 0, sizeof(pVScsiSense->abSenseBuf));
     27}
    2828
    29     AssertMsgReturn(pVScsiReq->pbSense, ("Sense buffer pointer is NULL\n"), SCSI_STATUS_OK);
    30     memset(pVScsiReq->pbSense, 0, pVScsiReq->cbSense);
     29int vscsiReqSenseOkSet(PVSCSISENSE pVScsiSense, PVSCSIREQINT pVScsiReq)
     30{
     31    memset(pVScsiSense->abSenseBuf, 0, sizeof(pVScsiSense->abSenseBuf));
    3132
    32     pVScsiReq->pbSense[0]  = (1 << 7) | SCSI_SENSE_RESPONSE_CODE_CURR_FIXED; /* Fixed format */
    33     pVScsiReq->pbSense[2]  = SCSI_SENSE_NONE;
    34     pVScsiReq->pbSense[7]  = 10;
    35     pVScsiReq->pbSense[12] = SCSI_ASC_NONE;
    36     pVScsiReq->pbSense[13] = SCSI_ASC_NONE; /* Should be ASCQ but it has the same value for success. */
     33    pVScsiSense->abSenseBuf[0]  = (1 << 7) | SCSI_SENSE_RESPONSE_CODE_CURR_FIXED; /* Fixed format */
     34    pVScsiSense->abSenseBuf[2]  = SCSI_SENSE_NONE;
     35    pVScsiSense->abSenseBuf[7]  = 10;
     36    pVScsiSense->abSenseBuf[12] = SCSI_ASC_NONE;
     37    pVScsiSense->abSenseBuf[13] = SCSI_ASC_NONE; /* Should be ASCQ but it has the same value for success. */
     38
     39    if (pVScsiReq->pbSense && pVScsiReq->cbSense)
     40        memcpy(pVScsiReq->pbSense, pVScsiSense->abSenseBuf, RT_MIN(sizeof(pVScsiSense->abSenseBuf), pVScsiReq->cbSense));
    3741
    3842    return SCSI_STATUS_OK;
    3943}
    4044
    41 int vscsiReqSenseErrorSet(PVSCSIREQINT pVScsiReq, uint8_t uSCSISenseKey, uint8_t uSCSIASC)
     45int vscsiReqSenseErrorSet(PVSCSISENSE pVScsiSense, PVSCSIREQINT pVScsiReq, uint8_t uSCSISenseKey, uint8_t uSCSIASC)
    4246{
    43     AssertMsgReturn(pVScsiReq->cbSense >= 18, ("Sense buffer is not big enough\n"), SCSI_STATUS_OK);
    44     AssertMsgReturn(pVScsiReq->pbSense, ("Sense buffer pointer is NULL\n"), SCSI_STATUS_OK);
    45     memset(pVScsiReq->pbSense, 0, pVScsiReq->cbSense);
    46     pVScsiReq->pbSense[0] = (1 << 7) | SCSI_SENSE_RESPONSE_CODE_CURR_FIXED; /* Fixed format */
    47     pVScsiReq->pbSense[2] = uSCSISenseKey;
    48     pVScsiReq->pbSense[7]  = 10;
    49     pVScsiReq->pbSense[12] = uSCSIASC;
    50     pVScsiReq->pbSense[13] = 0x00; /** @todo: Provide more info. */
     47    memset(pVScsiSense->abSenseBuf, 0, sizeof(pVScsiSense->abSenseBuf));
     48    pVScsiSense->abSenseBuf[0] = (1 << 7) | SCSI_SENSE_RESPONSE_CODE_CURR_FIXED; /* Fixed format */
     49    pVScsiSense->abSenseBuf[2] = uSCSISenseKey;
     50    pVScsiSense->abSenseBuf[7]  = 10;
     51    pVScsiSense->abSenseBuf[12] = uSCSIASC;
     52    pVScsiSense->abSenseBuf[13] = 0x00; /** @todo: Provide more info. */
     53
     54    if (pVScsiReq->pbSense && pVScsiReq->cbSense)
     55        memcpy(pVScsiReq->pbSense, pVScsiSense->abSenseBuf, RT_MIN(sizeof(pVScsiSense->abSenseBuf), pVScsiReq->cbSense));
     56
    5157    return SCSI_STATUS_CHECK_CONDITION;
    5258}
    5359
     60int vscsiReqSenseCmd(PVSCSISENSE pVScsiSense, PVSCSIREQINT pVScsiReq)
     61{
     62    /* Copy the current sense data to the buffer. */
     63    vscsiCopyToIoMemCtx(&pVScsiReq->IoMemCtx, pVScsiSense->abSenseBuf, sizeof(pVScsiSense->abSenseBuf));
     64    return vscsiReqSenseOkSet(pVScsiSense, pVScsiReq);
     65}
     66
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