VirtualBox

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

Last change on this file since 65620 was 65110, checked in by vboxsync, 8 years ago

Storage/Devices/DevATA: Make use of the new SCSI inline helpers and remove the the local inlines

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

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