VirtualBox

source: vbox/trunk/src/VBox/Devices/Storage/DevATA.cpp@ 5713

Last change on this file since 5713 was 5645, checked in by vboxsync, 17 years ago

ATA: On VERR_FILE_TOO_BIG clearly state that this relates the virtual hard disk (DVD/floppy is unlikely)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 236.1 KB
Line 
1/** @file
2 *
3 * VBox storage devices:
4 * ATA/ATAPI controller device (disk and cdrom).
5 */
6
7/*
8 * Copyright (C) 2006-2007 innotek GmbH
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License as published by the Free Software Foundation,
14 * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
15 * distribution. VirtualBox OSE is distributed in the hope that it will
16 * be useful, but WITHOUT ANY WARRANTY of any kind.
17 */
18
19
20/*******************************************************************************
21* Header Files *
22*******************************************************************************/
23#define LOG_GROUP LOG_GROUP_DEV_IDE
24#include <VBox/pdmdev.h>
25#include <iprt/assert.h>
26#include <iprt/string.h>
27#ifdef IN_RING3
28# include <iprt/uuid.h>
29# include <iprt/semaphore.h>
30# include <iprt/thread.h>
31# include <iprt/time.h>
32# include <iprt/alloc.h>
33#endif /* IN_RING3 */
34#include <iprt/critsect.h>
35#include <iprt/asm.h>
36#include <VBox/stam.h>
37#include <VBox/mm.h>
38#include <VBox/pgm.h>
39
40#include <VBox/scsi.h>
41
42#include "Builtins.h"
43#include "PIIX3ATABmDma.h"
44#include "ide.h"
45
46/**
47 * Maximum number of sectors to transfer in a READ/WRITE MULTIPLE request.
48 * Set to 1 to disable multi-sector read support. According to the ATA
49 * specification this must be a power of 2 and it must fit in an 8 bit
50 * value. Thus the only valid values are 1, 2, 4, 8, 16, 32, 64 and 128.
51 */
52#define ATA_MAX_MULT_SECTORS 128
53
54/**
55 * Fastest PIO mode supported by the drive.
56 */
57#define ATA_PIO_MODE_MAX 4
58/**
59 * Fastest MDMA mode supported by the drive.
60 */
61#define ATA_MDMA_MODE_MAX 2
62/**
63 * Fastest UDMA mode supported by the drive.
64 */
65#define ATA_UDMA_MODE_MAX 6
66
67
68/**
69 * The SSM saved state version.
70 */
71#define ATA_SAVED_STATE_VERSION 16
72
73/** The maximum number of release log entries per device. */
74#define MAX_LOG_REL_ERRORS 1024
75
76typedef struct ATADevState {
77 /** Flag indicating whether the current command uses LBA48 mode. */
78 bool fLBA48;
79 /** Flag indicating whether this drive implements the ATAPI command set. */
80 bool fATAPI;
81 /** Set if this interface has asserted the IRQ. */
82 bool fIrqPending;
83 /** Currently configured number of sectors in a multi-sector transfer. */
84 uint8_t cMultSectors;
85 /** PCHS disk geometry. */
86 uint32_t cCHSCylinders, cCHSHeads, cCHSSectors;
87 /** Total number of sectors on this disk. */
88 uint64_t cTotalSectors;
89 /** Number of sectors to transfer per IRQ. */
90 uint32_t cSectorsPerIRQ;
91
92 /** ATA/ATAPI register 1: feature (write-only). */
93 uint8_t uATARegFeature;
94 /** ATA/ATAPI register 1: feature, high order byte. */
95 uint8_t uATARegFeatureHOB;
96 /** ATA/ATAPI register 1: error (read-only). */
97 uint8_t uATARegError;
98 /** ATA/ATAPI register 2: sector count (read/write). */
99 uint8_t uATARegNSector;
100 /** ATA/ATAPI register 2: sector count, high order byte. */
101 uint8_t uATARegNSectorHOB;
102 /** ATA/ATAPI register 3: sector (read/write). */
103 uint8_t uATARegSector;
104 /** ATA/ATAPI register 3: sector, high order byte. */
105 uint8_t uATARegSectorHOB;
106 /** ATA/ATAPI register 4: cylinder low (read/write). */
107 uint8_t uATARegLCyl;
108 /** ATA/ATAPI register 4: cylinder low, high order byte. */
109 uint8_t uATARegLCylHOB;
110 /** ATA/ATAPI register 5: cylinder high (read/write). */
111 uint8_t uATARegHCyl;
112 /** ATA/ATAPI register 5: cylinder high, high order byte. */
113 uint8_t uATARegHCylHOB;
114 /** ATA/ATAPI register 6: select drive/head (read/write). */
115 uint8_t uATARegSelect;
116 /** ATA/ATAPI register 7: status (read-only). */
117 uint8_t uATARegStatus;
118 /** ATA/ATAPI register 7: command (write-only). */
119 uint8_t uATARegCommand;
120 /** ATA/ATAPI drive control register (write-only). */
121 uint8_t uATARegDevCtl;
122
123 /** Currently active transfer mode (MDMA/UDMA) and speed. */
124 uint8_t uATATransferMode;
125 /** Current transfer direction. */
126 uint8_t uTxDir;
127 /** Index of callback for begin transfer. */
128 uint8_t iBeginTransfer;
129 /** Index of callback for source/sink of data. */
130 uint8_t iSourceSink;
131 /** Flag indicating whether the current command transfers data in DMA mode. */
132 bool fDMA;
133 /** Set to indicate that ATAPI transfer semantics must be used. */
134 bool fATAPITransfer;
135
136 /** Total ATA/ATAPI transfer size, shared PIO/DMA. */
137 uint32_t cbTotalTransfer;
138 /** Elementary ATA/ATAPI transfer size, shared PIO/DMA. */
139 uint32_t cbElementaryTransfer;
140 /** Current read/write buffer position, shared PIO/DMA. */
141 uint32_t iIOBufferCur;
142 /** First element beyond end of valid buffer content, shared PIO/DMA. */
143 uint32_t iIOBufferEnd;
144
145 /** ATA/ATAPI current PIO read/write transfer position. Not shared with DMA for safety reasons. */
146 uint32_t iIOBufferPIODataStart;
147 /** ATA/ATAPI current PIO read/write transfer end. Not shared with DMA for safety reasons. */
148 uint32_t iIOBufferPIODataEnd;
149
150 /** ATAPI current LBA position. */
151 uint32_t iATAPILBA;
152 /** ATAPI current sector size. */
153 uint32_t cbATAPISector;
154 /** ATAPI current command. */
155 uint8_t aATAPICmd[ATAPI_PACKET_SIZE];
156 /** ATAPI sense key. */
157 uint8_t uATAPISenseKey;
158 /** ATAPI additional sense code. */
159 uint8_t uATAPIASC;
160 /** HACK: Countdown till we report a newly unmounted drive as mounted. */
161 uint8_t cNotifiedMediaChange;
162
163 /** The status LED state for this drive. */
164 PDMLED Led;
165
166 /** Size of I/O buffer. */
167 uint32_t cbIOBuffer;
168 /** Pointer to the I/O buffer. */
169 R3R0PTRTYPE(uint8_t *) pbIOBufferHC;
170 /** Pointer to the I/O buffer. */
171 GCPTRTYPE(uint8_t *) pbIOBufferGC;
172#if HC_ARCH_BITS == 64 && GC_ARCH_BITS != 64
173 RTGCPTR Aligmnent0; /**< Align the statistics at an 8-byte boundrary. */
174#endif
175
176 /*
177 * No data that is part of the saved state after this point!!!!!
178 */
179
180 /* Release statistics: number of ATA DMA commands. */
181 STAMCOUNTER StatATADMA;
182 /* Release statistics: number of ATA PIO commands. */
183 STAMCOUNTER StatATAPIO;
184 /* Release statistics: number of ATAPI PIO commands. */
185 STAMCOUNTER StatATAPIDMA;
186 /* Release statistics: number of ATAPI PIO commands. */
187 STAMCOUNTER StatATAPIPIO;
188
189 /** Statistics: number of read operations and the time spent reading. */
190 STAMPROFILEADV StatReads;
191 /** Statistics: number of bytes read. */
192 STAMCOUNTER StatBytesRead;
193 /** Statistics: number of write operations and the time spent writing. */
194 STAMPROFILEADV StatWrites;
195 /** Statistics: number of bytes written. */
196 STAMCOUNTER StatBytesWritten;
197 /** Statistics: number of flush operations and the time spend flushing. */
198 STAMPROFILE StatFlushes;
199
200 /** Enable passing through commands directly to the ATAPI drive. */
201 bool fATAPIPassthrough;
202 /** Number of errors we've reported to the release log.
203 * This is to prevent flooding caused by something going horribly wrong.
204 * this value against MAX_LOG_REL_ERRORS in places likely to cause floods
205 * like the ones we currently seeing on the linux smoke tests (2006-11-10). */
206 uint32_t cErrors;
207 /** Timestamp of last started command. 0 if no command pending. */
208 uint64_t u64CmdTS;
209
210 /** Pointer to the attached driver's base interface. */
211 R3PTRTYPE(PPDMIBASE) pDrvBase;
212 /** Pointer to the attached driver's block interface. */
213 R3PTRTYPE(PPDMIBLOCK) pDrvBlock;
214 /** Pointer to the attached driver's block bios interface. */
215 R3PTRTYPE(PPDMIBLOCKBIOS) pDrvBlockBios;
216 /** Pointer to the attached driver's mount interface.
217 * This is NULL if the driver isn't a removable unit. */
218 R3PTRTYPE(PPDMIMOUNT) pDrvMount;
219 /** The base interface. */
220 PDMIBASE IBase;
221 /** The block port interface. */
222 PDMIBLOCKPORT IPort;
223 /** The mount notify interface. */
224 PDMIMOUNTNOTIFY IMountNotify;
225 /** The LUN #. */
226 RTUINT iLUN;
227#if HC_ARCH_BITS == 64
228 RTUINT Alignment2; /**< Align pDevInsHC correctly. */
229#endif
230 /** Pointer to device instance. */
231 R3R0PTRTYPE(PPDMDEVINS) pDevInsHC;
232 /** Pointer to controller instance. */
233 R3R0PTRTYPE(struct ATACONTROLLER *) pControllerHC;
234 /** Pointer to device instance. */
235 GCPTRTYPE(PPDMDEVINS) pDevInsGC;
236 /** Pointer to controller instance. */
237 GCPTRTYPE(struct ATACONTROLLER *) pControllerGC;
238} ATADevState;
239
240
241typedef struct ATATransferRequest
242{
243 uint8_t iIf;
244 uint8_t iBeginTransfer;
245 uint8_t iSourceSink;
246 uint32_t cbTotalTransfer;
247 uint8_t uTxDir;
248} ATATransferRequest;
249
250
251typedef struct ATAAbortRequest
252{
253 uint8_t iIf;
254 bool fResetDrive;
255} ATAAbortRequest;
256
257
258typedef enum
259{
260 /** Begin a new transfer. */
261 ATA_AIO_NEW = 0,
262 /** Continue a DMA transfer. */
263 ATA_AIO_DMA,
264 /** Continue a PIO transfer. */
265 ATA_AIO_PIO,
266 /** Reset the drives on current controller, stop all transfer activity. */
267 ATA_AIO_RESET_ASSERTED,
268 /** Reset the drives on current controller, resume operation. */
269 ATA_AIO_RESET_CLEARED,
270 /** Abort the current transfer of a particular drive. */
271 ATA_AIO_ABORT
272} ATAAIO;
273
274
275typedef struct ATARequest
276{
277 ATAAIO ReqType;
278 union
279 {
280 ATATransferRequest t;
281 ATAAbortRequest a;
282 } u;
283} ATARequest;
284
285
286typedef struct ATACONTROLLER
287{
288 /** The base of the first I/O Port range. */
289 RTIOPORT IOPortBase1;
290 /** The base of the second I/O Port range. (0 if none) */
291 RTIOPORT IOPortBase2;
292 /** The assigned IRQ. */
293 RTUINT irq;
294 /** Access critical section */
295 PDMCRITSECT lock;
296
297 /** Selected drive. */
298 uint8_t iSelectedIf;
299 /** The interface on which to handle async I/O. */
300 uint8_t iAIOIf;
301 /** The state of the async I/O thread. */
302 uint8_t uAsyncIOState;
303 /** Flag indicating whether the next transfer is part of the current command. */
304 bool fChainedTransfer;
305 /** Set when the reset processing is currently active on this controller. */
306 bool fReset;
307 /** Flag whether the current transfer needs to be redone. */
308 bool fRedo;
309 /** Flag whether the redo suspend has been finished. */
310 bool fRedoIdle;
311 /** Flag whether the DMA operation to be redone is the final transfer. */
312 bool fRedoDMALastDesc;
313 /** The BusMaster DMA state. */
314 BMDMAState BmDma;
315 /** Pointer to first DMA descriptor. */
316 RTGCPHYS pFirstDMADesc;
317 /** Pointer to last DMA descriptor. */
318 RTGCPHYS pLastDMADesc;
319 /** Pointer to current DMA buffer (for redo operations). */
320 RTGCPHYS pRedoDMABuffer;
321 /** Size of current DMA buffer (for redo operations). */
322 uint32_t cbRedoDMABuffer;
323
324 /** The ATA/ATAPI interfaces of this controller. */
325 ATADevState aIfs[2];
326
327 /** Pointer to device instance. */
328 R3R0PTRTYPE(PPDMDEVINS) pDevInsHC;
329 /** Pointer to device instance. */
330 GCPTRTYPE(PPDMDEVINS) pDevInsGC;
331
332 /** Set when the destroying the device instance and the thread must exit. */
333 uint32_t volatile fShutdown;
334 /** The async I/O thread handle. NIL_RTTHREAD if no thread. */
335 RTTHREAD AsyncIOThread;
336 /** The event semaphore the thread is waiting on for requests. */
337 RTSEMEVENT AsyncIOSem;
338 /** The request queue for the AIO thread. One element is always unused. */
339 ATARequest aAsyncIORequests[4];
340 /** The position at which to insert a new request for the AIO thread. */
341 uint8_t AsyncIOReqHead;
342 /** The position at which to get a new request for the AIO thread. */
343 uint8_t AsyncIOReqTail;
344 uint8_t Alignment3[2]; /**< Explicit padding of the 2 byte gap. */
345 /** Magic delay before triggering interrupts in DMA mode. */
346 uint32_t DelayIRQMillies;
347 /** The mutex protecting the request queue. */
348 RTSEMMUTEX AsyncIORequestMutex;
349 /** The event semaphore the thread is waiting on during suspended I/O. */
350 RTSEMEVENT SuspendIOSem;
351#if HC_ARCH_BITS == 32
352 uint32_t Alignment0;
353#endif
354
355 /* Statistics */
356 STAMCOUNTER StatAsyncOps;
357 uint64_t StatAsyncMinWait;
358 uint64_t StatAsyncMaxWait;
359 STAMCOUNTER StatAsyncTimeUS;
360 STAMPROFILEADV StatAsyncTime;
361 STAMPROFILE StatLockWait;
362} ATACONTROLLER, *PATACONTROLLER;
363
364typedef struct PCIATAState {
365 PCIDEVICE dev;
366 /** The controllers. */
367 ATACONTROLLER aCts[2];
368 /** Pointer to device instance. */
369 PPDMDEVINSR3 pDevIns;
370 /** Status Port - Base interface. */
371 PDMIBASE IBase;
372 /** Status Port - Leds interface. */
373 PDMILEDPORTS ILeds;
374 /** Partner of ILeds. */
375 R3PTRTYPE(PPDMILEDCONNECTORS) pLedsConnector;
376 /** Flag whether GC is enabled. */
377 bool fGCEnabled;
378 /** Flag whether R0 is enabled. */
379 bool fR0Enabled;
380 /** Flag indicating whether PIIX4 or PIIX3 is being emulated. */
381 bool fPIIX4;
382 bool Alignment0[HC_ARCH_BITS == 64 ? 5 : 1]; /**< Align the struct size. */
383} PCIATAState;
384
385#define ATADEVSTATE_2_CONTROLLER(pIf) ( (pIf)->CTXSUFF(pController) )
386#define ATADEVSTATE_2_DEVINS(pIf) ( (pIf)->CTXSUFF(pDevIns) )
387#define CONTROLLER_2_DEVINS(pController) ( (pController)->CTXSUFF(pDevIns) )
388#define PDMIBASE_2_PCIATASTATE(pInterface) ( (PCIATAState *)((uintptr_t)(pInterface) - RT_OFFSETOF(PCIATAState, IBase)) )
389#define PDMILEDPORTS_2_PCIATASTATE(pInterface) ( (PCIATAState *)((uintptr_t)(pInterface) - RT_OFFSETOF(PCIATAState, ILeds)) )
390#define PDMIBASE_2_ATASTATE(pInterface) ( (ATADevState *)((uintptr_t)(pInterface) - RT_OFFSETOF(ATADevState, IBase)) )
391#define PDMIBLOCKPORT_2_ATASTATE(pInterface) ( (ATADevState *)((uintptr_t)(pInterface) - RT_OFFSETOF(ATADevState, IPort)) )
392#define PDMIMOUNT_2_ATASTATE(pInterface) ( (ATADevState *)((uintptr_t)(pInterface) - RT_OFFSETOF(ATADevState, IMount)) )
393#define PDMIMOUNTNOTIFY_2_ATASTATE(pInterface) ( (ATADevState *)((uintptr_t)(pInterface) - RT_OFFSETOF(ATADevState, IMountNotify)) )
394#define PCIDEV_2_PCIATASTATE(pPciDev) ( (PCIATAState *)(pPciDev) )
395
396#define ATACONTROLLER_IDX(pController) ( (pController) - PDMINS2DATA(CONTROLLER_2_DEVINS(pController), PCIATAState *)->aCts )
397
398
399#ifndef VBOX_DEVICE_STRUCT_TESTCASE
400/*******************************************************************************
401 * Internal Functions *
402 ******************************************************************************/
403__BEGIN_DECLS
404PDMBOTHCBDECL(int) ataIOPortWrite1(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
405PDMBOTHCBDECL(int) ataIOPortRead1(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *u32, unsigned cb);
406PDMBOTHCBDECL(int) ataIOPortWriteStr1(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, RTGCPTR *pGCPtrSrc, unsigned *pcTransfer, unsigned cb);
407PDMBOTHCBDECL(int) ataIOPortReadStr1(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, RTGCPTR *pGCPtrDst, unsigned *pcTransfer, unsigned cb);
408PDMBOTHCBDECL(int) ataIOPortWrite2(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
409PDMBOTHCBDECL(int) ataIOPortRead2(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *u32, unsigned cb);
410PDMBOTHCBDECL(int) ataBMDMAIOPortWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
411PDMBOTHCBDECL(int) ataBMDMAIOPortRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb);
412__END_DECLS
413
414
415
416DECLINLINE(void) ataSetStatusValue(ATADevState *s, uint8_t stat)
417{
418 PATACONTROLLER pCtl = ATADEVSTATE_2_CONTROLLER(s);
419
420 /* Freeze status register contents while processing RESET. */
421 if (!pCtl->fReset)
422 {
423 s->uATARegStatus = stat;
424 Log2(("%s: LUN#%d status %#04x\n", __FUNCTION__, s->iLUN, s->uATARegStatus));
425 }
426}
427
428
429DECLINLINE(void) ataSetStatus(ATADevState *s, uint8_t stat)
430{
431 PATACONTROLLER pCtl = ATADEVSTATE_2_CONTROLLER(s);
432
433 /* Freeze status register contents while processing RESET. */
434 if (!pCtl->fReset)
435 {
436 s->uATARegStatus |= stat;
437 Log2(("%s: LUN#%d status %#04x\n", __FUNCTION__, s->iLUN, s->uATARegStatus));
438 }
439}
440
441
442DECLINLINE(void) ataUnsetStatus(ATADevState *s, uint8_t stat)
443{
444 PATACONTROLLER pCtl = ATADEVSTATE_2_CONTROLLER(s);
445
446 /* Freeze status register contents while processing RESET. */
447 if (!pCtl->fReset)
448 {
449 s->uATARegStatus &= ~stat;
450 Log2(("%s: LUN#%d status %#04x\n", __FUNCTION__, s->iLUN, s->uATARegStatus));
451 }
452}
453
454#ifdef IN_RING3
455
456typedef void (*PBeginTransferFunc)(ATADevState *);
457typedef bool (*PSourceSinkFunc)(ATADevState *);
458
459static void ataReadWriteSectorsBT(ATADevState *);
460static void ataPacketBT(ATADevState *);
461static void atapiCmdBT(ATADevState *);
462static void atapiPassthroughCmdBT(ATADevState *);
463
464static bool ataIdentifySS(ATADevState *);
465static bool ataFlushSS(ATADevState *);
466static bool ataReadSectorsSS(ATADevState *);
467static bool ataWriteSectorsSS(ATADevState *);
468static bool ataExecuteDeviceDiagnosticSS(ATADevState *);
469static bool ataPacketSS(ATADevState *);
470static bool atapiGetConfigurationSS(ATADevState *);
471static bool atapiIdentifySS(ATADevState *);
472static bool atapiInquirySS(ATADevState *);
473static bool atapiMechanismStatusSS(ATADevState *);
474static bool atapiModeSenseErrorRecoverySS(ATADevState *);
475static bool atapiModeSenseCDStatusSS(ATADevState *);
476static bool atapiReadSS(ATADevState *);
477static bool atapiReadCapacitySS(ATADevState *);
478static bool atapiReadDiscInformationSS(ATADevState *);
479static bool atapiReadTOCNormalSS(ATADevState *);
480static bool atapiReadTOCMultiSS(ATADevState *);
481static bool atapiReadTOCRawSS(ATADevState *);
482static bool atapiReadTrackInformationSS(ATADevState *);
483static bool atapiRequestSenseSS(ATADevState *);
484static bool atapiPassthroughSS(ATADevState *);
485
486/**
487 * Begin of transfer function indexes for g_apfnBeginTransFuncs.
488 */
489typedef enum ATAFNBT
490{
491 ATAFN_BT_NULL = 0,
492 ATAFN_BT_READ_WRITE_SECTORS,
493 ATAFN_BT_PACKET,
494 ATAFN_BT_ATAPI_CMD,
495 ATAFN_BT_ATAPI_PASSTHROUGH_CMD,
496 ATAFN_BT_MAX
497} ATAFNBT;
498
499/**
500 * Array of end transfer functions, the index is ATAFNET.
501 * Make sure ATAFNET and this array match!
502 */
503static const PBeginTransferFunc g_apfnBeginTransFuncs[ATAFN_BT_MAX] =
504{
505 NULL,
506 ataReadWriteSectorsBT,
507 ataPacketBT,
508 atapiCmdBT,
509 atapiPassthroughCmdBT,
510};
511
512/**
513 * Source/sink function indexes for g_apfnSourceSinkFuncs.
514 */
515typedef enum ATAFNSS
516{
517 ATAFN_SS_NULL = 0,
518 ATAFN_SS_IDENTIFY,
519 ATAFN_SS_FLUSH,
520 ATAFN_SS_READ_SECTORS,
521 ATAFN_SS_WRITE_SECTORS,
522 ATAFN_SS_EXECUTE_DEVICE_DIAGNOSTIC,
523 ATAFN_SS_PACKET,
524 ATAFN_SS_ATAPI_GET_CONFIGURATION,
525 ATAFN_SS_ATAPI_IDENTIFY,
526 ATAFN_SS_ATAPI_INQUIRY,
527 ATAFN_SS_ATAPI_MECHANISM_STATUS,
528 ATAFN_SS_ATAPI_MODE_SENSE_ERROR_RECOVERY,
529 ATAFN_SS_ATAPI_MODE_SENSE_CD_STATUS,
530 ATAFN_SS_ATAPI_READ,
531 ATAFN_SS_ATAPI_READ_CAPACITY,
532 ATAFN_SS_ATAPI_READ_DISC_INFORMATION,
533 ATAFN_SS_ATAPI_READ_TOC_NORMAL,
534 ATAFN_SS_ATAPI_READ_TOC_MULTI,
535 ATAFN_SS_ATAPI_READ_TOC_RAW,
536 ATAFN_SS_ATAPI_READ_TRACK_INFORMATION,
537 ATAFN_SS_ATAPI_REQUEST_SENSE,
538 ATAFN_SS_ATAPI_PASSTHROUGH,
539 ATAFN_SS_MAX
540} ATAFNSS;
541
542/**
543 * Array of source/sink functions, the index is ATAFNSS.
544 * Make sure ATAFNSS and this array match!
545 */
546static const PSourceSinkFunc g_apfnSourceSinkFuncs[ATAFN_SS_MAX] =
547{
548 NULL,
549 ataIdentifySS,
550 ataFlushSS,
551 ataReadSectorsSS,
552 ataWriteSectorsSS,
553 ataExecuteDeviceDiagnosticSS,
554 ataPacketSS,
555 atapiGetConfigurationSS,
556 atapiIdentifySS,
557 atapiInquirySS,
558 atapiMechanismStatusSS,
559 atapiModeSenseErrorRecoverySS,
560 atapiModeSenseCDStatusSS,
561 atapiReadSS,
562 atapiReadCapacitySS,
563 atapiReadDiscInformationSS,
564 atapiReadTOCNormalSS,
565 atapiReadTOCMultiSS,
566 atapiReadTOCRawSS,
567 atapiReadTrackInformationSS,
568 atapiRequestSenseSS,
569 atapiPassthroughSS
570};
571
572
573static const ATARequest ataDMARequest = { ATA_AIO_DMA, };
574static const ATARequest ataPIORequest = { ATA_AIO_PIO, };
575static const ATARequest ataResetARequest = { ATA_AIO_RESET_ASSERTED, };
576static const ATARequest ataResetCRequest = { ATA_AIO_RESET_CLEARED, };
577
578
579static void ataAsyncIOClearRequests(PATACONTROLLER pCtl)
580{
581 int rc;
582
583 rc = RTSemMutexRequest(pCtl->AsyncIORequestMutex, RT_INDEFINITE_WAIT);
584 AssertRC(rc);
585 pCtl->AsyncIOReqHead = 0;
586 pCtl->AsyncIOReqTail = 0;
587 rc = RTSemMutexRelease(pCtl->AsyncIORequestMutex);
588 AssertRC(rc);
589}
590
591
592static void ataAsyncIOPutRequest(PATACONTROLLER pCtl, const ATARequest *pReq)
593{
594 int rc;
595
596 rc = RTSemMutexRequest(pCtl->AsyncIORequestMutex, RT_INDEFINITE_WAIT);
597 AssertRC(rc);
598 Assert((pCtl->AsyncIOReqHead + 1) % RT_ELEMENTS(pCtl->aAsyncIORequests) != pCtl->AsyncIOReqTail);
599 memcpy(&pCtl->aAsyncIORequests[pCtl->AsyncIOReqHead], pReq, sizeof(*pReq));
600 pCtl->AsyncIOReqHead++;
601 pCtl->AsyncIOReqHead %= RT_ELEMENTS(pCtl->aAsyncIORequests);
602 rc = RTSemMutexRelease(pCtl->AsyncIORequestMutex);
603 AssertRC(rc);
604 LogBird(("ata: %x: signalling\n", pCtl->IOPortBase1));
605 rc = PDMR3CritSectScheduleExitEvent(&pCtl->lock, pCtl->AsyncIOSem);
606 if (VBOX_FAILURE(rc))
607 {
608 LogBird(("ata: %x: schedule failed, rc=%Vrc\n", pCtl->IOPortBase1, rc));
609 rc = RTSemEventSignal(pCtl->AsyncIOSem);
610 AssertRC(rc);
611 }
612}
613
614
615static const ATARequest *ataAsyncIOGetCurrentRequest(PATACONTROLLER pCtl)
616{
617 int rc;
618 const ATARequest *pReq;
619
620 rc = RTSemMutexRequest(pCtl->AsyncIORequestMutex, RT_INDEFINITE_WAIT);
621 AssertRC(rc);
622 if (pCtl->AsyncIOReqHead != pCtl->AsyncIOReqTail)
623 pReq = &pCtl->aAsyncIORequests[pCtl->AsyncIOReqTail];
624 else
625 pReq = NULL;
626 rc = RTSemMutexRelease(pCtl->AsyncIORequestMutex);
627 AssertRC(rc);
628 return pReq;
629}
630
631
632/**
633 * Remove the request with the given type, as it's finished. The request
634 * is not removed blindly, as this could mean a RESET request that is not
635 * yet processed (but has cleared the request queue) is lost.
636 *
637 * @param pCtl Controller for which to remove the request.
638 * @param ReqType Type of the request to remove.
639 */
640static void ataAsyncIORemoveCurrentRequest(PATACONTROLLER pCtl, ATAAIO ReqType)
641{
642 int rc;
643
644 rc = RTSemMutexRequest(pCtl->AsyncIORequestMutex, RT_INDEFINITE_WAIT);
645 AssertRC(rc);
646 if (pCtl->AsyncIOReqHead != pCtl->AsyncIOReqTail && pCtl->aAsyncIORequests[pCtl->AsyncIOReqTail].ReqType == ReqType)
647 {
648 pCtl->AsyncIOReqTail++;
649 pCtl->AsyncIOReqTail %= RT_ELEMENTS(pCtl->aAsyncIORequests);
650 }
651 rc = RTSemMutexRelease(pCtl->AsyncIORequestMutex);
652 AssertRC(rc);
653}
654
655
656/**
657 * Dump the request queue for a particular controller. First dump the queue
658 * contents, then the already processed entries, as long as they haven't been
659 * overwritten.
660 *
661 * @param pCtl Controller for which to dump the queue.
662 */
663static void ataAsyncIODumpRequests(PATACONTROLLER pCtl)
664{
665 int rc;
666 uint8_t curr;
667
668 rc = RTSemMutexRequest(pCtl->AsyncIORequestMutex, RT_INDEFINITE_WAIT);
669 AssertRC(rc);
670 LogRel(("PIIX3 ATA: Ctl#%d: request queue dump (topmost is current):\n", ATACONTROLLER_IDX(pCtl)));
671 curr = pCtl->AsyncIOReqTail;
672 do
673 {
674 if (curr == pCtl->AsyncIOReqHead)
675 LogRel(("PIIX3 ATA: Ctl#%d: processed requests (topmost is oldest):\n", ATACONTROLLER_IDX(pCtl)));
676 switch (pCtl->aAsyncIORequests[curr].ReqType)
677 {
678 case ATA_AIO_NEW:
679 LogRel(("new transfer request, iIf=%d iBeginTransfer=%d iSourceSink=%d cbTotalTransfer=%d uTxDir=%d\n", pCtl->aAsyncIORequests[curr].u.t.iIf, pCtl->aAsyncIORequests[curr].u.t.iBeginTransfer, pCtl->aAsyncIORequests[curr].u.t.iSourceSink, pCtl->aAsyncIORequests[curr].u.t.cbTotalTransfer, pCtl->aAsyncIORequests[curr].u.t.uTxDir));
680 break;
681 case ATA_AIO_DMA:
682 LogRel(("dma transfer finished\n"));
683 break;
684 case ATA_AIO_PIO:
685 LogRel(("pio transfer finished\n"));
686 break;
687 case ATA_AIO_RESET_ASSERTED:
688 LogRel(("reset asserted request\n"));
689 break;
690 case ATA_AIO_RESET_CLEARED:
691 LogRel(("reset cleared request\n"));
692 break;
693 case ATA_AIO_ABORT:
694 LogRel(("abort request, iIf=%d fResetDrive=%d\n", pCtl->aAsyncIORequests[curr].u.a.iIf, pCtl->aAsyncIORequests[curr].u.a.fResetDrive));
695 break;
696 default:
697 LogRel(("unknown request %d\n", pCtl->aAsyncIORequests[curr].ReqType));
698 }
699 curr = (curr + 1) % RT_ELEMENTS(pCtl->aAsyncIORequests);
700 } while (curr != pCtl->AsyncIOReqTail);
701 rc = RTSemMutexRelease(pCtl->AsyncIORequestMutex);
702 AssertRC(rc);
703}
704
705
706/**
707 * Checks whether the request queue for a particular controller is empty
708 * or whether a particular controller is idle.
709 *
710 * @param pCtl Controller for which to check the queue.
711 * @param fStrict If set then the controller is checked to be idle.
712 */
713static bool ataAsyncIOIsIdle(PATACONTROLLER pCtl, bool fStrict)
714{
715 int rc;
716 bool fIdle;
717
718 rc = RTSemMutexRequest(pCtl->AsyncIORequestMutex, RT_INDEFINITE_WAIT);
719 AssertRC(rc);
720 fIdle = pCtl->fRedoIdle;
721 if (!fIdle)
722 fIdle = (pCtl->AsyncIOReqHead == pCtl->AsyncIOReqTail);
723 if (fStrict)
724 fIdle &= (pCtl->uAsyncIOState == ATA_AIO_NEW);
725 rc = RTSemMutexRelease(pCtl->AsyncIORequestMutex);
726 AssertRC(rc);
727 return fIdle;
728}
729
730
731/**
732 * Send a transfer request to the async I/O thread.
733 *
734 * @param s Pointer to the ATA device state data.
735 * @param cbTotalTransfer Data transfer size.
736 * @param uTxDir Data transfer direction.
737 * @param iBeginTransfer Index of BeginTransfer callback.
738 * @param iSourceSink Index of SourceSink callback.
739 * @param fChainedTransfer Whether this is a transfer that is part of the previous command/transfer.
740 */
741static void ataStartTransfer(ATADevState *s, uint32_t cbTotalTransfer, uint8_t uTxDir, ATAFNBT iBeginTransfer, ATAFNSS iSourceSink, bool fChainedTransfer)
742{
743 PATACONTROLLER pCtl = ATADEVSTATE_2_CONTROLLER(s);
744 ATARequest Req;
745
746 Assert(PDMCritSectIsOwner(&pCtl->lock));
747
748 /* Do not issue new requests while the RESET line is asserted. */
749 if (pCtl->fReset)
750 {
751 Log2(("%s: Ctl#%d: suppressed new request as RESET is active\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
752 return;
753 }
754
755 /* If the controller is already doing something else right now, ignore
756 * the command that is being submitted. Some broken guests issue commands
757 * twice (e.g. the Linux kernel that comes with Acronis True Image 8). */
758 if (!fChainedTransfer && !ataAsyncIOIsIdle(pCtl, true))
759 {
760 Log(("%s: Ctl#%d: ignored command %#04x, controller state %d\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl), s->uATARegCommand, pCtl->uAsyncIOState));
761 LogRel(("PIIX3 IDE: guest issued command %#04x while controller busy\n", s->uATARegCommand));
762 return;
763 }
764
765 Req.ReqType = ATA_AIO_NEW;
766 if (fChainedTransfer)
767 Req.u.t.iIf = pCtl->iAIOIf;
768 else
769 Req.u.t.iIf = pCtl->iSelectedIf;
770 Req.u.t.cbTotalTransfer = cbTotalTransfer;
771 Req.u.t.uTxDir = uTxDir;
772 Req.u.t.iBeginTransfer = iBeginTransfer;
773 Req.u.t.iSourceSink = iSourceSink;
774 ataSetStatusValue(s, ATA_STAT_BUSY);
775 pCtl->fChainedTransfer = fChainedTransfer;
776
777 /*
778 * Kick the worker thread into action.
779 */
780 Log2(("%s: Ctl#%d: message to async I/O thread, new request\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
781 ataAsyncIOPutRequest(pCtl, &Req);
782}
783
784
785/**
786 * Send an abort command request to the async I/O thread.
787 *
788 * @param s Pointer to the ATA device state data.
789 * @param fResetDrive Whether to reset the drive or just abort a command.
790 */
791static void ataAbortCurrentCommand(ATADevState *s, bool fResetDrive)
792{
793 PATACONTROLLER pCtl = ATADEVSTATE_2_CONTROLLER(s);
794 ATARequest Req;
795
796 Assert(PDMCritSectIsOwner(&pCtl->lock));
797
798 /* Do not issue new requests while the RESET line is asserted. */
799 if (pCtl->fReset)
800 {
801 Log2(("%s: Ctl#%d: suppressed aborting command as RESET is active\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
802 return;
803 }
804
805 Req.ReqType = ATA_AIO_ABORT;
806 Req.u.a.iIf = pCtl->iSelectedIf;
807 Req.u.a.fResetDrive = fResetDrive;
808 ataSetStatus(s, ATA_STAT_BUSY);
809 Log2(("%s: Ctl#%d: message to async I/O thread, abort command on LUN#%d\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl), s->iLUN));
810 ataAsyncIOPutRequest(pCtl, &Req);
811}
812
813
814static void ataSetIRQ(ATADevState *s)
815{
816 PATACONTROLLER pCtl = ATADEVSTATE_2_CONTROLLER(s);
817 PPDMDEVINS pDevIns = ATADEVSTATE_2_DEVINS(s);
818
819 if (!(s->uATARegDevCtl & ATA_DEVCTL_DISABLE_IRQ))
820 {
821 Log2(("%s: LUN#%d asserting IRQ\n", __FUNCTION__, s->iLUN));
822 /* The BMDMA unit unconditionally sets BM_STATUS_INT if the interrupt
823 * line is asserted. It monitors the line for a rising edge. */
824 if (!s->fIrqPending)
825 pCtl->BmDma.u8Status |= BM_STATUS_INT;
826 /* Only actually set the IRQ line if updating the currently selected drive. */
827 if (s == &pCtl->aIfs[pCtl->iSelectedIf])
828 {
829 /** @todo experiment with adaptive IRQ delivery: for reads it is
830 * better to wait for IRQ delivery, as it reduces latency. */
831 if (pCtl->irq == 16)
832 PDMDevHlpPCISetIrqNoWait(pDevIns, 0, 1);
833 else
834 PDMDevHlpISASetIrqNoWait(pDevIns, pCtl->irq, 1);
835 }
836 }
837 s->fIrqPending = true;
838}
839
840#endif /* IN_RING3 */
841
842static void ataUnsetIRQ(ATADevState *s)
843{
844 PATACONTROLLER pCtl = ATADEVSTATE_2_CONTROLLER(s);
845 PPDMDEVINS pDevIns = ATADEVSTATE_2_DEVINS(s);
846
847 if (!(s->uATARegDevCtl & ATA_DEVCTL_DISABLE_IRQ))
848 {
849 Log2(("%s: LUN#%d deasserting IRQ\n", __FUNCTION__, s->iLUN));
850 /* Only actually unset the IRQ line if updating the currently selected drive. */
851 if (s == &pCtl->aIfs[pCtl->iSelectedIf])
852 {
853 if (pCtl->irq == 16)
854 PDMDevHlpPCISetIrqNoWait(pDevIns, 0, 0);
855 else
856 PDMDevHlpISASetIrqNoWait(pDevIns, pCtl->irq, 0);
857 }
858 }
859 s->fIrqPending = false;
860}
861
862#ifdef IN_RING3
863
864static void ataPIOTransferStart(ATADevState *s, uint32_t start, uint32_t size)
865{
866 Log2(("%s: LUN#%d start %d size %d\n", __FUNCTION__, s->iLUN, start, size));
867 s->iIOBufferPIODataStart = start;
868 s->iIOBufferPIODataEnd = start + size;
869 ataSetStatus(s, ATA_STAT_DRQ);
870}
871
872
873static void ataPIOTransferStop(ATADevState *s)
874{
875 Log2(("%s: LUN#%d\n", __FUNCTION__, s->iLUN));
876 if (s->fATAPITransfer)
877 {
878 s->uATARegNSector = (s->uATARegNSector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
879 Log2(("%s: interrupt reason %#04x\n", __FUNCTION__, s->uATARegNSector));
880 ataSetIRQ(s);
881 s->fATAPITransfer = false;
882 }
883 s->cbTotalTransfer = 0;
884 s->cbElementaryTransfer = 0;
885 s->iIOBufferPIODataStart = 0;
886 s->iIOBufferPIODataEnd = 0;
887 s->iBeginTransfer = ATAFN_BT_NULL;
888 s->iSourceSink = ATAFN_SS_NULL;
889}
890
891
892static void ataPIOTransferLimitATAPI(ATADevState *s)
893{
894 uint32_t cbLimit, cbTransfer;
895
896 cbLimit = s->uATARegLCyl | (s->uATARegHCyl << 8);
897 /* Use maximum transfer size if the guest requested 0. Avoids a hang. */
898 if (cbLimit == 0)
899 cbLimit = 0xfffe;
900 Log2(("%s: byte count limit=%d\n", __FUNCTION__, cbLimit));
901 if (cbLimit == 0xffff)
902 cbLimit--;
903 cbTransfer = RT_MIN(s->cbTotalTransfer, s->iIOBufferEnd - s->iIOBufferCur);
904 if (cbTransfer > cbLimit)
905 {
906 /* Byte count limit for clipping must be even in this case */
907 if (cbLimit & 1)
908 cbLimit--;
909 cbTransfer = cbLimit;
910 }
911 s->uATARegLCyl = cbTransfer;
912 s->uATARegHCyl = cbTransfer >> 8;
913 s->cbElementaryTransfer = cbTransfer;
914}
915
916
917static uint32_t ataGetNSectors(ATADevState *s)
918{
919 /* 0 means either 256 (LBA28) or 65536 (LBA48) sectors. */
920 if (s->fLBA48)
921 {
922 if (!s->uATARegNSector && !s->uATARegNSectorHOB)
923 return 65536;
924 else
925 return s->uATARegNSectorHOB << 8 | s->uATARegNSector;
926 }
927 else
928 {
929 if (!s->uATARegNSector)
930 return 256;
931 else
932 return s->uATARegNSector;
933 }
934}
935
936
937static void ataPadString(uint8_t *pbDst, const char *pbSrc, uint32_t cbSize)
938{
939 for (uint32_t i = 0; i < cbSize; i++)
940 {
941 if (*pbSrc)
942 pbDst[i ^ 1] = *pbSrc++;
943 else
944 pbDst[i ^ 1] = ' ';
945 }
946}
947
948
949static void ataSCSIPadStr(uint8_t *pbDst, const char *pbSrc, uint32_t cbSize)
950{
951 for (uint32_t i = 0; i < cbSize; i++)
952 {
953 if (*pbSrc)
954 pbDst[i] = *pbSrc++;
955 else
956 pbDst[i] = ' ';
957 }
958}
959
960
961DECLINLINE(void) ataH2BE_U16(uint8_t *pbBuf, uint16_t val)
962{
963 pbBuf[0] = val >> 8;
964 pbBuf[1] = val;
965}
966
967
968DECLINLINE(void) ataH2BE_U24(uint8_t *pbBuf, uint32_t val)
969{
970 pbBuf[0] = val >> 16;
971 pbBuf[1] = val >> 8;
972 pbBuf[2] = val;
973}
974
975
976DECLINLINE(void) ataH2BE_U32(uint8_t *pbBuf, uint32_t val)
977{
978 pbBuf[0] = val >> 24;
979 pbBuf[1] = val >> 16;
980 pbBuf[2] = val >> 8;
981 pbBuf[3] = val;
982}
983
984
985DECLINLINE(uint16_t) ataBE2H_U16(const uint8_t *pbBuf)
986{
987 return (pbBuf[0] << 8) | pbBuf[1];
988}
989
990
991DECLINLINE(uint32_t) ataBE2H_U24(const uint8_t *pbBuf)
992{
993 return (pbBuf[0] << 16) | (pbBuf[1] << 8) | pbBuf[2];
994}
995
996
997DECLINLINE(uint32_t) ataBE2H_U32(const uint8_t *pbBuf)
998{
999 return (pbBuf[0] << 24) | (pbBuf[1] << 16) | (pbBuf[2] << 8) | pbBuf[3];
1000}
1001
1002
1003DECLINLINE(void) ataLBA2MSF(uint8_t *pbBuf, uint32_t iATAPILBA)
1004{
1005 iATAPILBA += 150;
1006 pbBuf[0] = (iATAPILBA / 75) / 60;
1007 pbBuf[1] = (iATAPILBA / 75) % 60;
1008 pbBuf[2] = iATAPILBA % 75;
1009}
1010
1011
1012DECLINLINE(uint32_t) ataMSF2LBA(const uint8_t *pbBuf)
1013{
1014 return (pbBuf[0] * 60 + pbBuf[1]) * 75 + pbBuf[2];
1015}
1016
1017
1018static void ataCmdOK(ATADevState *s, uint8_t status)
1019{
1020 s->uATARegError = 0; /* Not needed by ATA spec, but cannot hurt. */
1021 ataSetStatusValue(s, ATA_STAT_READY | status);
1022}
1023
1024
1025static void ataCmdError(ATADevState *s, uint8_t uErrorCode)
1026{
1027 Log(("%s: code=%#x\n", __FUNCTION__, uErrorCode));
1028 s->uATARegError = uErrorCode;
1029 ataSetStatusValue(s, ATA_STAT_READY | ATA_STAT_ERR);
1030 s->cbTotalTransfer = 0;
1031 s->cbElementaryTransfer = 0;
1032 s->iIOBufferCur = 0;
1033 s->iIOBufferEnd = 0;
1034 s->uTxDir = PDMBLOCKTXDIR_NONE;
1035 s->iBeginTransfer = ATAFN_BT_NULL;
1036 s->iSourceSink = ATAFN_SS_NULL;
1037}
1038
1039
1040static bool ataIdentifySS(ATADevState *s)
1041{
1042 uint16_t *p;
1043 char aSerial[20];
1044 int rc;
1045 RTUUID Uuid;
1046
1047 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
1048 Assert(s->cbElementaryTransfer == 512);
1049 rc = s->pDrvBlock ? s->pDrvBlock->pfnGetUuid(s->pDrvBlock, &Uuid) : RTUuidClear(&Uuid);
1050 if (VBOX_FAILURE(rc) || RTUuidIsNull(&Uuid))
1051 {
1052 PATACONTROLLER pCtl = ATADEVSTATE_2_CONTROLLER(s);
1053 /* Generate a predictable serial for drives which don't have a UUID. */
1054 RTStrPrintf(aSerial, sizeof(aSerial), "VB%x-%04x%04x",
1055 s->iLUN + ATADEVSTATE_2_DEVINS(s)->iInstance * 32,
1056 pCtl->IOPortBase1, pCtl->IOPortBase2);
1057 }
1058 else
1059 RTStrPrintf(aSerial, sizeof(aSerial), "VB%08x-%08x", Uuid.au32[0], Uuid.au32[3]);
1060
1061 p = (uint16_t *)s->CTXSUFF(pbIOBuffer);
1062 memset(p, 0, 512);
1063 p[0] = RT_H2LE_U16(0x0040);
1064 p[1] = RT_H2LE_U16(RT_MIN(s->cCHSCylinders, 16383));
1065 p[3] = RT_H2LE_U16(s->cCHSHeads);
1066 /* Block size; obsolete, but required for the BIOS. */
1067 p[5] = RT_H2LE_U16(512);
1068 p[6] = RT_H2LE_U16(s->cCHSSectors);
1069 ataPadString((uint8_t *)(p + 10), aSerial, 20); /* serial number */
1070 p[20] = RT_H2LE_U16(3); /* XXX: retired, cache type */
1071 p[21] = RT_H2LE_U16(512); /* XXX: retired, cache size in sectors */
1072 p[22] = RT_H2LE_U16(0); /* ECC bytes per sector */
1073 ataPadString((uint8_t *)(p + 23), "1.0", 8); /* firmware version */
1074 ataPadString((uint8_t *)(p + 27), "VBOX HARDDISK", 40); /* model */
1075#if ATA_MAX_MULT_SECTORS > 1
1076 p[47] = RT_H2LE_U16(0x8000 | ATA_MAX_MULT_SECTORS);
1077#endif
1078 p[48] = RT_H2LE_U16(1); /* dword I/O, used by the BIOS */
1079 p[49] = RT_H2LE_U16(1 << 11 | 1 << 9 | 1 << 8); /* DMA and LBA supported */
1080 p[50] = RT_H2LE_U16(1 << 14); /* No drive specific standby timer minimum */
1081 p[51] = RT_H2LE_U16(240); /* PIO transfer cycle */
1082 p[52] = RT_H2LE_U16(240); /* DMA transfer cycle */
1083 p[53] = RT_H2LE_U16(1 | 1 << 1 | 1 << 2); /* words 54-58,64-70,88 valid */
1084 p[54] = RT_H2LE_U16(RT_MIN(s->cCHSCylinders, 16383));
1085 p[55] = RT_H2LE_U16(s->cCHSHeads);
1086 p[56] = RT_H2LE_U16(s->cCHSSectors);
1087 p[57] = RT_H2LE_U16(RT_MIN(s->cCHSCylinders, 16383) * s->cCHSHeads * s->cCHSSectors);
1088 p[58] = RT_H2LE_U16(RT_MIN(s->cCHSCylinders, 16383) * s->cCHSHeads * s->cCHSSectors >> 16);
1089 if (s->cMultSectors)
1090 p[59] = RT_H2LE_U16(0x100 | s->cMultSectors);
1091 if (s->cTotalSectors <= (1 << 28) - 1)
1092 {
1093 p[60] = RT_H2LE_U16(s->cTotalSectors);
1094 p[61] = RT_H2LE_U16(s->cTotalSectors >> 16);
1095 }
1096 else
1097 {
1098 /* Report maximum number of sectors possible with LBA28 */
1099 p[60] = RT_H2LE_U16(((1 << 28) - 1) & 0xffff);
1100 p[61] = RT_H2LE_U16(((1 << 28) - 1) >> 16);
1101 }
1102 p[63] = RT_H2LE_U16(ATA_TRANSFER_ID(ATA_MODE_MDMA, ATA_MDMA_MODE_MAX, s->uATATransferMode)); /* MDMA modes supported / mode enabled */
1103 p[64] = RT_H2LE_U16(ATA_PIO_MODE_MAX > 2 ? (1 << (ATA_PIO_MODE_MAX - 2)) - 1 : 0); /* PIO modes beyond PIO2 supported */
1104 p[65] = RT_H2LE_U16(120); /* minimum DMA multiword tx cycle time */
1105 p[66] = RT_H2LE_U16(120); /* recommended DMA multiword tx cycle time */
1106 p[67] = RT_H2LE_U16(120); /* minimum PIO cycle time without flow control */
1107 p[68] = RT_H2LE_U16(120); /* minimum PIO cycle time with IORDY flow control */
1108 p[80] = RT_H2LE_U16(0x7e); /* support everything up to ATA/ATAPI-6 */
1109 p[81] = RT_H2LE_U16(0x22); /* conforms to ATA/ATAPI-6 */
1110 p[82] = RT_H2LE_U16(1 << 3 | 1 << 5 | 1 << 6); /* supports power management, write cache and look-ahead */
1111 if (s->cTotalSectors <= (1 << 28) - 1)
1112 p[83] = RT_H2LE_U16(1 << 14 | 1 << 12); /* supports FLUSH CACHE */
1113 else
1114 p[83] = RT_H2LE_U16(1 << 14 | 1 << 10 | 1 << 12 | 1 << 13); /* supports LBA48, FLUSH CACHE and FLUSH CACHE EXT */
1115 p[84] = RT_H2LE_U16(1 << 14);
1116 p[85] = RT_H2LE_U16(1 << 3 | 1 << 5 | 1 << 6); /* enabled power management, write cache and look-ahead */
1117 if (s->cTotalSectors <= (1 << 28) - 1)
1118 p[86] = RT_H2LE_U16(1 << 12); /* enabled FLUSH CACHE */
1119 else
1120 p[86] = RT_H2LE_U16(1 << 10 | 1 << 12 | 1 << 13); /* enabled LBA48, FLUSH CACHE and FLUSH CACHE EXT */
1121 p[87] = RT_H2LE_U16(1 << 14);
1122 p[88] = RT_H2LE_U16(ATA_TRANSFER_ID(ATA_MODE_UDMA, ATA_UDMA_MODE_MAX, s->uATATransferMode)); /* UDMA modes supported / mode enabled */
1123 p[93] = RT_H2LE_U16((1 | 1 << 1) << ((s->iLUN & 1) == 0 ? 0 : 8) | 1 << 13 | 1 << 14);
1124 if (s->cTotalSectors > (1 << 28) - 1)
1125 {
1126 p[100] = RT_H2LE_U16(s->cTotalSectors);
1127 p[101] = RT_H2LE_U16(s->cTotalSectors >> 16);
1128 p[102] = RT_H2LE_U16(s->cTotalSectors >> 32);
1129 p[103] = RT_H2LE_U16(s->cTotalSectors >> 48);
1130 }
1131 s->iSourceSink = ATAFN_SS_NULL;
1132 ataCmdOK(s, ATA_STAT_SEEK);
1133 return false;
1134}
1135
1136
1137static bool ataFlushSS(ATADevState *s)
1138{
1139 PATACONTROLLER pCtl = ATADEVSTATE_2_CONTROLLER(s);
1140 int rc;
1141
1142 Assert(s->uTxDir == PDMBLOCKTXDIR_NONE);
1143 Assert(!s->cbElementaryTransfer);
1144
1145 PDMCritSectLeave(&pCtl->lock);
1146
1147 STAM_PROFILE_START(&s->StatFlushes, f);
1148 rc = s->pDrvBlock->pfnFlush(s->pDrvBlock);
1149 AssertRC(rc);
1150 STAM_PROFILE_STOP(&s->StatFlushes, f);
1151
1152 STAM_PROFILE_START(&pCtl->StatLockWait, a);
1153 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
1154 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
1155 ataCmdOK(s, 0);
1156 return false;
1157}
1158
1159
1160static bool atapiIdentifySS(ATADevState *s)
1161{
1162 uint16_t *p;
1163 char aSerial[20];
1164 RTUUID Uuid;
1165 int rc;
1166
1167 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
1168 Assert(s->cbElementaryTransfer == 512);
1169 rc = s->pDrvBlock ? s->pDrvBlock->pfnGetUuid(s->pDrvBlock, &Uuid) : RTUuidClear(&Uuid);
1170 if (VBOX_FAILURE(rc) || RTUuidIsNull(&Uuid))
1171 {
1172 PATACONTROLLER pCtl = ATADEVSTATE_2_CONTROLLER(s);
1173 /* Generate a predictable serial for drives which don't have a UUID. */
1174 RTStrPrintf(aSerial, sizeof(aSerial), "VB%x-%04x%04x",
1175 s->iLUN + ATADEVSTATE_2_DEVINS(s)->iInstance * 32,
1176 pCtl->IOPortBase1, pCtl->IOPortBase2);
1177 }
1178 else
1179 RTStrPrintf(aSerial, sizeof(aSerial), "VB%08x-%08x", Uuid.au32[0], Uuid.au32[3]);
1180
1181 p = (uint16_t *)s->CTXSUFF(pbIOBuffer);
1182 memset(p, 0, 512);
1183 /* Removable CDROM, 50us response, 12 byte packets */
1184 p[0] = RT_H2LE_U16(2 << 14 | 5 << 8 | 1 << 7 | 2 << 5 | 0 << 0);
1185 ataPadString((uint8_t *)(p + 10), aSerial, 20); /* serial number */
1186 p[20] = RT_H2LE_U16(3); /* XXX: retired, cache type */
1187 p[21] = RT_H2LE_U16(512); /* XXX: retired, cache size in sectors */
1188 ataPadString((uint8_t *)(p + 23), "1.0", 8); /* firmware version */
1189 ataPadString((uint8_t *)(p + 27), "VBOX CD-ROM", 40); /* model */
1190 p[49] = RT_H2LE_U16(1 << 11 | 1 << 9 | 1 << 8); /* DMA and LBA supported */
1191 p[50] = RT_H2LE_U16(1 << 14); /* No drive specific standby timer minimum */
1192 p[51] = RT_H2LE_U16(240); /* PIO transfer cycle */
1193 p[52] = RT_H2LE_U16(240); /* DMA transfer cycle */
1194 p[53] = RT_H2LE_U16(1 << 1 | 1 << 2); /* words 64-70,88 are valid */
1195 p[63] = RT_H2LE_U16(ATA_TRANSFER_ID(ATA_MODE_MDMA, ATA_MDMA_MODE_MAX, s->uATATransferMode)); /* MDMA modes supported / mode enabled */
1196 p[64] = RT_H2LE_U16(ATA_PIO_MODE_MAX > 2 ? (1 << (ATA_PIO_MODE_MAX - 2)) - 1 : 0); /* PIO modes beyond PIO2 supported */
1197 p[65] = RT_H2LE_U16(120); /* minimum DMA multiword tx cycle time */
1198 p[66] = RT_H2LE_U16(120); /* recommended DMA multiword tx cycle time */
1199 p[67] = RT_H2LE_U16(120); /* minimum PIO cycle time without flow control */
1200 p[68] = RT_H2LE_U16(120); /* minimum PIO cycle time with IORDY flow control */
1201 p[73] = RT_H2LE_U16(0x003e); /* ATAPI CDROM major */
1202 p[74] = RT_H2LE_U16(9); /* ATAPI CDROM minor */
1203 p[75] = RT_H2LE_U16(1); /* queue depth 1 */
1204 p[80] = RT_H2LE_U16(0x7e); /* support everything up to ATA/ATAPI-6 */
1205 p[81] = RT_H2LE_U16(0x22); /* conforms to ATA/ATAPI-6 */
1206 p[82] = RT_H2LE_U16(1 << 4 | 1 << 9); /* supports packet command set and DEVICE RESET */
1207 p[83] = RT_H2LE_U16(1 << 14);
1208 p[84] = RT_H2LE_U16(1 << 14);
1209 p[85] = RT_H2LE_U16(1 << 4 | 1 << 9); /* enabled packet command set and DEVICE RESET */
1210 p[86] = RT_H2LE_U16(0);
1211 p[87] = RT_H2LE_U16(1 << 14);
1212 p[88] = RT_H2LE_U16(ATA_TRANSFER_ID(ATA_MODE_UDMA, ATA_UDMA_MODE_MAX, s->uATATransferMode)); /* UDMA modes supported / mode enabled */
1213 p[93] = RT_H2LE_U16((1 | 1 << 1) << ((s->iLUN & 1) == 0 ? 0 : 8) | 1 << 13 | 1 << 14);
1214 s->iSourceSink = ATAFN_SS_NULL;
1215 ataCmdOK(s, ATA_STAT_SEEK);
1216 return false;
1217}
1218
1219
1220static void ataSetSignature(ATADevState *s)
1221{
1222 s->uATARegSelect &= 0xf0; /* clear head */
1223 /* put signature */
1224 s->uATARegNSector = 1;
1225 s->uATARegSector = 1;
1226 if (s->fATAPI)
1227 {
1228 s->uATARegLCyl = 0x14;
1229 s->uATARegHCyl = 0xeb;
1230 }
1231 else if (s->pDrvBlock)
1232 {
1233 s->uATARegLCyl = 0;
1234 s->uATARegHCyl = 0;
1235 }
1236 else
1237 {
1238 s->uATARegLCyl = 0xff;
1239 s->uATARegHCyl = 0xff;
1240 }
1241}
1242
1243
1244static uint64_t ataGetSector(ATADevState *s)
1245{
1246 uint64_t iLBA;
1247 if (s->uATARegSelect & 0x40)
1248 {
1249 /* any LBA variant */
1250 if (s->fLBA48)
1251 {
1252 /* LBA48 */
1253 iLBA = ((uint64_t)s->uATARegHCylHOB << 40) |
1254 ((uint64_t)s->uATARegLCylHOB << 32) |
1255 ((uint64_t)s->uATARegSectorHOB << 24) |
1256 ((uint64_t)s->uATARegHCyl << 16) |
1257 ((uint64_t)s->uATARegLCyl << 8) |
1258 s->uATARegSector;
1259 }
1260 else
1261 {
1262 /* LBA */
1263 iLBA = ((s->uATARegSelect & 0x0f) << 24) | (s->uATARegHCyl << 16) |
1264 (s->uATARegLCyl << 8) | s->uATARegSector;
1265 }
1266 }
1267 else
1268 {
1269 /* CHS */
1270 iLBA = ((s->uATARegHCyl << 8) | s->uATARegLCyl) * s->cCHSHeads * s->cCHSSectors +
1271 (s->uATARegSelect & 0x0f) * s->cCHSSectors +
1272 (s->uATARegSector - 1);
1273 }
1274 return iLBA;
1275}
1276
1277static void ataSetSector(ATADevState *s, uint64_t iLBA)
1278{
1279 uint32_t cyl, r;
1280 if (s->uATARegSelect & 0x40)
1281 {
1282 /* any LBA variant */
1283 if (s->fLBA48)
1284 {
1285 /* LBA48 */
1286 s->uATARegHCylHOB = iLBA >> 40;
1287 s->uATARegLCylHOB = iLBA >> 32;
1288 s->uATARegSectorHOB = iLBA >> 24;
1289 s->uATARegHCyl = iLBA >> 16;
1290 s->uATARegLCyl = iLBA >> 8;
1291 s->uATARegSector = iLBA;
1292 }
1293 else
1294 {
1295 /* LBA */
1296 s->uATARegSelect = (s->uATARegSelect & 0xf0) | (iLBA >> 24);
1297 s->uATARegHCyl = (iLBA >> 16);
1298 s->uATARegLCyl = (iLBA >> 8);
1299 s->uATARegSector = (iLBA);
1300 }
1301 }
1302 else
1303 {
1304 /* CHS */
1305 cyl = iLBA / (s->cCHSHeads * s->cCHSSectors);
1306 r = iLBA % (s->cCHSHeads * s->cCHSSectors);
1307 s->uATARegHCyl = cyl >> 8;
1308 s->uATARegLCyl = cyl;
1309 s->uATARegSelect = (s->uATARegSelect & 0xf0) | ((r / s->cCHSSectors) & 0x0f);
1310 s->uATARegSector = (r % s->cCHSSectors) + 1;
1311 }
1312}
1313
1314
1315static int ataReadSectors(ATADevState *s, uint64_t u64Sector, void *pvBuf, uint32_t cSectors)
1316{
1317 PATACONTROLLER pCtl = ATADEVSTATE_2_CONTROLLER(s);
1318 int rc;
1319
1320 PDMCritSectLeave(&pCtl->lock);
1321
1322 STAM_PROFILE_ADV_START(&s->StatReads, r);
1323 s->Led.Asserted.s.fReading = s->Led.Actual.s.fReading = 1;
1324 rc = s->pDrvBlock->pfnRead(s->pDrvBlock, u64Sector * 512, pvBuf, cSectors * 512);
1325 s->Led.Actual.s.fReading = 0;
1326 STAM_PROFILE_ADV_STOP(&s->StatReads, r);
1327
1328 STAM_COUNTER_ADD(&s->StatBytesRead, cSectors * 512);
1329
1330 STAM_PROFILE_START(&pCtl->StatLockWait, a);
1331 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
1332 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
1333 return rc;
1334}
1335
1336
1337static int ataWriteSectors(ATADevState *s, uint64_t u64Sector, const void *pvBuf, uint32_t cSectors)
1338{
1339 PATACONTROLLER pCtl = ATADEVSTATE_2_CONTROLLER(s);
1340 int rc;
1341
1342 PDMCritSectLeave(&pCtl->lock);
1343
1344 STAM_PROFILE_ADV_START(&s->StatWrites, w);
1345 s->Led.Asserted.s.fWriting = s->Led.Actual.s.fWriting = 1;
1346 rc = s->pDrvBlock->pfnWrite(s->pDrvBlock, u64Sector * 512, pvBuf, cSectors * 512);
1347 s->Led.Actual.s.fWriting = 0;
1348 STAM_PROFILE_ADV_STOP(&s->StatWrites, w);
1349
1350 STAM_COUNTER_ADD(&s->StatBytesWritten, cSectors * 512);
1351
1352 STAM_PROFILE_START(&pCtl->StatLockWait, a);
1353 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
1354 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
1355 return rc;
1356}
1357
1358
1359static void ataReadWriteSectorsBT(ATADevState *s)
1360{
1361 uint32_t cSectors;
1362
1363 cSectors = s->cbTotalTransfer / 512;
1364 if (cSectors > s->cSectorsPerIRQ)
1365 s->cbElementaryTransfer = s->cSectorsPerIRQ * 512;
1366 else
1367 s->cbElementaryTransfer = cSectors * 512;
1368 if (s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE)
1369 ataCmdOK(s, 0);
1370}
1371
1372
1373static void ataWarningDiskFull(PPDMDEVINS pDevIns)
1374{
1375 int rc;
1376 LogRel(("PIIX3 ATA: Host disk full\n"));
1377 rc = VMSetRuntimeError(PDMDevHlpGetVM(pDevIns),
1378 false, "DevATA_DISKFULL",
1379 N_("Host system reported disk full. VM execution is suspended. You can resume after freeing some space"));
1380 AssertRC(rc);
1381}
1382
1383
1384static void ataWarningFileTooBig(PPDMDEVINS pDevIns)
1385{
1386 int rc;
1387 LogRel(("PIIX3 ATA: File too big\n"));
1388 rc = VMSetRuntimeError(PDMDevHlpGetVM(pDevIns),
1389 false, "DevATA_FILETOOBIG",
1390 N_("Host system reported that the file size limit of the host file system has been exceeded. VM execution is suspended. You need to move your virtual hard disk to a filesystem which allows bigger files"));
1391 AssertRC(rc);
1392}
1393
1394
1395static void ataWarningISCSI(PPDMDEVINS pDevIns)
1396{
1397 int rc;
1398 LogRel(("PIIX3 ATA: iSCSI target unavailable\n"));
1399 rc = VMSetRuntimeError(PDMDevHlpGetVM(pDevIns),
1400 false, "DevATA_ISCSIDOWN",
1401 N_("The iSCSI target has stopped responding. VM execution is suspended. You can resume when it is available again"));
1402 AssertRC(rc);
1403}
1404
1405
1406static bool ataReadSectorsSS(ATADevState *s)
1407{
1408 int rc;
1409 uint32_t cSectors;
1410 uint64_t iLBA;
1411
1412 cSectors = s->cbElementaryTransfer / 512;
1413 Assert(cSectors);
1414 iLBA = ataGetSector(s);
1415 Log(("%s: %d sectors at LBA %d\n", __FUNCTION__, cSectors, iLBA));
1416 rc = ataReadSectors(s, iLBA, s->CTXSUFF(pbIOBuffer), cSectors);
1417 if (VBOX_SUCCESS(rc))
1418 {
1419 ataSetSector(s, iLBA + cSectors);
1420 if (s->cbElementaryTransfer == s->cbTotalTransfer)
1421 s->iSourceSink = ATAFN_SS_NULL;
1422 ataCmdOK(s, ATA_STAT_SEEK);
1423 }
1424 else
1425 {
1426 if (rc == VERR_DISK_FULL)
1427 {
1428 ataWarningDiskFull(ATADEVSTATE_2_DEVINS(s));
1429 return true;
1430 }
1431 if (rc == VERR_FILE_TOO_BIG)
1432 {
1433 ataWarningFileTooBig(ATADEVSTATE_2_DEVINS(s));
1434 return true;
1435 }
1436 if (rc == VERR_BROKEN_PIPE || rc == VERR_NET_CONNECTION_REFUSED)
1437 {
1438 /* iSCSI connection abort (first error) or failure to reestablish
1439 * connection (second error). Pause VM. On resume we'll retry. */
1440 ataWarningISCSI(ATADEVSTATE_2_DEVINS(s));
1441 return true;
1442 }
1443 if (s->cErrors++ < MAX_LOG_REL_ERRORS)
1444 LogRel(("PIIX3 ATA: LUN#%d: disk read error (rc=%Vrc iSector=%#RX64 cSectors=%#RX32)\n",
1445 s->iLUN, rc, iLBA, cSectors));
1446 ataCmdError(s, ID_ERR);
1447 }
1448 /** @todo implement redo for iSCSI */
1449 return false;
1450}
1451
1452
1453static bool ataWriteSectorsSS(ATADevState *s)
1454{
1455 int rc;
1456 uint32_t cSectors;
1457 uint64_t iLBA;
1458
1459 cSectors = s->cbElementaryTransfer / 512;
1460 Assert(cSectors);
1461 iLBA = ataGetSector(s);
1462 Log(("%s: %d sectors at LBA %d\n", __FUNCTION__, cSectors, iLBA));
1463 rc = ataWriteSectors(s, iLBA, s->CTXSUFF(pbIOBuffer), cSectors);
1464 if (VBOX_SUCCESS(rc))
1465 {
1466 ataSetSector(s, iLBA + cSectors);
1467 if (!s->cbTotalTransfer)
1468 s->iSourceSink = ATAFN_SS_NULL;
1469 ataCmdOK(s, ATA_STAT_SEEK);
1470 }
1471 else
1472 {
1473 if (rc == VERR_DISK_FULL)
1474 {
1475 ataWarningDiskFull(ATADEVSTATE_2_DEVINS(s));
1476 return true;
1477 }
1478 if (rc == VERR_FILE_TOO_BIG)
1479 {
1480 ataWarningFileTooBig(ATADEVSTATE_2_DEVINS(s));
1481 return true;
1482 }
1483 if (rc == VERR_BROKEN_PIPE || rc == VERR_NET_CONNECTION_REFUSED)
1484 {
1485 /* iSCSI connection abort (first error) or failure to reestablish
1486 * connection (second error). Pause VM. On resume we'll retry. */
1487 ataWarningISCSI(ATADEVSTATE_2_DEVINS(s));
1488 return true;
1489 }
1490 if (s->cErrors++ < MAX_LOG_REL_ERRORS)
1491 LogRel(("PIIX3 ATA: LUN#%d: disk write error (rc=%Vrc iSector=%#RX64 cSectors=%#RX32)\n",
1492 s->iLUN, rc, iLBA, cSectors));
1493 ataCmdError(s, ID_ERR);
1494 }
1495 /** @todo implement redo for iSCSI */
1496 return false;
1497}
1498
1499
1500static void atapiCmdOK(ATADevState *s)
1501{
1502 s->uATARegError = 0;
1503 ataSetStatusValue(s, ATA_STAT_READY);
1504 s->uATARegNSector = (s->uATARegNSector & ~7)
1505 | ((s->uTxDir != PDMBLOCKTXDIR_TO_DEVICE) ? ATAPI_INT_REASON_IO : 0)
1506 | (!s->cbTotalTransfer ? ATAPI_INT_REASON_CD : 0);
1507 Log2(("%s: interrupt reason %#04x\n", __FUNCTION__, s->uATARegNSector));
1508 s->uATAPISenseKey = SCSI_SENSE_NONE;
1509 s->uATAPIASC = SCSI_ASC_NONE;
1510}
1511
1512
1513static void atapiCmdError(ATADevState *s, uint8_t uATAPISenseKey, uint8_t uATAPIASC)
1514{
1515 Log(("%s: sense=%#x asc=%#x\n", __FUNCTION__, uATAPISenseKey, uATAPIASC));
1516 s->uATARegError = uATAPISenseKey << 4;
1517 ataSetStatusValue(s, ATA_STAT_READY | ATA_STAT_ERR);
1518 s->uATARegNSector = (s->uATARegNSector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
1519 Log2(("%s: interrupt reason %#04x\n", __FUNCTION__, s->uATARegNSector));
1520 s->uATAPISenseKey = uATAPISenseKey;
1521 s->uATAPIASC = uATAPIASC;
1522 s->cbTotalTransfer = 0;
1523 s->cbElementaryTransfer = 0;
1524 s->iIOBufferCur = 0;
1525 s->iIOBufferEnd = 0;
1526 s->uTxDir = PDMBLOCKTXDIR_NONE;
1527 s->iBeginTransfer = ATAFN_BT_NULL;
1528 s->iSourceSink = ATAFN_SS_NULL;
1529}
1530
1531
1532static void atapiCmdBT(ATADevState *s)
1533{
1534 s->fATAPITransfer = true;
1535 s->cbElementaryTransfer = s->cbTotalTransfer;
1536 if (s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE)
1537 atapiCmdOK(s);
1538}
1539
1540
1541static void atapiPassthroughCmdBT(ATADevState *s)
1542{
1543 /* @todo implement an algorithm for correctly determining the read and
1544 * write sector size without sending additional commands to the drive.
1545 * This should be doable by saving processing the configuration requests
1546 * and replies. */
1547#if 0
1548 if (s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE)
1549 {
1550 uint8_t cmd = s->aATAPICmd[0];
1551 if (cmd == SCSI_WRITE_10 || cmd == SCSI_WRITE_12 || cmd == SCSI_WRITE_AND_VERIFY_10)
1552 {
1553 uint8_t aModeSenseCmd[10];
1554 uint8_t aModeSenseResult[16];
1555 uint8_t uDummySense;
1556 uint32_t cbTransfer;
1557 int rc;
1558
1559 cbTransfer = sizeof(aModeSenseResult);
1560 aModeSenseCmd[0] = SCSI_MODE_SENSE_10;
1561 aModeSenseCmd[1] = 0x08; /* disable block descriptor = 1 */
1562 aModeSenseCmd[2] = (SCSI_PAGECONTROL_CURRENT << 6) | SCSI_MODEPAGE_WRITE_PARAMETER;
1563 aModeSenseCmd[3] = 0; /* subpage code */
1564 aModeSenseCmd[4] = 0; /* reserved */
1565 aModeSenseCmd[5] = 0; /* reserved */
1566 aModeSenseCmd[6] = 0; /* reserved */
1567 aModeSenseCmd[7] = cbTransfer >> 8;
1568 aModeSenseCmd[8] = cbTransfer & 0xff;
1569 aModeSenseCmd[9] = 0; /* control */
1570 rc = s->pDrvBlock->pfnSendCmd(s->pDrvBlock, aModeSenseCmd, PDMBLOCKTXDIR_FROM_DEVICE, aModeSenseResult, &cbTransfer, &uDummySense, 500);
1571 if (VBOX_FAILURE(rc))
1572 {
1573 atapiCmdError(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_NONE);
1574 return;
1575 }
1576 /* Select sector size based on the current data block type. */
1577 switch (aModeSenseResult[12] & 0x0f)
1578 {
1579 case 0:
1580 s->cbATAPISector = 2352;
1581 break;
1582 case 1:
1583 s->cbATAPISector = 2368;
1584 break;
1585 case 2:
1586 case 3:
1587 s->cbATAPISector = 2448;
1588 break;
1589 case 8:
1590 case 10:
1591 s->cbATAPISector = 2048;
1592 break;
1593 case 9:
1594 s->cbATAPISector = 2336;
1595 break;
1596 case 11:
1597 s->cbATAPISector = 2056;
1598 break;
1599 case 12:
1600 s->cbATAPISector = 2324;
1601 break;
1602 case 13:
1603 s->cbATAPISector = 2332;
1604 break;
1605 default:
1606 s->cbATAPISector = 0;
1607 }
1608 Log2(("%s: sector size %d\n", __FUNCTION__, s->cbATAPISector));
1609 s->cbTotalTransfer *= s->cbATAPISector;
1610 if (s->cbTotalTransfer == 0)
1611 s->uTxDir = PDMBLOCKTXDIR_NONE;
1612 }
1613 }
1614#endif
1615 atapiCmdBT(s);
1616}
1617
1618
1619static bool atapiReadSS(ATADevState *s)
1620{
1621 PATACONTROLLER pCtl = ATADEVSTATE_2_CONTROLLER(s);
1622 int rc = VINF_SUCCESS;
1623 uint32_t cbTransfer, cSectors;
1624
1625 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
1626 cbTransfer = RT_MIN(s->cbTotalTransfer, s->cbIOBuffer);
1627 cSectors = cbTransfer / s->cbATAPISector;
1628 Assert(cSectors * s->cbATAPISector <= cbTransfer);
1629 Log(("%s: %d sectors at LBA %d\n", __FUNCTION__, cSectors, s->iATAPILBA));
1630
1631 PDMCritSectLeave(&pCtl->lock);
1632
1633 STAM_PROFILE_ADV_START(&s->StatReads, r);
1634 s->Led.Asserted.s.fReading = s->Led.Actual.s.fReading = 1;
1635 switch (s->cbATAPISector)
1636 {
1637 case 2048:
1638 rc = s->pDrvBlock->pfnRead(s->pDrvBlock, (uint64_t)s->iATAPILBA * s->cbATAPISector, s->CTXSUFF(pbIOBuffer), s->cbATAPISector * cSectors);
1639 break;
1640 case 2352:
1641 {
1642 uint8_t *pbBuf = s->CTXSUFF(pbIOBuffer);
1643
1644 for (uint32_t i = s->iATAPILBA; i < s->iATAPILBA + cSectors; i++)
1645 {
1646 /* sync bytes */
1647 *pbBuf++ = 0x00;
1648 memset(pbBuf, 0xff, 11);
1649 pbBuf += 11;
1650 /* MSF */
1651 ataLBA2MSF(pbBuf, i);
1652 pbBuf += 3;
1653 *pbBuf++ = 0x01; /* mode 1 data */
1654 /* data */
1655 rc = s->pDrvBlock->pfnRead(s->pDrvBlock, (uint64_t)i * 2048, pbBuf, 2048);
1656 if (VBOX_FAILURE(rc))
1657 break;
1658 pbBuf += 2048;
1659 /* ECC */
1660 memset(pbBuf, 0, 288);
1661 pbBuf += 288;
1662 }
1663 }
1664 break;
1665 default:
1666 break;
1667 }
1668 STAM_PROFILE_ADV_STOP(&s->StatReads, r);
1669
1670 STAM_PROFILE_START(&pCtl->StatLockWait, a);
1671 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
1672 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
1673
1674 if (VBOX_SUCCESS(rc))
1675 {
1676 s->Led.Actual.s.fReading = 0;
1677 STAM_COUNTER_ADD(&s->StatBytesRead, s->cbATAPISector * cSectors);
1678
1679 /* The initial buffer end value has been set up based on the total
1680 * transfer size. But the I/O buffer size limits what can actually be
1681 * done in one transfer, so set the actual value of the buffer end. */
1682 s->cbElementaryTransfer = cbTransfer;
1683 if (cbTransfer >= s->cbTotalTransfer)
1684 s->iSourceSink = ATAFN_SS_NULL;
1685 atapiCmdOK(s);
1686 s->iATAPILBA += cSectors;
1687 }
1688 else
1689 {
1690 if (s->cErrors++ < MAX_LOG_REL_ERRORS)
1691 LogRel(("PIIX3 ATA: LUN#%d: CD-ROM read error, %d sectors at LBA %d\n", s->iLUN, cSectors, s->iATAPILBA));
1692 atapiCmdError(s, SCSI_SENSE_MEDIUM_ERROR, SCSI_ASC_READ_ERROR);
1693 }
1694 return false;
1695}
1696
1697
1698static bool atapiPassthroughSS(ATADevState *s)
1699{
1700 PATACONTROLLER pCtl = ATADEVSTATE_2_CONTROLLER(s);
1701 int rc = VINF_SUCCESS;
1702 uint8_t uATAPISenseKey;
1703 size_t cbTransfer;
1704 PSTAMPROFILEADV pProf = NULL;
1705
1706 cbTransfer = s->cbElementaryTransfer;
1707
1708 if (s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE)
1709 Log3(("ATAPI PT data write (%d): %.*Vhxs\n", cbTransfer, cbTransfer, s->CTXSUFF(pbIOBuffer)));
1710
1711 /* Simple heuristics: if there is at least one sector of data
1712 * to transfer, it's worth updating the LEDs. */
1713 if (cbTransfer >= 2048)
1714 {
1715 if (s->uTxDir != PDMBLOCKTXDIR_TO_DEVICE)
1716 {
1717 s->Led.Asserted.s.fReading = s->Led.Actual.s.fReading = 1;
1718 pProf = &s->StatReads;
1719 }
1720 else
1721 {
1722 s->Led.Asserted.s.fWriting = s->Led.Actual.s.fWriting = 1;
1723 pProf = &s->StatWrites;
1724 }
1725 }
1726
1727 PDMCritSectLeave(&pCtl->lock);
1728
1729 if (pProf) { STAM_PROFILE_ADV_START(pProf, b); }
1730 if (cbTransfer > 100 * _1K)
1731 {
1732 /* Linux accepts commands with up to 100KB of data, but expects
1733 * us to handle commands with up to 128KB of data. The usual
1734 * imbalance of powers. */
1735 uint8_t aATAPICmd[ATAPI_PACKET_SIZE];
1736 uint32_t iATAPILBA, cSectors, cReqSectors;
1737 size_t cbCurrTX;
1738 uint8_t *pbBuf = s->CTXSUFF(pbIOBuffer);
1739
1740 switch (s->aATAPICmd[0])
1741 {
1742 case SCSI_READ_10:
1743 case SCSI_WRITE_10:
1744 case SCSI_WRITE_AND_VERIFY_10:
1745 iATAPILBA = ataBE2H_U32(s->aATAPICmd + 2);
1746 cSectors = ataBE2H_U16(s->aATAPICmd + 7);
1747 break;
1748 case SCSI_READ_12:
1749 case SCSI_WRITE_12:
1750 iATAPILBA = ataBE2H_U32(s->aATAPICmd + 2);
1751 cSectors = ataBE2H_U32(s->aATAPICmd + 6);
1752 break;
1753 case SCSI_READ_CD:
1754 iATAPILBA = ataBE2H_U32(s->aATAPICmd + 2);
1755 cSectors = ataBE2H_U24(s->aATAPICmd + 6) / s->cbATAPISector;
1756 break;
1757 case SCSI_READ_CD_MSF:
1758 iATAPILBA = ataMSF2LBA(s->aATAPICmd + 3);
1759 cSectors = ataMSF2LBA(s->aATAPICmd + 6) - iATAPILBA;
1760 break;
1761 default:
1762 AssertMsgFailed(("Don't know how to split command %#04x\n", s->aATAPICmd[0]));
1763 if (s->cErrors++ < MAX_LOG_REL_ERRORS)
1764 LogRel(("PIIX3 ATA: LUN#%d: CD-ROM passthrough split error\n", s->iLUN));
1765 atapiCmdError(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_ILLEGAL_OPCODE);
1766 {
1767 STAM_PROFILE_START(&pCtl->StatLockWait, a);
1768 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
1769 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
1770 }
1771 return false;
1772 }
1773 memcpy(aATAPICmd, s->aATAPICmd, ATAPI_PACKET_SIZE);
1774 cReqSectors = 0;
1775 for (uint32_t i = cSectors; i > 0; i -= cReqSectors)
1776 {
1777 if (i * s->cbATAPISector > 100 * _1K)
1778 cReqSectors = (100 * _1K) / s->cbATAPISector;
1779 else
1780 cReqSectors = i;
1781 cbCurrTX = s->cbATAPISector * cReqSectors;
1782 switch (s->aATAPICmd[0])
1783 {
1784 case SCSI_READ_10:
1785 case SCSI_WRITE_10:
1786 case SCSI_WRITE_AND_VERIFY_10:
1787 ataH2BE_U32(aATAPICmd + 2, iATAPILBA);
1788 ataH2BE_U16(aATAPICmd + 7, cReqSectors);
1789 break;
1790 case SCSI_READ_12:
1791 case SCSI_WRITE_12:
1792 ataH2BE_U32(aATAPICmd + 2, iATAPILBA);
1793 ataH2BE_U32(aATAPICmd + 6, cReqSectors);
1794 break;
1795 case SCSI_READ_CD:
1796 ataH2BE_U32(s->aATAPICmd + 2, iATAPILBA);
1797 ataH2BE_U24(s->aATAPICmd + 6, cbCurrTX);
1798 break;
1799 case SCSI_READ_CD_MSF:
1800 ataLBA2MSF(aATAPICmd + 3, iATAPILBA);
1801 ataLBA2MSF(aATAPICmd + 6, iATAPILBA + cReqSectors);
1802 break;
1803 }
1804 rc = s->pDrvBlock->pfnSendCmd(s->pDrvBlock, aATAPICmd, (PDMBLOCKTXDIR)s->uTxDir, pbBuf, &cbCurrTX, &uATAPISenseKey, 30000 /**< @todo timeout */);
1805 if (rc != VINF_SUCCESS)
1806 break;
1807 iATAPILBA += cReqSectors;
1808 pbBuf += s->cbATAPISector * cReqSectors;
1809 }
1810 }
1811 else
1812 rc = s->pDrvBlock->pfnSendCmd(s->pDrvBlock, s->aATAPICmd, (PDMBLOCKTXDIR)s->uTxDir, s->CTXSUFF(pbIOBuffer), &cbTransfer, &uATAPISenseKey, 30000 /**< @todo timeout */);
1813 if (pProf) { STAM_PROFILE_ADV_STOP(pProf, b); }
1814
1815 STAM_PROFILE_START(&pCtl->StatLockWait, a);
1816 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
1817 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
1818
1819 /* Update the LEDs and the read/write statistics. */
1820 if (cbTransfer >= 2048)
1821 {
1822 if (s->uTxDir != PDMBLOCKTXDIR_TO_DEVICE)
1823 {
1824 s->Led.Actual.s.fReading = 0;
1825 STAM_COUNTER_ADD(&s->StatBytesRead, cbTransfer);
1826 }
1827 else
1828 {
1829 s->Led.Actual.s.fWriting = 0;
1830 STAM_COUNTER_ADD(&s->StatBytesWritten, cbTransfer);
1831 }
1832 }
1833
1834 if (VBOX_SUCCESS(rc))
1835 {
1836 if (s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE)
1837 {
1838 Assert(cbTransfer <= s->cbTotalTransfer);
1839 /* Reply with the same amount of data as the real drive. */
1840 s->cbTotalTransfer = cbTransfer;
1841 /* The initial buffer end value has been set up based on the total
1842 * transfer size. But the I/O buffer size limits what can actually be
1843 * done in one transfer, so set the actual value of the buffer end. */
1844 s->cbElementaryTransfer = cbTransfer;
1845 if (s->aATAPICmd[0] == SCSI_INQUIRY)
1846 {
1847 /* Make sure that the real drive cannot be identified.
1848 * Motivation: changing the VM configuration should be as
1849 * invisible as possible to the guest. */
1850 Log3(("ATAPI PT inquiry data before (%d): %.*Vhxs\n", cbTransfer, cbTransfer, s->CTXSUFF(pbIOBuffer)));
1851 ataSCSIPadStr(s->CTXSUFF(pbIOBuffer) + 8, "VBOX", 8);
1852 ataSCSIPadStr(s->CTXSUFF(pbIOBuffer) + 16, "CD-ROM", 16);
1853 ataSCSIPadStr(s->CTXSUFF(pbIOBuffer) + 32, "1.0", 4);
1854 }
1855 if (cbTransfer)
1856 Log3(("ATAPI PT data read (%d): %.*Vhxs\n", cbTransfer, cbTransfer, s->CTXSUFF(pbIOBuffer)));
1857 }
1858 s->iSourceSink = ATAFN_SS_NULL;
1859 atapiCmdOK(s);
1860 }
1861 else
1862 {
1863 if (s->cErrors++ < MAX_LOG_REL_ERRORS)
1864 {
1865 uint8_t u8Cmd = s->aATAPICmd[0];
1866 do
1867 {
1868 /* don't log superflous errors */
1869 if ( rc == VERR_DEV_IO_ERROR
1870 && ( u8Cmd == SCSI_TEST_UNIT_READY
1871 || u8Cmd == SCSI_READ_CAPACITY
1872 || u8Cmd == SCSI_READ_TOC_PMA_ATIP))
1873 break;
1874 LogRel(("PIIX3 ATA: LUN#%d: CD-ROM passthrough command (%#04x) error %d %Vrc\n", s->iLUN, u8Cmd, uATAPISenseKey, rc));
1875 } while (0);
1876 }
1877 atapiCmdError(s, uATAPISenseKey, 0);
1878 /* This is a drive-reported error. atapiCmdError() sets both the error
1879 * error code in the ATA error register and in s->uATAPISenseKey. The
1880 * former is correct, the latter is not. Otherwise the drive would not
1881 * get the next REQUEST SENSE command which is necessary to clear the
1882 * error status of the drive. Easy fix: clear s->uATAPISenseKey. */
1883 s->uATAPISenseKey = SCSI_SENSE_NONE;
1884 s->uATAPIASC = SCSI_ASC_NONE;
1885 }
1886 return false;
1887}
1888
1889
1890static bool atapiReadSectors(ATADevState *s, uint32_t iATAPILBA, uint32_t cSectors, uint32_t cbSector)
1891{
1892 Assert(cSectors > 0);
1893 s->iATAPILBA = iATAPILBA;
1894 s->cbATAPISector = cbSector;
1895 ataStartTransfer(s, cSectors * cbSector, PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_READ, true);
1896 return false;
1897}
1898
1899
1900static bool atapiReadCapacitySS(ATADevState *s)
1901{
1902 uint8_t *pbBuf = s->CTXSUFF(pbIOBuffer);
1903
1904 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
1905 Assert(s->cbElementaryTransfer <= 8);
1906 ataH2BE_U32(pbBuf, s->cTotalSectors - 1);
1907 ataH2BE_U32(pbBuf + 4, 2048);
1908 s->iSourceSink = ATAFN_SS_NULL;
1909 atapiCmdOK(s);
1910 return false;
1911}
1912
1913
1914static bool atapiReadDiscInformationSS(ATADevState *s)
1915{
1916 uint8_t *pbBuf = s->CTXSUFF(pbIOBuffer);
1917
1918 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
1919 Assert(s->cbElementaryTransfer <= 34);
1920 memset(pbBuf, '\0', 34);
1921 ataH2BE_U16(pbBuf, 32);
1922 pbBuf[2] = (0 << 4) | (3 << 2) | (2 << 0); /* not erasable, complete session, complete disc */
1923 pbBuf[3] = 1; /* number of first track */
1924 pbBuf[4] = 1; /* number of sessions (LSB) */
1925 pbBuf[5] = 1; /* first track number in last session (LSB) */
1926 pbBuf[6] = 1; /* last track number in last session (LSB) */
1927 pbBuf[7] = (0 << 7) | (0 << 6) | (1 << 5) | (0 << 2) | (0 << 0); /* disc id not valid, disc bar code not valid, unrestricted use, not dirty, not RW medium */
1928 pbBuf[8] = 0; /* disc type = CD-ROM */
1929 pbBuf[9] = 0; /* number of sessions (MSB) */
1930 pbBuf[10] = 0; /* number of sessions (MSB) */
1931 pbBuf[11] = 0; /* number of sessions (MSB) */
1932 ataH2BE_U32(pbBuf + 16, 0x00ffffff); /* last session lead-in start time is not available */
1933 ataH2BE_U32(pbBuf + 20, 0x00ffffff); /* last possible start time for lead-out is not available */
1934 s->iSourceSink = ATAFN_SS_NULL;
1935 atapiCmdOK(s);
1936 return false;
1937}
1938
1939
1940static bool atapiReadTrackInformationSS(ATADevState *s)
1941{
1942 uint8_t *pbBuf = s->CTXSUFF(pbIOBuffer);
1943
1944 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
1945 Assert(s->cbElementaryTransfer <= 36);
1946 /* Accept address/number type of 1 only, and only track 1 exists. */
1947 if ((s->aATAPICmd[1] & 0x03) != 1 || ataBE2H_U32(&s->aATAPICmd[2]) != 1)
1948 {
1949 atapiCmdError(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INV_FIELD_IN_CMD_PACKET);
1950 return false;
1951 }
1952 memset(pbBuf, '\0', 36);
1953 ataH2BE_U16(pbBuf, 34);
1954 pbBuf[2] = 1; /* track number (LSB) */
1955 pbBuf[3] = 1; /* session number (LSB) */
1956 pbBuf[5] = (0 << 5) | (0 << 4) | (4 << 0); /* not damaged, primary copy, data track */
1957 pbBuf[6] = (0 << 7) | (0 << 6) | (0 << 5) | (0 << 6) | (1 << 0); /* not reserved track, not blank, not packet writing, not fixed packet, data mode 1 */
1958 pbBuf[7] = (0 << 1) | (0 << 0); /* last recorded address not valid, next recordable address not valid */
1959 ataH2BE_U32(pbBuf + 8, 0); /* track start address is 0 */
1960 ataH2BE_U32(pbBuf + 24, s->cTotalSectors); /* track size */
1961 pbBuf[32] = 0; /* track number (MSB) */
1962 pbBuf[33] = 0; /* session number (MSB) */
1963 s->iSourceSink = ATAFN_SS_NULL;
1964 atapiCmdOK(s);
1965 return false;
1966}
1967
1968
1969static bool atapiGetConfigurationSS(ATADevState *s)
1970{
1971 uint8_t *pbBuf = s->CTXSUFF(pbIOBuffer);
1972
1973 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
1974 Assert(s->cbElementaryTransfer <= 32);
1975 /* Accept valid request types only, and only starting feature 0. */
1976 if ((s->aATAPICmd[1] & 0x03) == 3 || ataBE2H_U16(&s->aATAPICmd[2]) != 0)
1977 {
1978 atapiCmdError(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INV_FIELD_IN_CMD_PACKET);
1979 return false;
1980 }
1981 memset(pbBuf, '\0', 32);
1982 ataH2BE_U32(pbBuf, 16);
1983 /** @todo implement switching between CD-ROM and DVD-ROM profile (the only
1984 * way to differentiate them right now is based on the image size). Also
1985 * implement signalling "no current profile" if no medium is loaded. */
1986 ataH2BE_U16(pbBuf + 6, 0x08); /* current profile: read-only CD */
1987
1988 ataH2BE_U16(pbBuf + 8, 0); /* feature 0: list of profiles supported */
1989 pbBuf[10] = (0 << 2) | (1 << 1) | (1 || 0); /* version 0, persistent, current */
1990 pbBuf[11] = 8; /* additional bytes for profiles */
1991 /* The MMC-3 spec says that DVD-ROM read capability should be reported
1992 * before CD-ROM read capability. */
1993 ataH2BE_U16(pbBuf + 12, 0x10); /* profile: read-only DVD */
1994 pbBuf[14] = (0 << 0); /* NOT current profile */
1995 ataH2BE_U16(pbBuf + 16, 0x08); /* profile: read only CD */
1996 pbBuf[18] = (1 << 0); /* current profile */
1997 /* Other profiles we might want to add in the future: 0x40 (BD-ROM) and 0x50 (HDDVD-ROM) */
1998 s->iSourceSink = ATAFN_SS_NULL;
1999 atapiCmdOK(s);
2000 return false;
2001}
2002
2003
2004static bool atapiInquirySS(ATADevState *s)
2005{
2006 uint8_t *pbBuf = s->CTXSUFF(pbIOBuffer);
2007
2008 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
2009 Assert(s->cbElementaryTransfer <= 36);
2010 pbBuf[0] = 0x05; /* CD-ROM */
2011 pbBuf[1] = 0x80; /* removable */
2012#if 1/*ndef VBOX*/ /** @todo implement MESN + AENC. (async notification on removal and stuff.) */
2013 pbBuf[2] = 0x00; /* ISO */
2014 pbBuf[3] = 0x21; /* ATAPI-2 (XXX: put ATAPI-4 ?) */
2015#else
2016 pbBuf[2] = 0x00; /* ISO */
2017 pbBuf[3] = 0x91; /* format 1, MESN=1, AENC=9 ??? */
2018#endif
2019 pbBuf[4] = 31; /* additional length */
2020 pbBuf[5] = 0; /* reserved */
2021 pbBuf[6] = 0; /* reserved */
2022 pbBuf[7] = 0; /* reserved */
2023 ataSCSIPadStr(pbBuf + 8, "VBOX", 8);
2024 ataSCSIPadStr(pbBuf + 16, "CD-ROM", 16);
2025 ataSCSIPadStr(pbBuf + 32, "1.0", 4);
2026 s->iSourceSink = ATAFN_SS_NULL;
2027 atapiCmdOK(s);
2028 return false;
2029}
2030
2031
2032static bool atapiModeSenseErrorRecoverySS(ATADevState *s)
2033{
2034 uint8_t *pbBuf = s->CTXSUFF(pbIOBuffer);
2035
2036 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
2037 Assert(s->cbElementaryTransfer <= 16);
2038 ataH2BE_U16(&pbBuf[0], 16 + 6);
2039 pbBuf[2] = 0x70;
2040 pbBuf[3] = 0;
2041 pbBuf[4] = 0;
2042 pbBuf[5] = 0;
2043 pbBuf[6] = 0;
2044 pbBuf[7] = 0;
2045
2046 pbBuf[8] = 0x01;
2047 pbBuf[9] = 0x06;
2048 pbBuf[10] = 0x00;
2049 pbBuf[11] = 0x05;
2050 pbBuf[12] = 0x00;
2051 pbBuf[13] = 0x00;
2052 pbBuf[14] = 0x00;
2053 pbBuf[15] = 0x00;
2054 s->iSourceSink = ATAFN_SS_NULL;
2055 atapiCmdOK(s);
2056 return false;
2057}
2058
2059
2060static bool atapiModeSenseCDStatusSS(ATADevState *s)
2061{
2062 uint8_t *pbBuf = s->CTXSUFF(pbIOBuffer);
2063
2064 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
2065 Assert(s->cbElementaryTransfer <= 40);
2066 ataH2BE_U16(&pbBuf[0], 38);
2067 pbBuf[2] = 0x70;
2068 pbBuf[3] = 0;
2069 pbBuf[4] = 0;
2070 pbBuf[5] = 0;
2071 pbBuf[6] = 0;
2072 pbBuf[7] = 0;
2073
2074 pbBuf[8] = 0x2a;
2075 pbBuf[9] = 30; /* page length */
2076 pbBuf[10] = 0x08; /* DVD-ROM read support */
2077 pbBuf[11] = 0x00; /* no write support */
2078 /* The following claims we support audio play. This is obviously false,
2079 * but the Linux generic CDROM support makes many features depend on this
2080 * capability. If it's not set, this causes many things to be disabled. */
2081 pbBuf[12] = 0x71; /* multisession support, mode 2 form 1/2 support, audio play */
2082 pbBuf[13] = 0x00; /* no subchannel reads supported */
2083 pbBuf[14] = (1 << 0) | (1 << 3) | (1 << 5); /* lock supported, eject supported, tray type loading mechanism */
2084 if (s->pDrvMount->pfnIsLocked(s->pDrvMount))
2085 pbBuf[14] |= 1 << 1; /* report lock state */
2086 pbBuf[15] = 0; /* no subchannel reads supported, no separate audio volume control, no changer etc. */
2087 ataH2BE_U16(&pbBuf[16], 5632); /* (obsolete) claim 32x speed support */
2088 ataH2BE_U16(&pbBuf[18], 2); /* number of audio volume levels */
2089 ataH2BE_U16(&pbBuf[20], s->cbIOBuffer / _1K); /* buffer size supported in Kbyte */
2090 ataH2BE_U16(&pbBuf[22], 5632); /* (obsolete) current read speed 32x */
2091 pbBuf[24] = 0; /* reserved */
2092 pbBuf[25] = 0; /* reserved for digital audio (see idx 15) */
2093 ataH2BE_U16(&pbBuf[26], 0); /* (obsolete) maximum write speed */
2094 ataH2BE_U16(&pbBuf[28], 0); /* (obsolete) current write speed */
2095 ataH2BE_U16(&pbBuf[30], 0); /* copy management revision supported 0=no CSS */
2096 pbBuf[32] = 0; /* reserved */
2097 pbBuf[33] = 0; /* reserved */
2098 pbBuf[34] = 0; /* reserved */
2099 pbBuf[35] = 1; /* rotation control CAV */
2100 ataH2BE_U16(&pbBuf[36], 0); /* current write speed */
2101 ataH2BE_U16(&pbBuf[38], 0); /* number of write speed performance descriptors */
2102 s->iSourceSink = ATAFN_SS_NULL;
2103 atapiCmdOK(s);
2104 return false;
2105}
2106
2107
2108static bool atapiRequestSenseSS(ATADevState *s)
2109{
2110 uint8_t *pbBuf = s->CTXSUFF(pbIOBuffer);
2111
2112 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
2113 Assert(s->cbElementaryTransfer <= 18);
2114 memset(pbBuf, 0, 18);
2115 pbBuf[0] = 0x70 | (1 << 7);
2116 pbBuf[2] = s->uATAPISenseKey;
2117 pbBuf[7] = 10;
2118 pbBuf[12] = s->uATAPIASC;
2119 s->iSourceSink = ATAFN_SS_NULL;
2120 atapiCmdOK(s);
2121 return false;
2122}
2123
2124
2125static bool atapiMechanismStatusSS(ATADevState *s)
2126{
2127 uint8_t *pbBuf = s->CTXSUFF(pbIOBuffer);
2128
2129 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
2130 Assert(s->cbElementaryTransfer <= 8);
2131 ataH2BE_U16(pbBuf, 0);
2132 /* no current LBA */
2133 pbBuf[2] = 0;
2134 pbBuf[3] = 0;
2135 pbBuf[4] = 0;
2136 pbBuf[5] = 1;
2137 ataH2BE_U16(pbBuf + 6, 0);
2138 s->iSourceSink = ATAFN_SS_NULL;
2139 atapiCmdOK(s);
2140 return false;
2141}
2142
2143
2144static bool atapiReadTOCNormalSS(ATADevState *s)
2145{
2146 uint8_t *pbBuf = s->CTXSUFF(pbIOBuffer), *q, iStartTrack;
2147 bool fMSF;
2148 uint32_t cbSize;
2149
2150 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
2151 fMSF = (s->aATAPICmd[1] >> 1) & 1;
2152 iStartTrack = s->aATAPICmd[6];
2153 if (iStartTrack > 1 && iStartTrack != 0xaa)
2154 {
2155 atapiCmdError(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INV_FIELD_IN_CMD_PACKET);
2156 return false;
2157 }
2158 q = pbBuf + 2;
2159 *q++ = 1; /* first session */
2160 *q++ = 1; /* last session */
2161 if (iStartTrack <= 1)
2162 {
2163 *q++ = 0; /* reserved */
2164 *q++ = 0x14; /* ADR, control */
2165 *q++ = 1; /* track number */
2166 *q++ = 0; /* reserved */
2167 if (fMSF)
2168 {
2169 *q++ = 0; /* reserved */
2170 ataLBA2MSF(q, 0);
2171 q += 3;
2172 }
2173 else
2174 {
2175 /* sector 0 */
2176 ataH2BE_U32(q, 0);
2177 q += 4;
2178 }
2179 }
2180 /* lead out track */
2181 *q++ = 0; /* reserved */
2182 *q++ = 0x14; /* ADR, control */
2183 *q++ = 0xaa; /* track number */
2184 *q++ = 0; /* reserved */
2185 if (fMSF)
2186 {
2187 *q++ = 0; /* reserved */
2188 ataLBA2MSF(q, s->cTotalSectors);
2189 q += 3;
2190 }
2191 else
2192 {
2193 ataH2BE_U32(q, s->cTotalSectors);
2194 q += 4;
2195 }
2196 cbSize = q - pbBuf;
2197 ataH2BE_U16(pbBuf, cbSize - 2);
2198 if (cbSize < s->cbTotalTransfer)
2199 s->cbTotalTransfer = cbSize;
2200 s->iSourceSink = ATAFN_SS_NULL;
2201 atapiCmdOK(s);
2202 return false;
2203}
2204
2205
2206static bool atapiReadTOCMultiSS(ATADevState *s)
2207{
2208 uint8_t *pbBuf = s->CTXSUFF(pbIOBuffer);
2209 bool fMSF;
2210
2211 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
2212 Assert(s->cbElementaryTransfer <= 12);
2213 fMSF = (s->aATAPICmd[1] >> 1) & 1;
2214 /* multi session: only a single session defined */
2215/** @todo double-check this stuff against what a real drive says for a CD-ROM (not a CD-R) with only a single data session. Maybe solve the problem with "cdrdao read-toc" not being able to figure out whether numbers are in BCD or hex. */
2216 memset(pbBuf, 0, 12);
2217 pbBuf[1] = 0x0a;
2218 pbBuf[2] = 0x01;
2219 pbBuf[3] = 0x01;
2220 pbBuf[5] = 0x14; /* ADR, control */
2221 pbBuf[6] = 1; /* first track in last complete session */
2222 if (fMSF)
2223 {
2224 pbBuf[8] = 0; /* reserved */
2225 ataLBA2MSF(&pbBuf[9], 0);
2226 }
2227 else
2228 {
2229 /* sector 0 */
2230 ataH2BE_U32(pbBuf + 8, 0);
2231 }
2232 s->iSourceSink = ATAFN_SS_NULL;
2233 atapiCmdOK(s);
2234 return false;
2235}
2236
2237
2238static bool atapiReadTOCRawSS(ATADevState *s)
2239{
2240 uint8_t *pbBuf = s->CTXSUFF(pbIOBuffer), *q, iStartTrack;
2241 bool fMSF;
2242 uint32_t cbSize;
2243
2244 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
2245 fMSF = (s->aATAPICmd[1] >> 1) & 1;
2246 iStartTrack = s->aATAPICmd[6];
2247
2248 q = pbBuf + 2;
2249 *q++ = 1; /* first session */
2250 *q++ = 1; /* last session */
2251
2252 *q++ = 1; /* session number */
2253 *q++ = 0x14; /* data track */
2254 *q++ = 0; /* track number */
2255 *q++ = 0xa0; /* first track in program area */
2256 *q++ = 0; /* min */
2257 *q++ = 0; /* sec */
2258 *q++ = 0; /* frame */
2259 *q++ = 0;
2260 *q++ = 1; /* first track */
2261 *q++ = 0x00; /* disk type CD-DA or CD data */
2262 *q++ = 0;
2263
2264 *q++ = 1; /* session number */
2265 *q++ = 0x14; /* data track */
2266 *q++ = 0; /* track number */
2267 *q++ = 0xa1; /* last track in program area */
2268 *q++ = 0; /* min */
2269 *q++ = 0; /* sec */
2270 *q++ = 0; /* frame */
2271 *q++ = 0;
2272 *q++ = 1; /* last track */
2273 *q++ = 0;
2274 *q++ = 0;
2275
2276 *q++ = 1; /* session number */
2277 *q++ = 0x14; /* data track */
2278 *q++ = 0; /* track number */
2279 *q++ = 0xa2; /* lead-out */
2280 *q++ = 0; /* min */
2281 *q++ = 0; /* sec */
2282 *q++ = 0; /* frame */
2283 if (fMSF)
2284 {
2285 *q++ = 0; /* reserved */
2286 ataLBA2MSF(q, s->cTotalSectors);
2287 q += 3;
2288 }
2289 else
2290 {
2291 ataH2BE_U32(q, s->cTotalSectors);
2292 q += 4;
2293 }
2294
2295 *q++ = 1; /* session number */
2296 *q++ = 0x14; /* ADR, control */
2297 *q++ = 0; /* track number */
2298 *q++ = 1; /* point */
2299 *q++ = 0; /* min */
2300 *q++ = 0; /* sec */
2301 *q++ = 0; /* frame */
2302 if (fMSF)
2303 {
2304 *q++ = 0; /* reserved */
2305 ataLBA2MSF(q, 0);
2306 q += 3;
2307 }
2308 else
2309 {
2310 /* sector 0 */
2311 ataH2BE_U32(q, 0);
2312 q += 4;
2313 }
2314
2315 cbSize = q - pbBuf;
2316 ataH2BE_U16(pbBuf, cbSize - 2);
2317 if (cbSize < s->cbTotalTransfer)
2318 s->cbTotalTransfer = cbSize;
2319 s->iSourceSink = ATAFN_SS_NULL;
2320 atapiCmdOK(s);
2321 return false;
2322}
2323
2324
2325static void atapiParseCmdVirtualATAPI(ATADevState *s)
2326{
2327 const uint8_t *pbPacket;
2328 uint8_t *pbBuf;
2329 uint32_t cbMax;
2330
2331 pbPacket = s->aATAPICmd;
2332 pbBuf = s->CTXSUFF(pbIOBuffer);
2333 switch (pbPacket[0])
2334 {
2335 case SCSI_TEST_UNIT_READY:
2336 if (s->cNotifiedMediaChange > 0)
2337 {
2338 if (s->cNotifiedMediaChange-- > 2)
2339 atapiCmdError(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
2340 else
2341 atapiCmdError(s, SCSI_SENSE_UNIT_ATTENTION, SCSI_ASC_MEDIUM_MAY_HAVE_CHANGED); /* media changed */
2342 }
2343 else if (s->pDrvMount->pfnIsMounted(s->pDrvMount))
2344 atapiCmdOK(s);
2345 else
2346 atapiCmdError(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
2347 break;
2348 case SCSI_MODE_SENSE_10:
2349 {
2350 uint8_t uPageControl, uPageCode;
2351 cbMax = ataBE2H_U16(pbPacket + 7);
2352 uPageControl = pbPacket[2] >> 6;
2353 uPageCode = pbPacket[2] & 0x3f;
2354 switch (uPageControl)
2355 {
2356 case SCSI_PAGECONTROL_CURRENT:
2357 switch (uPageCode)
2358 {
2359 case SCSI_MODEPAGE_ERROR_RECOVERY:
2360 ataStartTransfer(s, RT_MIN(cbMax, 16), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_MODE_SENSE_ERROR_RECOVERY, true);
2361 break;
2362 case SCSI_MODEPAGE_CD_STATUS:
2363 ataStartTransfer(s, RT_MIN(cbMax, 40), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_MODE_SENSE_CD_STATUS, true);
2364 break;
2365 default:
2366 goto error_cmd;
2367 }
2368 break;
2369 case SCSI_PAGECONTROL_CHANGEABLE:
2370 goto error_cmd;
2371 case SCSI_PAGECONTROL_DEFAULT:
2372 goto error_cmd;
2373 default:
2374 case SCSI_PAGECONTROL_SAVED:
2375 atapiCmdError(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_SAVING_PARAMETERS_NOT_SUPPORTED);
2376 break;
2377 }
2378 }
2379 break;
2380 case SCSI_REQUEST_SENSE:
2381 cbMax = pbPacket[4];
2382 ataStartTransfer(s, RT_MIN(cbMax, 18), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_REQUEST_SENSE, true);
2383 break;
2384 case SCSI_PREVENT_ALLOW_MEDIUM_REMOVAL:
2385 if (s->pDrvMount->pfnIsMounted(s->pDrvMount))
2386 {
2387 if (pbPacket[4] & 1)
2388 s->pDrvMount->pfnLock(s->pDrvMount);
2389 else
2390 s->pDrvMount->pfnUnlock(s->pDrvMount);
2391 atapiCmdOK(s);
2392 }
2393 else
2394 atapiCmdError(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
2395 break;
2396 case SCSI_READ_10:
2397 case SCSI_READ_12:
2398 {
2399 uint32_t cSectors, iATAPILBA;
2400
2401 if (s->cNotifiedMediaChange > 0)
2402 {
2403 s->cNotifiedMediaChange-- ;
2404 atapiCmdError(s, SCSI_SENSE_UNIT_ATTENTION, SCSI_ASC_MEDIUM_MAY_HAVE_CHANGED); /* media changed */
2405 break;
2406 }
2407 else if (!s->pDrvMount->pfnIsMounted(s->pDrvMount))
2408 {
2409 atapiCmdError(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
2410 break;
2411 }
2412 if (pbPacket[0] == SCSI_READ_10)
2413 cSectors = ataBE2H_U16(pbPacket + 7);
2414 else
2415 cSectors = ataBE2H_U32(pbPacket + 6);
2416 iATAPILBA = ataBE2H_U32(pbPacket + 2);
2417 if (cSectors == 0)
2418 {
2419 atapiCmdOK(s);
2420 break;
2421 }
2422 if ((uint64_t)iATAPILBA + cSectors > s->cTotalSectors)
2423 {
2424 /* Rate limited logging, one log line per second. For
2425 * guests that insist on reading from places outside the
2426 * valid area this often generates too many release log
2427 * entries otherwise. */
2428 static uint64_t uLastLogTS = 0;
2429 if (RTTimeMilliTS() >= uLastLogTS + 1000)
2430 {
2431 LogRel(("PIIX3 ATA: LUN#%d: CD-ROM block number %Ld invalid (READ)\n", s->iLUN, (uint64_t)iATAPILBA + cSectors));
2432 uLastLogTS = RTTimeMilliTS();
2433 }
2434 atapiCmdError(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_LOGICAL_BLOCK_OOR);
2435 break;
2436 }
2437 atapiReadSectors(s, iATAPILBA, cSectors, 2048);
2438 }
2439 break;
2440 case SCSI_READ_CD:
2441 {
2442 uint32_t cSectors, iATAPILBA;
2443
2444 if (s->cNotifiedMediaChange > 0)
2445 {
2446 s->cNotifiedMediaChange-- ;
2447 atapiCmdError(s, SCSI_SENSE_UNIT_ATTENTION, SCSI_ASC_MEDIUM_MAY_HAVE_CHANGED); /* media changed */
2448 break;
2449 }
2450 else if (!s->pDrvMount->pfnIsMounted(s->pDrvMount))
2451 {
2452 atapiCmdError(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
2453 break;
2454 }
2455 cSectors = (pbPacket[6] << 16) | (pbPacket[7] << 8) | pbPacket[8];
2456 iATAPILBA = ataBE2H_U32(pbPacket + 2);
2457 if (cSectors == 0)
2458 {
2459 atapiCmdOK(s);
2460 break;
2461 }
2462 if ((uint64_t)iATAPILBA + cSectors > s->cTotalSectors)
2463 {
2464 /* Rate limited logging, one log line per second. For
2465 * guests that insist on reading from places outside the
2466 * valid area this often generates too many release log
2467 * entries otherwise. */
2468 static uint64_t uLastLogTS = 0;
2469 if (RTTimeMilliTS() >= uLastLogTS + 1000)
2470 {
2471 LogRel(("PIIX3 ATA: LUN#%d: CD-ROM block number %Ld invalid (READ CD)\n", s->iLUN, (uint64_t)iATAPILBA + cSectors));
2472 uLastLogTS = RTTimeMilliTS();
2473 }
2474 atapiCmdError(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_LOGICAL_BLOCK_OOR);
2475 break;
2476 }
2477 switch (pbPacket[9] & 0xf8)
2478 {
2479 case 0x00:
2480 /* nothing */
2481 atapiCmdOK(s);
2482 break;
2483 case 0x10:
2484 /* normal read */
2485 atapiReadSectors(s, iATAPILBA, cSectors, 2048);
2486 break;
2487 case 0xf8:
2488 /* read all data */
2489 atapiReadSectors(s, iATAPILBA, cSectors, 2352);
2490 break;
2491 default:
2492 LogRel(("PIIX3 ATA: LUN#%d: CD-ROM sector format not supported\n", s->iLUN));
2493 atapiCmdError(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INV_FIELD_IN_CMD_PACKET);
2494 break;
2495 }
2496 }
2497 break;
2498 case SCSI_SEEK_10:
2499 {
2500 uint32_t iATAPILBA;
2501 if (s->cNotifiedMediaChange > 0)
2502 {
2503 s->cNotifiedMediaChange-- ;
2504 atapiCmdError(s, SCSI_SENSE_UNIT_ATTENTION, SCSI_ASC_MEDIUM_MAY_HAVE_CHANGED); /* media changed */
2505 break;
2506 }
2507 else if (!s->pDrvMount->pfnIsMounted(s->pDrvMount))
2508 {
2509 atapiCmdError(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
2510 break;
2511 }
2512 iATAPILBA = ataBE2H_U32(pbPacket + 2);
2513 if (iATAPILBA > s->cTotalSectors)
2514 {
2515 /* Rate limited logging, one log line per second. For
2516 * guests that insist on seeking to places outside the
2517 * valid area this often generates too many release log
2518 * entries otherwise. */
2519 static uint64_t uLastLogTS = 0;
2520 if (RTTimeMilliTS() >= uLastLogTS + 1000)
2521 {
2522 LogRel(("PIIX3 ATA: LUN#%d: CD-ROM block number %Ld invalid (SEEK)\n", s->iLUN, (uint64_t)iATAPILBA));
2523 uLastLogTS = RTTimeMilliTS();
2524 }
2525 atapiCmdError(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_LOGICAL_BLOCK_OOR);
2526 break;
2527 }
2528 atapiCmdOK(s);
2529 ataSetStatus(s, ATA_STAT_SEEK); /* Linux expects this. */
2530 }
2531 break;
2532 case SCSI_START_STOP_UNIT:
2533 {
2534 int rc = VINF_SUCCESS;
2535 switch (pbPacket[4] & 3)
2536 {
2537 case 0: /* 00 - Stop motor */
2538 case 1: /* 01 - Start motor */
2539 break;
2540 case 2: /* 10 - Eject media */
2541 /* This must be done from EMT. */
2542 {
2543 PATACONTROLLER pCtl = ATADEVSTATE_2_CONTROLLER(s);
2544 PPDMDEVINS pDevIns = ATADEVSTATE_2_DEVINS(s);
2545 PVMREQ pReq;
2546
2547 PDMCritSectLeave(&pCtl->lock);
2548 rc = VMR3ReqCall(PDMDevHlpGetVM(pDevIns), &pReq, RT_INDEFINITE_WAIT,
2549 (PFNRT)s->pDrvMount->pfnUnmount, 2, s->pDrvMount, false);
2550 AssertReleaseRC(rc);
2551 VMR3ReqFree(pReq);
2552 {
2553 STAM_PROFILE_START(&pCtl->StatLockWait, a);
2554 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
2555 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
2556 }
2557 }
2558 break;
2559 case 3: /* 11 - Load media */
2560 /** @todo rc = s->pDrvMount->pfnLoadMedia(s->pDrvMount) */
2561 break;
2562 }
2563 if (VBOX_SUCCESS(rc))
2564 atapiCmdOK(s);
2565 else
2566 atapiCmdError(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIA_LOAD_OR_EJECT_FAILED);
2567 }
2568 break;
2569 case SCSI_MECHANISM_STATUS:
2570 {
2571 cbMax = ataBE2H_U16(pbPacket + 8);
2572 ataStartTransfer(s, RT_MIN(cbMax, 8), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_MECHANISM_STATUS, true);
2573 }
2574 break;
2575 case SCSI_READ_TOC_PMA_ATIP:
2576 {
2577 uint8_t format;
2578
2579 if (s->cNotifiedMediaChange > 0)
2580 {
2581 s->cNotifiedMediaChange-- ;
2582 atapiCmdError(s, SCSI_SENSE_UNIT_ATTENTION, SCSI_ASC_MEDIUM_MAY_HAVE_CHANGED); /* media changed */
2583 break;
2584 }
2585 else if (!s->pDrvMount->pfnIsMounted(s->pDrvMount))
2586 {
2587 atapiCmdError(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
2588 break;
2589 }
2590 cbMax = ataBE2H_U16(pbPacket + 7);
2591 /* SCSI MMC-3 spec says format is at offset 2 (lower 4 bits),
2592 * but Linux kernel uses offset 9 (topmost 2 bits). Hope that
2593 * the other field is clear... */
2594 format = (pbPacket[2] & 0xf) | (pbPacket[9] >> 6);
2595 switch (format)
2596 {
2597 case 0:
2598 ataStartTransfer(s, cbMax, PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_READ_TOC_NORMAL, true);
2599 break;
2600 case 1:
2601 ataStartTransfer(s, RT_MIN(cbMax, 12), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_READ_TOC_MULTI, true);
2602 break;
2603 case 2:
2604 ataStartTransfer(s, cbMax, PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_READ_TOC_RAW, true);
2605 break;
2606 default:
2607 error_cmd:
2608 atapiCmdError(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INV_FIELD_IN_CMD_PACKET);
2609 break;
2610 }
2611 }
2612 break;
2613 case SCSI_READ_CAPACITY:
2614 if (s->cNotifiedMediaChange > 0)
2615 {
2616 s->cNotifiedMediaChange-- ;
2617 atapiCmdError(s, SCSI_SENSE_UNIT_ATTENTION, SCSI_ASC_MEDIUM_MAY_HAVE_CHANGED); /* media changed */
2618 break;
2619 }
2620 else if (!s->pDrvMount->pfnIsMounted(s->pDrvMount))
2621 {
2622 atapiCmdError(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
2623 break;
2624 }
2625 ataStartTransfer(s, 8, PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_READ_CAPACITY, true);
2626 break;
2627 case SCSI_READ_DISC_INFORMATION:
2628 if (s->cNotifiedMediaChange > 0)
2629 {
2630 s->cNotifiedMediaChange-- ;
2631 atapiCmdError(s, SCSI_SENSE_UNIT_ATTENTION, SCSI_ASC_MEDIUM_MAY_HAVE_CHANGED); /* media changed */
2632 break;
2633 }
2634 else if (!s->pDrvMount->pfnIsMounted(s->pDrvMount))
2635 {
2636 atapiCmdError(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
2637 break;
2638 }
2639 cbMax = ataBE2H_U16(pbPacket + 7);
2640 ataStartTransfer(s, RT_MIN(cbMax, 34), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_READ_DISC_INFORMATION, true);
2641 break;
2642 case SCSI_READ_TRACK_INFORMATION:
2643 if (s->cNotifiedMediaChange > 0)
2644 {
2645 s->cNotifiedMediaChange-- ;
2646 atapiCmdError(s, SCSI_SENSE_UNIT_ATTENTION, SCSI_ASC_MEDIUM_MAY_HAVE_CHANGED); /* media changed */
2647 break;
2648 }
2649 else if (!s->pDrvMount->pfnIsMounted(s->pDrvMount))
2650 {
2651 atapiCmdError(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
2652 break;
2653 }
2654 cbMax = ataBE2H_U16(pbPacket + 7);
2655 ataStartTransfer(s, RT_MIN(cbMax, 36), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_READ_TRACK_INFORMATION, true);
2656 break;
2657 case SCSI_GET_CONFIGURATION:
2658 /* No media change stuff here, it can confuse Linux guests. */
2659 cbMax = ataBE2H_U16(pbPacket + 7);
2660 ataStartTransfer(s, RT_MIN(cbMax, 32), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_GET_CONFIGURATION, true);
2661 break;
2662 case SCSI_INQUIRY:
2663 cbMax = pbPacket[4];
2664 ataStartTransfer(s, RT_MIN(cbMax, 36), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_INQUIRY, true);
2665 break;
2666 default:
2667 atapiCmdError(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_ILLEGAL_OPCODE);
2668 break;
2669 }
2670}
2671
2672
2673/*
2674 * Parse ATAPI commands, passing them directly to the CD/DVD drive.
2675 */
2676static void atapiParseCmdPassthrough(ATADevState *s)
2677{
2678 const uint8_t *pbPacket;
2679 uint8_t *pbBuf;
2680 uint32_t cSectors, iATAPILBA;
2681 uint32_t cbTransfer = 0;
2682 PDMBLOCKTXDIR uTxDir = PDMBLOCKTXDIR_NONE;
2683
2684 pbPacket = s->aATAPICmd;
2685 pbBuf = s->CTXSUFF(pbIOBuffer);
2686 switch (pbPacket[0])
2687 {
2688 case SCSI_BLANK:
2689 goto sendcmd;
2690 case SCSI_CLOSE_TRACK_SESSION:
2691 goto sendcmd;
2692 case SCSI_ERASE_10:
2693 iATAPILBA = ataBE2H_U32(pbPacket + 2);
2694 cbTransfer = ataBE2H_U16(pbPacket + 7);
2695 Log2(("ATAPI PT: lba %d\n", iATAPILBA));
2696 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
2697 goto sendcmd;
2698 case SCSI_FORMAT_UNIT:
2699 cbTransfer = s->uATARegLCyl | (s->uATARegHCyl << 8); /* use ATAPI transfer length */
2700 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
2701 goto sendcmd;
2702 case SCSI_GET_CONFIGURATION:
2703 cbTransfer = ataBE2H_U16(pbPacket + 7);
2704 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2705 goto sendcmd;
2706 case SCSI_GET_EVENT_STATUS_NOTIFICATION:
2707 cbTransfer = ataBE2H_U16(pbPacket + 7);
2708 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2709 goto sendcmd;
2710 case SCSI_GET_PERFORMANCE:
2711 cbTransfer = s->uATARegLCyl | (s->uATARegHCyl << 8); /* use ATAPI transfer length */
2712 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2713 goto sendcmd;
2714 case SCSI_INQUIRY:
2715 cbTransfer = pbPacket[4];
2716 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2717 goto sendcmd;
2718 case SCSI_LOAD_UNLOAD_MEDIUM:
2719 goto sendcmd;
2720 case SCSI_MECHANISM_STATUS:
2721 cbTransfer = ataBE2H_U16(pbPacket + 8);
2722 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2723 goto sendcmd;
2724 case SCSI_MODE_SELECT_10:
2725 cbTransfer = ataBE2H_U16(pbPacket + 7);
2726 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
2727 goto sendcmd;
2728 case SCSI_MODE_SENSE_10:
2729 cbTransfer = ataBE2H_U16(pbPacket + 7);
2730 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2731 goto sendcmd;
2732 case SCSI_PAUSE_RESUME:
2733 goto sendcmd;
2734 case SCSI_PLAY_AUDIO_10:
2735 goto sendcmd;
2736 case SCSI_PLAY_AUDIO_12:
2737 goto sendcmd;
2738 case SCSI_PLAY_AUDIO_MSF:
2739 goto sendcmd;
2740 case SCSI_PREVENT_ALLOW_MEDIUM_REMOVAL:
2741 /** @todo do not forget to unlock when a VM is shut down */
2742 goto sendcmd;
2743 case SCSI_READ_10:
2744 iATAPILBA = ataBE2H_U32(pbPacket + 2);
2745 cSectors = ataBE2H_U16(pbPacket + 7);
2746 Log2(("ATAPI PT: lba %d sectors %d\n", iATAPILBA, cSectors));
2747 s->cbATAPISector = 2048; /**< @todo this size is not always correct */
2748 cbTransfer = cSectors * s->cbATAPISector;
2749 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2750 goto sendcmd;
2751 case SCSI_READ_12:
2752 iATAPILBA = ataBE2H_U32(pbPacket + 2);
2753 cSectors = ataBE2H_U32(pbPacket + 6);
2754 Log2(("ATAPI PT: lba %d sectors %d\n", iATAPILBA, cSectors));
2755 s->cbATAPISector = 2048; /**< @todo this size is not always correct */
2756 cbTransfer = cSectors * s->cbATAPISector;
2757 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2758 goto sendcmd;
2759 case SCSI_READ_BUFFER:
2760 cbTransfer = ataBE2H_U24(pbPacket + 6);
2761 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2762 goto sendcmd;
2763 case SCSI_READ_BUFFER_CAPACITY:
2764 cbTransfer = ataBE2H_U16(pbPacket + 7);
2765 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2766 goto sendcmd;
2767 case SCSI_READ_CAPACITY:
2768 cbTransfer = 8;
2769 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2770 goto sendcmd;
2771 case SCSI_READ_CD:
2772 s->cbATAPISector = 2048; /**< @todo this size is not always correct */
2773 cbTransfer = ataBE2H_U24(pbPacket + 6) / s->cbATAPISector * s->cbATAPISector;
2774 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2775 goto sendcmd;
2776 case SCSI_READ_CD_MSF:
2777 cSectors = ataMSF2LBA(pbPacket + 6) - ataMSF2LBA(pbPacket + 3);
2778 if (cSectors > 32)
2779 cSectors = 32; /* Limit transfer size to 64~74K. Safety first. In any case this can only harm software doing CDDA extraction. */
2780 s->cbATAPISector = 2048; /**< @todo this size is not always correct */
2781 cbTransfer = cSectors * s->cbATAPISector;
2782 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2783 goto sendcmd;
2784 case SCSI_READ_DISC_INFORMATION:
2785 cbTransfer = ataBE2H_U16(pbPacket + 7);
2786 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2787 goto sendcmd;
2788 case SCSI_READ_DVD_STRUCTURE:
2789 cbTransfer = ataBE2H_U16(pbPacket + 8);
2790 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2791 goto sendcmd;
2792 case SCSI_READ_FORMAT_CAPACITIES:
2793 cbTransfer = ataBE2H_U16(pbPacket + 7);
2794 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2795 goto sendcmd;
2796 case SCSI_READ_SUBCHANNEL:
2797 cbTransfer = ataBE2H_U16(pbPacket + 7);
2798 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2799 goto sendcmd;
2800 case SCSI_READ_TOC_PMA_ATIP:
2801 cbTransfer = ataBE2H_U16(pbPacket + 7);
2802 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2803 goto sendcmd;
2804 case SCSI_READ_TRACK_INFORMATION:
2805 cbTransfer = ataBE2H_U16(pbPacket + 7);
2806 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2807 goto sendcmd;
2808 case SCSI_REPAIR_TRACK:
2809 goto sendcmd;
2810 case SCSI_REPORT_KEY:
2811 cbTransfer = ataBE2H_U16(pbPacket + 8);
2812 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2813 goto sendcmd;
2814 case SCSI_REQUEST_SENSE:
2815 cbTransfer = pbPacket[4];
2816 if (s->uATAPISenseKey != SCSI_SENSE_NONE)
2817 {
2818 ataStartTransfer(s, RT_MIN(cbTransfer, 18), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_REQUEST_SENSE, true);
2819 break;
2820 }
2821 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2822 goto sendcmd;
2823 case SCSI_RESERVE_TRACK:
2824 goto sendcmd;
2825 case SCSI_SCAN:
2826 goto sendcmd;
2827 case SCSI_SEEK_10:
2828 goto sendcmd;
2829 case SCSI_SEND_CUE_SHEET:
2830 cbTransfer = ataBE2H_U24(pbPacket + 6);
2831 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
2832 goto sendcmd;
2833 case SCSI_SEND_DVD_STRUCTURE:
2834 cbTransfer = ataBE2H_U16(pbPacket + 8);
2835 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
2836 goto sendcmd;
2837 case SCSI_SEND_EVENT:
2838 cbTransfer = ataBE2H_U16(pbPacket + 8);
2839 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
2840 goto sendcmd;
2841 case SCSI_SEND_KEY:
2842 cbTransfer = ataBE2H_U16(pbPacket + 8);
2843 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
2844 goto sendcmd;
2845 case SCSI_SEND_OPC_INFORMATION:
2846 cbTransfer = ataBE2H_U16(pbPacket + 7);
2847 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
2848 goto sendcmd;
2849 case SCSI_SET_CD_SPEED:
2850 goto sendcmd;
2851 case SCSI_SET_READ_AHEAD:
2852 goto sendcmd;
2853 case SCSI_SET_STREAMING:
2854 cbTransfer = ataBE2H_U16(pbPacket + 9);
2855 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
2856 goto sendcmd;
2857 case SCSI_START_STOP_UNIT:
2858 goto sendcmd;
2859 case SCSI_STOP_PLAY_SCAN:
2860 goto sendcmd;
2861 case SCSI_SYNCHRONIZE_CACHE:
2862 goto sendcmd;
2863 case SCSI_TEST_UNIT_READY:
2864 goto sendcmd;
2865 case SCSI_VERIFY_10:
2866 goto sendcmd;
2867 case SCSI_WRITE_10:
2868 iATAPILBA = ataBE2H_U32(pbPacket + 2);
2869 cSectors = ataBE2H_U16(pbPacket + 7);
2870 Log2(("ATAPI PT: lba %d sectors %d\n", iATAPILBA, cSectors));
2871#if 0
2872 /* The sector size is determined by the async I/O thread. */
2873 s->cbATAPISector = 0;
2874 /* Preliminary, will be corrected once the sector size is known. */
2875 cbTransfer = cSectors;
2876#else
2877 s->cbATAPISector = 2048; /**< @todo this size is not always correct */
2878 cbTransfer = cSectors * s->cbATAPISector;
2879#endif
2880 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
2881 goto sendcmd;
2882 case SCSI_WRITE_12:
2883 iATAPILBA = ataBE2H_U32(pbPacket + 2);
2884 cSectors = ataBE2H_U32(pbPacket + 6);
2885 Log2(("ATAPI PT: lba %d sectors %d\n", iATAPILBA, cSectors));
2886#if 0
2887 /* The sector size is determined by the async I/O thread. */
2888 s->cbATAPISector = 0;
2889 /* Preliminary, will be corrected once the sector size is known. */
2890 cbTransfer = cSectors;
2891#else
2892 s->cbATAPISector = 2048; /**< @todo this size is not always correct */
2893 cbTransfer = cSectors * s->cbATAPISector;
2894#endif
2895 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
2896 goto sendcmd;
2897 case SCSI_WRITE_AND_VERIFY_10:
2898 iATAPILBA = ataBE2H_U32(pbPacket + 2);
2899 cSectors = ataBE2H_U16(pbPacket + 7);
2900 Log2(("ATAPI PT: lba %d sectors %d\n", iATAPILBA, cSectors));
2901 /* The sector size is determined by the async I/O thread. */
2902 s->cbATAPISector = 0;
2903 /* Preliminary, will be corrected once the sector size is known. */
2904 cbTransfer = cSectors;
2905 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
2906 goto sendcmd;
2907 case SCSI_WRITE_BUFFER:
2908 switch (pbPacket[1] & 0x1f)
2909 {
2910 case 0x04: /* download microcode */
2911 case 0x05: /* download microcode and save */
2912 case 0x06: /* download microcode with offsets */
2913 case 0x07: /* download microcode with offsets and save */
2914 case 0x0e: /* download microcode with offsets and defer activation */
2915 case 0x0f: /* activate deferred microcode */
2916 LogRel(("PIIX3 ATA: LUN#%d: CD-ROM passthrough command attempted to update firmware, blocked\n", s->iLUN));
2917 atapiCmdError(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INV_FIELD_IN_CMD_PACKET);
2918 break;
2919 default:
2920 cbTransfer = ataBE2H_U16(pbPacket + 6);
2921 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
2922 goto sendcmd;
2923 }
2924 break;
2925 case SCSI_REPORT_LUNS: /* Not part of MMC-3, but used by Windows. */
2926 cbTransfer = ataBE2H_U32(pbPacket + 6);
2927 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2928 goto sendcmd;
2929 case SCSI_REZERO_UNIT:
2930 /* Obsolete command used by cdrecord. What else would one expect?
2931 * This command is not sent to the drive, it is handled internally,
2932 * as the Linux kernel doesn't like it (message "scsi: unknown
2933 * opcode 0x01" in syslog) and replies with a sense code of 0,
2934 * which sends cdrecord to an endless loop. */
2935 atapiCmdError(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_ILLEGAL_OPCODE);
2936 break;
2937 default:
2938 LogRel(("PIIX3 ATA: LUN#%d: passthrough unimplemented for command %#x\n", s->iLUN, pbPacket[0]));
2939 atapiCmdError(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_ILLEGAL_OPCODE);
2940 break;
2941 sendcmd:
2942 /* Send a command to the drive, passing data in/out as required. */
2943 Log2(("ATAPI PT: max size %d\n", cbTransfer));
2944 Assert(cbTransfer <= s->cbIOBuffer);
2945 if (cbTransfer == 0)
2946 uTxDir = PDMBLOCKTXDIR_NONE;
2947 ataStartTransfer(s, cbTransfer, uTxDir, ATAFN_BT_ATAPI_PASSTHROUGH_CMD, ATAFN_SS_ATAPI_PASSTHROUGH, true);
2948 }
2949}
2950
2951
2952static void atapiParseCmd(ATADevState *s)
2953{
2954 const uint8_t *pbPacket;
2955
2956 pbPacket = s->aATAPICmd;
2957#ifdef DEBUG
2958 Log(("%s: LUN#%d DMA=%d CMD=%#04x \"%s\"\n", __FUNCTION__, s->iLUN, s->fDMA, pbPacket[0], g_apszSCSICmdNames[pbPacket[0]]));
2959#else /* !DEBUG */
2960 Log(("%s: LUN#%d DMA=%d CMD=%#04x\n", __FUNCTION__, s->iLUN, s->fDMA, pbPacket[0]));
2961#endif /* !DEBUG */
2962 Log2(("%s: limit=%#x packet: %.*Vhxs\n", __FUNCTION__, s->uATARegLCyl | (s->uATARegHCyl << 8), ATAPI_PACKET_SIZE, pbPacket));
2963
2964 if (s->fATAPIPassthrough)
2965 atapiParseCmdPassthrough(s);
2966 else
2967 atapiParseCmdVirtualATAPI(s);
2968}
2969
2970
2971static bool ataPacketSS(ATADevState *s)
2972{
2973 s->fDMA = !!(s->uATARegFeature & 1);
2974 memcpy(s->aATAPICmd, s->CTXSUFF(pbIOBuffer), ATAPI_PACKET_SIZE);
2975 s->uTxDir = PDMBLOCKTXDIR_NONE;
2976 s->cbTotalTransfer = 0;
2977 s->cbElementaryTransfer = 0;
2978 atapiParseCmd(s);
2979 return false;
2980}
2981
2982
2983/**
2984 * Called when a media is mounted.
2985 *
2986 * @param pInterface Pointer to the interface structure containing the called function pointer.
2987 */
2988static DECLCALLBACK(void) ataMountNotify(PPDMIMOUNTNOTIFY pInterface)
2989{
2990 ATADevState *pIf = PDMIMOUNTNOTIFY_2_ATASTATE(pInterface);
2991 Log(("%s: changing LUN#%d\n", __FUNCTION__, pIf->iLUN));
2992
2993 /* Ignore the call if we're called while being attached. */
2994 if (!pIf->pDrvBlock)
2995 return;
2996
2997 if (pIf->fATAPI)
2998 pIf->cTotalSectors = pIf->pDrvBlock->pfnGetSize(pIf->pDrvBlock) / 2048;
2999 else
3000 pIf->cTotalSectors = pIf->pDrvBlock->pfnGetSize(pIf->pDrvBlock) / 512;
3001
3002 /* Report media changed in TEST UNIT and other (probably incorrect) places. */
3003 if (pIf->cNotifiedMediaChange < 2)
3004 pIf->cNotifiedMediaChange = 2;
3005}
3006
3007/**
3008 * Called when a media is unmounted
3009 * @param pInterface Pointer to the interface structure containing the called function pointer.
3010 */
3011static DECLCALLBACK(void) ataUnmountNotify(PPDMIMOUNTNOTIFY pInterface)
3012{
3013 ATADevState *pIf = PDMIMOUNTNOTIFY_2_ATASTATE(pInterface);
3014 Log(("%s:\n", __FUNCTION__));
3015 pIf->cTotalSectors = 0;
3016
3017 /*
3018 * Whatever I do, XP will not use the GET MEDIA STATUS nor the EVENT stuff.
3019 * However, it will respond to TEST UNIT with a 0x6 0x28 (media changed) sense code.
3020 * So, we'll give it 4 TEST UNIT command to catch up, two which the media is not
3021 * present and 2 in which it is changed.
3022 */
3023 pIf->cNotifiedMediaChange = 4;
3024}
3025
3026static void ataPacketBT(ATADevState *s)
3027{
3028 s->cbElementaryTransfer = s->cbTotalTransfer;
3029 s->uATARegNSector = (s->uATARegNSector & ~7) | ATAPI_INT_REASON_CD;
3030 Log2(("%s: interrupt reason %#04x\n", __FUNCTION__, s->uATARegNSector));
3031 ataSetStatusValue(s, ATA_STAT_READY);
3032}
3033
3034
3035static void ataResetDevice(ATADevState *s)
3036{
3037 s->cMultSectors = ATA_MAX_MULT_SECTORS;
3038 s->cNotifiedMediaChange = 0;
3039 ataUnsetIRQ(s);
3040
3041 s->uATARegSelect = 0x20;
3042 ataSetStatusValue(s, ATA_STAT_READY);
3043 ataSetSignature(s);
3044 s->cbTotalTransfer = 0;
3045 s->cbElementaryTransfer = 0;
3046 s->iIOBufferPIODataStart = 0;
3047 s->iIOBufferPIODataEnd = 0;
3048 s->iBeginTransfer = ATAFN_BT_NULL;
3049 s->iSourceSink = ATAFN_SS_NULL;
3050 s->fATAPITransfer = false;
3051 s->uATATransferMode = ATA_MODE_UDMA | 2; /* PIIX3 supports only up to UDMA2 */
3052
3053 s->uATARegFeature = 0;
3054}
3055
3056
3057static bool ataExecuteDeviceDiagnosticSS(ATADevState *s)
3058{
3059 ataSetSignature(s);
3060 ataSetStatusValue(s, 0); /* NOTE: READY is _not_ set */
3061 s->uATARegError = 0x01;
3062 return false;
3063}
3064
3065
3066static void ataParseCmd(ATADevState *s, uint8_t cmd)
3067{
3068#ifdef DEBUG
3069 Log(("%s: LUN#%d CMD=%#04x \"%s\"\n", __FUNCTION__, s->iLUN, cmd, g_apszATACmdNames[cmd]));
3070#else /* !DEBUG */
3071 Log(("%s: LUN#%d CMD=%#04x\n", __FUNCTION__, s->iLUN, cmd));
3072#endif /* !DEBUG */
3073 s->fLBA48 = false;
3074 s->fDMA = false;
3075 if (cmd == ATA_IDLE_IMMEDIATE)
3076 {
3077 /* Detect Linux timeout recovery, first tries IDLE IMMEDIATE (which
3078 * would overwrite the failing command unfortunately), then RESET. */
3079 int32_t uCmdWait = -1;
3080 uint64_t uNow = RTTimeNanoTS();
3081 if (s->u64CmdTS)
3082 uCmdWait = (uNow - s->u64CmdTS) / 1000;
3083 LogRel(("PIIX3 ATA: LUN#%d: IDLE IMMEDIATE, CmdIf=%#04x (%d usec ago)\n",
3084 s->iLUN, s->uATARegCommand, uCmdWait));
3085 }
3086 s->uATARegCommand = cmd;
3087 switch (cmd)
3088 {
3089 case ATA_IDENTIFY_DEVICE:
3090 if (s->pDrvBlock && !s->fATAPI)
3091 ataStartTransfer(s, 512, PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_NULL, ATAFN_SS_IDENTIFY, false);
3092 else
3093 {
3094 if (s->fATAPI)
3095 ataSetSignature(s);
3096 ataCmdError(s, ABRT_ERR);
3097 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
3098 }
3099 break;
3100 case ATA_INITIALIZE_DEVICE_PARAMETERS:
3101 case ATA_RECALIBRATE:
3102 ataCmdOK(s, ATA_STAT_SEEK);
3103 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
3104 break;
3105 case ATA_SET_MULTIPLE_MODE:
3106 if ( s->uATARegNSector != 0
3107 && ( s->uATARegNSector > ATA_MAX_MULT_SECTORS
3108 || (s->uATARegNSector & (s->uATARegNSector - 1)) != 0))
3109 {
3110 ataCmdError(s, ABRT_ERR);
3111 }
3112 else
3113 {
3114 Log2(("%s: set multi sector count to %d\n", __FUNCTION__, s->uATARegNSector));
3115 s->cMultSectors = s->uATARegNSector;
3116 ataCmdOK(s, 0);
3117 }
3118 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
3119 break;
3120 case ATA_READ_VERIFY_SECTORS_EXT:
3121 s->fLBA48 = true;
3122 case ATA_READ_VERIFY_SECTORS:
3123 case ATA_READ_VERIFY_SECTORS_WITHOUT_RETRIES:
3124 /* do sector number check ? */
3125 ataCmdOK(s, 0);
3126 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
3127 break;
3128 case ATA_READ_SECTORS_EXT:
3129 s->fLBA48 = true;
3130 case ATA_READ_SECTORS:
3131 case ATA_READ_SECTORS_WITHOUT_RETRIES:
3132 if (!s->pDrvBlock)
3133 goto abort_cmd;
3134 s->cSectorsPerIRQ = 1;
3135 ataStartTransfer(s, ataGetNSectors(s) * 512, PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_READ_WRITE_SECTORS, ATAFN_SS_READ_SECTORS, false);
3136 break;
3137 case ATA_WRITE_SECTORS_EXT:
3138 s->fLBA48 = true;
3139 case ATA_WRITE_SECTORS:
3140 case ATA_WRITE_SECTORS_WITHOUT_RETRIES:
3141 s->cSectorsPerIRQ = 1;
3142 ataStartTransfer(s, ataGetNSectors(s) * 512, PDMBLOCKTXDIR_TO_DEVICE, ATAFN_BT_READ_WRITE_SECTORS, ATAFN_SS_WRITE_SECTORS, false);
3143 break;
3144 case ATA_READ_MULTIPLE_EXT:
3145 s->fLBA48 = true;
3146 case ATA_READ_MULTIPLE:
3147 if (!s->cMultSectors)
3148 goto abort_cmd;
3149 s->cSectorsPerIRQ = s->cMultSectors;
3150 ataStartTransfer(s, ataGetNSectors(s) * 512, PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_READ_WRITE_SECTORS, ATAFN_SS_READ_SECTORS, false);
3151 break;
3152 case ATA_WRITE_MULTIPLE_EXT:
3153 s->fLBA48 = true;
3154 case ATA_WRITE_MULTIPLE:
3155 if (!s->cMultSectors)
3156 goto abort_cmd;
3157 s->cSectorsPerIRQ = s->cMultSectors;
3158 ataStartTransfer(s, ataGetNSectors(s) * 512, PDMBLOCKTXDIR_TO_DEVICE, ATAFN_BT_READ_WRITE_SECTORS, ATAFN_SS_WRITE_SECTORS, false);
3159 break;
3160 case ATA_READ_DMA_EXT:
3161 s->fLBA48 = true;
3162 case ATA_READ_DMA:
3163 case ATA_READ_DMA_WITHOUT_RETRIES:
3164 if (!s->pDrvBlock)
3165 goto abort_cmd;
3166 s->cSectorsPerIRQ = ATA_MAX_MULT_SECTORS;
3167 s->fDMA = true;
3168 ataStartTransfer(s, ataGetNSectors(s) * 512, PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_READ_WRITE_SECTORS, ATAFN_SS_READ_SECTORS, false);
3169 break;
3170 case ATA_WRITE_DMA_EXT:
3171 s->fLBA48 = true;
3172 case ATA_WRITE_DMA:
3173 case ATA_WRITE_DMA_WITHOUT_RETRIES:
3174 if (!s->pDrvBlock)
3175 goto abort_cmd;
3176 s->cSectorsPerIRQ = ATA_MAX_MULT_SECTORS;
3177 s->fDMA = true;
3178 ataStartTransfer(s, ataGetNSectors(s) * 512, PDMBLOCKTXDIR_TO_DEVICE, ATAFN_BT_READ_WRITE_SECTORS, ATAFN_SS_WRITE_SECTORS, false);
3179 break;
3180 case ATA_READ_NATIVE_MAX_ADDRESS_EXT:
3181 s->fLBA48 = true;
3182 ataSetSector(s, s->cTotalSectors - 1);
3183 ataCmdOK(s, 0);
3184 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
3185 break;
3186 case ATA_READ_NATIVE_MAX_ADDRESS:
3187 ataSetSector(s, RT_MIN(s->cTotalSectors, 1 << 28) - 1);
3188 ataCmdOK(s, 0);
3189 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
3190 break;
3191 case ATA_CHECK_POWER_MODE:
3192 s->uATARegNSector = 0xff; /* drive active or idle */
3193 ataCmdOK(s, 0);
3194 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
3195 break;
3196 case ATA_SET_FEATURES:
3197 Log2(("%s: feature=%#x\n", __FUNCTION__, s->uATARegFeature));
3198 if (!s->pDrvBlock)
3199 goto abort_cmd;
3200 switch (s->uATARegFeature)
3201 {
3202 case 0x02: /* write cache enable */
3203 Log2(("%s: write cache enable\n", __FUNCTION__));
3204 ataCmdOK(s, ATA_STAT_SEEK);
3205 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
3206 break;
3207 case 0xaa: /* read look-ahead enable */
3208 Log2(("%s: read look-ahead enable\n", __FUNCTION__));
3209 ataCmdOK(s, ATA_STAT_SEEK);
3210 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
3211 break;
3212 case 0x55: /* read look-ahead disable */
3213 Log2(("%s: read look-ahead disable\n", __FUNCTION__));
3214 ataCmdOK(s, ATA_STAT_SEEK);
3215 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
3216 break;
3217 case 0xcc: /* reverting to power-on defaults enable */
3218 Log2(("%s: revert to power-on defaults enable\n", __FUNCTION__));
3219 ataCmdOK(s, ATA_STAT_SEEK);
3220 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
3221 break;
3222 case 0x66: /* reverting to power-on defaults disable */
3223 Log2(("%s: revert to power-on defaults disable\n", __FUNCTION__));
3224 ataCmdOK(s, ATA_STAT_SEEK);
3225 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
3226 break;
3227 case 0x82: /* write cache disable */
3228 Log2(("%s: write cache disable\n", __FUNCTION__));
3229 /* As per the ATA/ATAPI-6 specs, a write cache disable
3230 * command MUST flush the write buffers to disc. */
3231 ataStartTransfer(s, 0, PDMBLOCKTXDIR_NONE, ATAFN_BT_NULL, ATAFN_SS_FLUSH, false);
3232 break;
3233 case 0x03: { /* set transfer mode */
3234 Log2(("%s: transfer mode %#04x\n", __FUNCTION__, s->uATARegNSector));
3235 switch (s->uATARegNSector & 0xf8)
3236 {
3237 case 0x00: /* PIO default */
3238 case 0x08: /* PIO mode */
3239 break;
3240 case ATA_MODE_MDMA: /* MDMA mode */
3241 s->uATATransferMode = (s->uATARegNSector & 0xf8) | RT_MIN(s->uATARegNSector & 0x07, ATA_MDMA_MODE_MAX);
3242 break;
3243 case ATA_MODE_UDMA: /* UDMA mode */
3244 s->uATATransferMode = (s->uATARegNSector & 0xf8) | RT_MIN(s->uATARegNSector & 0x07, ATA_UDMA_MODE_MAX);
3245 break;
3246 default:
3247 goto abort_cmd;
3248 }
3249 ataCmdOK(s, ATA_STAT_SEEK);
3250 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
3251 break;
3252 }
3253 default:
3254 goto abort_cmd;
3255 }
3256 /*
3257 * OS/2 workarond:
3258 * The OS/2 IDE driver from MCP2 appears to rely on the feature register being
3259 * reset here. According to the specification, this is a driver bug as the register
3260 * contents are undefined after the call. This means we can just as well reset it.
3261 */
3262 s->uATARegFeature = 0;
3263 break;
3264 case ATA_FLUSH_CACHE_EXT:
3265 case ATA_FLUSH_CACHE:
3266 if (!s->pDrvBlock || s->fATAPI)
3267 goto abort_cmd;
3268 ataStartTransfer(s, 0, PDMBLOCKTXDIR_NONE, ATAFN_BT_NULL, ATAFN_SS_FLUSH, false);
3269 break;
3270 case ATA_STANDBY_IMMEDIATE:
3271 ataCmdOK(s, 0);
3272 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
3273 break;
3274 case ATA_IDLE_IMMEDIATE:
3275 LogRel(("PIIX3 ATA: LUN#%d: aborting current command\n", s->iLUN));
3276 ataAbortCurrentCommand(s, false);
3277 break;
3278 /* ATAPI commands */
3279 case ATA_IDENTIFY_PACKET_DEVICE:
3280 if (s->fATAPI)
3281 ataStartTransfer(s, 512, PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_NULL, ATAFN_SS_ATAPI_IDENTIFY, false);
3282 else
3283 {
3284 ataCmdError(s, ABRT_ERR);
3285 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
3286 }
3287 break;
3288 case ATA_EXECUTE_DEVICE_DIAGNOSTIC:
3289 ataStartTransfer(s, 0, PDMBLOCKTXDIR_NONE, ATAFN_BT_NULL, ATAFN_SS_EXECUTE_DEVICE_DIAGNOSTIC, false);
3290 break;
3291 case ATA_DEVICE_RESET:
3292 if (!s->fATAPI)
3293 goto abort_cmd;
3294 LogRel(("PIIX3 ATA: LUN#%d: performing device RESET\n", s->iLUN));
3295 ataAbortCurrentCommand(s, true);
3296 break;
3297 case ATA_PACKET:
3298 if (!s->fATAPI)
3299 goto abort_cmd;
3300 /* overlapping commands not supported */
3301 if (s->uATARegFeature & 0x02)
3302 goto abort_cmd;
3303 ataStartTransfer(s, ATAPI_PACKET_SIZE, PDMBLOCKTXDIR_TO_DEVICE, ATAFN_BT_PACKET, ATAFN_SS_PACKET, false);
3304 break;
3305 default:
3306 abort_cmd:
3307 ataCmdError(s, ABRT_ERR);
3308 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
3309 break;
3310 }
3311}
3312
3313
3314/**
3315 * Waits for a particular async I/O thread to complete whatever it
3316 * is doing at the moment.
3317 *
3318 * @returns true on success.
3319 * @returns false when the thread is still processing.
3320 * @param pData Pointer to the controller data.
3321 * @param cMillies How long to wait (total).
3322 */
3323static bool ataWaitForAsyncIOIsIdle(PATACONTROLLER pCtl, unsigned cMillies)
3324{
3325 uint64_t u64Start;
3326
3327 /*
3328 * Wait for any pending async operation to finish
3329 */
3330 u64Start = RTTimeMilliTS();
3331 for (;;)
3332 {
3333 if (ataAsyncIOIsIdle(pCtl, false))
3334 return true;
3335 if (RTTimeMilliTS() - u64Start >= cMillies)
3336 break;
3337
3338 /* Sleep for a bit. */
3339 RTThreadSleep(100);
3340 }
3341
3342 return false;
3343}
3344
3345#endif /* IN_RING3 */
3346
3347static int ataIOPortWriteU8(PATACONTROLLER pCtl, uint32_t addr, uint32_t val)
3348{
3349 Log2(("%s: write addr=%#x val=%#04x\n", __FUNCTION__, addr, val));
3350 addr &= 7;
3351 switch (addr)
3352 {
3353 case 0:
3354 break;
3355 case 1: /* feature register */
3356 /* NOTE: data is written to the two drives */
3357 pCtl->aIfs[0].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
3358 pCtl->aIfs[1].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
3359 pCtl->aIfs[0].uATARegFeatureHOB = pCtl->aIfs[0].uATARegFeature;
3360 pCtl->aIfs[1].uATARegFeatureHOB = pCtl->aIfs[1].uATARegFeature;
3361 pCtl->aIfs[0].uATARegFeature = val;
3362 pCtl->aIfs[1].uATARegFeature = val;
3363 break;
3364 case 2: /* sector count */
3365 pCtl->aIfs[0].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
3366 pCtl->aIfs[1].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
3367 pCtl->aIfs[0].uATARegNSectorHOB = pCtl->aIfs[0].uATARegNSector;
3368 pCtl->aIfs[1].uATARegNSectorHOB = pCtl->aIfs[1].uATARegNSector;
3369 pCtl->aIfs[0].uATARegNSector = val;
3370 pCtl->aIfs[1].uATARegNSector = val;
3371 break;
3372 case 3: /* sector number */
3373 pCtl->aIfs[0].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
3374 pCtl->aIfs[1].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
3375 pCtl->aIfs[0].uATARegSectorHOB = pCtl->aIfs[0].uATARegSector;
3376 pCtl->aIfs[1].uATARegSectorHOB = pCtl->aIfs[1].uATARegSector;
3377 pCtl->aIfs[0].uATARegSector = val;
3378 pCtl->aIfs[1].uATARegSector = val;
3379 break;
3380 case 4: /* cylinder low */
3381 pCtl->aIfs[0].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
3382 pCtl->aIfs[1].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
3383 pCtl->aIfs[0].uATARegLCylHOB = pCtl->aIfs[0].uATARegLCyl;
3384 pCtl->aIfs[1].uATARegLCylHOB = pCtl->aIfs[1].uATARegLCyl;
3385 pCtl->aIfs[0].uATARegLCyl = val;
3386 pCtl->aIfs[1].uATARegLCyl = val;
3387 break;
3388 case 5: /* cylinder high */
3389 pCtl->aIfs[0].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
3390 pCtl->aIfs[1].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
3391 pCtl->aIfs[0].uATARegHCylHOB = pCtl->aIfs[0].uATARegHCyl;
3392 pCtl->aIfs[1].uATARegHCylHOB = pCtl->aIfs[1].uATARegHCyl;
3393 pCtl->aIfs[0].uATARegHCyl = val;
3394 pCtl->aIfs[1].uATARegHCyl = val;
3395 break;
3396 case 6: /* drive/head */
3397 pCtl->aIfs[0].uATARegSelect = (val & ~0x10) | 0xa0;
3398 pCtl->aIfs[1].uATARegSelect = (val | 0x10) | 0xa0;
3399 if (((val >> 4) & 1) != pCtl->iSelectedIf)
3400 {
3401 PPDMDEVINS pDevIns = CONTROLLER_2_DEVINS(pCtl);
3402
3403 /* select another drive */
3404 pCtl->iSelectedIf = (val >> 4) & 1;
3405 /* The IRQ line is multiplexed between the two drives, so
3406 * update the state when switching to another drive. Only need
3407 * to update interrupt line if it is enabled and there is a
3408 * state change. */
3409 if ( !(pCtl->aIfs[pCtl->iSelectedIf].uATARegDevCtl & ATA_DEVCTL_DISABLE_IRQ)
3410 && ( pCtl->aIfs[pCtl->iSelectedIf].fIrqPending
3411 != pCtl->aIfs[pCtl->iSelectedIf ^ 1].fIrqPending))
3412 {
3413 if (pCtl->aIfs[pCtl->iSelectedIf].fIrqPending)
3414 {
3415 Log2(("%s: LUN#%d asserting IRQ (drive select change)\n", __FUNCTION__, pCtl->aIfs[pCtl->iSelectedIf].iLUN));
3416 /* The BMDMA unit unconditionally sets BM_STATUS_INT if
3417 * the interrupt line is asserted. It monitors the line
3418 * for a rising edge. */
3419 pCtl->BmDma.u8Status |= BM_STATUS_INT;
3420 if (pCtl->irq == 16)
3421 PDMDevHlpPCISetIrqNoWait(pDevIns, 0, 1);
3422 else
3423 PDMDevHlpISASetIrqNoWait(pDevIns, pCtl->irq, 1);
3424 }
3425 else
3426 {
3427 Log2(("%s: LUN#%d deasserting IRQ (drive select change)\n", __FUNCTION__, pCtl->aIfs[pCtl->iSelectedIf].iLUN));
3428 if (pCtl->irq == 16)
3429 PDMDevHlpPCISetIrqNoWait(pDevIns, 0, 0);
3430 else
3431 PDMDevHlpISASetIrqNoWait(pDevIns, pCtl->irq, 0);
3432 }
3433 }
3434 }
3435 break;
3436 default:
3437 case 7: /* command */
3438 /* ignore commands to non existant slave */
3439 if (pCtl->iSelectedIf && !pCtl->aIfs[pCtl->iSelectedIf].pDrvBlock)
3440 break;
3441#ifndef IN_RING3
3442 /* Don't do anything complicated in GC */
3443 return VINF_IOM_HC_IOPORT_WRITE;
3444#else /* IN_RING3 */
3445 ataParseCmd(&pCtl->aIfs[pCtl->iSelectedIf], val);
3446#endif /* !IN_RING3 */
3447 }
3448 return VINF_SUCCESS;
3449}
3450
3451
3452static int ataIOPortReadU8(PATACONTROLLER pCtl, uint32_t addr, uint32_t *pu32)
3453{
3454 ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf];
3455 uint32_t val;
3456 bool fHOB;
3457
3458 fHOB = !!(s->uATARegDevCtl & (1 << 7));
3459 switch (addr & 7)
3460 {
3461 case 0: /* data register */
3462 val = 0xff;
3463 break;
3464 case 1: /* error register */
3465 /* The ATA specification is very terse when it comes to specifying
3466 * the precise effects of reading back the error/feature register.
3467 * The error register (read-only) shares the register number with
3468 * the feature register (write-only), so it seems that it's not
3469 * necessary to support the usual HOB readback here. */
3470 if (!s->pDrvBlock)
3471 val = 0;
3472 else
3473 val = s->uATARegError;
3474 break;
3475 case 2: /* sector count */
3476 if (!s->pDrvBlock)
3477 val = 0;
3478 else if (fHOB)
3479 val = s->uATARegNSectorHOB;
3480 else
3481 val = s->uATARegNSector;
3482 break;
3483 case 3: /* sector number */
3484 if (!s->pDrvBlock)
3485 val = 0;
3486 else if (fHOB)
3487 val = s->uATARegSectorHOB;
3488 else
3489 val = s->uATARegSector;
3490 break;
3491 case 4: /* cylinder low */
3492 if (!s->pDrvBlock)
3493 val = 0;
3494 else if (fHOB)
3495 val = s->uATARegLCylHOB;
3496 else
3497 val = s->uATARegLCyl;
3498 break;
3499 case 5: /* cylinder high */
3500 if (!s->pDrvBlock)
3501 val = 0;
3502 else if (fHOB)
3503 val = s->uATARegHCylHOB;
3504 else
3505 val = s->uATARegHCyl;
3506 break;
3507 case 6: /* drive/head */
3508 /* This register must always work as long as there is at least
3509 * one drive attached to the controller. It is common between
3510 * both drives anyway (completely identical content). */
3511 if (!pCtl->aIfs[0].pDrvBlock && !pCtl->aIfs[1].pDrvBlock)
3512 val = 0;
3513 else
3514 val = s->uATARegSelect;
3515 break;
3516 default:
3517 case 7: /* primary status */
3518 {
3519 /* Counter for number of busy status seen in GC in a row. */
3520 static unsigned cBusy = 0;
3521
3522 if (!s->pDrvBlock)
3523 val = 0;
3524 else
3525 val = s->uATARegStatus;
3526
3527 /* Give the async I/O thread an opportunity to make progress,
3528 * don't let it starve by guests polling frequently. EMT has a
3529 * lower priority than the async I/O thread, but sometimes the
3530 * host OS doesn't care. With some guests we are only allowed to
3531 * be busy for about 5 milliseconds in some situations. Note that
3532 * this is no guarantee for any other VBox thread getting
3533 * scheduled, so this just lowers the CPU load a bit when drives
3534 * are busy. It cannot help with timing problems. */
3535 if (val & ATA_STAT_BUSY)
3536 {
3537#ifdef IN_RING3
3538 cBusy = 0;
3539 PDMCritSectLeave(&pCtl->lock);
3540
3541 RTThreadYield();
3542
3543 {
3544 STAM_PROFILE_START(&pCtl->StatLockWait, a);
3545 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
3546 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
3547 }
3548
3549 val = s->uATARegStatus;
3550#else /* !IN_RING3 */
3551 /* Cannot yield CPU in guest context. And switching to host
3552 * context for each and every busy status is too costly,
3553 * especially on SMP systems where we don't gain much by
3554 * yielding the CPU to someone else. */
3555 if (++cBusy >= 20)
3556 {
3557 cBusy = 0;
3558 return VINF_IOM_HC_IOPORT_READ;
3559 }
3560#endif /* !IN_RING3 */
3561 }
3562 else
3563 cBusy = 0;
3564 ataUnsetIRQ(s);
3565 break;
3566 }
3567 }
3568 Log2(("%s: addr=%#x val=%#04x\n", __FUNCTION__, addr, val));
3569 *pu32 = val;
3570 return VINF_SUCCESS;
3571}
3572
3573
3574static uint32_t ataStatusRead(PATACONTROLLER pCtl, uint32_t addr)
3575{
3576 ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf];
3577 uint32_t val;
3578
3579 if ((!pCtl->aIfs[0].pDrvBlock && !pCtl->aIfs[1].pDrvBlock) ||
3580 (pCtl->iSelectedIf == 1 && !s->pDrvBlock))
3581 val = 0;
3582 else
3583 val = s->uATARegStatus;
3584 Log2(("%s: addr=%#x val=%#04x\n", __FUNCTION__, addr, val));
3585 return val;
3586}
3587
3588static int ataControlWrite(PATACONTROLLER pCtl, uint32_t addr, uint32_t val)
3589{
3590#ifndef IN_RING3
3591 if ((val ^ pCtl->aIfs[0].uATARegDevCtl) & ATA_DEVCTL_RESET)
3592 return VINF_IOM_HC_IOPORT_WRITE; /* The RESET stuff is too complicated for GC. */
3593#endif /* !IN_RING3 */
3594
3595 Log2(("%s: addr=%#x val=%#04x\n", __FUNCTION__, addr, val));
3596 /* RESET is common for both drives attached to a controller. */
3597 if (!(pCtl->aIfs[0].uATARegDevCtl & ATA_DEVCTL_RESET) &&
3598 (val & ATA_DEVCTL_RESET))
3599 {
3600#ifdef IN_RING3
3601 /* Software RESET low to high */
3602 int32_t uCmdWait0 = -1, uCmdWait1 = -1;
3603 uint64_t uNow = RTTimeNanoTS();
3604 if (pCtl->aIfs[0].u64CmdTS)
3605 uCmdWait0 = (uNow - pCtl->aIfs[0].u64CmdTS) / 1000;
3606 if (pCtl->aIfs[1].u64CmdTS)
3607 uCmdWait1 = (uNow - pCtl->aIfs[1].u64CmdTS) / 1000;
3608 LogRel(("PIIX3 ATA: Ctl#%d: RESET, DevSel=%d AIOIf=%d CmdIf0=%#04x (%d usec ago) CmdIf1=%#04x (%d usec ago)\n",
3609 ATACONTROLLER_IDX(pCtl), pCtl->iSelectedIf, pCtl->iAIOIf,
3610 pCtl->aIfs[0].uATARegCommand, uCmdWait0,
3611 pCtl->aIfs[1].uATARegCommand, uCmdWait1));
3612 pCtl->fReset = true;
3613 /* Everything must be done after the reset flag is set, otherwise
3614 * there are unavoidable races with the currently executing request
3615 * (which might just finish in the mean time). */
3616 pCtl->fChainedTransfer = false;
3617 for (uint32_t i = 0; i < RT_ELEMENTS(pCtl->aIfs); i++)
3618 {
3619 ataResetDevice(&pCtl->aIfs[i]);
3620 /* The following cannot be done using ataSetStatusValue() since the
3621 * reset flag is already set, which suppresses all status changes. */
3622 pCtl->aIfs[i].uATARegStatus = ATA_STAT_BUSY | ATA_STAT_SEEK;
3623 Log2(("%s: LUN#%d status %#04x\n", __FUNCTION__, pCtl->aIfs[i].iLUN, pCtl->aIfs[i].uATARegStatus));
3624 pCtl->aIfs[i].uATARegError = 0x01;
3625 }
3626 ataAsyncIOClearRequests(pCtl);
3627 Log2(("%s: Ctl#%d: message to async I/O thread, resetA\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
3628 if (val & ATA_DEVCTL_HOB)
3629 {
3630 val &= ~ATA_DEVCTL_HOB;
3631 Log2(("%s: ignored setting HOB\n", __FUNCTION__));
3632 }
3633 ataAsyncIOPutRequest(pCtl, &ataResetARequest);
3634#else /* !IN_RING3 */
3635 AssertMsgFailed(("RESET handling is too complicated for GC\n"));
3636#endif /* IN_RING3 */
3637 }
3638 else if ((pCtl->aIfs[0].uATARegDevCtl & ATA_DEVCTL_RESET) &&
3639 !(val & ATA_DEVCTL_RESET))
3640 {
3641#ifdef IN_RING3
3642 /* Software RESET high to low */
3643 Log(("%s: deasserting RESET\n", __FUNCTION__));
3644 Log2(("%s: Ctl#%d: message to async I/O thread, resetC\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
3645 if (val & ATA_DEVCTL_HOB)
3646 {
3647 val &= ~ATA_DEVCTL_HOB;
3648 Log2(("%s: ignored setting HOB\n", __FUNCTION__));
3649 }
3650 ataAsyncIOPutRequest(pCtl, &ataResetCRequest);
3651#else /* !IN_RING3 */
3652 AssertMsgFailed(("RESET handling is too complicated for GC\n"));
3653#endif /* IN_RING3 */
3654 }
3655
3656 /* Change of interrupt disable flag. Update interrupt line if interrupt
3657 * is pending on the current interface. */
3658 if ((val ^ pCtl->aIfs[0].uATARegDevCtl) & ATA_DEVCTL_DISABLE_IRQ
3659 && pCtl->aIfs[pCtl->iSelectedIf].fIrqPending)
3660 {
3661 if (!(val & ATA_DEVCTL_DISABLE_IRQ))
3662 {
3663 Log2(("%s: LUN#%d asserting IRQ (interrupt disable change)\n", __FUNCTION__, pCtl->aIfs[pCtl->iSelectedIf].iLUN));
3664 /* The BMDMA unit unconditionally sets BM_STATUS_INT if the
3665 * interrupt line is asserted. It monitors the line for a rising
3666 * edge. */
3667 pCtl->BmDma.u8Status |= BM_STATUS_INT;
3668 if (pCtl->irq == 16)
3669 PDMDevHlpPCISetIrqNoWait(CONTROLLER_2_DEVINS(pCtl), 0, 1);
3670 else
3671 PDMDevHlpISASetIrqNoWait(CONTROLLER_2_DEVINS(pCtl), pCtl->irq, 1);
3672 }
3673 else
3674 {
3675 Log2(("%s: LUN#%d deasserting IRQ (interrupt disable change)\n", __FUNCTION__, pCtl->aIfs[pCtl->iSelectedIf].iLUN));
3676 if (pCtl->irq == 16)
3677 PDMDevHlpPCISetIrqNoWait(CONTROLLER_2_DEVINS(pCtl), 0, 0);
3678 else
3679 PDMDevHlpISASetIrqNoWait(CONTROLLER_2_DEVINS(pCtl), pCtl->irq, 0);
3680 }
3681 }
3682
3683 if (val & ATA_DEVCTL_HOB)
3684 Log2(("%s: set HOB\n", __FUNCTION__));
3685
3686 pCtl->aIfs[0].uATARegDevCtl = val;
3687 pCtl->aIfs[1].uATARegDevCtl = val;
3688
3689 return VINF_SUCCESS;
3690}
3691
3692#ifdef IN_RING3
3693
3694static void ataPIOTransfer(PATACONTROLLER pCtl)
3695{
3696 ATADevState *s;
3697
3698 s = &pCtl->aIfs[pCtl->iAIOIf];
3699 Log3(("%s: if=%p\n", __FUNCTION__, s));
3700
3701 if (s->cbTotalTransfer && s->iIOBufferCur > s->iIOBufferEnd)
3702 {
3703 LogRel(("PIIX3 ATA: LUN#%d: %s data in the middle of a PIO transfer - VERY SLOW\n", s->iLUN, s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE ? "loading" : "storing"));
3704 /* Any guest OS that triggers this case has a pathetic ATA driver.
3705 * In a real system it would block the CPU via IORDY, here we do it
3706 * very similarly by not continuing with the current instruction
3707 * until the transfer to/from the storage medium is completed. */
3708 if (s->iSourceSink != ATAFN_SS_NULL)
3709 {
3710 bool fRedo;
3711 uint8_t status = s->uATARegStatus;
3712 ataSetStatusValue(s, ATA_STAT_BUSY);
3713 Log2(("%s: calling source/sink function\n", __FUNCTION__));
3714 fRedo = g_apfnSourceSinkFuncs[s->iSourceSink](s);
3715 pCtl->fRedo = fRedo;
3716 if (RT_UNLIKELY(fRedo))
3717 return;
3718 ataSetStatusValue(s, status);
3719 s->iIOBufferCur = 0;
3720 s->iIOBufferEnd = s->cbElementaryTransfer;
3721 }
3722 }
3723 if (s->cbTotalTransfer)
3724 {
3725 if (s->fATAPITransfer)
3726 ataPIOTransferLimitATAPI(s);
3727
3728 if (s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE && s->cbElementaryTransfer > s->cbTotalTransfer)
3729 s->cbElementaryTransfer = s->cbTotalTransfer;
3730
3731 Log2(("%s: %s tx_size=%d elem_tx_size=%d index=%d end=%d\n",
3732 __FUNCTION__, s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE ? "T2I" : "I2T",
3733 s->cbTotalTransfer, s->cbElementaryTransfer,
3734 s->iIOBufferCur, s->iIOBufferEnd));
3735 ataPIOTransferStart(s, s->iIOBufferCur, s->cbElementaryTransfer);
3736 s->cbTotalTransfer -= s->cbElementaryTransfer;
3737 s->iIOBufferCur += s->cbElementaryTransfer;
3738
3739 if (s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE && s->cbElementaryTransfer > s->cbTotalTransfer)
3740 s->cbElementaryTransfer = s->cbTotalTransfer;
3741 }
3742 else
3743 ataPIOTransferStop(s);
3744}
3745
3746
3747DECLINLINE(void) ataPIOTransferFinish(PATACONTROLLER pCtl, ATADevState *s)
3748{
3749 /* Do not interfere with RESET processing if the PIO transfer finishes
3750 * while the RESET line is asserted. */
3751 if (pCtl->fReset)
3752 {
3753 Log2(("%s: Ctl#%d: suppressed continuing PIO transfer as RESET is active\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
3754 return;
3755 }
3756
3757 if ( s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE
3758 || ( s->iSourceSink != ATAFN_SS_NULL
3759 && s->iIOBufferCur >= s->iIOBufferEnd))
3760 {
3761 /* Need to continue the transfer in the async I/O thread. This is
3762 * the case for write operations or generally for not yet finished
3763 * transfers (some data might need to be read). */
3764 ataUnsetStatus(s, ATA_STAT_READY | ATA_STAT_DRQ);
3765 ataSetStatus(s, ATA_STAT_BUSY);
3766
3767 Log2(("%s: Ctl#%d: message to async I/O thread, continuing PIO transfer\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
3768 ataAsyncIOPutRequest(pCtl, &ataPIORequest);
3769 }
3770 else
3771 {
3772 /* Either everything finished (though some data might still be pending)
3773 * or some data is pending before the next read is due. */
3774
3775 /* Continue a previously started transfer. */
3776 ataUnsetStatus(s, ATA_STAT_DRQ);
3777 ataSetStatus(s, ATA_STAT_READY);
3778
3779 if (s->cbTotalTransfer)
3780 {
3781 /* There is more to transfer, happens usually for large ATAPI
3782 * reads - the protocol limits the chunk size to 65534 bytes. */
3783 ataPIOTransfer(pCtl);
3784 ataSetIRQ(s);
3785 }
3786 else
3787 {
3788 Log2(("%s: Ctl#%d: skipping message to async I/O thread, ending PIO transfer\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
3789 /* Finish PIO transfer. */
3790 ataPIOTransfer(pCtl);
3791 Assert(!pCtl->fRedo);
3792 }
3793 }
3794}
3795
3796#endif /* IN_RING3 */
3797
3798static int ataDataWrite(PATACONTROLLER pCtl, uint32_t addr, uint32_t cbSize, const uint8_t *pbBuf)
3799{
3800 ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf];
3801 uint8_t *p;
3802
3803 if (s->iIOBufferPIODataStart < s->iIOBufferPIODataEnd)
3804 {
3805 Assert(s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE);
3806 p = s->CTXSUFF(pbIOBuffer) + s->iIOBufferPIODataStart;
3807#ifndef IN_RING3
3808 /* All but the last transfer unit is simple enough for GC, but
3809 * sending a request to the async IO thread is too complicated. */
3810 if (s->iIOBufferPIODataStart + cbSize < s->iIOBufferPIODataEnd)
3811 {
3812 memcpy(p, pbBuf, cbSize);
3813 s->iIOBufferPIODataStart += cbSize;
3814 }
3815 else
3816 return VINF_IOM_HC_IOPORT_WRITE;
3817#else /* IN_RING3 */
3818 memcpy(p, pbBuf, cbSize);
3819 s->iIOBufferPIODataStart += cbSize;
3820 if (s->iIOBufferPIODataStart >= s->iIOBufferPIODataEnd)
3821 ataPIOTransferFinish(pCtl, s);
3822#endif /* !IN_RING3 */
3823 }
3824 else
3825 Log2(("%s: DUMMY data\n", __FUNCTION__));
3826 Log3(("%s: addr=%#x val=%.*Vhxs\n", __FUNCTION__, addr, cbSize, pbBuf));
3827 return VINF_SUCCESS;
3828}
3829
3830static int ataDataRead(PATACONTROLLER pCtl, uint32_t addr, uint32_t cbSize, uint8_t *pbBuf)
3831{
3832 ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf];
3833 uint8_t *p;
3834
3835 if (s->iIOBufferPIODataStart < s->iIOBufferPIODataEnd)
3836 {
3837 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
3838 p = s->CTXSUFF(pbIOBuffer) + s->iIOBufferPIODataStart;
3839#ifndef IN_RING3
3840 /* All but the last transfer unit is simple enough for GC, but
3841 * sending a request to the async IO thread is too complicated. */
3842 if (s->iIOBufferPIODataStart + cbSize < s->iIOBufferPIODataEnd)
3843 {
3844 memcpy(pbBuf, p, cbSize);
3845 s->iIOBufferPIODataStart += cbSize;
3846 }
3847 else
3848 return VINF_IOM_HC_IOPORT_READ;
3849#else /* IN_RING3 */
3850 memcpy(pbBuf, p, cbSize);
3851 s->iIOBufferPIODataStart += cbSize;
3852 if (s->iIOBufferPIODataStart >= s->iIOBufferPIODataEnd)
3853 ataPIOTransferFinish(pCtl, s);
3854#endif /* !IN_RING3 */
3855 }
3856 else
3857 {
3858 Log2(("%s: DUMMY data\n", __FUNCTION__));
3859 memset(pbBuf, '\xff', cbSize);
3860 }
3861 Log3(("%s: addr=%#x val=%.*Vhxs\n", __FUNCTION__, addr, cbSize, pbBuf));
3862 return VINF_SUCCESS;
3863}
3864
3865#ifdef IN_RING3
3866
3867/* Attempt to guess the LCHS disk geometry from the MS-DOS master boot
3868 * record (partition table). */
3869static int ataGuessDiskLCHS(ATADevState *s, uint32_t *pcCylinders, uint32_t *pcHeads, uint32_t *pcSectors)
3870{
3871 uint8_t aMBR[512], *p;
3872 int rc;
3873 uint32_t iEndHead, iEndSector, cCHSCylinders, cCHSHeads, cCHSSectors;
3874
3875 if (s->fATAPI || !s->pDrvBlock)
3876 return VERR_INVALID_PARAMETER;
3877 rc = s->pDrvBlock->pfnRead(s->pDrvBlock, 0, aMBR, 1 * 512);
3878 if (VBOX_FAILURE(rc))
3879 return rc;
3880 /* Test MBR magic number. */
3881 if (aMBR[510] != 0x55 || aMBR[511] != 0xaa)
3882 return VERR_INVALID_PARAMETER;
3883 for (uint32_t i = 0; i < 4; i++)
3884 {
3885 /* Figure out the start of a partition table entry. */
3886 p = &aMBR[0x1be + i * 16];
3887 iEndHead = p[5];
3888 iEndSector = p[6] & 63;
3889 if ((p[12] | p[13] | p[14] | p[15]) && iEndSector & iEndHead)
3890 {
3891 /* Assumption: partition terminates on a cylinder boundary. */
3892 cCHSHeads = iEndHead + 1;
3893 cCHSSectors = iEndSector;
3894 cCHSCylinders = s->cTotalSectors / (cCHSHeads * cCHSSectors);
3895 if (cCHSCylinders >= 1)
3896 {
3897 *pcHeads = cCHSHeads;
3898 *pcSectors = cCHSSectors;
3899 *pcCylinders = cCHSCylinders;
3900 Log(("%s: LCHS=%d %d %d\n", __FUNCTION__, cCHSCylinders, cCHSHeads, cCHSSectors));
3901 return VINF_SUCCESS;
3902 }
3903 }
3904 }
3905 return VERR_INVALID_PARAMETER;
3906}
3907
3908
3909static void ataDMATransferStop(ATADevState *s)
3910{
3911 s->cbTotalTransfer = 0;
3912 s->cbElementaryTransfer = 0;
3913 s->iBeginTransfer = ATAFN_BT_NULL;
3914 s->iSourceSink = ATAFN_SS_NULL;
3915}
3916
3917
3918/**
3919 * Perform the entire DMA transfer in one go (unless a source/sink operation
3920 * has to be redone or a RESET comes in between). Unlike the PIO counterpart
3921 * this function cannot handle empty transfers.
3922 *
3923 * @param pCtl Controller for which to perform the transfer.
3924 */
3925static void ataDMATransfer(PATACONTROLLER pCtl)
3926{
3927 PPDMDEVINS pDevIns = CONTROLLER_2_DEVINS(pCtl);
3928 ATADevState *s = &pCtl->aIfs[pCtl->iAIOIf];
3929 bool fRedo;
3930 RTGCPHYS pDesc;
3931 uint32_t cbTotalTransfer, cbElementaryTransfer;
3932 uint32_t iIOBufferCur, iIOBufferEnd;
3933 uint32_t dmalen;
3934 PDMBLOCKTXDIR uTxDir;
3935 bool fLastDesc = false;
3936
3937 Assert(sizeof(BMDMADesc) == 8);
3938
3939 fRedo = pCtl->fRedo;
3940 if (RT_LIKELY(!fRedo))
3941 Assert(s->cbTotalTransfer);
3942 uTxDir = (PDMBLOCKTXDIR)s->uTxDir;
3943 cbTotalTransfer = s->cbTotalTransfer;
3944 cbElementaryTransfer = s->cbElementaryTransfer;
3945 iIOBufferCur = s->iIOBufferCur;
3946 iIOBufferEnd = s->iIOBufferEnd;
3947
3948 /* The DMA loop is designed to hold the lock only when absolutely
3949 * necessary. This avoids long freezes should the guest access the
3950 * ATA registers etc. for some reason. */
3951 PDMCritSectLeave(&pCtl->lock);
3952
3953 Log2(("%s: %s tx_size=%d elem_tx_size=%d index=%d end=%d\n",
3954 __FUNCTION__, uTxDir == PDMBLOCKTXDIR_FROM_DEVICE ? "T2I" : "I2T",
3955 cbTotalTransfer, cbElementaryTransfer,
3956 iIOBufferCur, iIOBufferEnd));
3957 for (pDesc = pCtl->pFirstDMADesc; pDesc <= pCtl->pLastDMADesc; pDesc += sizeof(BMDMADesc))
3958 {
3959 BMDMADesc DMADesc;
3960 RTGCPHYS pBuffer;
3961 uint32_t cbBuffer;
3962
3963 if (RT_UNLIKELY(fRedo))
3964 {
3965 pBuffer = pCtl->pRedoDMABuffer;
3966 cbBuffer = pCtl->cbRedoDMABuffer;
3967 fLastDesc = pCtl->fRedoDMALastDesc;
3968 }
3969 else
3970 {
3971 PDMDevHlpPhysRead(pDevIns, pDesc, &DMADesc, sizeof(BMDMADesc));
3972 pBuffer = RT_LE2H_U32(DMADesc.pBuffer);
3973 cbBuffer = RT_LE2H_U32(DMADesc.cbBuffer);
3974 fLastDesc = !!(cbBuffer & 0x80000000);
3975 cbBuffer &= 0xfffe;
3976 if (cbBuffer == 0)
3977 cbBuffer = 0x10000;
3978 if (cbBuffer > cbTotalTransfer)
3979 cbBuffer = cbTotalTransfer;
3980 }
3981
3982 while (RT_UNLIKELY(fRedo) || (cbBuffer && cbTotalTransfer))
3983 {
3984 if (RT_LIKELY(!fRedo))
3985 {
3986 dmalen = RT_MIN(cbBuffer, iIOBufferEnd - iIOBufferCur);
3987 Log2(("%s: DMA desc %#010x: addr=%#010x size=%#010x\n", __FUNCTION__,
3988 (int)pDesc, pBuffer, cbBuffer));
3989 if (uTxDir == PDMBLOCKTXDIR_FROM_DEVICE)
3990 PDMDevHlpPhysWrite(pDevIns, pBuffer, s->CTXSUFF(pbIOBuffer) + iIOBufferCur, dmalen);
3991 else
3992 PDMDevHlpPhysRead(pDevIns, pBuffer, s->CTXSUFF(pbIOBuffer) + iIOBufferCur, dmalen);
3993 iIOBufferCur += dmalen;
3994 cbTotalTransfer -= dmalen;
3995 cbBuffer -= dmalen;
3996 pBuffer += dmalen;
3997 }
3998 if ( iIOBufferCur == iIOBufferEnd
3999 && (uTxDir == PDMBLOCKTXDIR_TO_DEVICE || cbTotalTransfer))
4000 {
4001 if (uTxDir == PDMBLOCKTXDIR_FROM_DEVICE && cbElementaryTransfer > cbTotalTransfer)
4002 cbElementaryTransfer = cbTotalTransfer;
4003
4004 {
4005 STAM_PROFILE_START(&pCtl->StatLockWait, a);
4006 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
4007 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
4008 }
4009
4010 /* The RESET handler could have cleared the DMA transfer
4011 * state (since we didn't hold the lock until just now
4012 * the guest can continue in parallel). If so, the state
4013 * is already set up so the loop is exited immediately. */
4014 if (s->iSourceSink != ATAFN_SS_NULL)
4015 {
4016 s->iIOBufferCur = iIOBufferCur;
4017 s->iIOBufferEnd = iIOBufferEnd;
4018 s->cbElementaryTransfer = cbElementaryTransfer;
4019 s->cbTotalTransfer = cbTotalTransfer;
4020 Log2(("%s: calling source/sink function\n", __FUNCTION__));
4021 fRedo = g_apfnSourceSinkFuncs[s->iSourceSink](s);
4022 if (RT_UNLIKELY(fRedo))
4023 {
4024 pCtl->pFirstDMADesc = pDesc;
4025 pCtl->pRedoDMABuffer = pBuffer;
4026 pCtl->cbRedoDMABuffer = cbBuffer;
4027 pCtl->fRedoDMALastDesc = fLastDesc;
4028 }
4029 else
4030 {
4031 cbTotalTransfer = s->cbTotalTransfer;
4032 cbElementaryTransfer = s->cbElementaryTransfer;
4033
4034 if (uTxDir == PDMBLOCKTXDIR_TO_DEVICE && cbElementaryTransfer > cbTotalTransfer)
4035 cbElementaryTransfer = cbTotalTransfer;
4036 iIOBufferCur = 0;
4037 iIOBufferEnd = cbElementaryTransfer;
4038 }
4039 pCtl->fRedo = fRedo;
4040 }
4041 else
4042 {
4043 /* This forces the loop to exit immediately. */
4044 pDesc = pCtl->pLastDMADesc + 1;
4045 }
4046
4047 PDMCritSectLeave(&pCtl->lock);
4048 if (RT_UNLIKELY(fRedo))
4049 break;
4050 }
4051 }
4052
4053 if (RT_UNLIKELY(fRedo))
4054 break;
4055
4056 /* end of transfer */
4057 if (!cbTotalTransfer || fLastDesc)
4058 break;
4059
4060 {
4061 STAM_PROFILE_START(&pCtl->StatLockWait, a);
4062 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
4063 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
4064 }
4065
4066 if (!(pCtl->BmDma.u8Cmd & BM_CMD_START) || pCtl->fReset)
4067 {
4068 LogRel(("PIIX3 ATA: Ctl#%d: ABORT DMA%s\n", ATACONTROLLER_IDX(pCtl), pCtl->fReset ? " due to RESET" : ""));
4069 if (!pCtl->fReset)
4070 ataDMATransferStop(s);
4071 /* This forces the loop to exit immediately. */
4072 pDesc = pCtl->pLastDMADesc + 1;
4073 }
4074
4075 PDMCritSectLeave(&pCtl->lock);
4076 }
4077
4078 {
4079 STAM_PROFILE_START(&pCtl->StatLockWait, a);
4080 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
4081 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
4082 }
4083
4084 if (RT_UNLIKELY(fRedo))
4085 return;
4086
4087 if (fLastDesc)
4088 pCtl->BmDma.u8Status &= ~BM_STATUS_DMAING;
4089 s->cbTotalTransfer = cbTotalTransfer;
4090 s->cbElementaryTransfer = cbElementaryTransfer;
4091 s->iIOBufferCur = iIOBufferCur;
4092 s->iIOBufferEnd = iIOBufferEnd;
4093}
4094
4095
4096/**
4097 * Suspend I/O operations on a controller. Also suspends EMT, because it's
4098 * waiting for I/O to make progress. The next attempt to perform an I/O
4099 * operation will be made when EMT is resumed up again (as the resume
4100 * callback below restarts I/O).
4101 *
4102 * @param pCtl Controller for which to suspend I/O.
4103 */
4104static void ataSuspendRedo(PATACONTROLLER pCtl)
4105{
4106 PPDMDEVINS pDevIns = CONTROLLER_2_DEVINS(pCtl);
4107 PVMREQ pReq;
4108 int rc;
4109
4110 pCtl->fRedoIdle = true;
4111 rc = VMR3ReqCall(PDMDevHlpGetVM(pDevIns), &pReq, RT_INDEFINITE_WAIT,
4112 (PFNRT)pDevIns->pDevHlp->pfnVMSuspend, 1, pDevIns);
4113 AssertReleaseRC(rc);
4114 VMR3ReqFree(pReq);
4115}
4116
4117/** Asynch I/O thread for an interface. Once upon a time this was readable
4118 * code with several loops and a different semaphore for each purpose. But
4119 * then came the "how can one save the state in the middle of a PIO transfer"
4120 * question. The solution was to use an ASM, which is what's there now. */
4121static DECLCALLBACK(int) ataAsyncIOLoop(RTTHREAD ThreadSelf, void *pvUser)
4122{
4123 const ATARequest *pReq;
4124 uint64_t u64TS = 0; /* shut up gcc */
4125 uint64_t uWait;
4126 int rc = VINF_SUCCESS;
4127 PATACONTROLLER pCtl = (PATACONTROLLER)pvUser;
4128 ATADevState *s;
4129
4130 pReq = NULL;
4131 pCtl->fChainedTransfer = false;
4132 while (!pCtl->fShutdown)
4133 {
4134 /* Keep this thread from doing anything as long as EMT is suspended. */
4135 while (pCtl->fRedoIdle)
4136 {
4137 rc = RTSemEventWait(pCtl->SuspendIOSem, RT_INDEFINITE_WAIT);
4138 if (VBOX_FAILURE(rc) || pCtl->fShutdown)
4139 break;
4140
4141 pCtl->fRedoIdle = false;
4142 }
4143
4144 /* Wait for work. */
4145 if (pReq == NULL)
4146 {
4147 LogBird(("ata: %x: going to sleep...\n", pCtl->IOPortBase1));
4148 rc = RTSemEventWait(pCtl->AsyncIOSem, RT_INDEFINITE_WAIT);
4149 LogBird(("ata: %x: waking up\n", pCtl->IOPortBase1));
4150 if (VBOX_FAILURE(rc) || pCtl->fShutdown)
4151 break;
4152
4153 pReq = ataAsyncIOGetCurrentRequest(pCtl);
4154 }
4155
4156 if (pReq == NULL)
4157 continue;
4158
4159 ATAAIO ReqType = pReq->ReqType;
4160
4161 Log2(("%s: Ctl#%d: state=%d, req=%d\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl), pCtl->uAsyncIOState, ReqType));
4162 if (pCtl->uAsyncIOState != ReqType)
4163 {
4164 /* The new state is not the state that was expected by the normal
4165 * state changes. This is either a RESET/ABORT or there's something
4166 * really strange going on. */
4167 if ( (pCtl->uAsyncIOState == ATA_AIO_PIO || pCtl->uAsyncIOState == ATA_AIO_DMA)
4168 && (ReqType == ATA_AIO_PIO || ReqType == ATA_AIO_DMA))
4169 {
4170 /* Incorrect sequence of PIO/DMA states. Dump request queue. */
4171 ataAsyncIODumpRequests(pCtl);
4172 }
4173 AssertReleaseMsg(ReqType == ATA_AIO_RESET_ASSERTED || ReqType == ATA_AIO_RESET_CLEARED || ReqType == ATA_AIO_ABORT || pCtl->uAsyncIOState == ReqType, ("I/O state inconsistent: state=%d request=%d\n", pCtl->uAsyncIOState, ReqType));
4174 }
4175
4176 /* Do our work. */
4177 {
4178 STAM_PROFILE_START(&pCtl->StatLockWait, a);
4179 LogBird(("ata: %x: entering critsect\n", pCtl->IOPortBase1));
4180 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
4181 LogBird(("ata: %x: entered\n", pCtl->IOPortBase1));
4182 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
4183 }
4184
4185 if (pCtl->uAsyncIOState == ATA_AIO_NEW && !pCtl->fChainedTransfer)
4186 {
4187 u64TS = RTTimeNanoTS();
4188#if defined(DEBUG) || defined(VBOX_WITH_STATISTICS)
4189 STAM_PROFILE_ADV_START(&pCtl->StatAsyncTime, a);
4190#endif /* DEBUG || VBOX_WITH_STATISTICS */
4191 }
4192
4193 switch (ReqType)
4194 {
4195 case ATA_AIO_NEW:
4196
4197 pCtl->iAIOIf = pReq->u.t.iIf;
4198 s = &pCtl->aIfs[pCtl->iAIOIf];
4199 s->cbTotalTransfer = pReq->u.t.cbTotalTransfer;
4200 s->uTxDir = pReq->u.t.uTxDir;
4201 s->iBeginTransfer = pReq->u.t.iBeginTransfer;
4202 s->iSourceSink = pReq->u.t.iSourceSink;
4203 s->iIOBufferEnd = 0;
4204 s->u64CmdTS = u64TS;
4205
4206 if (s->fATAPI)
4207 {
4208 if (pCtl->fChainedTransfer)
4209 {
4210 /* Only count the actual transfers, not the PIO
4211 * transfer of the ATAPI command bytes. */
4212 if (s->fDMA)
4213 STAM_REL_COUNTER_INC(&s->StatATAPIDMA);
4214 else
4215 STAM_REL_COUNTER_INC(&s->StatATAPIPIO);
4216 }
4217 }
4218 else
4219 {
4220 if (s->fDMA)
4221 STAM_REL_COUNTER_INC(&s->StatATADMA);
4222 else
4223 STAM_REL_COUNTER_INC(&s->StatATAPIO);
4224 }
4225
4226 pCtl->fChainedTransfer = false;
4227
4228 if (s->iBeginTransfer != ATAFN_BT_NULL)
4229 {
4230 Log2(("%s: Ctl#%d: calling begin transfer function\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
4231 g_apfnBeginTransFuncs[s->iBeginTransfer](s);
4232 s->iBeginTransfer = ATAFN_BT_NULL;
4233 if (s->uTxDir != PDMBLOCKTXDIR_FROM_DEVICE)
4234 s->iIOBufferEnd = s->cbElementaryTransfer;
4235 }
4236 else
4237 {
4238 s->cbElementaryTransfer = s->cbTotalTransfer;
4239 s->iIOBufferEnd = s->cbTotalTransfer;
4240 }
4241 s->iIOBufferCur = 0;
4242
4243 if (s->uTxDir != PDMBLOCKTXDIR_TO_DEVICE)
4244 {
4245 if (s->iSourceSink != ATAFN_SS_NULL)
4246 {
4247 bool fRedo;
4248 Log2(("%s: Ctl#%d: calling source/sink function\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
4249 fRedo = g_apfnSourceSinkFuncs[s->iSourceSink](s);
4250 pCtl->fRedo = fRedo;
4251 if (RT_UNLIKELY(fRedo))
4252 {
4253 /* Operation failed at the initial transfer, restart
4254 * everything from scratch by resending the current
4255 * request. Occurs very rarely, not worth optimizing. */
4256 LogRel(("%s: Ctl#%d: redo entire operation\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
4257 ataAsyncIOPutRequest(pCtl, pReq);
4258 ataSuspendRedo(pCtl);
4259 break;
4260 }
4261 }
4262 else
4263 ataCmdOK(s, 0);
4264 s->iIOBufferEnd = s->cbElementaryTransfer;
4265
4266 }
4267
4268 /* Do not go into the transfer phase if RESET is asserted.
4269 * The CritSect is released while waiting for the host OS
4270 * to finish the I/O, thus RESET is possible here. Most
4271 * important: do not change uAsyncIOState. */
4272 if (pCtl->fReset)
4273 break;
4274
4275 if (s->fDMA)
4276 {
4277 if (s->cbTotalTransfer)
4278 {
4279 ataSetStatus(s, ATA_STAT_DRQ);
4280
4281 pCtl->uAsyncIOState = ATA_AIO_DMA;
4282 /* If BMDMA is already started, do the transfer now. */
4283 if (pCtl->BmDma.u8Cmd & BM_CMD_START)
4284 {
4285 Log2(("%s: Ctl#%d: message to async I/O thread, continuing DMA transfer immediately\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
4286 ataAsyncIOPutRequest(pCtl, &ataDMARequest);
4287 }
4288 }
4289 else
4290 {
4291 Assert(s->uTxDir == PDMBLOCKTXDIR_NONE); /* Any transfer which has an initial transfer size of 0 must be marked as such. */
4292 /* Finish DMA transfer. */
4293 ataDMATransferStop(s);
4294 ataSetIRQ(s);
4295 pCtl->uAsyncIOState = ATA_AIO_NEW;
4296 }
4297 }
4298 else
4299 {
4300 if (s->cbTotalTransfer)
4301 {
4302 ataPIOTransfer(pCtl);
4303 Assert(!pCtl->fRedo);
4304 if (s->fATAPITransfer || s->uTxDir != PDMBLOCKTXDIR_TO_DEVICE)
4305 ataSetIRQ(s);
4306
4307 if (s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE || s->iSourceSink != ATAFN_SS_NULL)
4308 {
4309 /* Write operations and not yet finished transfers
4310 * must be completed in the async I/O thread. */
4311 pCtl->uAsyncIOState = ATA_AIO_PIO;
4312 }
4313 else
4314 {
4315 /* Finished read operation can be handled inline
4316 * in the end of PIO transfer handling code. Linux
4317 * depends on this, as it waits only briefly for
4318 * devices to become ready after incoming data
4319 * transfer. Cannot find anything in the ATA spec
4320 * that backs this assumption, but as all kernels
4321 * are affected (though most of the time it does
4322 * not cause any harm) this must work. */
4323 pCtl->uAsyncIOState = ATA_AIO_NEW;
4324 }
4325 }
4326 else
4327 {
4328 Assert(s->uTxDir == PDMBLOCKTXDIR_NONE); /* Any transfer which has an initial transfer size of 0 must be marked as such. */
4329 /* Finish PIO transfer. */
4330 ataPIOTransfer(pCtl);
4331 Assert(!pCtl->fRedo);
4332 if (!s->fATAPITransfer)
4333 ataSetIRQ(s);
4334 pCtl->uAsyncIOState = ATA_AIO_NEW;
4335 }
4336 }
4337 break;
4338
4339 case ATA_AIO_DMA:
4340 {
4341 BMDMAState *bm = &pCtl->BmDma;
4342 s = &pCtl->aIfs[pCtl->iAIOIf]; /* Do not remove or there's an instant crash after loading the saved state */
4343 ATAFNSS iOriginalSourceSink = (ATAFNSS)s->iSourceSink; /* Used by the hack below, but gets reset by then. */
4344
4345 if (s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE)
4346 AssertRelease(bm->u8Cmd & BM_CMD_WRITE);
4347 else
4348 AssertRelease(!(bm->u8Cmd & BM_CMD_WRITE));
4349
4350 if (RT_LIKELY(!pCtl->fRedo))
4351 {
4352 /* The specs say that the descriptor table must not cross a
4353 * 4K boundary. */
4354 pCtl->pFirstDMADesc = bm->pvAddr;
4355 pCtl->pLastDMADesc = RT_ALIGN_32(bm->pvAddr + 1, _4K) - sizeof(BMDMADesc);
4356 }
4357 ataDMATransfer(pCtl);
4358
4359 if (RT_UNLIKELY(pCtl->fRedo))
4360 {
4361 LogRel(("PIIX3 ATA: Ctl#%d: redo DMA operation\n", ATACONTROLLER_IDX(pCtl)));
4362 ataAsyncIOPutRequest(pCtl, &ataDMARequest);
4363 ataSuspendRedo(pCtl);
4364 break;
4365 }
4366
4367 /* The infamous delay IRQ hack. */
4368 if ( iOriginalSourceSink == ATAFN_SS_WRITE_SECTORS
4369 && s->cbTotalTransfer == 0
4370 && pCtl->DelayIRQMillies)
4371 {
4372 /* Delay IRQ for writing. Required to get the Win2K
4373 * installation work reliably (otherwise it crashes,
4374 * usually during component install). So far no better
4375 * solution has been found. */
4376 Log(("%s: delay IRQ hack\n", __FUNCTION__));
4377 PDMCritSectLeave(&pCtl->lock);
4378 RTThreadSleep(pCtl->DelayIRQMillies);
4379 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
4380 }
4381
4382 ataUnsetStatus(s, ATA_STAT_DRQ);
4383 Assert(!pCtl->fChainedTransfer);
4384 Assert(s->iSourceSink == ATAFN_SS_NULL);
4385 if (s->fATAPITransfer)
4386 {
4387 s->uATARegNSector = (s->uATARegNSector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
4388 Log2(("%s: Ctl#%d: interrupt reason %#04x\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl), s->uATARegNSector));
4389 s->fATAPITransfer = false;
4390 }
4391 ataSetIRQ(s);
4392 pCtl->uAsyncIOState = ATA_AIO_NEW;
4393 break;
4394 }
4395
4396 case ATA_AIO_PIO:
4397 s = &pCtl->aIfs[pCtl->iAIOIf]; /* Do not remove or there's an instant crash after loading the saved state */
4398
4399 if (s->iSourceSink != ATAFN_SS_NULL)
4400 {
4401 bool fRedo;
4402 Log2(("%s: Ctl#%d: calling source/sink function\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
4403 fRedo = g_apfnSourceSinkFuncs[s->iSourceSink](s);
4404 pCtl->fRedo = fRedo;
4405 if (RT_UNLIKELY(fRedo))
4406 {
4407 LogRel(("PIIX3 ATA: Ctl#%d: redo PIO operation\n", ATACONTROLLER_IDX(pCtl)));
4408 ataAsyncIOPutRequest(pCtl, &ataPIORequest);
4409 ataSuspendRedo(pCtl);
4410 break;
4411 }
4412 s->iIOBufferCur = 0;
4413 s->iIOBufferEnd = s->cbElementaryTransfer;
4414 }
4415 else
4416 {
4417 /* Continue a previously started transfer. */
4418 ataUnsetStatus(s, ATA_STAT_BUSY);
4419 ataSetStatus(s, ATA_STAT_READY);
4420 }
4421
4422 /* It is possible that the drives on this controller get RESET
4423 * during the above call to the source/sink function. If that's
4424 * the case, don't restart the transfer and don't finish it the
4425 * usual way. RESET handling took care of all that already.
4426 * Most important: do not change uAsyncIOState. */
4427 if (pCtl->fReset)
4428 break;
4429
4430 if (s->cbTotalTransfer)
4431 {
4432 ataPIOTransfer(pCtl);
4433 ataSetIRQ(s);
4434
4435 if (s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE || s->iSourceSink != ATAFN_SS_NULL)
4436 {
4437 /* Write operations and not yet finished transfers
4438 * must be completed in the async I/O thread. */
4439 pCtl->uAsyncIOState = ATA_AIO_PIO;
4440 }
4441 else
4442 {
4443 /* Finished read operation can be handled inline
4444 * in the end of PIO transfer handling code. Linux
4445 * depends on this, as it waits only briefly for
4446 * devices to become ready after incoming data
4447 * transfer. Cannot find anything in the ATA spec
4448 * that backs this assumption, but as all kernels
4449 * are affected (though most of the time it does
4450 * not cause any harm) this must work. */
4451 pCtl->uAsyncIOState = ATA_AIO_NEW;
4452 }
4453 }
4454 else
4455 {
4456 /* Finish PIO transfer. */
4457 ataPIOTransfer(pCtl);
4458 if ( !pCtl->fChainedTransfer
4459 && !s->fATAPITransfer
4460 && s->uTxDir != PDMBLOCKTXDIR_FROM_DEVICE)
4461 {
4462 ataSetIRQ(s);
4463 }
4464 pCtl->uAsyncIOState = ATA_AIO_NEW;
4465 }
4466 break;
4467
4468 case ATA_AIO_RESET_ASSERTED:
4469 pCtl->uAsyncIOState = ATA_AIO_RESET_CLEARED;
4470 ataPIOTransferStop(&pCtl->aIfs[0]);
4471 ataPIOTransferStop(&pCtl->aIfs[1]);
4472 /* Do not change the DMA registers, they are not affected by the
4473 * ATA controller reset logic. It should be sufficient to issue a
4474 * new command, which is now possible as the state is cleared. */
4475 break;
4476
4477 case ATA_AIO_RESET_CLEARED:
4478 pCtl->uAsyncIOState = ATA_AIO_NEW;
4479 pCtl->fReset = false;
4480 LogRel(("PIIX3 ATA: Ctl#%d: finished processing RESET\n",
4481 ATACONTROLLER_IDX(pCtl)));
4482 for (uint32_t i = 0; i < RT_ELEMENTS(pCtl->aIfs); i++)
4483 {
4484 if (pCtl->aIfs[i].fATAPI)
4485 ataSetStatusValue(&pCtl->aIfs[i], 0); /* NOTE: READY is _not_ set */
4486 else
4487 ataSetStatusValue(&pCtl->aIfs[i], ATA_STAT_READY | ATA_STAT_SEEK);
4488 ataSetSignature(&pCtl->aIfs[i]);
4489 }
4490 break;
4491
4492 case ATA_AIO_ABORT:
4493 /* Abort the current command only if it operates on the same interface. */
4494 if (pCtl->iAIOIf == pReq->u.a.iIf)
4495 {
4496 s = &pCtl->aIfs[pCtl->iAIOIf];
4497
4498 pCtl->uAsyncIOState = ATA_AIO_NEW;
4499 /* Do not change the DMA registers, they are not affected by the
4500 * ATA controller reset logic. It should be sufficient to issue a
4501 * new command, which is now possible as the state is cleared. */
4502 if (pReq->u.a.fResetDrive)
4503 {
4504 ataResetDevice(s);
4505 ataExecuteDeviceDiagnosticSS(s);
4506 }
4507 else
4508 {
4509 ataPIOTransferStop(s);
4510 ataUnsetStatus(s, ATA_STAT_BUSY | ATA_STAT_DRQ | ATA_STAT_SEEK | ATA_STAT_ERR);
4511 ataSetStatus(s, ATA_STAT_READY);
4512 ataSetIRQ(s);
4513 }
4514 }
4515 break;
4516
4517 default:
4518 AssertMsgFailed(("Undefined async I/O state %d\n", pCtl->uAsyncIOState));
4519 }
4520
4521 ataAsyncIORemoveCurrentRequest(pCtl, ReqType);
4522 pReq = ataAsyncIOGetCurrentRequest(pCtl);
4523
4524 if (pCtl->uAsyncIOState == ATA_AIO_NEW && !pCtl->fChainedTransfer)
4525 {
4526#if defined(DEBUG) || defined(VBOX_WITH_STATISTICS)
4527 STAM_PROFILE_ADV_STOP(&pCtl->StatAsyncTime, a);
4528#endif /* DEBUG || VBOX_WITH_STATISTICS */
4529
4530 u64TS = RTTimeNanoTS() - u64TS;
4531 uWait = u64TS / 1000;
4532 Log(("%s: Ctl#%d: LUN#%d finished I/O transaction in %d microseconds\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl), pCtl->aIfs[pCtl->iAIOIf].iLUN, (uint32_t)(uWait)));
4533 /* Mark command as finished. */
4534 pCtl->aIfs[pCtl->iAIOIf].u64CmdTS = 0;
4535
4536 /*
4537 * Release logging of command execution times depends on the
4538 * command type. ATAPI commands often take longer (due to CD/DVD
4539 * spin up time etc.) so the threshold is different.
4540 */
4541 if (pCtl->aIfs[pCtl->iAIOIf].uATARegCommand != ATA_PACKET)
4542 {
4543 if (uWait > 8 * 1000 * 1000)
4544 {
4545 /*
4546 * Command took longer than 8 seconds. This is close
4547 * enough or over the guest's command timeout, so place
4548 * an entry in the release log to allow tracking such
4549 * timing errors (which are often caused by the host).
4550 */
4551 LogRel(("PIIX3 ATA: execution time for ATA command %#04x was %d seconds\n", pCtl->aIfs[pCtl->iAIOIf].uATARegCommand, uWait / (1000 * 1000)));
4552 }
4553 }
4554 else
4555 {
4556 if (uWait > 20 * 1000 * 1000)
4557 {
4558 /*
4559 * Command took longer than 20 seconds. This is close
4560 * enough or over the guest's command timeout, so place
4561 * an entry in the release log to allow tracking such
4562 * timing errors (which are often caused by the host).
4563 */
4564 LogRel(("PIIX3 ATA: execution time for ATAPI command %#04x was %d seconds\n", pCtl->aIfs[pCtl->iAIOIf].aATAPICmd[0], uWait / (1000 * 1000)));
4565 }
4566 }
4567
4568#if defined(DEBUG) || defined(VBOX_WITH_STATISTICS)
4569 if (uWait < pCtl->StatAsyncMinWait || !pCtl->StatAsyncMinWait)
4570 pCtl->StatAsyncMinWait = uWait;
4571 if (uWait > pCtl->StatAsyncMaxWait)
4572 pCtl->StatAsyncMaxWait = uWait;
4573
4574 STAM_COUNTER_ADD(&pCtl->StatAsyncTimeUS, uWait);
4575 STAM_COUNTER_INC(&pCtl->StatAsyncOps);
4576#endif /* DEBUG || VBOX_WITH_STATISTICS */
4577 }
4578
4579 LogBird(("ata: %x: leaving critsect\n", pCtl->IOPortBase1));
4580 PDMCritSectLeave(&pCtl->lock);
4581 }
4582
4583 /* Cleanup the state. */
4584 if (pCtl->AsyncIOSem)
4585 {
4586 RTSemEventDestroy(pCtl->AsyncIOSem);
4587 pCtl->AsyncIOSem = NIL_RTSEMEVENT;
4588 }
4589 if (pCtl->SuspendIOSem)
4590 {
4591 RTSemEventDestroy(pCtl->SuspendIOSem);
4592 pCtl->SuspendIOSem = NIL_RTSEMEVENT;
4593 }
4594 /* Do not destroy request mutex yet, still needed for proper shutdown. */
4595 pCtl->fShutdown = false;
4596 /* This must be last, as it also signals thread exit to EMT. */
4597 pCtl->AsyncIOThread = NIL_RTTHREAD;
4598
4599 Log2(("%s: Ctl#%d: return %Vrc\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl), rc));
4600 return rc;
4601}
4602
4603#endif /* IN_RING3 */
4604
4605static uint32_t ataBMDMACmdReadB(PATACONTROLLER pCtl, uint32_t addr)
4606{
4607 uint32_t val = pCtl->BmDma.u8Cmd;
4608 Log2(("%s: addr=%#06x val=%#04x\n", __FUNCTION__, addr, val));
4609 return val;
4610}
4611
4612
4613static void ataBMDMACmdWriteB(PATACONTROLLER pCtl, uint32_t addr, uint32_t val)
4614{
4615 Log2(("%s: addr=%#06x val=%#04x\n", __FUNCTION__, addr, val));
4616 if (!(val & BM_CMD_START))
4617 {
4618 pCtl->BmDma.u8Status &= ~BM_STATUS_DMAING;
4619 pCtl->BmDma.u8Cmd = val & (BM_CMD_START | BM_CMD_WRITE);
4620 }
4621 else
4622 {
4623#ifdef IN_RING3
4624 /* Check whether the guest OS wants to change DMA direction in
4625 * mid-flight. Not allowed, according to the PIIX3 specs. */
4626 Assert(!(pCtl->BmDma.u8Status & BM_STATUS_DMAING) || !((val ^ pCtl->BmDma.u8Cmd) & 0x04));
4627 pCtl->BmDma.u8Status |= BM_STATUS_DMAING;
4628 pCtl->BmDma.u8Cmd = val & (BM_CMD_START | BM_CMD_WRITE);
4629
4630 /* Do not continue DMA transfers while the RESET line is asserted. */
4631 if (pCtl->fReset)
4632 {
4633 Log2(("%s: Ctl#%d: suppressed continuing DMA transfer as RESET is active\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
4634 return;
4635 }
4636
4637 /* Do not start DMA transfers if there's a PIO transfer going on. */
4638 if (!pCtl->aIfs[pCtl->iSelectedIf].fDMA)
4639 return;
4640
4641 if (pCtl->aIfs[pCtl->iAIOIf].uATARegStatus & ATA_STAT_DRQ)
4642 {
4643 Log2(("%s: Ctl#%d: message to async I/O thread, continuing DMA transfer\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
4644 ataAsyncIOPutRequest(pCtl, &ataDMARequest);
4645 }
4646#else /* !IN_RING3 */
4647 AssertMsgFailed(("DMA START handling is too complicated for GC\n"));
4648#endif /* IN_RING3 */
4649 }
4650}
4651
4652static uint32_t ataBMDMAStatusReadB(PATACONTROLLER pCtl, uint32_t addr)
4653{
4654 uint32_t val = pCtl->BmDma.u8Status;
4655 Log2(("%s: addr=%#06x val=%#04x\n", __FUNCTION__, addr, val));
4656 return val;
4657}
4658
4659static void ataBMDMAStatusWriteB(PATACONTROLLER pCtl, uint32_t addr, uint32_t val)
4660{
4661 Log2(("%s: addr=%#06x val=%#04x\n", __FUNCTION__, addr, val));
4662 pCtl->BmDma.u8Status = (val & (BM_STATUS_D0DMA | BM_STATUS_D1DMA))
4663 | (pCtl->BmDma.u8Status & BM_STATUS_DMAING)
4664 | (pCtl->BmDma.u8Status & ~val & (BM_STATUS_ERROR | BM_STATUS_INT));
4665}
4666
4667static uint32_t ataBMDMAAddrReadL(PATACONTROLLER pCtl, uint32_t addr)
4668{
4669 uint32_t val = (uint32_t)pCtl->BmDma.pvAddr;
4670 Log2(("%s: addr=%#06x val=%#010x\n", __FUNCTION__, addr, val));
4671 return val;
4672}
4673
4674static void ataBMDMAAddrWriteL(PATACONTROLLER pCtl, uint32_t addr, uint32_t val)
4675{
4676 Log2(("%s: addr=%#06x val=%#010x\n", __FUNCTION__, addr, val));
4677 pCtl->BmDma.pvAddr = val & ~3;
4678}
4679
4680static void ataBMDMAAddrWriteLowWord(PATACONTROLLER pCtl, uint32_t addr, uint32_t val)
4681{
4682 Log2(("%s: addr=%#06x val=%#010x\n", __FUNCTION__, addr, val));
4683 pCtl->BmDma.pvAddr = (pCtl->BmDma.pvAddr & 0xFFFF0000) | RT_LOWORD(val & ~3);
4684
4685}
4686
4687static void ataBMDMAAddrWriteHighWord(PATACONTROLLER pCtl, uint32_t addr, uint32_t val)
4688{
4689 Log2(("%s: addr=%#06x val=%#010x\n", __FUNCTION__, addr, val));
4690 pCtl->BmDma.pvAddr = (RT_LOWORD(val) << 16) | RT_LOWORD(pCtl->BmDma.pvAddr);
4691}
4692
4693#define VAL(port, size) ( ((port) & 7) | ((size) << 3) )
4694
4695/**
4696 * Port I/O Handler for bus master DMA IN operations.
4697 * @see FNIOMIOPORTIN for details.
4698 */
4699PDMBOTHCBDECL(int) ataBMDMAIOPortRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
4700{
4701 uint32_t i = (uint32_t)(uintptr_t)pvUser;
4702 PCIATAState *pData = PDMINS2DATA(pDevIns, PCIATAState *);
4703 PATACONTROLLER pCtl = &pData->aCts[i];
4704 int rc;
4705
4706 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_HC_IOPORT_READ);
4707 if (rc != VINF_SUCCESS)
4708 return rc;
4709 switch (VAL(Port, cb))
4710 {
4711 case VAL(0, 1): *pu32 = ataBMDMACmdReadB(pCtl, Port); break;
4712 case VAL(0, 2): *pu32 = ataBMDMACmdReadB(pCtl, Port); break;
4713 case VAL(2, 1): *pu32 = ataBMDMAStatusReadB(pCtl, Port); break;
4714 case VAL(2, 2): *pu32 = ataBMDMAStatusReadB(pCtl, Port); break;
4715 case VAL(4, 4): *pu32 = ataBMDMAAddrReadL(pCtl, Port); break;
4716 default:
4717 AssertMsgFailed(("%s: Unsupported read from port %x size=%d\n", __FUNCTION__, Port, cb));
4718 PDMCritSectLeave(&pCtl->lock);
4719 return VERR_IOM_IOPORT_UNUSED;
4720 }
4721 PDMCritSectLeave(&pCtl->lock);
4722 return rc;
4723}
4724
4725/**
4726 * Port I/O Handler for bus master DMA OUT operations.
4727 * @see FNIOMIOPORTOUT for details.
4728 */
4729PDMBOTHCBDECL(int) ataBMDMAIOPortWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
4730{
4731 uint32_t i = (uint32_t)(uintptr_t)pvUser;
4732 PCIATAState *pData = PDMINS2DATA(pDevIns, PCIATAState *);
4733 PATACONTROLLER pCtl = &pData->aCts[i];
4734 int rc;
4735
4736 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_HC_IOPORT_WRITE);
4737 if (rc != VINF_SUCCESS)
4738 return rc;
4739 switch (VAL(Port, cb))
4740 {
4741 case VAL(0, 1):
4742#ifndef IN_RING3
4743 if (u32 & BM_CMD_START)
4744 {
4745 rc = VINF_IOM_HC_IOPORT_WRITE;
4746 break;
4747 }
4748#endif /* !IN_RING3 */
4749 ataBMDMACmdWriteB(pCtl, Port, u32);
4750 break;
4751 case VAL(2, 1): ataBMDMAStatusWriteB(pCtl, Port, u32); break;
4752 case VAL(4, 4): ataBMDMAAddrWriteL(pCtl, Port, u32); break;
4753 case VAL(4, 2): ataBMDMAAddrWriteLowWord(pCtl, Port, u32); break;
4754 case VAL(6, 2): ataBMDMAAddrWriteHighWord(pCtl, Port, u32); break;
4755 default: AssertMsgFailed(("%s: Unsupported write to port %x size=%d val=%x\n", __FUNCTION__, Port, cb, u32)); break;
4756 }
4757 PDMCritSectLeave(&pCtl->lock);
4758 return rc;
4759}
4760
4761#undef VAL
4762
4763#ifdef IN_RING3
4764
4765/**
4766 * Callback function for mapping an PCI I/O region.
4767 *
4768 * @return VBox status code.
4769 * @param pPciDev Pointer to PCI device. Use pPciDev->pDevIns to get the device instance.
4770 * @param iRegion The region number.
4771 * @param GCPhysAddress Physical address of the region. If iType is PCI_ADDRESS_SPACE_IO, this is an
4772 * I/O port, else it's a physical address.
4773 * This address is *NOT* relative to pci_mem_base like earlier!
4774 * @param enmType One of the PCI_ADDRESS_SPACE_* values.
4775 */
4776static DECLCALLBACK(int) ataBMDMAIORangeMap(PPCIDEVICE pPciDev, /*unsigned*/ int iRegion, RTGCPHYS GCPhysAddress, uint32_t cb, PCIADDRESSSPACE enmType)
4777{
4778 PCIATAState *pData = PCIDEV_2_PCIATASTATE(pPciDev);
4779 int rc = VINF_SUCCESS;
4780 Assert(enmType == PCI_ADDRESS_SPACE_IO);
4781 Assert(iRegion == 4);
4782 AssertMsg(RT_ALIGN(GCPhysAddress, 8) == GCPhysAddress, ("Expected 8 byte alignment. GCPhysAddress=%#x\n", GCPhysAddress));
4783
4784 /* Register the port range. */
4785 for (uint32_t i = 0; i < RT_ELEMENTS(pData->aCts); i++)
4786 {
4787 int rc2 = PDMDevHlpIOPortRegister(pPciDev->pDevIns, (RTIOPORT)GCPhysAddress + i * 8, 8,
4788 (RTHCPTR)i, ataBMDMAIOPortWrite, ataBMDMAIOPortRead, NULL, NULL, "ATA Bus Master DMA");
4789 AssertRC(rc2);
4790 if (rc2 < rc)
4791 rc = rc2;
4792
4793 if (pData->fGCEnabled)
4794 {
4795 rc2 = PDMDevHlpIOPortRegisterGC(pPciDev->pDevIns, (RTIOPORT)GCPhysAddress + i * 8, 8,
4796 (RTGCPTR)i, "ataBMDMAIOPortWrite", "ataBMDMAIOPortRead", NULL, NULL, "ATA Bus Master DMA");
4797 AssertRC(rc2);
4798 if (rc2 < rc)
4799 rc = rc2;
4800 }
4801 if (pData->fR0Enabled)
4802 {
4803 rc2 = PDMDevHlpIOPortRegisterR0(pPciDev->pDevIns, (RTIOPORT)GCPhysAddress + i * 8, 8,
4804 (RTR0PTR)i, "ataBMDMAIOPortWrite", "ataBMDMAIOPortRead", NULL, NULL, "ATA Bus Master DMA");
4805 AssertRC(rc2);
4806 if (rc2 < rc)
4807 rc = rc2;
4808 }
4809 }
4810 return rc;
4811}
4812
4813
4814/**
4815 * Reset notification.
4816 *
4817 * @returns VBox status.
4818 * @param pDevIns The device instance data.
4819 */
4820static DECLCALLBACK(void) ataReset(PPDMDEVINS pDevIns)
4821{
4822 PCIATAState *pData = PDMINS2DATA(pDevIns, PCIATAState *);
4823
4824 for (uint32_t i = 0; i < RT_ELEMENTS(pData->aCts); i++)
4825 {
4826 pData->aCts[i].iSelectedIf = 0;
4827 pData->aCts[i].iAIOIf = 0;
4828 pData->aCts[i].BmDma.u8Cmd = 0;
4829 /* Report that both drives present on the bus are in DMA mode. This
4830 * pretends that there is a BIOS that has set it up. Normal reset
4831 * default is 0x00. */
4832 pData->aCts[i].BmDma.u8Status = (pData->aCts[i].aIfs[0].pDrvBase != NULL ? BM_STATUS_D0DMA : 0)
4833 | (pData->aCts[i].aIfs[1].pDrvBase != NULL ? BM_STATUS_D1DMA : 0);
4834 pData->aCts[i].BmDma.pvAddr = 0;
4835
4836 pData->aCts[i].fReset = true;
4837 pData->aCts[i].fRedo = false;
4838 pData->aCts[i].fRedoIdle = false;
4839 ataAsyncIOClearRequests(&pData->aCts[i]);
4840 Log2(("%s: Ctl#%d: message to async I/O thread, reset controller\n", __FUNCTION__, i));
4841 ataAsyncIOPutRequest(&pData->aCts[i], &ataResetARequest);
4842 ataAsyncIOPutRequest(&pData->aCts[i], &ataResetCRequest);
4843 if (!ataWaitForAsyncIOIsIdle(&pData->aCts[i], 30000))
4844 AssertReleaseMsgFailed(("Async I/O thread busy after reset\n"));
4845
4846 for (uint32_t j = 0; j < RT_ELEMENTS(pData->aCts[i].aIfs); j++)
4847 ataResetDevice(&pData->aCts[i].aIfs[j]);
4848 }
4849}
4850
4851
4852/* -=-=-=-=-=- PCIATAState::IBase -=-=-=-=-=- */
4853
4854/**
4855 * Queries an interface to the driver.
4856 *
4857 * @returns Pointer to interface.
4858 * @returns NULL if the interface was not supported by the device.
4859 * @param pInterface Pointer to ATADevState::IBase.
4860 * @param enmInterface The requested interface identification.
4861 */
4862static DECLCALLBACK(void *) ataStatus_QueryInterface(PPDMIBASE pInterface, PDMINTERFACE enmInterface)
4863{
4864 PCIATAState *pData = PDMIBASE_2_PCIATASTATE(pInterface);
4865 switch (enmInterface)
4866 {
4867 case PDMINTERFACE_BASE:
4868 return &pData->IBase;
4869 case PDMINTERFACE_LED_PORTS:
4870 return &pData->ILeds;
4871 default:
4872 return NULL;
4873 }
4874}
4875
4876
4877/* -=-=-=-=-=- PCIATAState::ILeds -=-=-=-=-=- */
4878
4879/**
4880 * Gets the pointer to the status LED of a unit.
4881 *
4882 * @returns VBox status code.
4883 * @param pInterface Pointer to the interface structure containing the called function pointer.
4884 * @param iLUN The unit which status LED we desire.
4885 * @param ppLed Where to store the LED pointer.
4886 */
4887static DECLCALLBACK(int) ataStatus_QueryStatusLed(PPDMILEDPORTS pInterface, unsigned iLUN, PPDMLED *ppLed)
4888{
4889 PCIATAState *pData = PDMILEDPORTS_2_PCIATASTATE(pInterface);
4890 if (iLUN >= 0 && iLUN <= 4)
4891 {
4892 switch (iLUN)
4893 {
4894 case 0: *ppLed = &pData->aCts[0].aIfs[0].Led; break;
4895 case 1: *ppLed = &pData->aCts[0].aIfs[1].Led; break;
4896 case 2: *ppLed = &pData->aCts[1].aIfs[0].Led; break;
4897 case 3: *ppLed = &pData->aCts[1].aIfs[1].Led; break;
4898 }
4899 Assert((*ppLed)->u32Magic == PDMLED_MAGIC);
4900 return VINF_SUCCESS;
4901 }
4902 return VERR_PDM_LUN_NOT_FOUND;
4903}
4904
4905
4906/* -=-=-=-=-=- ATADevState::IBase -=-=-=-=-=- */
4907
4908/**
4909 * Queries an interface to the driver.
4910 *
4911 * @returns Pointer to interface.
4912 * @returns NULL if the interface was not supported by the device.
4913 * @param pInterface Pointer to ATADevState::IBase.
4914 * @param enmInterface The requested interface identification.
4915 */
4916static DECLCALLBACK(void *) ataQueryInterface(PPDMIBASE pInterface, PDMINTERFACE enmInterface)
4917{
4918 ATADevState *pIf = PDMIBASE_2_ATASTATE(pInterface);
4919 switch (enmInterface)
4920 {
4921 case PDMINTERFACE_BASE:
4922 return &pIf->IBase;
4923 case PDMINTERFACE_BLOCK_PORT:
4924 return &pIf->IPort;
4925 case PDMINTERFACE_MOUNT_NOTIFY:
4926 return &pIf->IMountNotify;
4927 default:
4928 return NULL;
4929 }
4930}
4931
4932#endif /* IN_RING3 */
4933
4934
4935/* -=-=-=-=-=- Wrappers -=-=-=-=-=- */
4936
4937/**
4938 * Port I/O Handler for primary port range OUT operations.
4939 * @see FNIOMIOPORTOUT for details.
4940 */
4941PDMBOTHCBDECL(int) ataIOPortWrite1(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
4942{
4943 uint32_t i = (uint32_t)(uintptr_t)pvUser;
4944 PCIATAState *pData = PDMINS2DATA(pDevIns, PCIATAState *);
4945 PATACONTROLLER pCtl = &pData->aCts[i];
4946 int rc = VINF_SUCCESS;
4947
4948 Assert(i < 2);
4949
4950 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_HC_IOPORT_WRITE);
4951 if (rc != VINF_SUCCESS)
4952 return rc;
4953 if (cb == 1)
4954 rc = ataIOPortWriteU8(pCtl, Port, u32);
4955 else if (Port == pCtl->IOPortBase1)
4956 {
4957 Assert(cb == 2 || cb == 4);
4958 rc = ataDataWrite(pCtl, Port, cb, (const uint8_t *)&u32);
4959 }
4960 else
4961 AssertMsgFailed(("ataIOPortWrite1: unsupported write to port %x val=%x size=%d\n", Port, u32, cb));
4962 LogBird(("ata: leaving critsect\n"));
4963 PDMCritSectLeave(&pCtl->lock);
4964 LogBird(("ata: left critsect\n"));
4965 return rc;
4966}
4967
4968
4969/**
4970 * Port I/O Handler for primary port range IN operations.
4971 * @see FNIOMIOPORTIN for details.
4972 */
4973PDMBOTHCBDECL(int) ataIOPortRead1(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
4974{
4975 uint32_t i = (uint32_t)(uintptr_t)pvUser;
4976 PCIATAState *pData = PDMINS2DATA(pDevIns, PCIATAState *);
4977 PATACONTROLLER pCtl = &pData->aCts[i];
4978 int rc = VINF_SUCCESS;
4979
4980 Assert(i < 2);
4981
4982 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_HC_IOPORT_READ);
4983 if (rc != VINF_SUCCESS)
4984 return rc;
4985 if (cb == 1)
4986 {
4987 rc = ataIOPortReadU8(pCtl, Port, pu32);
4988 }
4989 else if (Port == pCtl->IOPortBase1)
4990 {
4991 Assert(cb == 2 || cb == 4);
4992 rc = ataDataRead(pCtl, Port, cb, (uint8_t *)pu32);
4993 if (cb == 2)
4994 *pu32 &= 0xffff;
4995 }
4996 else
4997 {
4998 AssertMsgFailed(("ataIOPortRead1: unsupported read from port %x size=%d\n", Port, cb));
4999 rc = VERR_IOM_IOPORT_UNUSED;
5000 }
5001 PDMCritSectLeave(&pCtl->lock);
5002 return rc;
5003}
5004
5005#ifndef IN_RING0
5006/**
5007 * Port I/O Handler for primary port range IN string operations.
5008 * @see FNIOMIOPORTINSTRING for details.
5009 */
5010PDMBOTHCBDECL(int) ataIOPortReadStr1(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, RTGCPTR *pGCPtrDst, unsigned *pcTransfer, unsigned cb)
5011{
5012 uint32_t i = (uint32_t)(uintptr_t)pvUser;
5013 PCIATAState *pData = PDMINS2DATA(pDevIns, PCIATAState *);
5014 PATACONTROLLER pCtl = &pData->aCts[i];
5015 int rc = VINF_SUCCESS;
5016
5017 Assert(i < 2);
5018
5019 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_HC_IOPORT_READ);
5020 if (rc != VINF_SUCCESS)
5021 return rc;
5022 if (Port == pCtl->IOPortBase1)
5023 {
5024 uint32_t cTransAvailable, cTransfer = *pcTransfer, cbTransfer;
5025 RTGCPTR GCDst = *pGCPtrDst;
5026 ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf];
5027 Assert(cb == 2 || cb == 4);
5028
5029 cTransAvailable = (s->iIOBufferPIODataEnd - s->iIOBufferPIODataStart) / cb;
5030#ifndef IN_RING3
5031 /* The last transfer unit cannot be handled in GC, as it involves thread communication. */
5032 cTransAvailable--;
5033#endif /* !IN_RING3 */
5034 /* Do not handle the dummy transfer stuff here, leave it to the single-word transfers.
5035 * They are not performance-critical and generally shouldn't occur at all. */
5036 if (cTransAvailable > cTransfer)
5037 cTransAvailable = cTransfer;
5038 cbTransfer = cTransAvailable * cb;
5039
5040#ifdef IN_GC
5041 for (uint32_t i = 0; i < cbTransfer; i += cb)
5042 MMGCRamWriteNoTrapHandler((char *)GCDst + i, s->CTXSUFF(pbIOBuffer) + s->iIOBufferPIODataStart + i, cb);
5043#else /* !IN_GC */
5044 rc = PGMPhysWriteGCPtrDirty(PDMDevHlpGetVM(pDevIns), GCDst, s->CTXSUFF(pbIOBuffer) + s->iIOBufferPIODataStart, cbTransfer);
5045 Assert(rc == VINF_SUCCESS);
5046#endif /* IN_GC */
5047
5048 if (cbTransfer)
5049 Log3(("%s: addr=%#x val=%.*Vhxs\n", __FUNCTION__, Port, cbTransfer, s->CTXSUFF(pbIOBuffer) + s->iIOBufferPIODataStart));
5050 s->iIOBufferPIODataStart += cbTransfer;
5051 *pGCPtrDst = (RTGCPTR)((RTGCUINTPTR)GCDst + cbTransfer);
5052 *pcTransfer = cTransfer - cTransAvailable;
5053#ifdef IN_RING3
5054 if (s->iIOBufferPIODataStart >= s->iIOBufferPIODataEnd)
5055 ataPIOTransferFinish(pCtl, s);
5056#endif /* IN_RING3 */
5057 }
5058 PDMCritSectLeave(&pCtl->lock);
5059 return rc;
5060}
5061
5062
5063/**
5064 * Port I/O Handler for primary port range OUT string operations.
5065 * @see FNIOMIOPORTOUTSTRING for details.
5066 */
5067PDMBOTHCBDECL(int) ataIOPortWriteStr1(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, RTGCPTR *pGCPtrSrc, unsigned *pcTransfer, unsigned cb)
5068{
5069 uint32_t i = (uint32_t)(uintptr_t)pvUser;
5070 PCIATAState *pData = PDMINS2DATA(pDevIns, PCIATAState *);
5071 PATACONTROLLER pCtl = &pData->aCts[i];
5072 int rc;
5073
5074 Assert(i < 2);
5075
5076 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_HC_IOPORT_WRITE);
5077 if (rc != VINF_SUCCESS)
5078 return rc;
5079 if (Port == pCtl->IOPortBase1)
5080 {
5081 uint32_t cTransAvailable, cTransfer = *pcTransfer, cbTransfer;
5082 RTGCPTR GCSrc = *pGCPtrSrc;
5083 ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf];
5084 Assert(cb == 2 || cb == 4);
5085
5086 cTransAvailable = (s->iIOBufferPIODataEnd - s->iIOBufferPIODataStart) / cb;
5087#ifndef IN_RING3
5088 /* The last transfer unit cannot be handled in GC, as it involves thread communication. */
5089 cTransAvailable--;
5090#endif /* !IN_RING3 */
5091 /* Do not handle the dummy transfer stuff here, leave it to the single-word transfers.
5092 * They are not performance-critical and generally shouldn't occur at all. */
5093 if (cTransAvailable > cTransfer)
5094 cTransAvailable = cTransfer;
5095 cbTransfer = cTransAvailable * cb;
5096
5097#ifdef IN_GC
5098 for (uint32_t i = 0; i < cbTransfer; i += cb)
5099 MMGCRamReadNoTrapHandler(s->CTXSUFF(pbIOBuffer) + s->iIOBufferPIODataStart + i, (char *)GCSrc + i, cb);
5100#else /* !IN_GC */
5101 rc = PGMPhysReadGCPtr(PDMDevHlpGetVM(pDevIns), s->CTXSUFF(pbIOBuffer) + s->iIOBufferPIODataStart, GCSrc, cbTransfer);
5102 Assert(rc == VINF_SUCCESS);
5103#endif /* IN_GC */
5104
5105 if (cbTransfer)
5106 Log3(("%s: addr=%#x val=%.*Vhxs\n", __FUNCTION__, Port, cbTransfer, s->CTXSUFF(pbIOBuffer) + s->iIOBufferPIODataStart));
5107 s->iIOBufferPIODataStart += cbTransfer;
5108 *pGCPtrSrc = (RTGCPTR)((RTGCUINTPTR)GCSrc + cbTransfer);
5109 *pcTransfer = cTransfer - cTransAvailable;
5110#ifdef IN_RING3
5111 if (s->iIOBufferPIODataStart >= s->iIOBufferPIODataEnd)
5112 ataPIOTransferFinish(pCtl, s);
5113#endif /* IN_RING3 */
5114 }
5115 PDMCritSectLeave(&pCtl->lock);
5116 return rc;
5117}
5118#endif /* !IN_RING0 */
5119
5120/**
5121 * Port I/O Handler for secondary port range OUT operations.
5122 * @see FNIOMIOPORTOUT for details.
5123 */
5124PDMBOTHCBDECL(int) ataIOPortWrite2(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
5125{
5126 uint32_t i = (uint32_t)(uintptr_t)pvUser;
5127 PCIATAState *pData = PDMINS2DATA(pDevIns, PCIATAState *);
5128 PATACONTROLLER pCtl = &pData->aCts[i];
5129 int rc;
5130
5131 Assert(i < 2);
5132
5133 if (cb != 1)
5134 return VINF_SUCCESS;
5135 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_HC_IOPORT_WRITE);
5136 if (rc != VINF_SUCCESS)
5137 return rc;
5138 rc = ataControlWrite(pCtl, Port, u32);
5139 PDMCritSectLeave(&pCtl->lock);
5140 return rc;
5141}
5142
5143
5144/**
5145 * Port I/O Handler for secondary port range IN operations.
5146 * @see FNIOMIOPORTIN for details.
5147 */
5148PDMBOTHCBDECL(int) ataIOPortRead2(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
5149{
5150 uint32_t i = (uint32_t)(uintptr_t)pvUser;
5151 PCIATAState *pData = PDMINS2DATA(pDevIns, PCIATAState *);
5152 PATACONTROLLER pCtl = &pData->aCts[i];
5153 int rc;
5154
5155 Assert(i < 2);
5156
5157 if (cb != 1)
5158 return VERR_IOM_IOPORT_UNUSED;
5159
5160 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_HC_IOPORT_READ);
5161 if (rc != VINF_SUCCESS)
5162 return rc;
5163 *pu32 = ataStatusRead(pCtl, Port);
5164 PDMCritSectLeave(&pCtl->lock);
5165 return VINF_SUCCESS;
5166}
5167
5168#ifdef IN_RING3
5169
5170/**
5171 * Waits for all async I/O threads to complete whatever they
5172 * are doing at the moment.
5173 *
5174 * @returns true on success.
5175 * @returns false when one or more threads is still processing.
5176 * @param pData Pointer to the instance data.
5177 * @param cMillies How long to wait (total).
5178 */
5179static bool ataWaitForAllAsyncIOIsIdle(PPDMDEVINS pDevIns, unsigned cMillies)
5180{
5181 PCIATAState *pData = PDMINS2DATA(pDevIns, PCIATAState *);
5182 bool fVMLocked;
5183 uint64_t u64Start;
5184 PATACONTROLLER pCtl;
5185 bool fAllIdle = false;
5186
5187 /* The only way to deal cleanly with the VM lock is to check whether
5188 * it is owned now (it always is owned by EMT, which is the current
5189 * thread). Since this function is called several times during VM
5190 * shutdown, and the VM lock is only held for the first call (which
5191 * can be either from ataPowerOff or ataSuspend), there is no other
5192 * reasonable solution. */
5193 fVMLocked = VMMR3LockIsOwner(PDMDevHlpGetVM(pDevIns));
5194
5195 if (fVMLocked)
5196 pDevIns->pDevHlp->pfnUnlockVM(pDevIns);
5197 /*
5198 * Wait for any pending async operation to finish
5199 */
5200 u64Start = RTTimeMilliTS();
5201 for (;;)
5202 {
5203 /* Check all async I/O threads. */
5204 fAllIdle = true;
5205 for (uint32_t i = 0; i < RT_ELEMENTS(pData->aCts); i++)
5206 {
5207 pCtl = &pData->aCts[i];
5208 fAllIdle &= ataAsyncIOIsIdle(pCtl, false);
5209 if (!fAllIdle)
5210 break;
5211 }
5212 if ( fAllIdle
5213 || RTTimeMilliTS() - u64Start >= cMillies)
5214 break;
5215
5216 /* Sleep for a bit. */
5217 RTThreadSleep(100);
5218 }
5219
5220 if (fVMLocked)
5221 pDevIns->pDevHlp->pfnLockVM(pDevIns);
5222
5223 if (!fAllIdle)
5224 LogRel(("PIIX3 ATA: Ctl#%d is still executing, DevSel=%d AIOIf=%d CmdIf0=%#04x CmdIf1=%#04x\n",
5225 ATACONTROLLER_IDX(pCtl), pCtl->iSelectedIf, pCtl->iAIOIf,
5226 pCtl->aIfs[0].uATARegCommand, pCtl->aIfs[1].uATARegCommand));
5227
5228 return fAllIdle;
5229}
5230
5231
5232DECLINLINE(void) ataRelocBuffer(PPDMDEVINS pDevIns, ATADevState *s)
5233{
5234 if (s->pbIOBufferHC)
5235 s->pbIOBufferGC = MMHyperHC2GC(PDMDevHlpGetVM(pDevIns), s->pbIOBufferHC);
5236}
5237
5238
5239/**
5240 * @copydoc FNPDMDEVRELOCATE
5241 */
5242static DECLCALLBACK(void) ataRelocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta)
5243{
5244 PCIATAState *pData = PDMINS2DATA(pDevIns, PCIATAState *);
5245
5246 for (uint32_t i = 0; i < RT_ELEMENTS(pData->aCts); i++)
5247 {
5248 pData->aCts[i].pDevInsGC += offDelta;
5249 pData->aCts[i].aIfs[0].pDevInsGC += offDelta;
5250 pData->aCts[i].aIfs[0].pControllerGC += offDelta;
5251 ataRelocBuffer(pDevIns, &pData->aCts[i].aIfs[0]);
5252 pData->aCts[i].aIfs[1].pDevInsGC += offDelta;
5253 pData->aCts[i].aIfs[1].pControllerGC += offDelta;
5254 ataRelocBuffer(pDevIns, &pData->aCts[i].aIfs[1]);
5255 }
5256}
5257
5258
5259/**
5260 * Destroy a driver instance.
5261 *
5262 * Most VM resources are freed by the VM. This callback is provided so that any non-VM
5263 * resources can be freed correctly.
5264 *
5265 * @param pDevIns The device instance data.
5266 */
5267static DECLCALLBACK(int) ataDestruct(PPDMDEVINS pDevIns)
5268{
5269 PCIATAState *pData = PDMINS2DATA(pDevIns, PCIATAState *);
5270 int rc;
5271
5272 Log(("%s:\n", __FUNCTION__));
5273
5274 /*
5275 * Terminate all async helper threads
5276 */
5277 for (uint32_t i = 0; i < RT_ELEMENTS(pData->aCts); i++)
5278 {
5279 if (pData->aCts[i].AsyncIOThread != NIL_RTTHREAD)
5280 {
5281 ASMAtomicXchgU32(&pData->aCts[i].fShutdown, true);
5282 rc = RTSemEventSignal(pData->aCts[i].AsyncIOSem);
5283 AssertRC(rc);
5284 }
5285 }
5286
5287 /*
5288 * Wait for them to complete whatever they are doing and then
5289 * for them to terminate.
5290 */
5291 if (ataWaitForAllAsyncIOIsIdle(pDevIns, 20000))
5292 {
5293 uint64_t u64Start = RTTimeMilliTS();
5294 bool fAllDone;
5295 for (;;)
5296 {
5297 /* check */
5298 fAllDone = true;
5299 for (uint32_t i = 0; i < RT_ELEMENTS(pData->aCts) && fAllDone; i++)
5300 fAllDone &= (pData->aCts[i].AsyncIOThread == NIL_RTTHREAD);
5301
5302 if ( fAllDone
5303 || RTTimeMilliTS() - u64Start >= 500)
5304 break;
5305
5306 /* Sleep for a bit. */
5307 RTThreadSleep(100);
5308 }
5309 AssertMsg(fAllDone, ("Some of the async I/O threads are still running!\n"));
5310 }
5311 else
5312 AssertMsgFailed(("Async I/O is still busy!\n"));
5313
5314 /*
5315 * Now the request mutexes are no longer needed. Free resources.
5316 */
5317 for (uint32_t i = 0; i < RT_ELEMENTS(pData->aCts); i++)
5318 {
5319 if (pData->aCts[i].AsyncIORequestMutex)
5320 {
5321 RTSemMutexDestroy(pData->aCts[i].AsyncIORequestMutex);
5322 pData->aCts[i].AsyncIORequestMutex = NIL_RTSEMEVENT;
5323 }
5324 }
5325 return VINF_SUCCESS;
5326}
5327
5328
5329/**
5330 * Detach notification.
5331 *
5332 * The DVD drive has been unplugged.
5333 *
5334 * @param pDevIns The device instance.
5335 * @param iLUN The logical unit which is being detached.
5336 */
5337static DECLCALLBACK(void) ataDetach(PPDMDEVINS pDevIns, unsigned iLUN)
5338{
5339 PCIATAState *pThis = PDMINS2DATA(pDevIns, PCIATAState *);
5340 PATACONTROLLER pCtl;
5341 ATADevState *pIf;
5342 unsigned iController;
5343 unsigned iInterface;
5344
5345 /*
5346 * Locate the controller and stuff.
5347 */
5348 iController = iLUN / RT_ELEMENTS(pThis->aCts[0].aIfs);
5349 AssertReleaseMsg(iController < RT_ELEMENTS(pThis->aCts), ("iController=%d iLUN=%d\n", iController, iLUN));
5350 pCtl = &pThis->aCts[iController];
5351
5352 iInterface = iLUN % RT_ELEMENTS(pThis->aCts[0].aIfs);
5353 pIf = &pCtl->aIfs[iInterface];
5354
5355 /*
5356 * Zero some important members.
5357 */
5358 pIf->pDrvBase = NULL;
5359 pIf->pDrvBlock = NULL;
5360 pIf->pDrvBlockBios = NULL;
5361 pIf->pDrvMount = NULL;
5362}
5363
5364
5365/**
5366 * Configure a LUN.
5367 *
5368 * @returns VBox status code.
5369 * @param pDevIns The device instance.
5370 * @param pIf The ATA unit state.
5371 */
5372static int ataConfigLun(PPDMDEVINS pDevIns, ATADevState *pIf)
5373{
5374 int rc;
5375 PDMBLOCKTYPE enmType;
5376
5377 /*
5378 * Query Block, Bios and Mount interfaces.
5379 */
5380 pIf->pDrvBlock = (PDMIBLOCK *)pIf->pDrvBase->pfnQueryInterface(pIf->pDrvBase, PDMINTERFACE_BLOCK);
5381 if (!pIf->pDrvBlock)
5382 {
5383 AssertMsgFailed(("Configuration error: LUN#%d hasn't a block interface!\n", pIf->iLUN));
5384 return VERR_PDM_MISSING_INTERFACE;
5385 }
5386
5387 /** @todo implement the BIOS invisible code path. */
5388 pIf->pDrvBlockBios = (PDMIBLOCKBIOS *)pIf->pDrvBase->pfnQueryInterface(pIf->pDrvBase, PDMINTERFACE_BLOCK_BIOS);
5389 if (!pIf->pDrvBlockBios)
5390 {
5391 AssertMsgFailed(("Configuration error: LUN#%d hasn't a block BIOS interface!\n", pIf->iLUN));
5392 return VERR_PDM_MISSING_INTERFACE;
5393 }
5394 pIf->pDrvMount = (PDMIMOUNT *)pIf->pDrvBase->pfnQueryInterface(pIf->pDrvBase, PDMINTERFACE_MOUNT);
5395
5396 /*
5397 * Validate type.
5398 */
5399 enmType = pIf->pDrvBlock->pfnGetType(pIf->pDrvBlock);
5400 if ( enmType != PDMBLOCKTYPE_CDROM
5401 && enmType != PDMBLOCKTYPE_DVD
5402 && enmType != PDMBLOCKTYPE_HARD_DISK)
5403 {
5404 AssertMsgFailed(("Configuration error: LUN#%d isn't a disk or cd/dvd-rom. enmType=%d\n", pIf->iLUN, enmType));
5405 return VERR_PDM_UNSUPPORTED_BLOCK_TYPE;
5406 }
5407 if ( ( enmType == PDMBLOCKTYPE_DVD
5408 || enmType == PDMBLOCKTYPE_CDROM)
5409 && !pIf->pDrvMount)
5410 {
5411 AssertMsgFailed(("Internal error: cdrom without a mountable interface, WTF???!\n"));
5412 return VERR_INTERNAL_ERROR;
5413 }
5414 pIf->fATAPI = enmType == PDMBLOCKTYPE_DVD || enmType == PDMBLOCKTYPE_CDROM;
5415 pIf->fATAPIPassthrough = pIf->fATAPI ? (pIf->pDrvBlock->pfnSendCmd != NULL) : false;
5416
5417 /*
5418 * Allocate I/O buffer.
5419 */
5420 PVM pVM = PDMDevHlpGetVM(pDevIns);
5421 if (pIf->cbIOBuffer)
5422 {
5423 /* Buffer is (probably) already allocated. Validate the fields,
5424 * because memory corruption can also overwrite pIf->cbIOBuffer. */
5425 if (pIf->fATAPI)
5426 AssertRelease(pIf->cbIOBuffer == _128K);
5427 else
5428 AssertRelease(pIf->cbIOBuffer == ATA_MAX_MULT_SECTORS * 512);
5429 Assert(pIf->pbIOBufferHC);
5430 Assert(pIf->pbIOBufferGC == MMHyperHC2GC(pVM, pIf->pbIOBufferHC));
5431 }
5432 else
5433 {
5434 if (pIf->fATAPI)
5435 pIf->cbIOBuffer = _128K;
5436 else
5437 pIf->cbIOBuffer = ATA_MAX_MULT_SECTORS * 512;
5438 Assert(!pIf->pbIOBufferHC);
5439 rc = MMHyperAlloc(pVM, pIf->cbIOBuffer, 1, MM_TAG_PDM_DEVICE_USER, (void **)&pIf->pbIOBufferHC);
5440 if (VBOX_FAILURE(rc))
5441 return VERR_NO_MEMORY;
5442 pIf->pbIOBufferGC = MMHyperHC2GC(pVM, pIf->pbIOBufferHC);
5443 }
5444
5445 /*
5446 * Init geometry.
5447 */
5448 if (pIf->fATAPI)
5449 {
5450 pIf->cTotalSectors = pIf->pDrvBlock->pfnGetSize(pIf->pDrvBlock) / 2048;
5451 rc = pIf->pDrvBlockBios->pfnGetGeometry(pIf->pDrvBlockBios, &pIf->cCHSCylinders, &pIf->cCHSHeads, &pIf->cCHSSectors);
5452 pIf->cCHSCylinders = 0; /* dummy */
5453 pIf->cCHSHeads = 0; /* dummy */
5454 pIf->cCHSSectors = 0; /* dummy */
5455 if (rc != VERR_PDM_MEDIA_NOT_MOUNTED)
5456 {
5457 pIf->pDrvBlockBios->pfnSetTranslation(pIf->pDrvBlockBios, PDMBIOSTRANSLATION_NONE);
5458 pIf->pDrvBlockBios->pfnSetGeometry(pIf->pDrvBlockBios, pIf->cCHSCylinders, pIf->cCHSHeads, pIf->cCHSSectors);
5459 }
5460 LogRel(("PIIX3 ATA: LUN#%d: CD/DVD, total number of sectors %Ld, passthrough %s\n", pIf->iLUN, pIf->cTotalSectors, (pIf->fATAPIPassthrough ? "enabled" : "disabled")));
5461 }
5462 else
5463 {
5464 pIf->cTotalSectors = pIf->pDrvBlock->pfnGetSize(pIf->pDrvBlock) / 512;
5465 rc = pIf->pDrvBlockBios->pfnGetGeometry(pIf->pDrvBlockBios, &pIf->cCHSCylinders, &pIf->cCHSHeads, &pIf->cCHSSectors);
5466 if (rc == VERR_PDM_MEDIA_NOT_MOUNTED)
5467 {
5468 pIf->cCHSCylinders = 0;
5469 pIf->cCHSHeads = 16; /*??*/
5470 pIf->cCHSSectors = 63; /*??*/
5471 }
5472 else if (VBOX_FAILURE(rc))
5473 {
5474 PDMBIOSTRANSLATION enmTranslation;
5475 rc = pIf->pDrvBlockBios->pfnGetTranslation(pIf->pDrvBlockBios, &enmTranslation);
5476 if (rc == VERR_PDM_TRANSLATION_NOT_SET)
5477 {
5478 enmTranslation = PDMBIOSTRANSLATION_AUTO;
5479 pIf->cCHSCylinders = 0;
5480 rc = VINF_SUCCESS;
5481 }
5482 AssertRC(rc);
5483
5484 if ( enmTranslation == PDMBIOSTRANSLATION_AUTO
5485 && ( pIf->cCHSCylinders == 0
5486 || pIf->cCHSHeads == 0
5487 || pIf->cCHSSectors == 0
5488 )
5489 )
5490 {
5491 /* Image contains no geometry information, detect geometry. */
5492 rc = ataGuessDiskLCHS(pIf, &pIf->cCHSCylinders, &pIf->cCHSHeads, &pIf->cCHSSectors);
5493 if (VBOX_SUCCESS(rc))
5494 {
5495 /* Caution: the above function returns LCHS, but the
5496 * disk must report proper PCHS values for disks bigger
5497 * than approximately 512MB. */
5498 if (pIf->cCHSSectors == 63 && (pIf->cCHSHeads != 16 || pIf->cCHSCylinders >= 1024))
5499 {
5500 pIf->cCHSCylinders = pIf->cTotalSectors / 63 / 16;
5501 pIf->cCHSHeads = 16;
5502 pIf->cCHSSectors = 63;
5503 /* Set the disk CHS translation mode. */
5504 pIf->pDrvBlockBios->pfnSetTranslation(pIf->pDrvBlockBios, PDMBIOSTRANSLATION_LBA);
5505 }
5506 /* Set the disk geometry information. */
5507 rc = pIf->pDrvBlockBios->pfnSetGeometry(pIf->pDrvBlockBios, pIf->cCHSCylinders, pIf->cCHSHeads, pIf->cCHSSectors);
5508 }
5509 else
5510 {
5511 /* Flag geometry as invalid, will be replaced below by the
5512 * default geometry. */
5513 pIf->cCHSCylinders = 0;
5514 }
5515 }
5516 if (!pIf->cCHSCylinders)
5517 {
5518 /* If there is no geometry, use standard physical disk geometry.
5519 * This uses LCHS to LBA translation in the BIOS (which selects
5520 * the logical sector count 63 and the logical head count to be
5521 * the smallest of 16,32,64,128,255 which makes the logical
5522 * cylinder count smaller than 1024 - if that's not possible, it
5523 * uses 255 heads, so up to about 8 GByte maximum with the
5524 * standard int13 interface, which supports 1024 cylinders). */
5525 uint64_t cCHSCylinders = pIf->cTotalSectors / (16 * 63);
5526 pIf->cCHSCylinders = (uint32_t)RT_MAX(cCHSCylinders, 1);
5527 pIf->cCHSHeads = 16;
5528 pIf->cCHSSectors = 63;
5529 /* Set the disk geometry information. */
5530 rc = pIf->pDrvBlockBios->pfnSetGeometry(pIf->pDrvBlockBios, pIf->cCHSCylinders, pIf->cCHSHeads, pIf->cCHSSectors);
5531 }
5532 }
5533 else
5534 {
5535 PDMBIOSTRANSLATION enmTranslation;
5536 rc = pIf->pDrvBlockBios->pfnGetTranslation(pIf->pDrvBlockBios, &enmTranslation);
5537 if (( rc == VERR_PDM_TRANSLATION_NOT_SET
5538 || enmTranslation == PDMBIOSTRANSLATION_LBA)
5539 && pIf->cCHSSectors == 63
5540 && (pIf->cCHSHeads != 16 || pIf->cCHSCylinders >= 1024))
5541 {
5542 /* Use the official LBA physical CHS geometry. */
5543 uint64_t cCHSCylinders = pIf->cTotalSectors / (16 * 63);
5544 pIf->cCHSCylinders = RT_MAX((uint32_t)RT_MIN(cCHSCylinders, 16383), 1);
5545 pIf->cCHSHeads = 16;
5546 pIf->cCHSSectors = 63;
5547 /* DO NOT write back the disk geometry information. This
5548 * intentionally sets the ATA geometry only. */
5549 }
5550 }
5551 LogRel(("PIIX3 ATA: LUN#%d: disk, CHS=%d/%d/%d, total number of sectors %Ld\n", pIf->iLUN, pIf->cCHSCylinders, pIf->cCHSHeads, pIf->cCHSSectors, pIf->cTotalSectors));
5552 }
5553 return VINF_SUCCESS;
5554}
5555
5556
5557/**
5558 * Attach command.
5559 *
5560 * This is called when we change block driver for the DVD drive.
5561 *
5562 * @returns VBox status code.
5563 * @param pDevIns The device instance.
5564 * @param iLUN The logical unit which is being detached.
5565 */
5566static DECLCALLBACK(int) ataAttach(PPDMDEVINS pDevIns, unsigned iLUN)
5567{
5568 PCIATAState *pThis = PDMINS2DATA(pDevIns, PCIATAState *);
5569 PATACONTROLLER pCtl;
5570 ATADevState *pIf;
5571 int rc;
5572 unsigned iController;
5573 unsigned iInterface;
5574
5575 /*
5576 * Locate the controller and stuff.
5577 */
5578 iController = iLUN / RT_ELEMENTS(pThis->aCts[0].aIfs);
5579 AssertReleaseMsg(iController < RT_ELEMENTS(pThis->aCts), ("iController=%d iLUN=%d\n", iController, iLUN));
5580 pCtl = &pThis->aCts[iController];
5581
5582 iInterface = iLUN % RT_ELEMENTS(pThis->aCts[0].aIfs);
5583 pIf = &pCtl->aIfs[iInterface];
5584
5585 /* the usual paranoia */
5586 AssertRelease(!pIf->pDrvBase);
5587 AssertRelease(!pIf->pDrvBlock);
5588 Assert(ATADEVSTATE_2_CONTROLLER(pIf) == pCtl);
5589 Assert(pIf->iLUN == iLUN);
5590
5591 /*
5592 * Try attach the block device and get the interfaces,
5593 * required as well as optional.
5594 */
5595 rc = PDMDevHlpDriverAttach(pDevIns, pIf->iLUN, &pIf->IBase, &pIf->pDrvBase, NULL);
5596 if (VBOX_SUCCESS(rc))
5597 rc = ataConfigLun(pDevIns, pIf);
5598 else
5599 AssertMsgFailed(("Failed to attach LUN#%d. rc=%Vrc\n", pIf->iLUN, rc));
5600
5601 if (VBOX_FAILURE(rc))
5602 {
5603 pIf->pDrvBase = NULL;
5604 pIf->pDrvBlock = NULL;
5605 }
5606 return rc;
5607}
5608
5609
5610/**
5611 * Suspend notification.
5612 *
5613 * @returns VBox status.
5614 * @param pDevIns The device instance data.
5615 */
5616static DECLCALLBACK(void) ataSuspend(PPDMDEVINS pDevIns)
5617{
5618 Log(("%s:\n", __FUNCTION__));
5619 if (!ataWaitForAllAsyncIOIsIdle(pDevIns, 20000))
5620 AssertMsgFailed(("Async I/O didn't stop in 20 seconds!\n"));
5621 return;
5622}
5623
5624
5625/**
5626 * Resume notification.
5627 *
5628 * @returns VBox status.
5629 * @param pDevIns The device instance data.
5630 */
5631static DECLCALLBACK(void) ataResume(PPDMDEVINS pDevIns)
5632{
5633 PCIATAState *pData = PDMINS2DATA(pDevIns, PCIATAState *);
5634 int rc;
5635
5636 Log(("%s:\n", __FUNCTION__));
5637 for (uint32_t i = 0; i < RT_ELEMENTS(pData->aCts); i++)
5638 {
5639 if (pData->aCts[i].fRedo && pData->aCts[i].fRedoIdle)
5640 {
5641 rc = RTSemEventSignal(pData->aCts[i].SuspendIOSem);
5642 AssertRC(rc);
5643 }
5644 }
5645 return;
5646}
5647
5648
5649/**
5650 * Power Off notification.
5651 *
5652 * @returns VBox status.
5653 * @param pDevIns The device instance data.
5654 */
5655static DECLCALLBACK(void) ataPowerOff(PPDMDEVINS pDevIns)
5656{
5657 Log(("%s:\n", __FUNCTION__));
5658 if (!ataWaitForAllAsyncIOIsIdle(pDevIns, 20000))
5659 AssertMsgFailed(("Async I/O didn't stop in 20 seconds!\n"));
5660 return;
5661}
5662
5663
5664/**
5665 * Prepare state save and load operation.
5666 *
5667 * @returns VBox status code.
5668 * @param pDevIns Device instance of the device which registered the data unit.
5669 * @param pSSM SSM operation handle.
5670 */
5671static DECLCALLBACK(int) ataSaveLoadPrep(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
5672{
5673 PCIATAState *pData = PDMINS2DATA(pDevIns, PCIATAState *);
5674
5675 /* sanity - the suspend notification will wait on the async stuff. */
5676 for (uint32_t i = 0; i < RT_ELEMENTS(pData->aCts); i++)
5677 {
5678 Assert(ataAsyncIOIsIdle(&pData->aCts[i], false));
5679 if (!ataAsyncIOIsIdle(&pData->aCts[i], false))
5680 return VERR_SSM_IDE_ASYNC_TIMEOUT;
5681 }
5682 return VINF_SUCCESS;
5683}
5684
5685
5686/**
5687 * Saves a state of the ATA device.
5688 *
5689 * @returns VBox status code.
5690 * @param pDevIns The device instance.
5691 * @param pSSMHandle The handle to save the state to.
5692 */
5693static DECLCALLBACK(int) ataSaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSMHandle)
5694{
5695 PCIATAState *pData = PDMINS2DATA(pDevIns, PCIATAState *);
5696
5697 for (uint32_t i = 0; i < RT_ELEMENTS(pData->aCts); i++)
5698 {
5699 SSMR3PutU8(pSSMHandle, pData->aCts[i].iSelectedIf);
5700 SSMR3PutU8(pSSMHandle, pData->aCts[i].iAIOIf);
5701 SSMR3PutU8(pSSMHandle, pData->aCts[i].uAsyncIOState);
5702 SSMR3PutBool(pSSMHandle, pData->aCts[i].fChainedTransfer);
5703 SSMR3PutBool(pSSMHandle, pData->aCts[i].fReset);
5704 SSMR3PutBool(pSSMHandle, pData->aCts[i].fRedo);
5705 SSMR3PutBool(pSSMHandle, pData->aCts[i].fRedoIdle);
5706 SSMR3PutBool(pSSMHandle, pData->aCts[i].fRedoDMALastDesc);
5707 SSMR3PutMem(pSSMHandle, &pData->aCts[i].BmDma, sizeof(pData->aCts[i].BmDma));
5708 SSMR3PutGCPhys(pSSMHandle, pData->aCts[i].pFirstDMADesc);
5709 SSMR3PutGCPhys(pSSMHandle, pData->aCts[i].pLastDMADesc);
5710 SSMR3PutGCPhys(pSSMHandle, pData->aCts[i].pRedoDMABuffer);
5711 SSMR3PutU32(pSSMHandle, pData->aCts[i].cbRedoDMABuffer);
5712
5713 for (uint32_t j = 0; j < RT_ELEMENTS(pData->aCts[i].aIfs); j++)
5714 {
5715 SSMR3PutBool(pSSMHandle, pData->aCts[i].aIfs[j].fLBA48);
5716 SSMR3PutBool(pSSMHandle, pData->aCts[i].aIfs[j].fATAPI);
5717 SSMR3PutBool(pSSMHandle, pData->aCts[i].aIfs[j].fIrqPending);
5718 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].cMultSectors);
5719 SSMR3PutU32(pSSMHandle, pData->aCts[i].aIfs[j].cCHSCylinders);
5720 SSMR3PutU32(pSSMHandle, pData->aCts[i].aIfs[j].cCHSHeads);
5721 SSMR3PutU32(pSSMHandle, pData->aCts[i].aIfs[j].cCHSSectors);
5722 SSMR3PutU32(pSSMHandle, pData->aCts[i].aIfs[j].cSectorsPerIRQ);
5723 SSMR3PutU64(pSSMHandle, pData->aCts[i].aIfs[j].cTotalSectors);
5724 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].uATARegFeature);
5725 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].uATARegFeatureHOB);
5726 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].uATARegError);
5727 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].uATARegNSector);
5728 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].uATARegNSectorHOB);
5729 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].uATARegSector);
5730 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].uATARegSectorHOB);
5731 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].uATARegLCyl);
5732 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].uATARegLCylHOB);
5733 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].uATARegHCyl);
5734 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].uATARegHCylHOB);
5735 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].uATARegSelect);
5736 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].uATARegStatus);
5737 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].uATARegCommand);
5738 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].uATARegDevCtl);
5739 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].uATATransferMode);
5740 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].uTxDir);
5741 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].iBeginTransfer);
5742 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].iSourceSink);
5743 SSMR3PutBool(pSSMHandle, pData->aCts[i].aIfs[j].fDMA);
5744 SSMR3PutBool(pSSMHandle, pData->aCts[i].aIfs[j].fATAPITransfer);
5745 SSMR3PutU32(pSSMHandle, pData->aCts[i].aIfs[j].cbTotalTransfer);
5746 SSMR3PutU32(pSSMHandle, pData->aCts[i].aIfs[j].cbElementaryTransfer);
5747 SSMR3PutU32(pSSMHandle, pData->aCts[i].aIfs[j].iIOBufferCur);
5748 SSMR3PutU32(pSSMHandle, pData->aCts[i].aIfs[j].iIOBufferEnd);
5749 SSMR3PutU32(pSSMHandle, pData->aCts[i].aIfs[j].iIOBufferPIODataStart);
5750 SSMR3PutU32(pSSMHandle, pData->aCts[i].aIfs[j].iIOBufferPIODataEnd);
5751 SSMR3PutU32(pSSMHandle, pData->aCts[i].aIfs[j].iATAPILBA);
5752 SSMR3PutU32(pSSMHandle, pData->aCts[i].aIfs[j].cbATAPISector);
5753 SSMR3PutMem(pSSMHandle, &pData->aCts[i].aIfs[j].aATAPICmd, sizeof(pData->aCts[i].aIfs[j].aATAPICmd));
5754 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].uATAPISenseKey);
5755 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].uATAPIASC);
5756 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].cNotifiedMediaChange);
5757 SSMR3PutMem(pSSMHandle, &pData->aCts[i].aIfs[j].Led, sizeof(pData->aCts[i].aIfs[j].Led));
5758 SSMR3PutU32(pSSMHandle, pData->aCts[i].aIfs[j].cbIOBuffer);
5759 if (pData->aCts[i].aIfs[j].cbIOBuffer)
5760 SSMR3PutMem(pSSMHandle, pData->aCts[i].aIfs[j].CTXSUFF(pbIOBuffer), pData->aCts[i].aIfs[j].cbIOBuffer);
5761 else
5762 Assert(pData->aCts[i].aIfs[j].CTXSUFF(pbIOBuffer) == NULL);
5763 }
5764 }
5765 SSMR3PutBool(pSSMHandle, pData->fPIIX4);
5766
5767 return SSMR3PutU32(pSSMHandle, ~0); /* sanity/terminator */
5768}
5769
5770
5771/**
5772 * Loads a saved ATA device state.
5773 *
5774 * @returns VBox status code.
5775 * @param pDevIns The device instance.
5776 * @param pSSMHandle The handle to the saved state.
5777 * @param u32Version The data unit version number.
5778 */
5779static DECLCALLBACK(int) ataLoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSMHandle, uint32_t u32Version)
5780{
5781 PCIATAState *pData = PDMINS2DATA(pDevIns, PCIATAState *);
5782 int rc;
5783 uint32_t u32;
5784
5785 if (u32Version != ATA_SAVED_STATE_VERSION)
5786 {
5787 AssertMsgFailed(("u32Version=%d\n", u32Version));
5788 return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
5789 }
5790
5791 /*
5792 * Restore valid parts of the PCIATAState structure
5793 */
5794 for (uint32_t i = 0; i < RT_ELEMENTS(pData->aCts); i++)
5795 {
5796 /* integrity check */
5797 if (!ataAsyncIOIsIdle(&pData->aCts[i], false))
5798 {
5799 AssertMsgFailed(("Async I/O for controller %d is active\n", i));
5800 rc = VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
5801 return rc;
5802 }
5803
5804 SSMR3GetU8(pSSMHandle, &pData->aCts[i].iSelectedIf);
5805 SSMR3GetU8(pSSMHandle, &pData->aCts[i].iAIOIf);
5806 SSMR3GetU8(pSSMHandle, &pData->aCts[i].uAsyncIOState);
5807 SSMR3GetBool(pSSMHandle, &pData->aCts[i].fChainedTransfer);
5808 SSMR3GetBool(pSSMHandle, (bool *)&pData->aCts[i].fReset);
5809 SSMR3GetBool(pSSMHandle, (bool *)&pData->aCts[i].fRedo);
5810 SSMR3GetBool(pSSMHandle, (bool *)&pData->aCts[i].fRedoIdle);
5811 SSMR3GetBool(pSSMHandle, (bool *)&pData->aCts[i].fRedoDMALastDesc);
5812 SSMR3GetMem(pSSMHandle, &pData->aCts[i].BmDma, sizeof(pData->aCts[i].BmDma));
5813 SSMR3GetGCPhys(pSSMHandle, &pData->aCts[i].pFirstDMADesc);
5814 SSMR3GetGCPhys(pSSMHandle, &pData->aCts[i].pLastDMADesc);
5815 SSMR3GetGCPhys(pSSMHandle, &pData->aCts[i].pRedoDMABuffer);
5816 SSMR3GetU32(pSSMHandle, &pData->aCts[i].cbRedoDMABuffer);
5817
5818 for (uint32_t j = 0; j < RT_ELEMENTS(pData->aCts[i].aIfs); j++)
5819 {
5820 SSMR3GetBool(pSSMHandle, &pData->aCts[i].aIfs[j].fLBA48);
5821 SSMR3GetBool(pSSMHandle, &pData->aCts[i].aIfs[j].fATAPI);
5822 SSMR3GetBool(pSSMHandle, &pData->aCts[i].aIfs[j].fIrqPending);
5823 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].cMultSectors);
5824 SSMR3GetU32(pSSMHandle, &pData->aCts[i].aIfs[j].cCHSCylinders);
5825 SSMR3GetU32(pSSMHandle, &pData->aCts[i].aIfs[j].cCHSHeads);
5826 SSMR3GetU32(pSSMHandle, &pData->aCts[i].aIfs[j].cCHSSectors);
5827 SSMR3GetU32(pSSMHandle, &pData->aCts[i].aIfs[j].cSectorsPerIRQ);
5828 SSMR3GetU64(pSSMHandle, &pData->aCts[i].aIfs[j].cTotalSectors);
5829 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].uATARegFeature);
5830 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].uATARegFeatureHOB);
5831 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].uATARegError);
5832 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].uATARegNSector);
5833 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].uATARegNSectorHOB);
5834 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].uATARegSector);
5835 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].uATARegSectorHOB);
5836 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].uATARegLCyl);
5837 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].uATARegLCylHOB);
5838 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].uATARegHCyl);
5839 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].uATARegHCylHOB);
5840 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].uATARegSelect);
5841 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].uATARegStatus);
5842 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].uATARegCommand);
5843 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].uATARegDevCtl);
5844 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].uATATransferMode);
5845 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].uTxDir);
5846 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].iBeginTransfer);
5847 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].iSourceSink);
5848 SSMR3GetBool(pSSMHandle, &pData->aCts[i].aIfs[j].fDMA);
5849 SSMR3GetBool(pSSMHandle, &pData->aCts[i].aIfs[j].fATAPITransfer);
5850 SSMR3GetU32(pSSMHandle, &pData->aCts[i].aIfs[j].cbTotalTransfer);
5851 SSMR3GetU32(pSSMHandle, &pData->aCts[i].aIfs[j].cbElementaryTransfer);
5852 SSMR3GetU32(pSSMHandle, &pData->aCts[i].aIfs[j].iIOBufferCur);
5853 SSMR3GetU32(pSSMHandle, &pData->aCts[i].aIfs[j].iIOBufferEnd);
5854 SSMR3GetU32(pSSMHandle, &pData->aCts[i].aIfs[j].iIOBufferPIODataStart);
5855 SSMR3GetU32(pSSMHandle, &pData->aCts[i].aIfs[j].iIOBufferPIODataEnd);
5856 SSMR3GetU32(pSSMHandle, &pData->aCts[i].aIfs[j].iATAPILBA);
5857 SSMR3GetU32(pSSMHandle, &pData->aCts[i].aIfs[j].cbATAPISector);
5858 SSMR3GetMem(pSSMHandle, &pData->aCts[i].aIfs[j].aATAPICmd, sizeof(pData->aCts[i].aIfs[j].aATAPICmd));
5859 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].uATAPISenseKey);
5860 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].uATAPIASC);
5861 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].cNotifiedMediaChange);
5862 SSMR3GetMem(pSSMHandle, &pData->aCts[i].aIfs[j].Led, sizeof(pData->aCts[i].aIfs[j].Led));
5863 SSMR3GetU32(pSSMHandle, &pData->aCts[i].aIfs[j].cbIOBuffer);
5864 if (pData->aCts[i].aIfs[j].cbIOBuffer)
5865 {
5866 if (pData->aCts[i].aIfs[j].CTXSUFF(pbIOBuffer))
5867 SSMR3GetMem(pSSMHandle, pData->aCts[i].aIfs[j].CTXSUFF(pbIOBuffer), pData->aCts[i].aIfs[j].cbIOBuffer);
5868 else
5869 {
5870 LogRel(("ATA: No buffer for %d/%d\n", i, j));
5871 if (SSMR3HandleGetAfter(pSSMHandle) != SSMAFTER_DEBUG_IT)
5872 return VERR_SSM_LOAD_CONFIG_MISMATCH;
5873
5874 /* skip the buffer if we're loading for the debugger / animator. */
5875 uint8_t u8Ignored;
5876 size_t cbLeft = pData->aCts[i].aIfs[j].cbIOBuffer;
5877 while (cbLeft-- > 0)
5878 SSMR3GetU8(pSSMHandle, &u8Ignored);
5879 }
5880 }
5881 else
5882 Assert(pData->aCts[i].aIfs[j].CTXSUFF(pbIOBuffer) == NULL);
5883 }
5884 }
5885 SSMR3GetBool(pSSMHandle, &pData->fPIIX4);
5886
5887 rc = SSMR3GetU32(pSSMHandle, &u32);
5888 if (VBOX_FAILURE(rc))
5889 return rc;
5890 if (u32 != ~0U)
5891 {
5892 AssertMsgFailed(("u32=%#x expected ~0\n", u32));
5893 rc = VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
5894 return rc;
5895 }
5896
5897 return VINF_SUCCESS;
5898}
5899
5900
5901/**
5902 * Construct a device instance for a VM.
5903 *
5904 * @returns VBox status.
5905 * @param pDevIns The device instance data.
5906 * If the registration structure is needed, pDevIns->pDevReg points to it.
5907 * @param iInstance Instance number. Use this to figure out which registers and such to use.
5908 * The device number is also found in pDevIns->iInstance, but since it's
5909 * likely to be freqently used PDM passes it as parameter.
5910 * @param pCfgHandle Configuration node handle for the device. Use this to obtain the configuration
5911 * of the device instance. It's also found in pDevIns->pCfgHandle, but like
5912 * iInstance it's expected to be used a bit in this function.
5913 */
5914static DECLCALLBACK(int) ataConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfgHandle)
5915{
5916 PCIATAState *pData = PDMINS2DATA(pDevIns, PCIATAState *);
5917 PPDMIBASE pBase;
5918 int rc;
5919 bool fGCEnabled;
5920 bool fR0Enabled;
5921 uint32_t DelayIRQMillies;
5922
5923 Assert(iInstance == 0);
5924
5925 /*
5926 * Validate and read configuration.
5927 */
5928 if (!CFGMR3AreValuesValid(pCfgHandle, "GCEnabled\0IRQDelay\0R0Enabled\0PIIX4\0"))
5929 return PDMDEV_SET_ERROR(pDevIns, VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES,
5930 N_("PIIX3 configuration error: unknown option specified."));
5931
5932 rc = CFGMR3QueryBool(pCfgHandle, "GCEnabled", &fGCEnabled);
5933 if (rc == VERR_CFGM_VALUE_NOT_FOUND)
5934 fGCEnabled = true;
5935 else if (VBOX_FAILURE(rc))
5936 return PDMDEV_SET_ERROR(pDevIns, rc,
5937 N_("PIIX3 configuration error: failed to read GCEnabled as boolean."));
5938 Log(("%s: fGCEnabled=%d\n", __FUNCTION__, fGCEnabled));
5939
5940 rc = CFGMR3QueryBool(pCfgHandle, "R0Enabled", &fR0Enabled);
5941 if (rc == VERR_CFGM_VALUE_NOT_FOUND)
5942 fR0Enabled = true;
5943 else if (VBOX_FAILURE(rc))
5944 return PDMDEV_SET_ERROR(pDevIns, rc,
5945 N_("PIIX3 configuration error: failed to read R0Enabled as boolean."));
5946 Log(("%s: fR0Enabled=%d\n", __FUNCTION__, fR0Enabled));
5947
5948 rc = CFGMR3QueryU32(pCfgHandle, "IRQDelay", &DelayIRQMillies);
5949 if (rc == VERR_CFGM_VALUE_NOT_FOUND)
5950 DelayIRQMillies = 0;
5951 else if (VBOX_FAILURE(rc))
5952 return PDMDEV_SET_ERROR(pDevIns, rc,
5953 N_("PIIX3 configuration error: failed to read IRQDelay as integer."));
5954 Log(("%s: DelayIRQMillies=%d\n", __FUNCTION__, DelayIRQMillies));
5955 Assert(DelayIRQMillies < 50);
5956
5957 rc = CFGMR3QueryBool(pCfgHandle, "PIIX4", &pData->fPIIX4);
5958 if (rc == VERR_CFGM_VALUE_NOT_FOUND)
5959 pData->fPIIX4 = false;
5960 else if (VBOX_FAILURE(rc))
5961 return PDMDEV_SET_ERROR(pDevIns, rc,
5962 N_("PIIX3 configuration error: failed to read PIIX4 as boolean."));
5963 Log(("%s: fPIIX4=%d\n", __FUNCTION__, pData->fPIIX4));
5964
5965 /*
5966 * Initialize data (most of it anyway).
5967 */
5968 /* Status LUN. */
5969 pData->IBase.pfnQueryInterface = ataStatus_QueryInterface;
5970 pData->ILeds.pfnQueryStatusLed = ataStatus_QueryStatusLed;
5971
5972 /* pci */
5973 pData->dev.config[0x00] = 0x86; /* Vendor: Intel */
5974 pData->dev.config[0x01] = 0x80;
5975 if (pData->fPIIX4)
5976 {
5977 pData->dev.config[0x02] = 0x11; /* Device: PIIX4 IDE */
5978 pData->dev.config[0x03] = 0x71;
5979 pData->dev.config[0x08] = 0x01; /* Revision: PIIX4E */
5980 pData->dev.config[0x48] = 0x00; /* UDMACTL */
5981 pData->dev.config[0x4A] = 0x00; /* UDMATIM */
5982 pData->dev.config[0x4B] = 0x00;
5983 }
5984 else
5985 {
5986 pData->dev.config[0x02] = 0x10; /* Device: PIIX3 IDE */
5987 pData->dev.config[0x03] = 0x70;
5988 }
5989 pData->dev.config[0x04] = PCI_COMMAND_IOACCESS | PCI_COMMAND_MEMACCESS | PCI_COMMAND_BUSMASTER;
5990 pData->dev.config[0x09] = 0x8a; /* programming interface = PCI_IDE bus master is supported */
5991 pData->dev.config[0x0a] = 0x01; /* class_sub = PCI_IDE */
5992 pData->dev.config[0x0b] = 0x01; /* class_base = PCI_mass_storage */
5993 pData->dev.config[0x0e] = 0x00; /* header_type */
5994
5995 pData->pDevIns = pDevIns;
5996 pData->fGCEnabled = fGCEnabled;
5997 pData->fR0Enabled = fR0Enabled;
5998 for (uint32_t i = 0; i < RT_ELEMENTS(pData->aCts); i++)
5999 {
6000 pData->aCts[i].pDevInsHC = pDevIns;
6001 pData->aCts[i].pDevInsGC = PDMDEVINS_2_GCPTR(pDevIns);
6002 pData->aCts[i].DelayIRQMillies = (uint32_t)DelayIRQMillies;
6003 for (uint32_t j = 0; j < RT_ELEMENTS(pData->aCts[i].aIfs); j++)
6004 {
6005 pData->aCts[i].aIfs[j].iLUN = i * RT_ELEMENTS(pData->aCts) + j;
6006 pData->aCts[i].aIfs[j].pDevInsHC = pDevIns;
6007 pData->aCts[i].aIfs[j].pDevInsGC = PDMDEVINS_2_GCPTR(pDevIns);
6008 pData->aCts[i].aIfs[j].pControllerHC = &pData->aCts[i];
6009 pData->aCts[i].aIfs[j].pControllerGC = MMHyperHC2GC(PDMDevHlpGetVM(pDevIns), &pData->aCts[i]);
6010 pData->aCts[i].aIfs[j].IBase.pfnQueryInterface = ataQueryInterface;
6011 pData->aCts[i].aIfs[j].IMountNotify.pfnMountNotify = ataMountNotify;
6012 pData->aCts[i].aIfs[j].IMountNotify.pfnUnmountNotify = ataUnmountNotify;
6013 pData->aCts[i].aIfs[j].Led.u32Magic = PDMLED_MAGIC;
6014 }
6015 }
6016
6017 Assert(RT_ELEMENTS(pData->aCts) == 2);
6018 pData->aCts[0].irq = 14;
6019 pData->aCts[0].IOPortBase1 = 0x1f0;
6020 pData->aCts[0].IOPortBase2 = 0x3f6;
6021 pData->aCts[1].irq = 15;
6022 pData->aCts[1].IOPortBase1 = 0x170;
6023 pData->aCts[1].IOPortBase2 = 0x376;
6024
6025 /*
6026 * Register the PCI device.
6027 * N.B. There's a hack in the PIIX3 PCI bridge device to assign this
6028 * device the slot next to itself.
6029 */
6030 rc = PDMDevHlpPCIRegister(pDevIns, &pData->dev);
6031 if (VBOX_FAILURE(rc))
6032 return PDMDEV_SET_ERROR(pDevIns, rc,
6033 N_("PIIX3 cannot register PCI device."));
6034 AssertMsg(pData->dev.devfn == 9 || iInstance != 0, ("pData->dev.devfn=%d\n", pData->dev.devfn));
6035 rc = PDMDevHlpPCIIORegionRegister(pDevIns, 4, 0x10, PCI_ADDRESS_SPACE_IO, ataBMDMAIORangeMap);
6036 if (VBOX_FAILURE(rc))
6037 return PDMDEV_SET_ERROR(pDevIns, rc,
6038 N_("PIIX3 cannot register PCI I/O region for BMDMA."));
6039
6040 /*
6041 * Register the I/O ports.
6042 * The ports are all hardcoded and enforced by the PIIX3 host bridge controller.
6043 */
6044 for (uint32_t i = 0; i < RT_ELEMENTS(pData->aCts); i++)
6045 {
6046 rc = PDMDevHlpIOPortRegister(pDevIns, pData->aCts[i].IOPortBase1, 8, (RTHCPTR)i,
6047 ataIOPortWrite1, ataIOPortRead1, ataIOPortWriteStr1, ataIOPortReadStr1, "ATA I/O Base 1");
6048 if (VBOX_FAILURE(rc))
6049 return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot register I/O handlers."));
6050
6051 if (fGCEnabled)
6052 {
6053 rc = PDMDevHlpIOPortRegisterGC(pDevIns, pData->aCts[i].IOPortBase1, 8, (RTGCPTR)i,
6054 "ataIOPortWrite1", "ataIOPortRead1", "ataIOPortWriteStr1", "ataIOPortReadStr1", "ATA I/O Base 1");
6055 if (VBOX_FAILURE(rc))
6056 return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot register I/O handlers (GC)."));
6057 }
6058
6059 if (fR0Enabled)
6060 {
6061#if 1
6062 rc = PDMDevHlpIOPortRegisterR0(pDevIns, pData->aCts[i].IOPortBase1, 8, (RTR0PTR)i,
6063 "ataIOPortWrite1", "ataIOPortRead1", NULL, NULL, "ATA I/O Base 1");
6064#else
6065 rc = PDMDevHlpIOPortRegisterR0(pDevIns, pData->aCts[i].IOPortBase1, 8, (RTR0PTR)i,
6066 "ataIOPortWrite1", "ataIOPortRead1", "ataIOPortWriteStr1", "ataIOPortReadStr1", "ATA I/O Base 1");
6067#endif
6068 if (VBOX_FAILURE(rc))
6069 return PDMDEV_SET_ERROR(pDevIns, rc, "PIIX3 cannot register I/O handlers (R0).");
6070 }
6071
6072 rc = PDMDevHlpIOPortRegister(pDevIns, pData->aCts[i].IOPortBase2, 1, (RTHCPTR)i,
6073 ataIOPortWrite2, ataIOPortRead2, NULL, NULL, "ATA I/O Base 2");
6074 if (VBOX_FAILURE(rc))
6075 return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot register base2 I/O handlers."));
6076
6077 if (fGCEnabled)
6078 {
6079 rc = PDMDevHlpIOPortRegisterGC(pDevIns, pData->aCts[i].IOPortBase2, 1, (RTGCPTR)i,
6080 "ataIOPortWrite2", "ataIOPortRead2", NULL, NULL, "ATA I/O Base 2");
6081 if (VBOX_FAILURE(rc))
6082 return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot register base2 I/O handlers (GC)."));
6083 }
6084 if (fR0Enabled)
6085 {
6086 rc = PDMDevHlpIOPortRegisterR0(pDevIns, pData->aCts[i].IOPortBase2, 1, (RTR0PTR)i,
6087 "ataIOPortWrite2", "ataIOPortRead2", NULL, NULL, "ATA I/O Base 2");
6088 if (VBOX_FAILURE(rc))
6089 return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot register base2 I/O handlers (R0)."));
6090 }
6091
6092 for (uint32_t j = 0; j < RT_ELEMENTS(pData->aCts[i].aIfs); j++)
6093 {
6094 ATADevState *pIf = &pData->aCts[i].aIfs[j];
6095 PDMDevHlpSTAMRegisterF(pDevIns, &pIf->StatATADMA, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of ATA DMA transfers.", "/Devices/ATA%d/Unit%d/DMA", i, j);
6096 PDMDevHlpSTAMRegisterF(pDevIns, &pIf->StatATAPIO, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of ATA PIO transfers.", "/Devices/ATA%d/Unit%d/PIO", i, j);
6097 PDMDevHlpSTAMRegisterF(pDevIns, &pIf->StatATAPIDMA, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of ATAPI DMA transfers.", "/Devices/ATA%d/Unit%d/AtapiDMA", i, j);
6098 PDMDevHlpSTAMRegisterF(pDevIns, &pIf->StatATAPIPIO, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of ATAPI PIO transfers.", "/Devices/ATA%d/Unit%d/AtapiPIO", i, j);
6099#ifdef VBOX_WITH_STATISTICS /** @todo release too. */
6100 PDMDevHlpSTAMRegisterF(pDevIns, &pIf->StatReads, STAMTYPE_PROFILE_ADV, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling of the read operations.", "/Devices/ATA%d/Unit%d/Reads", i, j);
6101 PDMDevHlpSTAMRegisterF(pDevIns, &pIf->StatBytesRead, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES, "Amount of data read.", "/Devices/ATA%d/Unit%d/ReadBytes", i, j);
6102 PDMDevHlpSTAMRegisterF(pDevIns, &pIf->StatWrites, STAMTYPE_PROFILE_ADV, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling of the write operations.","/Devices/ATA%d/Unit%d/Writes", i, j);
6103 PDMDevHlpSTAMRegisterF(pDevIns, &pIf->StatBytesWritten, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES, "Amount of data written.", "/Devices/ATA%d/Unit%d/WrittenBytes", i, j);
6104 PDMDevHlpSTAMRegisterF(pDevIns, &pIf->StatFlushes, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling of the flush operations.","/Devices/ATA%d/Unit%d/Flushes", i, j);
6105#endif
6106 }
6107#ifdef VBOX_WITH_STATISTICS /** @todo release too. */
6108 PDMDevHlpSTAMRegisterF(pDevIns, &pData->aCts[i].StatAsyncOps, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "The number of async operations.", "/Devices/ATA%d/Async/Operations", i);
6109 /** @todo STAMUNIT_MICROSECS */
6110 PDMDevHlpSTAMRegisterF(pDevIns, &pData->aCts[i].StatAsyncMinWait, STAMTYPE_U64_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_NONE, "Minimum wait in microseconds.", "/Devices/ATA%d/Async/MinWait", i);
6111 PDMDevHlpSTAMRegisterF(pDevIns, &pData->aCts[i].StatAsyncMaxWait, STAMTYPE_U64_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_NONE, "Maximum wait in microseconds.", "/Devices/ATA%d/Async/MaxWait", i);
6112 PDMDevHlpSTAMRegisterF(pDevIns, &pData->aCts[i].StatAsyncTimeUS, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_NONE, "Total time spent in microseconds.","/Devices/ATA%d/Async/TotalTimeUS", i);
6113 PDMDevHlpSTAMRegisterF(pDevIns, &pData->aCts[i].StatAsyncTime, STAMTYPE_PROFILE_ADV, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling of async operations.", "/Devices/ATA%d/Async/Time", i);
6114 PDMDevHlpSTAMRegisterF(pDevIns, &pData->aCts[i].StatLockWait, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling of locks.", "/Devices/ATA%d/Async/LockWait", i);
6115#endif /* VBOX_WITH_STATISTICS */
6116
6117 /* Initialize per-controller critical section */
6118 char szName[24];
6119 RTStrPrintf(szName, sizeof(szName), "ATA%d", i);
6120 rc = PDMDevHlpCritSectInit(pDevIns, &pData->aCts[i].lock, szName);
6121 if (VBOX_FAILURE(rc))
6122 return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot initialize critical section."));
6123 }
6124
6125 /*
6126 * Attach status driver (optional).
6127 */
6128 rc = PDMDevHlpDriverAttach(pDevIns, PDM_STATUS_LUN, &pData->IBase, &pBase, "Status Port");
6129 if (VBOX_SUCCESS(rc))
6130 pData->pLedsConnector = (PDMILEDCONNECTORS *)pBase->pfnQueryInterface(pBase, PDMINTERFACE_LED_CONNECTORS);
6131 else if (rc != VERR_PDM_NO_ATTACHED_DRIVER)
6132 {
6133 AssertMsgFailed(("Failed to attach to status driver. rc=%Vrc\n", rc));
6134 return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot attach to status driver."));
6135 }
6136
6137 /*
6138 * Attach the units.
6139 */
6140 uint32_t cbTotalBuffer = 0;
6141 for (uint32_t i = 0; i < RT_ELEMENTS(pData->aCts); i++)
6142 {
6143 PATACONTROLLER pCtl = &pData->aCts[i];
6144
6145 /*
6146 * Start the worker thread.
6147 */
6148 pCtl->uAsyncIOState = ATA_AIO_NEW;
6149 rc = RTSemEventCreate(&pCtl->AsyncIOSem);
6150 AssertRC(rc);
6151 rc = RTSemEventCreate(&pCtl->SuspendIOSem);
6152 AssertRC(rc);
6153 rc = RTSemMutexCreate(&pCtl->AsyncIORequestMutex);
6154 AssertRC(rc);
6155 ataAsyncIOClearRequests(pCtl);
6156 rc = RTThreadCreate(&pCtl->AsyncIOThread, ataAsyncIOLoop, (void *)pCtl, 128*1024, RTTHREADTYPE_IO, 0, "ATA");
6157 AssertRC(rc);
6158 Assert(pCtl->AsyncIOThread != NIL_RTTHREAD && pCtl->AsyncIOSem != NIL_RTSEMEVENT && pCtl->SuspendIOSem != NIL_RTSEMEVENT && pCtl->AsyncIORequestMutex != NIL_RTSEMMUTEX);
6159 Log(("%s: controller %d AIO thread id %#x; sem %p susp_sem %p mutex %p\n", __FUNCTION__, i, pCtl->AsyncIOThread, pCtl->AsyncIOSem, pCtl->SuspendIOSem, pCtl->AsyncIORequestMutex));
6160
6161 for (uint32_t j = 0; j < RT_ELEMENTS(pCtl->aIfs); j++)
6162 {
6163 static const char *s_apszDescs[RT_ELEMENTS(pData->aCts)][RT_ELEMENTS(pCtl->aIfs)] =
6164 {
6165 { "Primary Master", "Primary Slave" },
6166 { "Secondary Master", "Secondary Slave" }
6167 };
6168
6169 /*
6170 * Try attach the block device and get the interfaces,
6171 * required as well as optional.
6172 */
6173 ATADevState *pIf = &pCtl->aIfs[j];
6174
6175 rc = PDMDevHlpDriverAttach(pDevIns, pIf->iLUN, &pIf->IBase, &pIf->pDrvBase, s_apszDescs[i][j]);
6176 if (VBOX_SUCCESS(rc))
6177 rc = ataConfigLun(pDevIns, pIf);
6178 else if (rc == VERR_PDM_NO_ATTACHED_DRIVER)
6179 {
6180 pIf->pDrvBase = NULL;
6181 pIf->pDrvBlock = NULL;
6182 pIf->cbIOBuffer = 0;
6183 pIf->pbIOBufferHC = NULL;
6184 pIf->pbIOBufferGC = NIL_RTGCPHYS;
6185 LogRel(("PIIX3 ATA: LUN#%d: no unit\n", pIf->iLUN));
6186 }
6187 else
6188 {
6189 AssertMsgFailed(("Failed to attach LUN#%d. rc=%Vrc\n", pIf->iLUN, rc));
6190 switch (rc)
6191 {
6192 case VERR_ACCESS_DENIED:
6193 /* Error already catched by DrvHostBase */
6194 return rc;
6195 default:
6196 return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS, N_(
6197 "PIIX3 cannot attach drive to the %s"), s_apszDescs[i][j]);
6198 }
6199 }
6200 cbTotalBuffer += pIf->cbIOBuffer;
6201 }
6202 }
6203
6204 rc = PDMDevHlpSSMRegister(pDevIns, pDevIns->pDevReg->szDeviceName, iInstance,
6205 ATA_SAVED_STATE_VERSION, sizeof(*pData) + cbTotalBuffer,
6206 ataSaveLoadPrep, ataSaveExec, NULL,
6207 ataSaveLoadPrep, ataLoadExec, NULL);
6208 if (VBOX_FAILURE(rc))
6209 return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot register save state handlers."));
6210
6211 /*
6212 * Initialize the device state.
6213 */
6214 ataReset(pDevIns);
6215
6216 return VINF_SUCCESS;
6217}
6218
6219
6220/**
6221 * The device registration structure.
6222 */
6223const PDMDEVREG g_DevicePIIX3IDE =
6224{
6225 /* u32Version */
6226 PDM_DEVREG_VERSION,
6227 /* szDeviceName */
6228 "piix3ide",
6229 /* szGCMod */
6230 "VBoxDDGC.gc",
6231 /* szR0Mod */
6232 "VBoxDDR0.r0",
6233 /* pszDescription */
6234 "Intel PIIX3 ATA controller.\n"
6235 " LUN #0 is primary master.\n"
6236 " LUN #1 is primary slave.\n"
6237 " LUN #2 is secondary master.\n"
6238 " LUN #3 is secondary slave.\n"
6239 " LUN #999 is the LED/Status connector.",
6240 /* fFlags */
6241 PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT | PDM_DEVREG_FLAGS_GUEST_BITS_DEFAULT | PDM_DEVREG_FLAGS_GC | PDM_DEVREG_FLAGS_R0,
6242 /* fClass */
6243 PDM_DEVREG_CLASS_STORAGE,
6244 /* cMaxInstances */
6245 1,
6246 /* cbInstance */
6247 sizeof(PCIATAState),
6248 /* pfnConstruct */
6249 ataConstruct,
6250 /* pfnDestruct */
6251 ataDestruct,
6252 /* pfnRelocate */
6253 ataRelocate,
6254 /* pfnIOCtl */
6255 NULL,
6256 /* pfnPowerOn */
6257 NULL,
6258 /* pfnReset */
6259 ataReset,
6260 /* pfnSuspend */
6261 ataSuspend,
6262 /* pfnResume */
6263 ataResume,
6264 /* pfnAttach */
6265 ataAttach,
6266 /* pfnDetach */
6267 ataDetach,
6268 /* pfnQueryInterface. */
6269 NULL,
6270 /* pfnInitComplete */
6271 NULL,
6272 /* pfnPowerOff */
6273 ataPowerOff
6274};
6275#endif /* IN_RING3 */
6276#endif /* !VBOX_DEVICE_STRUCT_TESTCASE */
6277
Note: See TracBrowser for help on using the repository browser.

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