VirtualBox

Changeset 12508 in vbox


Ignore:
Timestamp:
Sep 16, 2008 4:52:11 PM (17 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
36646
Message:

Device/Storage: fix CD/DVD media change problems in passthrough mode.

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/pdmifs.h

    r12476 r12508  
    643643     * @thread  Any thread.
    644644     */
    645     DECLR3CALLBACKMEMBER(int, pfnSendCmd,(PPDMIBLOCK pInterface, const uint8_t *pbCmd, PDMBLOCKTXDIR enmTxDir, void *pvBuf, size_t *pcbBuf, uint8_t *pbSenseKey, uint32_t cTimeoutMillies));
     645    DECLR3CALLBACKMEMBER(int, pfnSendCmd,(PPDMIBLOCK pInterface, const uint8_t *pbCmd, PDMBLOCKTXDIR enmTxDir, void *pvBuf, size_t *pcbBuf, uint8_t *pabSense, size_t cbSense, uint32_t cTimeoutMillies));
    646646
    647647    /**
  • trunk/src/VBox/Devices/Storage/ATAController.h

    r11159 r12508  
    6161 */
    6262#define ATA_UDMA_MODE_MAX 6
     63
     64/** ATAPI sense info size. */
     65#define ATAPI_SENSE_SIZE 64
    6366
    6467/** The maximum number of release log entries per device. */
     
    149152    /** ATAPI current command. */
    150153    uint8_t aATAPICmd[ATAPI_PACKET_SIZE];
    151     /** ATAPI sense key. */
    152     uint8_t uATAPISenseKey;
    153     /** ATAPI additional sense code. */
    154     uint8_t uATAPIASC;
     154    /** ATAPI sense data. */
     155    uint8_t abATAPISense[ATAPI_SENSE_SIZE];
    155156    /** HACK: Countdown till we report a newly unmounted drive as mounted. */
    156157    uint8_t cNotifiedMediaChange;
  • trunk/src/VBox/Devices/Storage/DevATA.cpp

    r11582 r12508  
    2828
    2929/**
    30  * The SSM saved state version.
     30 * The SSM saved state versions.
    3131 */
    32 #define ATA_SAVED_STATE_VERSION 16
     32#define ATA_SAVED_STATE_VERSION 17
     33#define ATA_SAVED_STATE_VERSION_WITHOUT_FULL_SENSE 16
    3334
    3435
     
    12131214        | (!s->cbTotalTransfer ? ATAPI_INT_REASON_CD : 0);
    12141215    Log2(("%s: interrupt reason %#04x\n", __FUNCTION__, s->uATARegNSector));
    1215     s->uATAPISenseKey = SCSI_SENSE_NONE;
    1216     s->uATAPIASC = SCSI_ASC_NONE;
    1217 }
    1218 
    1219 
    1220 static void atapiCmdError(ATADevState *s, uint8_t uATAPISenseKey, uint8_t uATAPIASC)
    1221 {
    1222     Log(("%s: sense=%#x asc=%#x\n", __FUNCTION__, uATAPISenseKey, uATAPIASC));
    1223     s->uATARegError = uATAPISenseKey << 4;
     1216
     1217    memset(s->abATAPISense, '\0', sizeof(s->abATAPISense));
     1218    s->abATAPISense[0] = 0x70 | (1 << 7);
     1219    s->abATAPISense[7] = 10;
     1220}
     1221
     1222
     1223static void atapiCmdError(ATADevState *s, const uint8_t *pabATAPISense, size_t cbATAPISense)
     1224{
     1225    Log(("%s: sense=%#x asc=%#x\n", __FUNCTION__, pabATAPISense[2] & 0x0f, pabATAPISense[12]));
     1226    s->uATARegError = pabATAPISense[2] << 4;
    12241227    ataSetStatusValue(s, ATA_STAT_READY | ATA_STAT_ERR);
    12251228    s->uATARegNSector = (s->uATARegNSector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
    12261229    Log2(("%s: interrupt reason %#04x\n", __FUNCTION__, s->uATARegNSector));
    1227     s->uATAPISenseKey = uATAPISenseKey;
    1228     s->uATAPIASC = uATAPIASC;
     1230    memset(s->abATAPISense, '\0', sizeof(s->abATAPISense));
     1231    memcpy(s->abATAPISense, pabATAPISense, RT_MIN(cbATAPISense, sizeof(s->abATAPISense)));
    12291232    s->cbTotalTransfer = 0;
    12301233    s->cbElementaryTransfer = 0;
     
    12341237    s->iBeginTransfer = ATAFN_BT_NULL;
    12351238    s->iSourceSink = ATAFN_SS_NULL;
     1239}
     1240
     1241
     1242/** @todo deprecated function - doesn't provide enough info. Replace by direct
     1243 * calls to atapiCmdError()  with full data. */
     1244static void atapiCmdErrorSimple(ATADevState *s, uint8_t uATAPISenseKey, uint8_t uATAPIASC)
     1245{
     1246    uint8_t abATAPISense[ATAPI_SENSE_SIZE];
     1247    memset(abATAPISense, '\0', sizeof(abATAPISense));
     1248    abATAPISense[0] = 0x70 | (1 << 7);
     1249    abATAPISense[2] = uATAPISenseKey & 0x0f;
     1250    abATAPISense[7] = 10;
     1251    abATAPISense[12] = uATAPIASC;
     1252    atapiCmdError(s, abATAPISense, sizeof(abATAPISense));
    12361253}
    12371254
     
    12781295            if (RT_FAILURE(rc))
    12791296            {
    1280                 atapiCmdError(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_NONE);
     1297                atapiCmdErrorSimple(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_NONE);
    12811298                return;
    12821299            }
     
    13971414        if (s->cErrors++ < MAX_LOG_REL_ERRORS)
    13981415            LogRel(("PIIX3 ATA: LUN#%d: CD-ROM read error, %d sectors at LBA %d\n", s->iLUN, cSectors, s->iATAPILBA));
    1399         atapiCmdError(s, SCSI_SENSE_MEDIUM_ERROR, SCSI_ASC_READ_ERROR);
     1416        atapiCmdErrorSimple(s, SCSI_SENSE_MEDIUM_ERROR, SCSI_ASC_READ_ERROR);
    14001417    }
    14011418    return false;
     
    14071424    PATACONTROLLER pCtl = ATADEVSTATE_2_CONTROLLER(s);
    14081425    int rc = VINF_SUCCESS;
    1409     uint8_t uATAPISenseKey;
     1426    uint8_t abATAPISense[ATAPI_SENSE_SIZE];
    14101427    size_t cbTransfer;
    14111428    PSTAMPROFILEADV pProf = NULL;
     
    14701487                if (s->cErrors++ < MAX_LOG_REL_ERRORS)
    14711488                    LogRel(("PIIX3 ATA: LUN#%d: CD-ROM passthrough split error\n", s->iLUN));
    1472                 atapiCmdError(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_ILLEGAL_OPCODE);
     1489                atapiCmdErrorSimple(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_ILLEGAL_OPCODE);
    14731490                {
    14741491                STAM_PROFILE_START(&pCtl->StatLockWait, a);
     
    15091526                    break;
    15101527            }
    1511             rc = s->pDrvBlock->pfnSendCmd(s->pDrvBlock, aATAPICmd, (PDMBLOCKTXDIR)s->uTxDir, pbBuf, &cbCurrTX, &uATAPISenseKey, 30000 /**< @todo timeout */);
     1528            rc = s->pDrvBlock->pfnSendCmd(s->pDrvBlock, aATAPICmd, (PDMBLOCKTXDIR)s->uTxDir, pbBuf, &cbCurrTX, abATAPISense, sizeof(abATAPISense), 30000 /**< @todo timeout */);
    15121529            if (rc != VINF_SUCCESS)
    15131530                break;
     
    15171534    }
    15181535    else
    1519         rc = s->pDrvBlock->pfnSendCmd(s->pDrvBlock, s->aATAPICmd, (PDMBLOCKTXDIR)s->uTxDir, s->CTX_SUFF(pbIOBuffer), &cbTransfer, &uATAPISenseKey, 30000 /**< @todo timeout */);
     1536        rc = s->pDrvBlock->pfnSendCmd(s->pDrvBlock, s->aATAPICmd, (PDMBLOCKTXDIR)s->uTxDir, s->CTX_SUFF(pbIOBuffer), &cbTransfer, abATAPISense, sizeof(abATAPISense), 30000 /**< @todo timeout */);
    15201537    if (pProf) { STAM_PROFILE_ADV_STOP(pProf, b); }
    15211538
     
    15801597                    break;
    15811598                s->cErrors++;
    1582                 LogRel(("PIIX3 ATA: LUN#%d: CD-ROM passthrough command (%#04x) error %d %Rrc\n", s->iLUN, u8Cmd, uATAPISenseKey, rc));
     1599                LogRel(("PIIX3 ATA: LUN#%d: CD-ROM passthrough command (%#04x) error %d %Rrc\n", s->iLUN, u8Cmd, abATAPISense[2] & 0x0f, rc));
    15831600            } while (0);
    15841601        }
    1585         atapiCmdError(s, uATAPISenseKey, 0);
    1586         /* This is a drive-reported error. atapiCmdError() sets both the error
    1587          * error code in the ATA error register and in s->uATAPISenseKey. The
    1588          * former is correct, the latter is not. Otherwise the drive would not
    1589          * get the next REQUEST SENSE command which is necessary to clear the
    1590          * error status of the drive. Easy fix: clear s->uATAPISenseKey. */
    1591         s->uATAPISenseKey = SCSI_SENSE_NONE;
    1592         s->uATAPIASC = SCSI_ASC_NONE;
     1602        atapiCmdError(s, abATAPISense, sizeof(abATAPISense));
    15931603    }
    15941604    return false;
     
    16551665    if ((s->aATAPICmd[1] & 0x03) != 1 || ataBE2H_U32(&s->aATAPICmd[2]) != 1)
    16561666    {
    1657         atapiCmdError(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INV_FIELD_IN_CMD_PACKET);
     1667        atapiCmdErrorSimple(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INV_FIELD_IN_CMD_PACKET);
    16581668        return false;
    16591669    }
     
    16841694    if ((s->aATAPICmd[1] & 0x03) == 3 || ataBE2H_U16(&s->aATAPICmd[2]) != 0)
    16851695    {
    1686         atapiCmdError(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INV_FIELD_IN_CMD_PACKET);
     1696        atapiCmdErrorSimple(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INV_FIELD_IN_CMD_PACKET);
    16871697        return false;
    16881698    }
     
    18191829
    18201830    Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
    1821     Assert(s->cbElementaryTransfer <= 18);
    1822     memset(pbBuf, 0, 18);
    1823     pbBuf[0] = 0x70 | (1 << 7);
    1824     pbBuf[2] = s->uATAPISenseKey;
    1825     pbBuf[7] = 10;
    1826     pbBuf[12] = s->uATAPIASC;
     1831    memset(pbBuf, '\0', s->cbElementaryTransfer);
     1832    memcpy(pbBuf, s->abATAPISense, RT_MIN(s->cbElementaryTransfer, sizeof(s->abATAPISense)));
    18271833    s->iSourceSink = ATAFN_SS_NULL;
    18281834    atapiCmdOK(s);
     
    18611867    if (iStartTrack > 1 && iStartTrack != 0xaa)
    18621868    {
    1863         atapiCmdError(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INV_FIELD_IN_CMD_PACKET);
     1869        atapiCmdErrorSimple(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INV_FIELD_IN_CMD_PACKET);
    18641870        return false;
    18651871    }
     
    20452051            {
    20462052                if (s->cNotifiedMediaChange-- > 2)
    2047                     atapiCmdError(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
     2053                    atapiCmdErrorSimple(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
    20482054                else
    2049                     atapiCmdError(s, SCSI_SENSE_UNIT_ATTENTION, SCSI_ASC_MEDIUM_MAY_HAVE_CHANGED); /* media changed */
     2055                    atapiCmdErrorSimple(s, SCSI_SENSE_UNIT_ATTENTION, SCSI_ASC_MEDIUM_MAY_HAVE_CHANGED); /* media changed */
    20502056            }
    20512057            else if (s->pDrvMount->pfnIsMounted(s->pDrvMount))
    20522058                atapiCmdOK(s);
    20532059            else
    2054                 atapiCmdError(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
     2060                atapiCmdErrorSimple(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
    20552061            break;
    20562062        case SCSI_MODE_SENSE_10:
     
    20812087                    default:
    20822088                    case SCSI_PAGECONTROL_SAVED:
    2083                         atapiCmdError(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_SAVING_PARAMETERS_NOT_SUPPORTED);
     2089                        atapiCmdErrorSimple(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_SAVING_PARAMETERS_NOT_SUPPORTED);
    20842090                        break;
    20852091                }
     
    21002106            }
    21012107            else
    2102                 atapiCmdError(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
     2108                atapiCmdErrorSimple(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
    21032109            break;
    21042110        case SCSI_READ_10:
     
    21102116                {
    21112117                    s->cNotifiedMediaChange-- ;
    2112                     atapiCmdError(s, SCSI_SENSE_UNIT_ATTENTION, SCSI_ASC_MEDIUM_MAY_HAVE_CHANGED); /* media changed */
     2118                    atapiCmdErrorSimple(s, SCSI_SENSE_UNIT_ATTENTION, SCSI_ASC_MEDIUM_MAY_HAVE_CHANGED); /* media changed */
    21132119                    break;
    21142120                }
    21152121                else if (!s->pDrvMount->pfnIsMounted(s->pDrvMount))
    21162122                {
    2117                     atapiCmdError(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
     2123                    atapiCmdErrorSimple(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
    21182124                    break;
    21192125                }
     
    21402146                        uLastLogTS = RTTimeMilliTS();
    21412147                    }
    2142                     atapiCmdError(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_LOGICAL_BLOCK_OOR);
     2148                    atapiCmdErrorSimple(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_LOGICAL_BLOCK_OOR);
    21432149                    break;
    21442150                }
     
    21532159                {
    21542160                    s->cNotifiedMediaChange-- ;
    2155                     atapiCmdError(s, SCSI_SENSE_UNIT_ATTENTION, SCSI_ASC_MEDIUM_MAY_HAVE_CHANGED); /* media changed */
     2161                    atapiCmdErrorSimple(s, SCSI_SENSE_UNIT_ATTENTION, SCSI_ASC_MEDIUM_MAY_HAVE_CHANGED); /* media changed */
    21562162                    break;
    21572163                }
    21582164                else if (!s->pDrvMount->pfnIsMounted(s->pDrvMount))
    21592165                {
    2160                     atapiCmdError(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
     2166                    atapiCmdErrorSimple(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
    21612167                    break;
    21622168                }
     
    21802186                        uLastLogTS = RTTimeMilliTS();
    21812187                    }
    2182                     atapiCmdError(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_LOGICAL_BLOCK_OOR);
     2188                    atapiCmdErrorSimple(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_LOGICAL_BLOCK_OOR);
    21832189                    break;
    21842190                }
     
    21992205                    default:
    22002206                        LogRel(("PIIX3 ATA: LUN#%d: CD-ROM sector format not supported\n", s->iLUN));
    2201                         atapiCmdError(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INV_FIELD_IN_CMD_PACKET);
     2207                        atapiCmdErrorSimple(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INV_FIELD_IN_CMD_PACKET);
    22022208                        break;
    22032209                }
     
    22102216                {
    22112217                    s->cNotifiedMediaChange-- ;
    2212                     atapiCmdError(s, SCSI_SENSE_UNIT_ATTENTION, SCSI_ASC_MEDIUM_MAY_HAVE_CHANGED); /* media changed */
     2218                    atapiCmdErrorSimple(s, SCSI_SENSE_UNIT_ATTENTION, SCSI_ASC_MEDIUM_MAY_HAVE_CHANGED); /* media changed */
    22132219                    break;
    22142220                }
    22152221                else if (!s->pDrvMount->pfnIsMounted(s->pDrvMount))
    22162222                {
    2217                     atapiCmdError(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
     2223                    atapiCmdErrorSimple(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
    22182224                    break;
    22192225                }
     
    22312237                        uLastLogTS = RTTimeMilliTS();
    22322238                    }
    2233                     atapiCmdError(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_LOGICAL_BLOCK_OOR);
     2239                    atapiCmdErrorSimple(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_LOGICAL_BLOCK_OOR);
    22342240                    break;
    22352241                }
     
    22722278                    atapiCmdOK(s);
    22732279                else
    2274                     atapiCmdError(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIA_LOAD_OR_EJECT_FAILED);
     2280                    atapiCmdErrorSimple(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIA_LOAD_OR_EJECT_FAILED);
    22752281            }
    22762282            break;
     
    22882294                {
    22892295                    s->cNotifiedMediaChange-- ;
    2290                     atapiCmdError(s, SCSI_SENSE_UNIT_ATTENTION, SCSI_ASC_MEDIUM_MAY_HAVE_CHANGED); /* media changed */
     2296                    atapiCmdErrorSimple(s, SCSI_SENSE_UNIT_ATTENTION, SCSI_ASC_MEDIUM_MAY_HAVE_CHANGED); /* media changed */
    22912297                    break;
    22922298                }
    22932299                else if (!s->pDrvMount->pfnIsMounted(s->pDrvMount))
    22942300                {
    2295                     atapiCmdError(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
     2301                    atapiCmdErrorSimple(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
    22962302                    break;
    22972303                }
     
    23142320                    default:
    23152321                    error_cmd:
    2316                         atapiCmdError(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INV_FIELD_IN_CMD_PACKET);
     2322                        atapiCmdErrorSimple(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INV_FIELD_IN_CMD_PACKET);
    23172323                        break;
    23182324                }
     
    23232329            {
    23242330                s->cNotifiedMediaChange-- ;
    2325                 atapiCmdError(s, SCSI_SENSE_UNIT_ATTENTION, SCSI_ASC_MEDIUM_MAY_HAVE_CHANGED); /* media changed */
     2331                atapiCmdErrorSimple(s, SCSI_SENSE_UNIT_ATTENTION, SCSI_ASC_MEDIUM_MAY_HAVE_CHANGED); /* media changed */
    23262332                break;
    23272333            }
    23282334            else if (!s->pDrvMount->pfnIsMounted(s->pDrvMount))
    23292335            {
    2330                 atapiCmdError(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
     2336                atapiCmdErrorSimple(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
    23312337                break;
    23322338            }
     
    23372343            {
    23382344                s->cNotifiedMediaChange-- ;
    2339                 atapiCmdError(s, SCSI_SENSE_UNIT_ATTENTION, SCSI_ASC_MEDIUM_MAY_HAVE_CHANGED); /* media changed */
     2345                atapiCmdErrorSimple(s, SCSI_SENSE_UNIT_ATTENTION, SCSI_ASC_MEDIUM_MAY_HAVE_CHANGED); /* media changed */
    23402346                break;
    23412347            }
    23422348            else if (!s->pDrvMount->pfnIsMounted(s->pDrvMount))
    23432349            {
    2344                 atapiCmdError(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
     2350                atapiCmdErrorSimple(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
    23452351                break;
    23462352            }
     
    23522358            {
    23532359                s->cNotifiedMediaChange-- ;
    2354                 atapiCmdError(s, SCSI_SENSE_UNIT_ATTENTION, SCSI_ASC_MEDIUM_MAY_HAVE_CHANGED); /* media changed */
     2360                atapiCmdErrorSimple(s, SCSI_SENSE_UNIT_ATTENTION, SCSI_ASC_MEDIUM_MAY_HAVE_CHANGED); /* media changed */
    23552361                break;
    23562362            }
    23572363            else if (!s->pDrvMount->pfnIsMounted(s->pDrvMount))
    23582364            {
    2359                 atapiCmdError(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
     2365                atapiCmdErrorSimple(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
    23602366                break;
    23612367            }
     
    23732379            break;
    23742380        default:
    2375             atapiCmdError(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_ILLEGAL_OPCODE);
     2381            atapiCmdErrorSimple(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_ILLEGAL_OPCODE);
    23762382            break;
    23772383    }
     
    25222528        case SCSI_REQUEST_SENSE:
    25232529            cbTransfer = pbPacket[4];
    2524             if (s->uATAPISenseKey != SCSI_SENSE_NONE)
     2530            if ((s->abATAPISense[2] & 0x0f) != SCSI_SENSE_NONE)
    25252531            {
    25262532                ataStartTransfer(s, RT_MIN(cbTransfer, 18), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_REQUEST_SENSE, true);
     
    26232629                case 0x0f: /* activate deferred microcode */
    26242630                    LogRel(("PIIX3 ATA: LUN#%d: CD-ROM passthrough command attempted to update firmware, blocked\n", s->iLUN));
    2625                     atapiCmdError(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INV_FIELD_IN_CMD_PACKET);
     2631                    atapiCmdErrorSimple(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INV_FIELD_IN_CMD_PACKET);
    26262632                    break;
    26272633                default:
     
    26412647             * opcode 0x01" in syslog) and replies with a sense code of 0,
    26422648             * which sends cdrecord to an endless loop. */
    2643             atapiCmdError(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_ILLEGAL_OPCODE);
     2649            atapiCmdErrorSimple(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_ILLEGAL_OPCODE);
    26442650            break;
    26452651        default:
    26462652            LogRel(("PIIX3 ATA: LUN#%d: passthrough unimplemented for command %#x\n", s->iLUN, pbPacket[0]));
    2647             atapiCmdError(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_ILLEGAL_OPCODE);
     2653            atapiCmdErrorSimple(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_ILLEGAL_OPCODE);
    26482654            break;
    26492655        sendcmd:
     
    53555361            SSMR3PutU32(pSSMHandle, pThis->aCts[i].aIfs[j].cbATAPISector);
    53565362            SSMR3PutMem(pSSMHandle, &pThis->aCts[i].aIfs[j].aATAPICmd, sizeof(pThis->aCts[i].aIfs[j].aATAPICmd));
    5357             SSMR3PutU8(pSSMHandle, pThis->aCts[i].aIfs[j].uATAPISenseKey);
    5358             SSMR3PutU8(pSSMHandle, pThis->aCts[i].aIfs[j].uATAPIASC);
     5363            SSMR3PutMem(pSSMHandle, &pThis->aCts[i].aIfs[j].abATAPISense, sizeof(pThis->aCts[i].aIfs[j].abATAPISense));
    53595364            SSMR3PutU8(pSSMHandle, pThis->aCts[i].aIfs[j].cNotifiedMediaChange);
    53605365            SSMR3PutMem(pSSMHandle, &pThis->aCts[i].aIfs[j].Led, sizeof(pThis->aCts[i].aIfs[j].Led));
     
    53865391    uint32_t        u32;
    53875392
    5388     if (u32Version != ATA_SAVED_STATE_VERSION)
     5393    if (    u32Version != ATA_SAVED_STATE_VERSION
     5394        &&  u32Version != ATA_SAVED_STATE_VERSION_WITHOUT_FULL_SENSE)
    53895395    {
    53905396        AssertMsgFailed(("u32Version=%d\n", u32Version));
     
    54605466            SSMR3GetU32(pSSMHandle, &pThis->aCts[i].aIfs[j].cbATAPISector);
    54615467            SSMR3GetMem(pSSMHandle, &pThis->aCts[i].aIfs[j].aATAPICmd, sizeof(pThis->aCts[i].aIfs[j].aATAPICmd));
    5462             SSMR3GetU8(pSSMHandle, &pThis->aCts[i].aIfs[j].uATAPISenseKey);
    5463             SSMR3GetU8(pSSMHandle, &pThis->aCts[i].aIfs[j].uATAPIASC);
     5468            if (u32Version != ATA_SAVED_STATE_VERSION_WITHOUT_FULL_SENSE)
     5469            {
     5470                SSMR3GetMem(pSSMHandle, pThis->aCts[i].aIfs[j].abATAPISense, sizeof(pThis->aCts[i].aIfs[j].abATAPISense));
     5471            }
     5472            else
     5473            {
     5474                uint8_t uATAPISenseKey, uATAPIASC;
     5475                memset(pThis->aCts[i].aIfs[j].abATAPISense, '\0', sizeof(pThis->aCts[i].aIfs[j].abATAPISense));
     5476                pThis->aCts[i].aIfs[j].abATAPISense[0] = 0x70 | (1 << 7);
     5477                pThis->aCts[i].aIfs[j].abATAPISense[7] = 10;
     5478                SSMR3GetU8(pSSMHandle, &uATAPISenseKey);
     5479                SSMR3GetU8(pSSMHandle, &uATAPIASC);
     5480                pThis->aCts[i].aIfs[j].abATAPISense[2] = uATAPISenseKey & 0x0f;
     5481                pThis->aCts[i].aIfs[j].abATAPISense[12] = uATAPIASC;
     5482            }
     5483            /** @todo triple-check this hack after passthrough is working */
    54645484            SSMR3GetU8(pSSMHandle, &pThis->aCts[i].aIfs[j].cNotifiedMediaChange);
    54655485            SSMR3GetMem(pSSMHandle, &pThis->aCts[i].aIfs[j].Led, sizeof(pThis->aCts[i].aIfs[j].Led));
  • trunk/src/VBox/Devices/Storage/DrvHostDVD.cpp

    r12125 r12508  
    393393
    394394/** @copydoc PDMIBLOCK::pfnSendCmd */
    395 static int drvHostDvdSendCmd(PPDMIBLOCK pInterface, const uint8_t *pbCmd, PDMBLOCKTXDIR enmTxDir, void *pvBuf, size_t *pcbBuf,
    396                              uint8_t *pbStat, uint32_t cTimeoutMillies)
     395static int drvHostDvdSendCmd(PPDMIBLOCK pInterface, const uint8_t *pbCmd,
     396                             PDMBLOCKTXDIR enmTxDir, void *pvBuf, size_t *pcbBuf,
     397                             uint8_t *pabSense, size_t cbSense, uint32_t cTimeoutMillies)
    397398{
    398399    PDRVHOSTBASE pThis = PDMIBLOCK_2_DRVHOSTBASE(pInterface);
     
    407408    if (enmTxDir == PDMBLOCKTXDIR_FROM_DEVICE)
    408409        memset(pvBuf, '\0', *pcbBuf); /* we got read size, but zero it anyway. */
    409     uint8_t abSense[32];
    410     rc = DRVHostBaseScsiCmd(pThis, pbCmd, 12, PDMBLOCKTXDIR_FROM_DEVICE, pvBuf, pcbBuf, abSense, sizeof(abSense), cTimeoutMillies);
     410    rc = DRVHostBaseScsiCmd(pThis, pbCmd, 12, PDMBLOCKTXDIR_FROM_DEVICE, pvBuf, pcbBuf, pabSense, cbSense, cTimeoutMillies);
    411411    if (rc == VERR_UNRESOLVED_ERROR)
    412     {
    413         *pbStat = abSense[2] & 0x0f;
    414412        rc = VINF_SUCCESS;
    415     }
    416413
    417414#elif defined(RT_OS_L4)
     
    455452    cgc.buflen = *pcbBuf;
    456453    cgc.stat = 0;
    457     cgc.sense = &sense;
     454    Assert(cbSense >= sizeof(struct request_sense));
     455    cgc.sense = (struct request_sense *)pabSense;
    458456    cgc.data_direction = direction;
    459457    cgc.quiet = false;
     
    468466        else
    469467        {
     468            rc = RTErrConvertFromErrno(errno);
    470469            if (rc == VERR_ACCESS_DENIED && cgc.sense->sense_key == SCSI_SENSE_NONE)
    471470                cgc.sense->sense_key = SCSI_SENSE_ILLEGAL_REQUEST;
    472             *pbStat = cgc.sense->sense_key;
    473             rc = RTErrConvertFromErrno(errno);
    474471            Log2(("%s: error status %d, rc=%Rrc\n", __FUNCTION__, cgc.stat, rc));
    475472        }
     
    513510            AssertMsgFailedReturn(("%d\n", enmTxDir), VERR_INTERNAL_ERROR);
    514511    }
    515     char aSense[32];
    516512    usc.uscsi_flags |= USCSI_RQENABLE;
    517     usc.uscsi_rqbuf = aSense;
    518     usc.uscsi_rqlen = 32;
     513    usc.uscsi_rqbuf = pabSense;
     514    usc.uscsi_rqlen = cbSense;
    519515    usc.uscsi_cdb = (caddr_t)&scdb;
    520516    usc.uscsi_cdblen = 12;
     
    539535        if (usc.uscsi_status)
    540536        {
    541             *pbStat = aSense[2] & 0x0f;
    542537            rc = RTErrConvertFromErrno(errno);
    543538            Log2(("%s: error status. rc=%Rrc\n", __FUNCTION__, rc));
    544539        }
    545         else
    546             *pbStat = SCSI_SENSE_NONE;
    547540    }
    548541    Log2(("%s: after ioctl: residual buflen=%d original buflen=%d\n", __FUNCTION__, usc.uscsi_resid, usc.uscsi_buflen));
     
    589582    Req.spt.DataIn = direction;
    590583    Req.spt.TimeOutValue = (cTimeoutMillies + 999) / 1000; /* Convert to seconds */
    591     Req.spt.SenseInfoLength = sizeof(Req.aSense);
     584    Assert(cbSense <= sizeof(Req.aSense))
     585    Req.spt.SenseInfoLength = cbSense;
    592586    Req.spt.SenseInfoOffset = RT_OFFSETOF(struct _REQ, aSense);
    593587    if (DeviceIoControl((HANDLE)pThis->FileDevice, IOCTL_SCSI_PASS_THROUGH_DIRECT,
     
    595589    {
    596590        if (cbReturned > RT_OFFSETOF(struct _REQ, aSense))
    597             *pbStat = Req.aSense[2] & 0x0f;
     591            memcpy(pabSense, Req.aSense, cbSense);
    598592        else
    599             *pbStat = SCSI_SENSE_NONE;
     593            memset(pabSense, '\0', cbSense);
    600594        /* Windows shares the property of not properly reflecting the actually
    601595         * transferred data size. See above. Assume that everything worked ok. */
Note: See TracChangeset for help on using the changeset viewer.

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