VirtualBox

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

最後變更 在這個檔案從18193是 18193,由 vboxsync 提交於 16 年 前

ATA: Implement READ DVD STRUCTURE

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

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