VirtualBox

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

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

Devices: warnings

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

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