VirtualBox

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

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

Devices: warnings

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 299.5 KB
 
1/* $Id: DevATA.cpp 62925 2016-08-03 15:04:09Z 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 if (uTxDir == PDMMEDIATXDIR_FROM_DEVICE)
5302 PDMDevHlpPCIPhysWrite(pDevIns, pBuffer, s->CTX_SUFF(pbIOBuffer) + iIOBufferCur, dmalen);
5303 else
5304 PDMDevHlpPCIPhysRead(pDevIns, pBuffer, s->CTX_SUFF(pbIOBuffer) + iIOBufferCur, dmalen);
5305
5306 iIOBufferCur += dmalen;
5307 cbTotalTransfer -= dmalen;
5308 cbBuffer -= dmalen;
5309 pBuffer += dmalen;
5310 }
5311 if ( iIOBufferCur == iIOBufferEnd
5312 && (uTxDir == PDMMEDIATXDIR_TO_DEVICE || cbTotalTransfer))
5313 {
5314 if (uTxDir == PDMMEDIATXDIR_FROM_DEVICE && cbElementaryTransfer > cbTotalTransfer)
5315 cbElementaryTransfer = cbTotalTransfer;
5316
5317 {
5318 STAM_PROFILE_START(&pCtl->StatLockWait, a);
5319 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
5320 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
5321 }
5322
5323 /* The RESET handler could have cleared the DMA transfer
5324 * state (since we didn't hold the lock until just now
5325 * the guest can continue in parallel). If so, the state
5326 * is already set up so the loop is exited immediately. */
5327 if (s->iSourceSink != ATAFN_SS_NULL)
5328 {
5329 s->iIOBufferCur = iIOBufferCur;
5330 s->iIOBufferEnd = iIOBufferEnd;
5331 s->cbElementaryTransfer = cbElementaryTransfer;
5332 s->cbTotalTransfer = cbTotalTransfer;
5333 Log2(("%s: calling source/sink function\n", __FUNCTION__));
5334 fRedo = g_apfnSourceSinkFuncs[s->iSourceSink](s);
5335 if (RT_UNLIKELY(fRedo))
5336 {
5337 pCtl->pFirstDMADesc = pDesc;
5338 pCtl->pRedoDMABuffer = pBuffer;
5339 pCtl->cbRedoDMABuffer = cbBuffer;
5340 pCtl->fRedoDMALastDesc = fLastDesc;
5341 }
5342 else
5343 {
5344 cbTotalTransfer = s->cbTotalTransfer;
5345 cbElementaryTransfer = s->cbElementaryTransfer;
5346
5347 if (uTxDir == PDMMEDIATXDIR_TO_DEVICE && cbElementaryTransfer > cbTotalTransfer)
5348 cbElementaryTransfer = cbTotalTransfer;
5349 iIOBufferCur = 0;
5350 iIOBufferEnd = cbElementaryTransfer;
5351 }
5352 pCtl->fRedo = fRedo;
5353 }
5354 else
5355 {
5356 /* This forces the loop to exit immediately. */
5357 pDesc = pCtl->pLastDMADesc + 1;
5358 }
5359
5360 PDMCritSectLeave(&pCtl->lock);
5361 if (RT_UNLIKELY(fRedo))
5362 break;
5363 }
5364 }
5365
5366 if (RT_UNLIKELY(fRedo))
5367 break;
5368
5369 /* end of transfer */
5370 if (!cbTotalTransfer || fLastDesc)
5371 break;
5372
5373 {
5374 STAM_PROFILE_START(&pCtl->StatLockWait, a);
5375 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
5376 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
5377 }
5378
5379 if (!(pCtl->BmDma.u8Cmd & BM_CMD_START) || pCtl->fReset)
5380 {
5381 LogRel(("PIIX3 ATA: Ctl#%d: ABORT DMA%s\n", ATACONTROLLER_IDX(pCtl), pCtl->fReset ? " due to RESET" : ""));
5382 if (!pCtl->fReset)
5383 ataR3DMATransferStop(s);
5384 /* This forces the loop to exit immediately. */
5385 pDesc = pCtl->pLastDMADesc + 1;
5386 }
5387
5388 PDMCritSectLeave(&pCtl->lock);
5389 }
5390
5391 {
5392 STAM_PROFILE_START(&pCtl->StatLockWait, a);
5393 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
5394 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
5395 }
5396
5397 if (RT_UNLIKELY(fRedo))
5398 return;
5399
5400 if (fLastDesc)
5401 pCtl->BmDma.u8Status &= ~BM_STATUS_DMAING;
5402 s->cbTotalTransfer = cbTotalTransfer;
5403 s->cbElementaryTransfer = cbElementaryTransfer;
5404 s->iIOBufferCur = iIOBufferCur;
5405 s->iIOBufferEnd = iIOBufferEnd;
5406}
5407
5408/**
5409 * Signal PDM that we're idle (if we actually are).
5410 *
5411 * @param pCtl The controller.
5412 */
5413static void ataR3AsyncSignalIdle(PATACONTROLLER pCtl)
5414{
5415 /*
5416 * Take the lock here and recheck the idle indicator to avoid
5417 * unnecessary work and racing ataR3WaitForAsyncIOIsIdle.
5418 */
5419 int rc = PDMCritSectEnter(&pCtl->AsyncIORequestLock, VINF_SUCCESS);
5420 AssertRC(rc);
5421
5422 if ( pCtl->fSignalIdle
5423 && ataR3AsyncIOIsIdle(pCtl, false /*fStrict*/))
5424 {
5425 PDMDevHlpAsyncNotificationCompleted(pCtl->pDevInsR3);
5426 RTThreadUserSignal(pCtl->AsyncIOThread); /* for ataR3Construct/ataR3ResetCommon. */
5427 }
5428
5429 rc = PDMCritSectLeave(&pCtl->AsyncIORequestLock);
5430 AssertRC(rc);
5431}
5432
5433/**
5434 * Async I/O thread for an interface.
5435 *
5436 * Once upon a time this was readable code with several loops and a different
5437 * semaphore for each purpose. But then came the "how can one save the state in
5438 * the middle of a PIO transfer" question. The solution was to use an ASM,
5439 * which is what's there now.
5440 */
5441static DECLCALLBACK(int) ataR3AsyncIOThread(RTTHREAD hThreadSelf, void *pvUser)
5442{
5443 RT_NOREF1(hThreadSelf);
5444 const ATARequest *pReq;
5445 uint64_t u64TS = 0; /* shut up gcc */
5446 uint64_t uWait;
5447 int rc = VINF_SUCCESS;
5448 PATACONTROLLER pCtl = (PATACONTROLLER)pvUser;
5449 ATADevState *s;
5450
5451 pReq = NULL;
5452 pCtl->fChainedTransfer = false;
5453 while (!pCtl->fShutdown)
5454 {
5455 /* Keep this thread from doing anything as long as EMT is suspended. */
5456 while (pCtl->fRedoIdle)
5457 {
5458 if (pCtl->fSignalIdle)
5459 ataR3AsyncSignalIdle(pCtl);
5460 rc = RTSemEventWait(pCtl->SuspendIOSem, RT_INDEFINITE_WAIT);
5461 /* Continue if we got a signal by RTThreadPoke().
5462 * We will get notified if there is a request to process.
5463 */
5464 if (RT_UNLIKELY(rc == VERR_INTERRUPTED))
5465 continue;
5466 if (RT_FAILURE(rc) || pCtl->fShutdown)
5467 break;
5468
5469 pCtl->fRedoIdle = false;
5470 }
5471
5472 /* Wait for work. */
5473 while (pReq == NULL)
5474 {
5475 if (pCtl->fSignalIdle)
5476 ataR3AsyncSignalIdle(pCtl);
5477 rc = SUPSemEventWaitNoResume(pCtl->pSupDrvSession, pCtl->hAsyncIOSem, RT_INDEFINITE_WAIT);
5478 /* Continue if we got a signal by RTThreadPoke().
5479 * We will get notified if there is a request to process.
5480 */
5481 if (RT_UNLIKELY(rc == VERR_INTERRUPTED))
5482 continue;
5483 if (RT_FAILURE(rc) || RT_UNLIKELY(pCtl->fShutdown))
5484 break;
5485
5486 pReq = ataR3AsyncIOGetCurrentRequest(pCtl);
5487 }
5488
5489 if (RT_FAILURE(rc) || pCtl->fShutdown)
5490 break;
5491
5492 if (pReq == NULL)
5493 continue;
5494
5495 ATAAIO ReqType = pReq->ReqType;
5496
5497 Log2(("%s: Ctl#%d: state=%d, req=%d\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl), pCtl->uAsyncIOState, ReqType));
5498 if (pCtl->uAsyncIOState != ReqType)
5499 {
5500 /* The new state is not the state that was expected by the normal
5501 * state changes. This is either a RESET/ABORT or there's something
5502 * really strange going on. */
5503 if ( (pCtl->uAsyncIOState == ATA_AIO_PIO || pCtl->uAsyncIOState == ATA_AIO_DMA)
5504 && (ReqType == ATA_AIO_PIO || ReqType == ATA_AIO_DMA))
5505 {
5506 /* Incorrect sequence of PIO/DMA states. Dump request queue. */
5507 ataR3AsyncIODumpRequests(pCtl);
5508 }
5509 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));
5510 }
5511
5512 /* Do our work. */
5513 {
5514 STAM_PROFILE_START(&pCtl->StatLockWait, a);
5515 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
5516 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
5517 }
5518
5519 if (pCtl->uAsyncIOState == ATA_AIO_NEW && !pCtl->fChainedTransfer)
5520 {
5521 u64TS = RTTimeNanoTS();
5522#if defined(DEBUG) || defined(VBOX_WITH_STATISTICS)
5523 STAM_PROFILE_ADV_START(&pCtl->StatAsyncTime, a);
5524#endif
5525 }
5526
5527 switch (ReqType)
5528 {
5529 case ATA_AIO_NEW:
5530
5531 pCtl->iAIOIf = pReq->u.t.iIf;
5532 s = &pCtl->aIfs[pCtl->iAIOIf];
5533 s->cbTotalTransfer = pReq->u.t.cbTotalTransfer;
5534 s->uTxDir = pReq->u.t.uTxDir;
5535 s->iBeginTransfer = pReq->u.t.iBeginTransfer;
5536 s->iSourceSink = pReq->u.t.iSourceSink;
5537 s->iIOBufferEnd = 0;
5538 s->u64CmdTS = u64TS;
5539
5540 if (s->fATAPI)
5541 {
5542 if (pCtl->fChainedTransfer)
5543 {
5544 /* Only count the actual transfers, not the PIO
5545 * transfer of the ATAPI command bytes. */
5546 if (s->fDMA)
5547 STAM_REL_COUNTER_INC(&s->StatATAPIDMA);
5548 else
5549 STAM_REL_COUNTER_INC(&s->StatATAPIPIO);
5550 }
5551 }
5552 else
5553 {
5554 if (s->fDMA)
5555 STAM_REL_COUNTER_INC(&s->StatATADMA);
5556 else
5557 STAM_REL_COUNTER_INC(&s->StatATAPIO);
5558 }
5559
5560 pCtl->fChainedTransfer = false;
5561
5562 if (s->iBeginTransfer != ATAFN_BT_NULL)
5563 {
5564 Log2(("%s: Ctl#%d: calling begin transfer function\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
5565 g_apfnBeginTransFuncs[s->iBeginTransfer](s);
5566 s->iBeginTransfer = ATAFN_BT_NULL;
5567 if (s->uTxDir != PDMMEDIATXDIR_FROM_DEVICE)
5568 s->iIOBufferEnd = s->cbElementaryTransfer;
5569 }
5570 else
5571 {
5572 s->cbElementaryTransfer = s->cbTotalTransfer;
5573 s->iIOBufferEnd = s->cbTotalTransfer;
5574 }
5575 s->iIOBufferCur = 0;
5576
5577 if (s->uTxDir != PDMMEDIATXDIR_TO_DEVICE)
5578 {
5579 if (s->iSourceSink != ATAFN_SS_NULL)
5580 {
5581 bool fRedo;
5582 Log2(("%s: Ctl#%d: calling source/sink function\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
5583 fRedo = g_apfnSourceSinkFuncs[s->iSourceSink](s);
5584 pCtl->fRedo = fRedo;
5585 if (RT_UNLIKELY(fRedo && !pCtl->fReset))
5586 {
5587 /* Operation failed at the initial transfer, restart
5588 * everything from scratch by resending the current
5589 * request. Occurs very rarely, not worth optimizing. */
5590 LogRel(("%s: Ctl#%d: redo entire operation\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
5591 ataHCAsyncIOPutRequest(pCtl, pReq);
5592 break;
5593 }
5594 }
5595 else
5596 ataR3CmdOK(s, 0);
5597 s->iIOBufferEnd = s->cbElementaryTransfer;
5598
5599 }
5600
5601 /* Do not go into the transfer phase if RESET is asserted.
5602 * The CritSect is released while waiting for the host OS
5603 * to finish the I/O, thus RESET is possible here. Most
5604 * important: do not change uAsyncIOState. */
5605 if (pCtl->fReset)
5606 break;
5607
5608 if (s->fDMA)
5609 {
5610 if (s->cbTotalTransfer)
5611 {
5612 ataSetStatus(s, ATA_STAT_DRQ);
5613
5614 pCtl->uAsyncIOState = ATA_AIO_DMA;
5615 /* If BMDMA is already started, do the transfer now. */
5616 if (pCtl->BmDma.u8Cmd & BM_CMD_START)
5617 {
5618 Log2(("%s: Ctl#%d: message to async I/O thread, continuing DMA transfer immediately\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
5619 ataHCAsyncIOPutRequest(pCtl, &g_ataDMARequest);
5620 }
5621 }
5622 else
5623 {
5624 Assert(s->uTxDir == PDMMEDIATXDIR_NONE); /* Any transfer which has an initial transfer size of 0 must be marked as such. */
5625 /* Finish DMA transfer. */
5626 ataR3DMATransferStop(s);
5627 ataHCSetIRQ(s);
5628 pCtl->uAsyncIOState = ATA_AIO_NEW;
5629 }
5630 }
5631 else
5632 {
5633 if (s->cbTotalTransfer)
5634 {
5635 ataHCPIOTransfer(pCtl);
5636 Assert(!pCtl->fRedo);
5637 if (s->fATAPITransfer || s->uTxDir != PDMMEDIATXDIR_TO_DEVICE)
5638 ataHCSetIRQ(s);
5639
5640 if (s->uTxDir == PDMMEDIATXDIR_TO_DEVICE || s->iSourceSink != ATAFN_SS_NULL)
5641 {
5642 /* Write operations and not yet finished transfers
5643 * must be completed in the async I/O thread. */
5644 pCtl->uAsyncIOState = ATA_AIO_PIO;
5645 }
5646 else
5647 {
5648 /* Finished read operation can be handled inline
5649 * in the end of PIO transfer handling code. Linux
5650 * depends on this, as it waits only briefly for
5651 * devices to become ready after incoming data
5652 * transfer. Cannot find anything in the ATA spec
5653 * that backs this assumption, but as all kernels
5654 * are affected (though most of the time it does
5655 * not cause any harm) this must work. */
5656 pCtl->uAsyncIOState = ATA_AIO_NEW;
5657 }
5658 }
5659 else
5660 {
5661 Assert(s->uTxDir == PDMMEDIATXDIR_NONE); /* Any transfer which has an initial transfer size of 0 must be marked as such. */
5662 /* Finish PIO transfer. */
5663 ataHCPIOTransfer(pCtl);
5664 Assert(!pCtl->fRedo);
5665 if (!s->fATAPITransfer)
5666 ataHCSetIRQ(s);
5667 pCtl->uAsyncIOState = ATA_AIO_NEW;
5668 }
5669 }
5670 break;
5671
5672 case ATA_AIO_DMA:
5673 {
5674 BMDMAState *bm = &pCtl->BmDma;
5675 s = &pCtl->aIfs[pCtl->iAIOIf]; /* Do not remove or there's an instant crash after loading the saved state */
5676 ATAFNSS iOriginalSourceSink = (ATAFNSS)s->iSourceSink; /* Used by the hack below, but gets reset by then. */
5677
5678 if (s->uTxDir == PDMMEDIATXDIR_FROM_DEVICE)
5679 AssertRelease(bm->u8Cmd & BM_CMD_WRITE);
5680 else
5681 AssertRelease(!(bm->u8Cmd & BM_CMD_WRITE));
5682
5683 if (RT_LIKELY(!pCtl->fRedo))
5684 {
5685 /* The specs say that the descriptor table must not cross a
5686 * 4K boundary. */
5687 pCtl->pFirstDMADesc = bm->pvAddr;
5688 pCtl->pLastDMADesc = RT_ALIGN_32(bm->pvAddr + 1, _4K) - sizeof(BMDMADesc);
5689 }
5690 ataR3DMATransfer(pCtl);
5691
5692 if (RT_UNLIKELY(pCtl->fRedo && !pCtl->fReset))
5693 {
5694 LogRel(("PIIX3 ATA: Ctl#%d: redo DMA operation\n", ATACONTROLLER_IDX(pCtl)));
5695 ataHCAsyncIOPutRequest(pCtl, &g_ataDMARequest);
5696 break;
5697 }
5698
5699 /* The infamous delay IRQ hack. */
5700 if ( iOriginalSourceSink == ATAFN_SS_WRITE_SECTORS
5701 && s->cbTotalTransfer == 0
5702 && pCtl->DelayIRQMillies)
5703 {
5704 /* Delay IRQ for writing. Required to get the Win2K
5705 * installation work reliably (otherwise it crashes,
5706 * usually during component install). So far no better
5707 * solution has been found. */
5708 Log(("%s: delay IRQ hack\n", __FUNCTION__));
5709 PDMCritSectLeave(&pCtl->lock);
5710 RTThreadSleep(pCtl->DelayIRQMillies);
5711 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
5712 }
5713
5714 ataUnsetStatus(s, ATA_STAT_DRQ);
5715 Assert(!pCtl->fChainedTransfer);
5716 Assert(s->iSourceSink == ATAFN_SS_NULL);
5717 if (s->fATAPITransfer)
5718 {
5719 s->uATARegNSector = (s->uATARegNSector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
5720 Log2(("%s: Ctl#%d: interrupt reason %#04x\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl), s->uATARegNSector));
5721 s->fATAPITransfer = false;
5722 }
5723 ataHCSetIRQ(s);
5724 pCtl->uAsyncIOState = ATA_AIO_NEW;
5725 break;
5726 }
5727
5728 case ATA_AIO_PIO:
5729 s = &pCtl->aIfs[pCtl->iAIOIf]; /* Do not remove or there's an instant crash after loading the saved state */
5730
5731 if (s->iSourceSink != ATAFN_SS_NULL)
5732 {
5733 bool fRedo;
5734 Log2(("%s: Ctl#%d: calling source/sink function\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
5735 fRedo = g_apfnSourceSinkFuncs[s->iSourceSink](s);
5736 pCtl->fRedo = fRedo;
5737 if (RT_UNLIKELY(fRedo && !pCtl->fReset))
5738 {
5739 LogRel(("PIIX3 ATA: Ctl#%d: redo PIO operation\n", ATACONTROLLER_IDX(pCtl)));
5740 ataHCAsyncIOPutRequest(pCtl, &g_ataPIORequest);
5741 break;
5742 }
5743 s->iIOBufferCur = 0;
5744 s->iIOBufferEnd = s->cbElementaryTransfer;
5745 }
5746 else
5747 {
5748 /* Continue a previously started transfer. */
5749 ataUnsetStatus(s, ATA_STAT_BUSY);
5750 ataSetStatus(s, ATA_STAT_READY);
5751 }
5752
5753 /* It is possible that the drives on this controller get RESET
5754 * during the above call to the source/sink function. If that's
5755 * the case, don't restart the transfer and don't finish it the
5756 * usual way. RESET handling took care of all that already.
5757 * Most important: do not change uAsyncIOState. */
5758 if (pCtl->fReset)
5759 break;
5760
5761 if (s->cbTotalTransfer)
5762 {
5763 ataHCPIOTransfer(pCtl);
5764 ataHCSetIRQ(s);
5765
5766 if (s->uTxDir == PDMMEDIATXDIR_TO_DEVICE || s->iSourceSink != ATAFN_SS_NULL)
5767 {
5768 /* Write operations and not yet finished transfers
5769 * must be completed in the async I/O thread. */
5770 pCtl->uAsyncIOState = ATA_AIO_PIO;
5771 }
5772 else
5773 {
5774 /* Finished read operation can be handled inline
5775 * in the end of PIO transfer handling code. Linux
5776 * depends on this, as it waits only briefly for
5777 * devices to become ready after incoming data
5778 * transfer. Cannot find anything in the ATA spec
5779 * that backs this assumption, but as all kernels
5780 * are affected (though most of the time it does
5781 * not cause any harm) this must work. */
5782 pCtl->uAsyncIOState = ATA_AIO_NEW;
5783 }
5784 }
5785 else
5786 {
5787 /* Finish PIO transfer. */
5788 ataHCPIOTransfer(pCtl);
5789 if ( !pCtl->fChainedTransfer
5790 && !s->fATAPITransfer
5791 && s->uTxDir != PDMMEDIATXDIR_FROM_DEVICE)
5792 {
5793 ataHCSetIRQ(s);
5794 }
5795 pCtl->uAsyncIOState = ATA_AIO_NEW;
5796 }
5797 break;
5798
5799 case ATA_AIO_RESET_ASSERTED:
5800 pCtl->uAsyncIOState = ATA_AIO_RESET_CLEARED;
5801 ataHCPIOTransferStop(&pCtl->aIfs[0]);
5802 ataHCPIOTransferStop(&pCtl->aIfs[1]);
5803 /* Do not change the DMA registers, they are not affected by the
5804 * ATA controller reset logic. It should be sufficient to issue a
5805 * new command, which is now possible as the state is cleared. */
5806 break;
5807
5808 case ATA_AIO_RESET_CLEARED:
5809 pCtl->uAsyncIOState = ATA_AIO_NEW;
5810 pCtl->fReset = false;
5811 /* Ensure that half-completed transfers are not redone. A reset
5812 * cancels the entire transfer, so continuing is wrong. */
5813 pCtl->fRedo = false;
5814 pCtl->fRedoDMALastDesc = false;
5815 LogRel(("PIIX3 ATA: Ctl#%d: finished processing RESET\n",
5816 ATACONTROLLER_IDX(pCtl)));
5817 for (uint32_t i = 0; i < RT_ELEMENTS(pCtl->aIfs); i++)
5818 {
5819 if (pCtl->aIfs[i].fATAPI)
5820 ataSetStatusValue(&pCtl->aIfs[i], 0); /* NOTE: READY is _not_ set */
5821 else
5822 ataSetStatusValue(&pCtl->aIfs[i], ATA_STAT_READY | ATA_STAT_SEEK);
5823 ataR3SetSignature(&pCtl->aIfs[i]);
5824 }
5825 break;
5826
5827 case ATA_AIO_ABORT:
5828 /* Abort the current command no matter what. There cannot be
5829 * any command activity on the other drive otherwise using
5830 * one thread per controller wouldn't work at all. */
5831 s = &pCtl->aIfs[pReq->u.a.iIf];
5832
5833 pCtl->uAsyncIOState = ATA_AIO_NEW;
5834 /* Do not change the DMA registers, they are not affected by the
5835 * ATA controller reset logic. It should be sufficient to issue a
5836 * new command, which is now possible as the state is cleared. */
5837 if (pReq->u.a.fResetDrive)
5838 {
5839 ataR3ResetDevice(s);
5840 ataR3ExecuteDeviceDiagnosticSS(s);
5841 }
5842 else
5843 {
5844 /* Stop any pending DMA transfer. */
5845 s->fDMA = false;
5846 ataHCPIOTransferStop(s);
5847 ataUnsetStatus(s, ATA_STAT_BUSY | ATA_STAT_DRQ | ATA_STAT_SEEK | ATA_STAT_ERR);
5848 ataSetStatus(s, ATA_STAT_READY);
5849 ataHCSetIRQ(s);
5850 }
5851 break;
5852
5853 default:
5854 AssertMsgFailed(("Undefined async I/O state %d\n", pCtl->uAsyncIOState));
5855 }
5856
5857 ataR3AsyncIORemoveCurrentRequest(pCtl, ReqType);
5858 pReq = ataR3AsyncIOGetCurrentRequest(pCtl);
5859
5860 if (pCtl->uAsyncIOState == ATA_AIO_NEW && !pCtl->fChainedTransfer)
5861 {
5862# if defined(DEBUG) || defined(VBOX_WITH_STATISTICS)
5863 STAM_PROFILE_ADV_STOP(&pCtl->StatAsyncTime, a);
5864# endif
5865
5866 u64TS = RTTimeNanoTS() - u64TS;
5867 uWait = u64TS / 1000;
5868 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)));
5869 /* Mark command as finished. */
5870 pCtl->aIfs[pCtl->iAIOIf].u64CmdTS = 0;
5871
5872 /*
5873 * Release logging of command execution times depends on the
5874 * command type. ATAPI commands often take longer (due to CD/DVD
5875 * spin up time etc.) so the threshold is different.
5876 */
5877 if (pCtl->aIfs[pCtl->iAIOIf].uATARegCommand != ATA_PACKET)
5878 {
5879 if (uWait > 8 * 1000 * 1000)
5880 {
5881 /*
5882 * Command took longer than 8 seconds. This is close
5883 * enough or over the guest's command timeout, so place
5884 * an entry in the release log to allow tracking such
5885 * timing errors (which are often caused by the host).
5886 */
5887 LogRel(("PIIX3 ATA: execution time for ATA command %#04x was %d seconds\n", pCtl->aIfs[pCtl->iAIOIf].uATARegCommand, uWait / (1000 * 1000)));
5888 }
5889 }
5890 else
5891 {
5892 if (uWait > 20 * 1000 * 1000)
5893 {
5894 /*
5895 * Command took longer than 20 seconds. This is close
5896 * enough or over the guest's command timeout, so place
5897 * an entry in the release log to allow tracking such
5898 * timing errors (which are often caused by the host).
5899 */
5900 LogRel(("PIIX3 ATA: execution time for ATAPI command %#04x was %d seconds\n", pCtl->aIfs[pCtl->iAIOIf].aATAPICmd[0], uWait / (1000 * 1000)));
5901 }
5902 }
5903
5904# if defined(DEBUG) || defined(VBOX_WITH_STATISTICS)
5905 if (uWait < pCtl->StatAsyncMinWait || !pCtl->StatAsyncMinWait)
5906 pCtl->StatAsyncMinWait = uWait;
5907 if (uWait > pCtl->StatAsyncMaxWait)
5908 pCtl->StatAsyncMaxWait = uWait;
5909
5910 STAM_COUNTER_ADD(&pCtl->StatAsyncTimeUS, uWait);
5911 STAM_COUNTER_INC(&pCtl->StatAsyncOps);
5912# endif /* DEBUG || VBOX_WITH_STATISTICS */
5913 }
5914
5915 PDMCritSectLeave(&pCtl->lock);
5916 }
5917
5918 /* Signal the ultimate idleness. */
5919 RTThreadUserSignal(pCtl->AsyncIOThread);
5920 if (pCtl->fSignalIdle)
5921 PDMDevHlpAsyncNotificationCompleted(pCtl->pDevInsR3);
5922
5923 /* Cleanup the state. */
5924 /* Do not destroy request lock yet, still needed for proper shutdown. */
5925 pCtl->fShutdown = false;
5926
5927 Log2(("%s: Ctl#%d: return %Rrc\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl), rc));
5928 return rc;
5929}
5930
5931#endif /* IN_RING3 */
5932
5933static uint32_t ataBMDMACmdReadB(PATACONTROLLER pCtl, uint32_t addr)
5934{
5935 uint32_t val = pCtl->BmDma.u8Cmd;
5936 RT_NOREF1(addr);
5937 Log2(("%s: addr=%#06x val=%#04x\n", __FUNCTION__, addr, val));
5938 return val;
5939}
5940
5941
5942static void ataBMDMACmdWriteB(PATACONTROLLER pCtl, uint32_t addr, uint32_t val)
5943{
5944 RT_NOREF1(addr);
5945 Log2(("%s: addr=%#06x val=%#04x\n", __FUNCTION__, addr, val));
5946 if (!(val & BM_CMD_START))
5947 {
5948 pCtl->BmDma.u8Status &= ~BM_STATUS_DMAING;
5949 pCtl->BmDma.u8Cmd = val & (BM_CMD_START | BM_CMD_WRITE);
5950 }
5951 else
5952 {
5953#ifndef IN_RC
5954 /* Check whether the guest OS wants to change DMA direction in
5955 * mid-flight. Not allowed, according to the PIIX3 specs. */
5956 Assert(!(pCtl->BmDma.u8Status & BM_STATUS_DMAING) || !((val ^ pCtl->BmDma.u8Cmd) & 0x04));
5957 uint8_t uOldBmDmaStatus = pCtl->BmDma.u8Status;
5958 pCtl->BmDma.u8Status |= BM_STATUS_DMAING;
5959 pCtl->BmDma.u8Cmd = val & (BM_CMD_START | BM_CMD_WRITE);
5960
5961 /* Do not continue DMA transfers while the RESET line is asserted. */
5962 if (pCtl->fReset)
5963 {
5964 Log2(("%s: Ctl#%d: suppressed continuing DMA transfer as RESET is active\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
5965 return;
5966 }
5967
5968 /* Do not start DMA transfers if there's a PIO transfer going on,
5969 * or if there is already a transfer started on this controller. */
5970 if ( !pCtl->aIfs[pCtl->iSelectedIf].fDMA
5971 || (uOldBmDmaStatus & BM_STATUS_DMAING))
5972 return;
5973
5974 if (pCtl->aIfs[pCtl->iAIOIf].uATARegStatus & ATA_STAT_DRQ)
5975 {
5976 Log2(("%s: Ctl#%d: message to async I/O thread, continuing DMA transfer\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
5977 ataHCAsyncIOPutRequest(pCtl, &g_ataDMARequest);
5978 }
5979#else /* !IN_RING3 */
5980 AssertMsgFailed(("DMA START handling is too complicated for RC\n"));
5981#endif /* IN_RING3 */
5982 }
5983}
5984
5985static uint32_t ataBMDMAStatusReadB(PATACONTROLLER pCtl, uint32_t addr)
5986{
5987 uint32_t val = pCtl->BmDma.u8Status;
5988 RT_NOREF1(addr);
5989 Log2(("%s: addr=%#06x val=%#04x\n", __FUNCTION__, addr, val));
5990 return val;
5991}
5992
5993static void ataBMDMAStatusWriteB(PATACONTROLLER pCtl, uint32_t addr, uint32_t val)
5994{
5995 RT_NOREF1(addr);
5996 Log2(("%s: addr=%#06x val=%#04x\n", __FUNCTION__, addr, val));
5997 pCtl->BmDma.u8Status = (val & (BM_STATUS_D0DMA | BM_STATUS_D1DMA))
5998 | (pCtl->BmDma.u8Status & BM_STATUS_DMAING)
5999 | (pCtl->BmDma.u8Status & ~val & (BM_STATUS_ERROR | BM_STATUS_INT));
6000}
6001
6002static uint32_t ataBMDMAAddrReadL(PATACONTROLLER pCtl, uint32_t addr)
6003{
6004 uint32_t val = (uint32_t)pCtl->BmDma.pvAddr;
6005 RT_NOREF1(addr);
6006 Log2(("%s: addr=%#06x val=%#010x\n", __FUNCTION__, addr, val));
6007 return val;
6008}
6009
6010static void ataBMDMAAddrWriteL(PATACONTROLLER pCtl, uint32_t addr, uint32_t val)
6011{
6012 RT_NOREF1(addr);
6013 Log2(("%s: addr=%#06x val=%#010x\n", __FUNCTION__, addr, val));
6014 pCtl->BmDma.pvAddr = val & ~3;
6015}
6016
6017static void ataBMDMAAddrWriteLowWord(PATACONTROLLER pCtl, uint32_t addr, uint32_t val)
6018{
6019 RT_NOREF1(addr);
6020 Log2(("%s: addr=%#06x val=%#010x\n", __FUNCTION__, addr, val));
6021 pCtl->BmDma.pvAddr = (pCtl->BmDma.pvAddr & 0xFFFF0000) | RT_LOWORD(val & ~3);
6022
6023}
6024
6025static void ataBMDMAAddrWriteHighWord(PATACONTROLLER pCtl, uint32_t addr, uint32_t val)
6026{
6027 Log2(("%s: addr=%#06x val=%#010x\n", __FUNCTION__, addr, val));
6028 RT_NOREF1(addr);
6029 pCtl->BmDma.pvAddr = (RT_LOWORD(val) << 16) | RT_LOWORD(pCtl->BmDma.pvAddr);
6030}
6031
6032#define VAL(port, size) ( ((port) & 7) | ((size) << 3) )
6033
6034/**
6035 * Port I/O Handler for bus master DMA IN operations.
6036 * @see FNIOMIOPORTIN for details.
6037 */
6038PDMBOTHCBDECL(int) ataBMDMAIOPortRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
6039{
6040 uint32_t i = (uint32_t)(uintptr_t)pvUser;
6041 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
6042 PATACONTROLLER pCtl = &pThis->aCts[i];
6043
6044 int rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_R3_IOPORT_READ);
6045 if (rc != VINF_SUCCESS)
6046 return rc;
6047 switch (VAL(Port, cb))
6048 {
6049 case VAL(0, 1): *pu32 = ataBMDMACmdReadB(pCtl, Port); break;
6050 case VAL(0, 2): *pu32 = ataBMDMACmdReadB(pCtl, Port); break;
6051 case VAL(2, 1): *pu32 = ataBMDMAStatusReadB(pCtl, Port); break;
6052 case VAL(2, 2): *pu32 = ataBMDMAStatusReadB(pCtl, Port); break;
6053 case VAL(4, 4): *pu32 = ataBMDMAAddrReadL(pCtl, Port); break;
6054 case VAL(0, 4):
6055 /* The SCO OpenServer tries to read 4 bytes starting from offset 0. */
6056 *pu32 = ataBMDMACmdReadB(pCtl, Port) | (ataBMDMAStatusReadB(pCtl, Port) << 16);
6057 break;
6058 default:
6059 AssertMsgFailed(("%s: Unsupported read from port %x size=%d\n", __FUNCTION__, Port, cb));
6060 PDMCritSectLeave(&pCtl->lock);
6061 return VERR_IOM_IOPORT_UNUSED;
6062 }
6063 PDMCritSectLeave(&pCtl->lock);
6064 return rc;
6065}
6066
6067/**
6068 * Port I/O Handler for bus master DMA OUT operations.
6069 * @see FNIOMIOPORTOUT for details.
6070 */
6071PDMBOTHCBDECL(int) ataBMDMAIOPortWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
6072{
6073 uint32_t i = (uint32_t)(uintptr_t)pvUser;
6074 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
6075 PATACONTROLLER pCtl = &pThis->aCts[i];
6076
6077 int rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_R3_IOPORT_WRITE);
6078 if (rc != VINF_SUCCESS)
6079 return rc;
6080 switch (VAL(Port, cb))
6081 {
6082 case VAL(0, 1):
6083#ifdef IN_RC
6084 if (u32 & BM_CMD_START)
6085 {
6086 rc = VINF_IOM_R3_IOPORT_WRITE;
6087 break;
6088 }
6089#endif
6090 ataBMDMACmdWriteB(pCtl, Port, u32);
6091 break;
6092 case VAL(2, 1): ataBMDMAStatusWriteB(pCtl, Port, u32); break;
6093 case VAL(4, 4): ataBMDMAAddrWriteL(pCtl, Port, u32); break;
6094 case VAL(4, 2): ataBMDMAAddrWriteLowWord(pCtl, Port, u32); break;
6095 case VAL(6, 2): ataBMDMAAddrWriteHighWord(pCtl, Port, u32); break;
6096 default: AssertMsgFailed(("%s: Unsupported write to port %x size=%d val=%x\n", __FUNCTION__, Port, cb, u32)); break;
6097 }
6098 PDMCritSectLeave(&pCtl->lock);
6099 return rc;
6100}
6101
6102#undef VAL
6103
6104#ifdef IN_RING3
6105
6106/**
6107 * Callback function for mapping an PCI I/O region.
6108 *
6109 * @return VBox status code.
6110 * @param pPciDev Pointer to PCI device. Use pPciDev->pDevIns to get the device instance.
6111 * @param iRegion The region number.
6112 * @param GCPhysAddress Physical address of the region. If iType is PCI_ADDRESS_SPACE_IO, this is an
6113 * I/O port, else it's a physical address.
6114 * This address is *NOT* relative to pci_mem_base like earlier!
6115 * @param enmType One of the PCI_ADDRESS_SPACE_* values.
6116 */
6117static DECLCALLBACK(int) ataR3BMDMAIORangeMap(PPCIDEVICE pPciDev, /*unsigned*/ int iRegion,
6118 RTGCPHYS GCPhysAddress, uint32_t cb, PCIADDRESSSPACE enmType)
6119{
6120 RT_NOREF(iRegion, cb, enmType);
6121 PCIATAState *pThis = PCIDEV_2_PCIATASTATE(pPciDev);
6122 int rc = VINF_SUCCESS;
6123 Assert(enmType == PCI_ADDRESS_SPACE_IO);
6124 Assert(iRegion == 4);
6125 AssertMsg(RT_ALIGN(GCPhysAddress, 8) == GCPhysAddress, ("Expected 8 byte alignment. GCPhysAddress=%#x\n", GCPhysAddress));
6126
6127 /* Register the port range. */
6128 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
6129 {
6130 int rc2 = PDMDevHlpIOPortRegister(pPciDev->pDevIns, (RTIOPORT)GCPhysAddress + i * 8, 8,
6131 (RTHCPTR)(uintptr_t)i, ataBMDMAIOPortWrite, ataBMDMAIOPortRead,
6132 NULL, NULL, "ATA Bus Master DMA");
6133 AssertRC(rc2);
6134 if (rc2 < rc)
6135 rc = rc2;
6136
6137 if (pThis->fRCEnabled)
6138 {
6139 rc2 = PDMDevHlpIOPortRegisterRC(pPciDev->pDevIns, (RTIOPORT)GCPhysAddress + i * 8, 8,
6140 (RTGCPTR)i, "ataBMDMAIOPortWrite", "ataBMDMAIOPortRead",
6141 NULL, NULL, "ATA Bus Master DMA");
6142 AssertRC(rc2);
6143 if (rc2 < rc)
6144 rc = rc2;
6145 }
6146 if (pThis->fR0Enabled)
6147 {
6148 rc2 = PDMDevHlpIOPortRegisterR0(pPciDev->pDevIns, (RTIOPORT)GCPhysAddress + i * 8, 8,
6149 (RTR0PTR)i, "ataBMDMAIOPortWrite", "ataBMDMAIOPortRead",
6150 NULL, NULL, "ATA Bus Master DMA");
6151 AssertRC(rc2);
6152 if (rc2 < rc)
6153 rc = rc2;
6154 }
6155 }
6156 return rc;
6157}
6158
6159
6160/* -=-=-=-=-=- PCIATAState::IBase -=-=-=-=-=- */
6161
6162/**
6163 * @interface_method_impl{PDMIBASE,pfnQueryInterface}
6164 */
6165static DECLCALLBACK(void *) ataR3Status_QueryInterface(PPDMIBASE pInterface, const char *pszIID)
6166{
6167 PCIATAState *pThis = PDMIBASE_2_PCIATASTATE(pInterface);
6168 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pThis->IBase);
6169 PDMIBASE_RETURN_INTERFACE(pszIID, PDMILEDPORTS, &pThis->ILeds);
6170 return NULL;
6171}
6172
6173
6174/* -=-=-=-=-=- PCIATAState::ILeds -=-=-=-=-=- */
6175
6176/**
6177 * Gets the pointer to the status LED of a unit.
6178 *
6179 * @returns VBox status code.
6180 * @param pInterface Pointer to the interface structure containing the called function pointer.
6181 * @param iLUN The unit which status LED we desire.
6182 * @param ppLed Where to store the LED pointer.
6183 */
6184static DECLCALLBACK(int) ataR3Status_QueryStatusLed(PPDMILEDPORTS pInterface, unsigned iLUN, PPDMLED *ppLed)
6185{
6186 PCIATAState *pThis = PDMILEDPORTS_2_PCIATASTATE(pInterface);
6187 if (iLUN < 4)
6188 {
6189 switch (iLUN)
6190 {
6191 case 0: *ppLed = &pThis->aCts[0].aIfs[0].Led; break;
6192 case 1: *ppLed = &pThis->aCts[0].aIfs[1].Led; break;
6193 case 2: *ppLed = &pThis->aCts[1].aIfs[0].Led; break;
6194 case 3: *ppLed = &pThis->aCts[1].aIfs[1].Led; break;
6195 }
6196 Assert((*ppLed)->u32Magic == PDMLED_MAGIC);
6197 return VINF_SUCCESS;
6198 }
6199 return VERR_PDM_LUN_NOT_FOUND;
6200}
6201
6202
6203/* -=-=-=-=-=- ATADevState::IBase -=-=-=-=-=- */
6204
6205/**
6206 * @interface_method_impl{PDMIBASE,pfnQueryInterface}
6207 */
6208static DECLCALLBACK(void *) ataR3QueryInterface(PPDMIBASE pInterface, const char *pszIID)
6209{
6210 ATADevState *pIf = PDMIBASE_2_ATASTATE(pInterface);
6211 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pIf->IBase);
6212 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMEDIAPORT, &pIf->IPort);
6213 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMOUNTNOTIFY, &pIf->IMountNotify);
6214 return NULL;
6215}
6216
6217
6218/* -=-=-=-=-=- ATADevState::IPort -=-=-=-=-=- */
6219
6220/**
6221 * @interface_method_impl{PDMIMEDIAPORT,pfnQueryDeviceLocation}
6222 */
6223static DECLCALLBACK(int) ataR3QueryDeviceLocation(PPDMIMEDIAPORT pInterface, const char **ppcszController,
6224 uint32_t *piInstance, uint32_t *piLUN)
6225{
6226 ATADevState *pIf = PDMIMEDIAPORT_2_ATASTATE(pInterface);
6227 PPDMDEVINS pDevIns = pIf->CTX_SUFF(pDevIns);
6228
6229 AssertPtrReturn(ppcszController, VERR_INVALID_POINTER);
6230 AssertPtrReturn(piInstance, VERR_INVALID_POINTER);
6231 AssertPtrReturn(piLUN, VERR_INVALID_POINTER);
6232
6233 *ppcszController = pDevIns->pReg->szName;
6234 *piInstance = pDevIns->iInstance;
6235 *piLUN = pIf->iLUN;
6236
6237 return VINF_SUCCESS;
6238}
6239
6240#endif /* IN_RING3 */
6241
6242/* -=-=-=-=-=- Wrappers -=-=-=-=-=- */
6243
6244
6245/**
6246 * Port I/O Handler for primary port range OUT operations.
6247 * @see FNIOMIOPORTOUT for details.
6248 */
6249PDMBOTHCBDECL(int) ataIOPortWrite1Other(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
6250{
6251 uint32_t i = (uint32_t)(uintptr_t)pvUser;
6252 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
6253 PATACONTROLLER pCtl = &pThis->aCts[i];
6254
6255 Assert(i < 2);
6256 Assert(Port != pCtl->IOPortBase1);
6257
6258 int rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_R3_IOPORT_WRITE);
6259 if (rc == VINF_SUCCESS)
6260 {
6261 /* Writes to the other command block ports should be 8-bit only. If they
6262 * are not, the high bits are simply discarded. Undocumented, but observed
6263 * on a real PIIX4 system.
6264 */
6265 if (cb > 1)
6266 Log(("ataIOPortWrite1: suspect write to port %x val=%x size=%d\n", Port, u32, cb));
6267
6268 rc = ataIOPortWriteU8(pCtl, Port, u32);
6269
6270 PDMCritSectLeave(&pCtl->lock);
6271 }
6272 return rc;
6273}
6274
6275
6276/**
6277 * Port I/O Handler for primary port range IN operations.
6278 * @see FNIOMIOPORTIN for details.
6279 */
6280PDMBOTHCBDECL(int) ataIOPortRead1Other(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
6281{
6282 uint32_t i = (uint32_t)(uintptr_t)pvUser;
6283 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
6284 PATACONTROLLER pCtl = &pThis->aCts[i];
6285
6286 Assert(i < 2);
6287 Assert(Port != pCtl->IOPortBase1);
6288
6289 int rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_R3_IOPORT_READ);
6290 if (rc == VINF_SUCCESS)
6291 {
6292 /* Reads from the other command block registers should be 8-bit only.
6293 * If they are not, the low byte is propagated to the high bits.
6294 * Undocumented, but observed on a real PIIX4 system.
6295 */
6296 rc = ataIOPortReadU8(pCtl, Port, pu32);
6297 if (cb > 1)
6298 {
6299 uint32_t pad;
6300
6301 /* Replicate the 8-bit result into the upper three bytes. */
6302 pad = *pu32 & 0xff;
6303 pad = pad | (pad << 8);
6304 pad = pad | (pad << 16);
6305 *pu32 = pad;
6306 Log(("ataIOPortRead1: suspect read from port %x size=%d\n", Port, cb));
6307 }
6308 PDMCritSectLeave(&pCtl->lock);
6309 }
6310 return rc;
6311}
6312
6313
6314/**
6315 * Port I/O Handler for secondary port range OUT operations.
6316 * @see FNIOMIOPORTOUT for details.
6317 */
6318PDMBOTHCBDECL(int) ataIOPortWrite2(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
6319{
6320 uint32_t i = (uint32_t)(uintptr_t)pvUser;
6321 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
6322 PATACONTROLLER pCtl = &pThis->aCts[i];
6323 int rc;
6324
6325 Assert(i < 2);
6326
6327 if (cb == 1)
6328 {
6329 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_R3_IOPORT_WRITE);
6330 if (rc == VINF_SUCCESS)
6331 {
6332 rc = ataControlWrite(pCtl, Port, u32);
6333 PDMCritSectLeave(&pCtl->lock);
6334 }
6335 }
6336 else
6337 rc = VINF_SUCCESS;
6338 return rc;
6339}
6340
6341
6342/**
6343 * Port I/O Handler for secondary port range IN operations.
6344 * @see FNIOMIOPORTIN for details.
6345 */
6346PDMBOTHCBDECL(int) ataIOPortRead2(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
6347{
6348 uint32_t i = (uint32_t)(uintptr_t)pvUser;
6349 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
6350 PATACONTROLLER pCtl = &pThis->aCts[i];
6351 int rc;
6352
6353 Assert(i < 2);
6354
6355 if (cb == 1)
6356 {
6357 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_R3_IOPORT_READ);
6358 if (rc == VINF_SUCCESS)
6359 {
6360 *pu32 = ataStatusRead(pCtl, Port);
6361 PDMCritSectLeave(&pCtl->lock);
6362 }
6363 }
6364 else
6365 rc = VERR_IOM_IOPORT_UNUSED;
6366 return rc;
6367}
6368
6369#ifdef IN_RING3
6370
6371
6372DECLINLINE(void) ataR3RelocBuffer(PPDMDEVINS pDevIns, ATADevState *s)
6373{
6374 if (s->pbIOBufferR3)
6375 s->pbIOBufferRC = MMHyperR3ToRC(PDMDevHlpGetVM(pDevIns), s->pbIOBufferR3);
6376}
6377
6378
6379/**
6380 * Detach notification.
6381 *
6382 * The DVD drive has been unplugged.
6383 *
6384 * @param pDevIns The device instance.
6385 * @param iLUN The logical unit which is being detached.
6386 * @param fFlags Flags, combination of the PDMDEVATT_FLAGS_* \#defines.
6387 */
6388static DECLCALLBACK(void) ataR3Detach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags)
6389{
6390 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
6391 AssertMsg(fFlags & PDM_TACH_FLAGS_NOT_HOT_PLUG,
6392 ("PIIX3IDE: Device does not support hotplugging\n")); RT_NOREF(fFlags);
6393
6394 /*
6395 * Locate the controller and stuff.
6396 */
6397 unsigned iController = iLUN / RT_ELEMENTS(pThis->aCts[0].aIfs);
6398 AssertReleaseMsg(iController < RT_ELEMENTS(pThis->aCts), ("iController=%d iLUN=%d\n", iController, iLUN));
6399 PATACONTROLLER pCtl = &pThis->aCts[iController];
6400
6401 unsigned iInterface = iLUN % RT_ELEMENTS(pThis->aCts[0].aIfs);
6402 ATADevState *pIf = &pCtl->aIfs[iInterface];
6403
6404 /*
6405 * Zero some important members.
6406 */
6407 pIf->pDrvBase = NULL;
6408 pIf->pDrvMedia = NULL;
6409 pIf->pDrvMount = NULL;
6410
6411 /*
6412 * In case there was a medium inserted.
6413 */
6414 ataR3MediumRemoved(pIf);
6415}
6416
6417
6418/**
6419 * Configure a LUN.
6420 *
6421 * @returns VBox status code.
6422 * @param pDevIns The device instance.
6423 * @param pIf The ATA unit state.
6424 */
6425static int ataR3ConfigLun(PPDMDEVINS pDevIns, ATADevState *pIf)
6426{
6427 int rc = VINF_SUCCESS;
6428 PDMMEDIATYPE enmType;
6429
6430 /*
6431 * Query Block, Bios and Mount interfaces.
6432 */
6433 pIf->pDrvMedia = PDMIBASE_QUERY_INTERFACE(pIf->pDrvBase, PDMIMEDIA);
6434 if (!pIf->pDrvMedia)
6435 {
6436 AssertMsgFailed(("Configuration error: LUN#%d hasn't a block interface!\n", pIf->iLUN));
6437 return VERR_PDM_MISSING_INTERFACE;
6438 }
6439
6440 pIf->pDrvMount = PDMIBASE_QUERY_INTERFACE(pIf->pDrvBase, PDMIMOUNT);
6441
6442 /*
6443 * Validate type.
6444 */
6445 enmType = pIf->pDrvMedia->pfnGetType(pIf->pDrvMedia);
6446 if ( enmType != PDMMEDIATYPE_CDROM
6447 && enmType != PDMMEDIATYPE_DVD
6448 && enmType != PDMMEDIATYPE_HARD_DISK)
6449 {
6450 AssertMsgFailed(("Configuration error: LUN#%d isn't a disk or cd/dvd-rom. enmType=%d\n", pIf->iLUN, enmType));
6451 return VERR_PDM_UNSUPPORTED_BLOCK_TYPE;
6452 }
6453 if ( ( enmType == PDMMEDIATYPE_DVD
6454 || enmType == PDMMEDIATYPE_CDROM)
6455 && !pIf->pDrvMount)
6456 {
6457 AssertMsgFailed(("Internal error: cdrom without a mountable interface, WTF???!\n"));
6458 return VERR_INTERNAL_ERROR;
6459 }
6460 pIf->fATAPI = enmType == PDMMEDIATYPE_DVD || enmType == PDMMEDIATYPE_CDROM;
6461 pIf->fATAPIPassthrough = pIf->fATAPI ? (pIf->pDrvMedia->pfnSendCmd != NULL) : false;
6462
6463 /*
6464 * Allocate I/O buffer.
6465 */
6466 if (pIf->fATAPI)
6467 pIf->cbSector = 2048;
6468 else
6469 pIf->cbSector = pIf->pDrvMedia->pfnGetSectorSize(pIf->pDrvMedia);
6470
6471 PVM pVM = PDMDevHlpGetVM(pDevIns);
6472 if (pIf->cbIOBuffer)
6473 {
6474 /* Buffer is (probably) already allocated. Validate the fields,
6475 * because memory corruption can also overwrite pIf->cbIOBuffer. */
6476 if (pIf->fATAPI)
6477 AssertRelease(pIf->cbIOBuffer == _128K);
6478 else
6479 AssertRelease(pIf->cbIOBuffer == ATA_MAX_MULT_SECTORS * pIf->cbSector);
6480 Assert(pIf->pbIOBufferR3);
6481 Assert(pIf->pbIOBufferR0 == MMHyperR3ToR0(pVM, pIf->pbIOBufferR3));
6482 Assert(pIf->pbIOBufferRC == MMHyperR3ToRC(pVM, pIf->pbIOBufferR3));
6483 }
6484 else
6485 {
6486 if (pIf->fATAPI)
6487 pIf->cbIOBuffer = _128K;
6488 else
6489 pIf->cbIOBuffer = ATA_MAX_MULT_SECTORS * pIf->cbSector;
6490 Assert(!pIf->pbIOBufferR3);
6491 rc = MMR3HyperAllocOnceNoRel(pVM, pIf->cbIOBuffer, 0, MM_TAG_PDM_DEVICE_USER, (void **)&pIf->pbIOBufferR3);
6492 if (RT_FAILURE(rc))
6493 return VERR_NO_MEMORY;
6494 pIf->pbIOBufferR0 = MMHyperR3ToR0(pVM, pIf->pbIOBufferR3);
6495 pIf->pbIOBufferRC = MMHyperR3ToRC(pVM, pIf->pbIOBufferR3);
6496 }
6497
6498 /*
6499 * Init geometry (only for non-CD/DVD media).
6500 */
6501 if (pIf->fATAPI)
6502 {
6503 pIf->cTotalSectors = pIf->pDrvMedia->pfnGetSize(pIf->pDrvMedia) / pIf->cbSector;
6504 pIf->PCHSGeometry.cCylinders = 0; /* dummy */
6505 pIf->PCHSGeometry.cHeads = 0; /* dummy */
6506 pIf->PCHSGeometry.cSectors = 0; /* dummy */
6507 LogRel(("PIIX3 ATA: LUN#%d: CD/DVD, total number of sectors %Ld, passthrough %s\n", pIf->iLUN, pIf->cTotalSectors, (pIf->fATAPIPassthrough ? "enabled" : "disabled")));
6508 }
6509 else
6510 {
6511 pIf->cTotalSectors = pIf->pDrvMedia->pfnGetSize(pIf->pDrvMedia) / pIf->cbSector;
6512 rc = pIf->pDrvMedia->pfnBiosGetPCHSGeometry(pIf->pDrvMedia, &pIf->PCHSGeometry);
6513 if (rc == VERR_PDM_MEDIA_NOT_MOUNTED)
6514 {
6515 pIf->PCHSGeometry.cCylinders = 0;
6516 pIf->PCHSGeometry.cHeads = 16; /*??*/
6517 pIf->PCHSGeometry.cSectors = 63; /*??*/
6518 }
6519 else if (rc == VERR_PDM_GEOMETRY_NOT_SET)
6520 {
6521 pIf->PCHSGeometry.cCylinders = 0; /* autodetect marker */
6522 rc = VINF_SUCCESS;
6523 }
6524 AssertRC(rc);
6525
6526 if ( pIf->PCHSGeometry.cCylinders == 0
6527 || pIf->PCHSGeometry.cHeads == 0
6528 || pIf->PCHSGeometry.cSectors == 0
6529 )
6530 {
6531 uint64_t cCylinders = pIf->cTotalSectors / (16 * 63);
6532 pIf->PCHSGeometry.cCylinders = RT_MAX(RT_MIN(cCylinders, 16383), 1);
6533 pIf->PCHSGeometry.cHeads = 16;
6534 pIf->PCHSGeometry.cSectors = 63;
6535 /* Set the disk geometry information. Ignore errors. */
6536 pIf->pDrvMedia->pfnBiosSetPCHSGeometry(pIf->pDrvMedia, &pIf->PCHSGeometry);
6537 rc = VINF_SUCCESS;
6538 }
6539 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));
6540
6541 if (pIf->pDrvMedia->pfnDiscard)
6542 LogRel(("PIIX3 ATA: LUN#%d: TRIM enabled\n", pIf->iLUN));
6543 }
6544 return rc;
6545}
6546
6547
6548/**
6549 * Attach command.
6550 *
6551 * This is called when we change block driver for the DVD drive.
6552 *
6553 * @returns VBox status code.
6554 * @param pDevIns The device instance.
6555 * @param iLUN The logical unit which is being detached.
6556 * @param fFlags Flags, combination of the PDMDEVATT_FLAGS_* \#defines.
6557 */
6558static DECLCALLBACK(int) ataR3Attach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags)
6559{
6560 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
6561 PATACONTROLLER pCtl;
6562 ATADevState *pIf;
6563 int rc;
6564 unsigned iController;
6565 unsigned iInterface;
6566
6567 AssertMsgReturn(fFlags & PDM_TACH_FLAGS_NOT_HOT_PLUG,
6568 ("PIIX3IDE: Device does not support hotplugging\n"),
6569 VERR_INVALID_PARAMETER);
6570
6571 /*
6572 * Locate the controller and stuff.
6573 */
6574 iController = iLUN / RT_ELEMENTS(pThis->aCts[0].aIfs);
6575 AssertReleaseMsg(iController < RT_ELEMENTS(pThis->aCts), ("iController=%d iLUN=%d\n", iController, iLUN));
6576 pCtl = &pThis->aCts[iController];
6577
6578 iInterface = iLUN % RT_ELEMENTS(pThis->aCts[0].aIfs);
6579 pIf = &pCtl->aIfs[iInterface];
6580
6581 /* the usual paranoia */
6582 AssertRelease(!pIf->pDrvBase);
6583 AssertRelease(!pIf->pDrvMedia);
6584 Assert(ATADEVSTATE_2_CONTROLLER(pIf) == pCtl);
6585 Assert(pIf->iLUN == iLUN);
6586
6587 /*
6588 * Try attach the block device and get the interfaces,
6589 * required as well as optional.
6590 */
6591 rc = PDMDevHlpDriverAttach(pDevIns, pIf->iLUN, &pIf->IBase, &pIf->pDrvBase, NULL);
6592 if (RT_SUCCESS(rc))
6593 {
6594 rc = ataR3ConfigLun(pDevIns, pIf);
6595 /*
6596 * In case there is a medium inserted.
6597 */
6598 ataR3MediumInserted(pIf);
6599 ataR3MediumTypeSet(pIf, ATA_MEDIA_TYPE_UNKNOWN);
6600 }
6601 else
6602 AssertMsgFailed(("Failed to attach LUN#%d. rc=%Rrc\n", pIf->iLUN, rc));
6603
6604 if (RT_FAILURE(rc))
6605 {
6606 pIf->pDrvBase = NULL;
6607 pIf->pDrvMedia = NULL;
6608 }
6609 return rc;
6610}
6611
6612
6613/**
6614 * Resume notification.
6615 *
6616 * @returns VBox status code.
6617 * @param pDevIns The device instance data.
6618 */
6619static DECLCALLBACK(void) ataR3Resume(PPDMDEVINS pDevIns)
6620{
6621 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
6622 int rc;
6623
6624 Log(("%s:\n", __FUNCTION__));
6625 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
6626 {
6627 if (pThis->aCts[i].fRedo && pThis->aCts[i].fRedoIdle)
6628 {
6629 rc = RTSemEventSignal(pThis->aCts[i].SuspendIOSem);
6630 AssertRC(rc);
6631 }
6632 }
6633 return;
6634}
6635
6636
6637/**
6638 * Checks if all (both) the async I/O threads have quiesced.
6639 *
6640 * @returns true on success.
6641 * @returns false when one or more threads is still processing.
6642 * @param pThis Pointer to the instance data.
6643 */
6644static bool ataR3AllAsyncIOIsIdle(PPDMDEVINS pDevIns)
6645{
6646 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
6647
6648 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
6649 if (pThis->aCts[i].AsyncIOThread != NIL_RTTHREAD)
6650 {
6651 bool fRc = ataR3AsyncIOIsIdle(&pThis->aCts[i], false /*fStrict*/);
6652 if (!fRc)
6653 {
6654 /* Make it signal PDM & itself when its done */
6655 PDMCritSectEnter(&pThis->aCts[i].AsyncIORequestLock, VERR_IGNORED);
6656 ASMAtomicWriteBool(&pThis->aCts[i].fSignalIdle, true);
6657 PDMCritSectLeave(&pThis->aCts[i].AsyncIORequestLock);
6658
6659 fRc = ataR3AsyncIOIsIdle(&pThis->aCts[i], false /*fStrict*/);
6660 if (!fRc)
6661 {
6662#if 0 /** @todo Need to do some time tracking here... */
6663 LogRel(("PIIX3 ATA: Ctl#%u is still executing, DevSel=%d AIOIf=%d CmdIf0=%#04x CmdIf1=%#04x\n",
6664 i, pThis->aCts[i].iSelectedIf, pThis->aCts[i].iAIOIf,
6665 pThis->aCts[i].aIfs[0].uATARegCommand, pThis->aCts[i].aIfs[1].uATARegCommand));
6666#endif
6667 return false;
6668 }
6669 }
6670 ASMAtomicWriteBool(&pThis->aCts[i].fSignalIdle, false);
6671 }
6672 return true;
6673}
6674
6675/**
6676 * Prepare state save and load operation.
6677 *
6678 * @returns VBox status code.
6679 * @param pDevIns Device instance of the device which registered the data unit.
6680 * @param pSSM SSM operation handle.
6681 */
6682static DECLCALLBACK(int) ataR3SaveLoadPrep(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
6683{
6684 RT_NOREF1(pSSM);
6685 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
6686
6687 /* sanity - the suspend notification will wait on the async stuff. */
6688 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
6689 AssertLogRelMsgReturn(ataR3AsyncIOIsIdle(&pThis->aCts[i], false /*fStrict*/),
6690 ("i=%u\n", i),
6691 VERR_SSM_IDE_ASYNC_TIMEOUT);
6692 return VINF_SUCCESS;
6693}
6694
6695/**
6696 * @copydoc FNSSMDEVLIVEEXEC
6697 */
6698static DECLCALLBACK(int) ataR3LiveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uPass)
6699{
6700 RT_NOREF1(uPass);
6701 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
6702
6703 SSMR3PutU8(pSSM, pThis->u8Type);
6704 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
6705 {
6706 SSMR3PutBool(pSSM, true); /* For controller enabled / disabled. */
6707 for (uint32_t j = 0; j < RT_ELEMENTS(pThis->aCts[i].aIfs); j++)
6708 {
6709 SSMR3PutBool(pSSM, pThis->aCts[i].aIfs[j].pDrvBase != NULL);
6710 SSMR3PutStrZ(pSSM, pThis->aCts[i].aIfs[j].szSerialNumber);
6711 SSMR3PutStrZ(pSSM, pThis->aCts[i].aIfs[j].szFirmwareRevision);
6712 SSMR3PutStrZ(pSSM, pThis->aCts[i].aIfs[j].szModelNumber);
6713 }
6714 }
6715
6716 return VINF_SSM_DONT_CALL_AGAIN;
6717}
6718
6719/**
6720 * @copydoc FNSSMDEVSAVEEXEC
6721 */
6722static DECLCALLBACK(int) ataR3SaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
6723{
6724 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
6725
6726 ataR3LiveExec(pDevIns, pSSM, SSM_PASS_FINAL);
6727
6728 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
6729 {
6730 SSMR3PutU8(pSSM, pThis->aCts[i].iSelectedIf);
6731 SSMR3PutU8(pSSM, pThis->aCts[i].iAIOIf);
6732 SSMR3PutU8(pSSM, pThis->aCts[i].uAsyncIOState);
6733 SSMR3PutBool(pSSM, pThis->aCts[i].fChainedTransfer);
6734 SSMR3PutBool(pSSM, pThis->aCts[i].fReset);
6735 SSMR3PutBool(pSSM, pThis->aCts[i].fRedo);
6736 SSMR3PutBool(pSSM, pThis->aCts[i].fRedoIdle);
6737 SSMR3PutBool(pSSM, pThis->aCts[i].fRedoDMALastDesc);
6738 SSMR3PutMem(pSSM, &pThis->aCts[i].BmDma, sizeof(pThis->aCts[i].BmDma));
6739 SSMR3PutGCPhys32(pSSM, pThis->aCts[i].pFirstDMADesc);
6740 SSMR3PutGCPhys32(pSSM, pThis->aCts[i].pLastDMADesc);
6741 SSMR3PutGCPhys32(pSSM, pThis->aCts[i].pRedoDMABuffer);
6742 SSMR3PutU32(pSSM, pThis->aCts[i].cbRedoDMABuffer);
6743
6744 for (uint32_t j = 0; j < RT_ELEMENTS(pThis->aCts[i].aIfs); j++)
6745 {
6746 SSMR3PutBool(pSSM, pThis->aCts[i].aIfs[j].fLBA48);
6747 SSMR3PutBool(pSSM, pThis->aCts[i].aIfs[j].fATAPI);
6748 SSMR3PutBool(pSSM, pThis->aCts[i].aIfs[j].fIrqPending);
6749 SSMR3PutU8(pSSM, pThis->aCts[i].aIfs[j].cMultSectors);
6750 SSMR3PutU32(pSSM, pThis->aCts[i].aIfs[j].PCHSGeometry.cCylinders);
6751 SSMR3PutU32(pSSM, pThis->aCts[i].aIfs[j].PCHSGeometry.cHeads);
6752 SSMR3PutU32(pSSM, pThis->aCts[i].aIfs[j].PCHSGeometry.cSectors);
6753 SSMR3PutU32(pSSM, pThis->aCts[i].aIfs[j].cSectorsPerIRQ);
6754 SSMR3PutU64(pSSM, pThis->aCts[i].aIfs[j].cTotalSectors);
6755 SSMR3PutU8(pSSM, pThis->aCts[i].aIfs[j].uATARegFeature);
6756 SSMR3PutU8(pSSM, pThis->aCts[i].aIfs[j].uATARegFeatureHOB);
6757 SSMR3PutU8(pSSM, pThis->aCts[i].aIfs[j].uATARegError);
6758 SSMR3PutU8(pSSM, pThis->aCts[i].aIfs[j].uATARegNSector);
6759 SSMR3PutU8(pSSM, pThis->aCts[i].aIfs[j].uATARegNSectorHOB);
6760 SSMR3PutU8(pSSM, pThis->aCts[i].aIfs[j].uATARegSector);
6761 SSMR3PutU8(pSSM, pThis->aCts[i].aIfs[j].uATARegSectorHOB);
6762 SSMR3PutU8(pSSM, pThis->aCts[i].aIfs[j].uATARegLCyl);
6763 SSMR3PutU8(pSSM, pThis->aCts[i].aIfs[j].uATARegLCylHOB);
6764 SSMR3PutU8(pSSM, pThis->aCts[i].aIfs[j].uATARegHCyl);
6765 SSMR3PutU8(pSSM, pThis->aCts[i].aIfs[j].uATARegHCylHOB);
6766 SSMR3PutU8(pSSM, pThis->aCts[i].aIfs[j].uATARegSelect);
6767 SSMR3PutU8(pSSM, pThis->aCts[i].aIfs[j].uATARegStatus);
6768 SSMR3PutU8(pSSM, pThis->aCts[i].aIfs[j].uATARegCommand);
6769 SSMR3PutU8(pSSM, pThis->aCts[i].aIfs[j].uATARegDevCtl);
6770 SSMR3PutU8(pSSM, pThis->aCts[i].aIfs[j].uATATransferMode);
6771 SSMR3PutU8(pSSM, pThis->aCts[i].aIfs[j].uTxDir);
6772 SSMR3PutU8(pSSM, pThis->aCts[i].aIfs[j].iBeginTransfer);
6773 SSMR3PutU8(pSSM, pThis->aCts[i].aIfs[j].iSourceSink);
6774 SSMR3PutBool(pSSM, pThis->aCts[i].aIfs[j].fDMA);
6775 SSMR3PutBool(pSSM, pThis->aCts[i].aIfs[j].fATAPITransfer);
6776 SSMR3PutU32(pSSM, pThis->aCts[i].aIfs[j].cbTotalTransfer);
6777 SSMR3PutU32(pSSM, pThis->aCts[i].aIfs[j].cbElementaryTransfer);
6778 SSMR3PutU32(pSSM, pThis->aCts[i].aIfs[j].iIOBufferCur);
6779 SSMR3PutU32(pSSM, pThis->aCts[i].aIfs[j].iIOBufferEnd);
6780 SSMR3PutU32(pSSM, pThis->aCts[i].aIfs[j].iIOBufferPIODataStart);
6781 SSMR3PutU32(pSSM, pThis->aCts[i].aIfs[j].iIOBufferPIODataEnd);
6782 SSMR3PutU32(pSSM, pThis->aCts[i].aIfs[j].iATAPILBA);
6783 SSMR3PutU32(pSSM, pThis->aCts[i].aIfs[j].cbATAPISector);
6784 SSMR3PutMem(pSSM, &pThis->aCts[i].aIfs[j].aATAPICmd, sizeof(pThis->aCts[i].aIfs[j].aATAPICmd));
6785 SSMR3PutMem(pSSM, &pThis->aCts[i].aIfs[j].abATAPISense, sizeof(pThis->aCts[i].aIfs[j].abATAPISense));
6786 SSMR3PutU8(pSSM, pThis->aCts[i].aIfs[j].cNotifiedMediaChange);
6787 SSMR3PutU32(pSSM, pThis->aCts[i].aIfs[j].MediaEventStatus);
6788 SSMR3PutMem(pSSM, &pThis->aCts[i].aIfs[j].Led, sizeof(pThis->aCts[i].aIfs[j].Led));
6789 SSMR3PutU32(pSSM, pThis->aCts[i].aIfs[j].cbIOBuffer);
6790 if (pThis->aCts[i].aIfs[j].cbIOBuffer)
6791 SSMR3PutMem(pSSM, pThis->aCts[i].aIfs[j].CTX_SUFF(pbIOBuffer), pThis->aCts[i].aIfs[j].cbIOBuffer);
6792 else
6793 Assert(pThis->aCts[i].aIfs[j].CTX_SUFF(pbIOBuffer) == NULL);
6794 }
6795 }
6796
6797 return SSMR3PutU32(pSSM, UINT32_MAX); /* sanity/terminator */
6798}
6799
6800/**
6801 * Converts the LUN number into a message string.
6802 */
6803static const char *ataR3StringifyLun(unsigned iLun)
6804{
6805 switch (iLun)
6806 {
6807 case 0: return "primary master";
6808 case 1: return "primary slave";
6809 case 2: return "secondary master";
6810 case 3: return "secondary slave";
6811 default: AssertFailedReturn("unknown lun");
6812 }
6813}
6814
6815/**
6816 * FNSSMDEVLOADEXEC
6817 */
6818static DECLCALLBACK(int) ataR3LoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
6819{
6820 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
6821 int rc;
6822 uint32_t u32;
6823
6824 if ( uVersion != ATA_SAVED_STATE_VERSION
6825 && uVersion != ATA_SAVED_STATE_VERSION_VBOX_30
6826 && uVersion != ATA_SAVED_STATE_VERSION_WITHOUT_FULL_SENSE
6827 && uVersion != ATA_SAVED_STATE_VERSION_WITHOUT_EVENT_STATUS
6828 && uVersion != ATA_SAVED_STATE_VERSION_WITH_BOOL_TYPE)
6829 {
6830 AssertMsgFailed(("uVersion=%d\n", uVersion));
6831 return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
6832 }
6833
6834 /*
6835 * Verify the configuration.
6836 */
6837 if (uVersion > ATA_SAVED_STATE_VERSION_VBOX_30)
6838 {
6839 uint8_t u8Type;
6840 rc = SSMR3GetU8(pSSM, &u8Type);
6841 AssertRCReturn(rc, rc);
6842 if (u8Type != pThis->u8Type)
6843 return SSMR3SetCfgError(pSSM, RT_SRC_POS, N_("Config mismatch: u8Type - saved=%u config=%u"), u8Type, pThis->u8Type);
6844
6845 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
6846 {
6847 bool fEnabled;
6848 rc = SSMR3GetBool(pSSM, &fEnabled);
6849 AssertRCReturn(rc, rc);
6850 if (!fEnabled)
6851 return SSMR3SetCfgError(pSSM, RT_SRC_POS, N_("Ctr#%u onfig mismatch: fEnabled != true"), i);
6852
6853 for (uint32_t j = 0; j < RT_ELEMENTS(pThis->aCts[i].aIfs); j++)
6854 {
6855 ATADevState const *pIf = &pThis->aCts[i].aIfs[j];
6856
6857 bool fInUse;
6858 rc = SSMR3GetBool(pSSM, &fInUse);
6859 AssertRCReturn(rc, rc);
6860 if (fInUse != (pIf->pDrvBase != NULL))
6861 return SSMR3SetCfgError(pSSM, RT_SRC_POS,
6862 N_("The %s VM is missing a %s device. Please make sure the source and target VMs have compatible storage configurations"),
6863 fInUse ? "target" : "source", ataR3StringifyLun(pIf->iLUN) );
6864
6865 char szSerialNumber[ATA_SERIAL_NUMBER_LENGTH+1];
6866 rc = SSMR3GetStrZ(pSSM, szSerialNumber, sizeof(szSerialNumber));
6867 AssertRCReturn(rc, rc);
6868 if (strcmp(szSerialNumber, pIf->szSerialNumber))
6869 LogRel(("PIIX3 ATA: LUN#%u config mismatch: Serial number - saved='%s' config='%s'\n",
6870 pIf->iLUN, szSerialNumber, pIf->szSerialNumber));
6871
6872 char szFirmwareRevision[ATA_FIRMWARE_REVISION_LENGTH+1];
6873 rc = SSMR3GetStrZ(pSSM, szFirmwareRevision, sizeof(szFirmwareRevision));
6874 AssertRCReturn(rc, rc);
6875 if (strcmp(szFirmwareRevision, pIf->szFirmwareRevision))
6876 LogRel(("PIIX3 ATA: LUN#%u config mismatch: Firmware revision - saved='%s' config='%s'\n",
6877 pIf->iLUN, szFirmwareRevision, pIf->szFirmwareRevision));
6878
6879 char szModelNumber[ATA_MODEL_NUMBER_LENGTH+1];
6880 rc = SSMR3GetStrZ(pSSM, szModelNumber, sizeof(szModelNumber));
6881 AssertRCReturn(rc, rc);
6882 if (strcmp(szModelNumber, pIf->szModelNumber))
6883 LogRel(("PIIX3 ATA: LUN#%u config mismatch: Model number - saved='%s' config='%s'\n",
6884 pIf->iLUN, szModelNumber, pIf->szModelNumber));
6885 }
6886 }
6887 }
6888 if (uPass != SSM_PASS_FINAL)
6889 return VINF_SUCCESS;
6890
6891 /*
6892 * Restore valid parts of the PCIATAState structure
6893 */
6894 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
6895 {
6896 /* integrity check */
6897 if (!ataR3AsyncIOIsIdle(&pThis->aCts[i], false))
6898 {
6899 AssertMsgFailed(("Async I/O for controller %d is active\n", i));
6900 return VERR_INTERNAL_ERROR_4;
6901 }
6902
6903 SSMR3GetU8(pSSM, &pThis->aCts[i].iSelectedIf);
6904 SSMR3GetU8(pSSM, &pThis->aCts[i].iAIOIf);
6905 SSMR3GetU8(pSSM, &pThis->aCts[i].uAsyncIOState);
6906 SSMR3GetBool(pSSM, &pThis->aCts[i].fChainedTransfer);
6907 SSMR3GetBool(pSSM, (bool *)&pThis->aCts[i].fReset);
6908 SSMR3GetBool(pSSM, (bool *)&pThis->aCts[i].fRedo);
6909 SSMR3GetBool(pSSM, (bool *)&pThis->aCts[i].fRedoIdle);
6910 SSMR3GetBool(pSSM, (bool *)&pThis->aCts[i].fRedoDMALastDesc);
6911 SSMR3GetMem(pSSM, &pThis->aCts[i].BmDma, sizeof(pThis->aCts[i].BmDma));
6912 SSMR3GetGCPhys32(pSSM, &pThis->aCts[i].pFirstDMADesc);
6913 SSMR3GetGCPhys32(pSSM, &pThis->aCts[i].pLastDMADesc);
6914 SSMR3GetGCPhys32(pSSM, &pThis->aCts[i].pRedoDMABuffer);
6915 SSMR3GetU32(pSSM, &pThis->aCts[i].cbRedoDMABuffer);
6916
6917 for (uint32_t j = 0; j < RT_ELEMENTS(pThis->aCts[i].aIfs); j++)
6918 {
6919 SSMR3GetBool(pSSM, &pThis->aCts[i].aIfs[j].fLBA48);
6920 SSMR3GetBool(pSSM, &pThis->aCts[i].aIfs[j].fATAPI);
6921 SSMR3GetBool(pSSM, &pThis->aCts[i].aIfs[j].fIrqPending);
6922 SSMR3GetU8(pSSM, &pThis->aCts[i].aIfs[j].cMultSectors);
6923 SSMR3GetU32(pSSM, &pThis->aCts[i].aIfs[j].PCHSGeometry.cCylinders);
6924 SSMR3GetU32(pSSM, &pThis->aCts[i].aIfs[j].PCHSGeometry.cHeads);
6925 SSMR3GetU32(pSSM, &pThis->aCts[i].aIfs[j].PCHSGeometry.cSectors);
6926 SSMR3GetU32(pSSM, &pThis->aCts[i].aIfs[j].cSectorsPerIRQ);
6927 SSMR3GetU64(pSSM, &pThis->aCts[i].aIfs[j].cTotalSectors);
6928 SSMR3GetU8(pSSM, &pThis->aCts[i].aIfs[j].uATARegFeature);
6929 SSMR3GetU8(pSSM, &pThis->aCts[i].aIfs[j].uATARegFeatureHOB);
6930 SSMR3GetU8(pSSM, &pThis->aCts[i].aIfs[j].uATARegError);
6931 SSMR3GetU8(pSSM, &pThis->aCts[i].aIfs[j].uATARegNSector);
6932 SSMR3GetU8(pSSM, &pThis->aCts[i].aIfs[j].uATARegNSectorHOB);
6933 SSMR3GetU8(pSSM, &pThis->aCts[i].aIfs[j].uATARegSector);
6934 SSMR3GetU8(pSSM, &pThis->aCts[i].aIfs[j].uATARegSectorHOB);
6935 SSMR3GetU8(pSSM, &pThis->aCts[i].aIfs[j].uATARegLCyl);
6936 SSMR3GetU8(pSSM, &pThis->aCts[i].aIfs[j].uATARegLCylHOB);
6937 SSMR3GetU8(pSSM, &pThis->aCts[i].aIfs[j].uATARegHCyl);
6938 SSMR3GetU8(pSSM, &pThis->aCts[i].aIfs[j].uATARegHCylHOB);
6939 SSMR3GetU8(pSSM, &pThis->aCts[i].aIfs[j].uATARegSelect);
6940 SSMR3GetU8(pSSM, &pThis->aCts[i].aIfs[j].uATARegStatus);
6941 SSMR3GetU8(pSSM, &pThis->aCts[i].aIfs[j].uATARegCommand);
6942 SSMR3GetU8(pSSM, &pThis->aCts[i].aIfs[j].uATARegDevCtl);
6943 SSMR3GetU8(pSSM, &pThis->aCts[i].aIfs[j].uATATransferMode);
6944 SSMR3GetU8(pSSM, &pThis->aCts[i].aIfs[j].uTxDir);
6945 SSMR3GetU8(pSSM, &pThis->aCts[i].aIfs[j].iBeginTransfer);
6946 SSMR3GetU8(pSSM, &pThis->aCts[i].aIfs[j].iSourceSink);
6947 SSMR3GetBool(pSSM, &pThis->aCts[i].aIfs[j].fDMA);
6948 SSMR3GetBool(pSSM, &pThis->aCts[i].aIfs[j].fATAPITransfer);
6949 SSMR3GetU32(pSSM, &pThis->aCts[i].aIfs[j].cbTotalTransfer);
6950 SSMR3GetU32(pSSM, &pThis->aCts[i].aIfs[j].cbElementaryTransfer);
6951 /* NB: cbPIOTransferLimit could be saved/restored but it's sufficient
6952 * to re-calculate it here, with a tiny risk that it could be
6953 * unnecessarily low for the current transfer only. Could be changed
6954 * when changing the saved state in the future.
6955 */
6956 pThis->aCts[i].aIfs[j].cbPIOTransferLimit = (pThis->aCts[i].aIfs[j].uATARegHCyl << 8) | pThis->aCts[i].aIfs[j].uATARegLCyl;
6957 SSMR3GetU32(pSSM, &pThis->aCts[i].aIfs[j].iIOBufferCur);
6958 SSMR3GetU32(pSSM, &pThis->aCts[i].aIfs[j].iIOBufferEnd);
6959 SSMR3GetU32(pSSM, &pThis->aCts[i].aIfs[j].iIOBufferPIODataStart);
6960 SSMR3GetU32(pSSM, &pThis->aCts[i].aIfs[j].iIOBufferPIODataEnd);
6961 SSMR3GetU32(pSSM, &pThis->aCts[i].aIfs[j].iATAPILBA);
6962 SSMR3GetU32(pSSM, &pThis->aCts[i].aIfs[j].cbATAPISector);
6963 SSMR3GetMem(pSSM, &pThis->aCts[i].aIfs[j].aATAPICmd, sizeof(pThis->aCts[i].aIfs[j].aATAPICmd));
6964 if (uVersion > ATA_SAVED_STATE_VERSION_WITHOUT_FULL_SENSE)
6965 {
6966 SSMR3GetMem(pSSM, pThis->aCts[i].aIfs[j].abATAPISense, sizeof(pThis->aCts[i].aIfs[j].abATAPISense));
6967 }
6968 else
6969 {
6970 uint8_t uATAPISenseKey, uATAPIASC;
6971 memset(pThis->aCts[i].aIfs[j].abATAPISense, '\0', sizeof(pThis->aCts[i].aIfs[j].abATAPISense));
6972 pThis->aCts[i].aIfs[j].abATAPISense[0] = 0x70 | (1 << 7);
6973 pThis->aCts[i].aIfs[j].abATAPISense[7] = 10;
6974 SSMR3GetU8(pSSM, &uATAPISenseKey);
6975 SSMR3GetU8(pSSM, &uATAPIASC);
6976 pThis->aCts[i].aIfs[j].abATAPISense[2] = uATAPISenseKey & 0x0f;
6977 pThis->aCts[i].aIfs[j].abATAPISense[12] = uATAPIASC;
6978 }
6979 /** @todo triple-check this hack after passthrough is working */
6980 SSMR3GetU8(pSSM, &pThis->aCts[i].aIfs[j].cNotifiedMediaChange);
6981 if (uVersion > ATA_SAVED_STATE_VERSION_WITHOUT_EVENT_STATUS)
6982 SSMR3GetU32(pSSM, (uint32_t*)&pThis->aCts[i].aIfs[j].MediaEventStatus);
6983 else
6984 pThis->aCts[i].aIfs[j].MediaEventStatus = ATA_EVENT_STATUS_UNCHANGED;
6985 SSMR3GetMem(pSSM, &pThis->aCts[i].aIfs[j].Led, sizeof(pThis->aCts[i].aIfs[j].Led));
6986 SSMR3GetU32(pSSM, &pThis->aCts[i].aIfs[j].cbIOBuffer);
6987 if (pThis->aCts[i].aIfs[j].cbIOBuffer)
6988 {
6989 if (pThis->aCts[i].aIfs[j].CTX_SUFF(pbIOBuffer))
6990 SSMR3GetMem(pSSM, pThis->aCts[i].aIfs[j].CTX_SUFF(pbIOBuffer), pThis->aCts[i].aIfs[j].cbIOBuffer);
6991 else
6992 {
6993 LogRel(("ATA: No buffer for %d/%d\n", i, j));
6994 if (SSMR3HandleGetAfter(pSSM) != SSMAFTER_DEBUG_IT)
6995 return SSMR3SetCfgError(pSSM, RT_SRC_POS, N_("No buffer for %d/%d"), i, j);
6996
6997 /* skip the buffer if we're loading for the debugger / animator. */
6998 uint8_t u8Ignored;
6999 size_t cbLeft = pThis->aCts[i].aIfs[j].cbIOBuffer;
7000 while (cbLeft-- > 0)
7001 SSMR3GetU8(pSSM, &u8Ignored);
7002 }
7003 }
7004 else
7005 Assert(pThis->aCts[i].aIfs[j].CTX_SUFF(pbIOBuffer) == NULL);
7006 }
7007 }
7008 if (uVersion <= ATA_SAVED_STATE_VERSION_VBOX_30)
7009 SSMR3GetU8(pSSM, &pThis->u8Type);
7010
7011 rc = SSMR3GetU32(pSSM, &u32);
7012 if (RT_FAILURE(rc))
7013 return rc;
7014 if (u32 != ~0U)
7015 {
7016 AssertMsgFailed(("u32=%#x expected ~0\n", u32));
7017 rc = VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
7018 return rc;
7019 }
7020
7021 return VINF_SUCCESS;
7022}
7023
7024
7025/**
7026 * Callback employed by ataSuspend and ataR3PowerOff.
7027 *
7028 * @returns true if we've quiesced, false if we're still working.
7029 * @param pDevIns The device instance.
7030 */
7031static DECLCALLBACK(bool) ataR3IsAsyncSuspendOrPowerOffDone(PPDMDEVINS pDevIns)
7032{
7033 return ataR3AllAsyncIOIsIdle(pDevIns);
7034}
7035
7036
7037/**
7038 * Common worker for ataSuspend and ataR3PowerOff.
7039 */
7040static void ataR3SuspendOrPowerOff(PPDMDEVINS pDevIns)
7041{
7042 if (!ataR3AllAsyncIOIsIdle(pDevIns))
7043 PDMDevHlpSetAsyncNotification(pDevIns, ataR3IsAsyncSuspendOrPowerOffDone);
7044}
7045
7046
7047/**
7048 * Power Off notification.
7049 *
7050 * @returns VBox status code.
7051 * @param pDevIns The device instance data.
7052 */
7053static DECLCALLBACK(void) ataR3PowerOff(PPDMDEVINS pDevIns)
7054{
7055 Log(("%s:\n", __FUNCTION__));
7056 ataR3SuspendOrPowerOff(pDevIns);
7057}
7058
7059
7060/**
7061 * Suspend notification.
7062 *
7063 * @returns VBox status code.
7064 * @param pDevIns The device instance data.
7065 */
7066static DECLCALLBACK(void) ataR3Suspend(PPDMDEVINS pDevIns)
7067{
7068 Log(("%s:\n", __FUNCTION__));
7069 ataR3SuspendOrPowerOff(pDevIns);
7070}
7071
7072
7073/**
7074 * Callback employed by ataR3Reset.
7075 *
7076 * @returns true if we've quiesced, false if we're still working.
7077 * @param pDevIns The device instance.
7078 */
7079static DECLCALLBACK(bool) ataR3IsAsyncResetDone(PPDMDEVINS pDevIns)
7080{
7081 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
7082
7083 if (!ataR3AllAsyncIOIsIdle(pDevIns))
7084 return false;
7085
7086 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
7087 {
7088 PDMCritSectEnter(&pThis->aCts[i].lock, VERR_INTERNAL_ERROR);
7089 for (uint32_t j = 0; j < RT_ELEMENTS(pThis->aCts[i].aIfs); j++)
7090 ataR3ResetDevice(&pThis->aCts[i].aIfs[j]);
7091 PDMCritSectLeave(&pThis->aCts[i].lock);
7092 }
7093 return true;
7094}
7095
7096
7097/**
7098 * Common reset worker for ataR3Reset and ataR3Construct.
7099 *
7100 * @returns VBox status code.
7101 * @param pDevIns The device instance data.
7102 * @param fConstruct Indicates who is calling.
7103 */
7104static int ataR3ResetCommon(PPDMDEVINS pDevIns, bool fConstruct)
7105{
7106 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
7107
7108 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
7109 {
7110 PDMCritSectEnter(&pThis->aCts[i].lock, VERR_INTERNAL_ERROR);
7111
7112 pThis->aCts[i].iSelectedIf = 0;
7113 pThis->aCts[i].iAIOIf = 0;
7114 pThis->aCts[i].BmDma.u8Cmd = 0;
7115 /* Report that both drives present on the bus are in DMA mode. This
7116 * pretends that there is a BIOS that has set it up. Normal reset
7117 * default is 0x00. */
7118 pThis->aCts[i].BmDma.u8Status = (pThis->aCts[i].aIfs[0].pDrvBase != NULL ? BM_STATUS_D0DMA : 0)
7119 | (pThis->aCts[i].aIfs[1].pDrvBase != NULL ? BM_STATUS_D1DMA : 0);
7120 pThis->aCts[i].BmDma.pvAddr = 0;
7121
7122 pThis->aCts[i].fReset = true;
7123 pThis->aCts[i].fRedo = false;
7124 pThis->aCts[i].fRedoIdle = false;
7125 ataR3AsyncIOClearRequests(&pThis->aCts[i]);
7126 Log2(("%s: Ctl#%d: message to async I/O thread, reset controller\n", __FUNCTION__, i));
7127 ataHCAsyncIOPutRequest(&pThis->aCts[i], &g_ataResetARequest);
7128 ataHCAsyncIOPutRequest(&pThis->aCts[i], &g_ataResetCRequest);
7129
7130 PDMCritSectLeave(&pThis->aCts[i].lock);
7131 }
7132
7133 int rcRet = VINF_SUCCESS;
7134 if (!fConstruct)
7135 {
7136 /*
7137 * Setup asynchronous notification completion if the requests haven't
7138 * completed yet.
7139 */
7140 if (!ataR3IsAsyncResetDone(pDevIns))
7141 PDMDevHlpSetAsyncNotification(pDevIns, ataR3IsAsyncResetDone);
7142 }
7143 else
7144 {
7145 /*
7146 * Wait for the requests for complete.
7147 *
7148 * Would be real nice if we could do it all from EMT(0) and not
7149 * involve the worker threads, then we could dispense with all the
7150 * waiting and semaphore ping-pong here...
7151 */
7152 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
7153 {
7154 if (pThis->aCts[i].AsyncIOThread != NIL_RTTHREAD)
7155 {
7156 int rc = PDMCritSectEnter(&pThis->aCts[i].AsyncIORequestLock, VERR_IGNORED);
7157 AssertRC(rc);
7158
7159 ASMAtomicWriteBool(&pThis->aCts[i].fSignalIdle, true);
7160 rc = RTThreadUserReset(pThis->aCts[i].AsyncIOThread);
7161 AssertRC(rc);
7162
7163 rc = PDMCritSectLeave(&pThis->aCts[i].AsyncIORequestLock);
7164 AssertRC(rc);
7165
7166 if (!ataR3AsyncIOIsIdle(&pThis->aCts[i], false /*fStrict*/))
7167 {
7168 rc = RTThreadUserWait(pThis->aCts[i].AsyncIOThread, 30*1000 /*ms*/);
7169 if (RT_FAILURE(rc))
7170 rc = RTThreadUserWait(pThis->aCts[i].AsyncIOThread, 1000 /*ms*/);
7171 if (RT_FAILURE(rc))
7172 {
7173 AssertRC(rc);
7174 rcRet = rc;
7175 }
7176 }
7177 }
7178 ASMAtomicWriteBool(&pThis->aCts[i].fSignalIdle, false);
7179 }
7180 if (RT_SUCCESS(rcRet))
7181 {
7182 rcRet = ataR3IsAsyncResetDone(pDevIns) ? VINF_SUCCESS : VERR_INTERNAL_ERROR;
7183 AssertRC(rcRet);
7184 }
7185 }
7186 return rcRet;
7187}
7188
7189/**
7190 * Reset notification.
7191 *
7192 * @param pDevIns The device instance data.
7193 */
7194static DECLCALLBACK(void) ataR3Reset(PPDMDEVINS pDevIns)
7195{
7196 ataR3ResetCommon(pDevIns, false /*fConstruct*/);
7197}
7198
7199/**
7200 * @copydoc FNPDMDEVRELOCATE
7201 */
7202static DECLCALLBACK(void) ataR3Relocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta)
7203{
7204 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
7205
7206 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
7207 {
7208 pThis->aCts[i].pDevInsRC += offDelta;
7209 pThis->aCts[i].aIfs[0].pDevInsRC += offDelta;
7210 pThis->aCts[i].aIfs[0].pControllerRC += offDelta;
7211 ataR3RelocBuffer(pDevIns, &pThis->aCts[i].aIfs[0]);
7212 pThis->aCts[i].aIfs[1].pDevInsRC += offDelta;
7213 pThis->aCts[i].aIfs[1].pControllerRC += offDelta;
7214 ataR3RelocBuffer(pDevIns, &pThis->aCts[i].aIfs[1]);
7215 }
7216}
7217
7218/**
7219 * Destroy a driver instance.
7220 *
7221 * Most VM resources are freed by the VM. This callback is provided so that any non-VM
7222 * resources can be freed correctly.
7223 *
7224 * @param pDevIns The device instance data.
7225 */
7226static DECLCALLBACK(int) ataR3Destruct(PPDMDEVINS pDevIns)
7227{
7228 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
7229 int rc;
7230
7231 Log(("ataR3Destruct\n"));
7232 PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns);
7233
7234 /*
7235 * Tell the async I/O threads to terminate.
7236 */
7237 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
7238 {
7239 if (pThis->aCts[i].AsyncIOThread != NIL_RTTHREAD)
7240 {
7241 ASMAtomicWriteU32(&pThis->aCts[i].fShutdown, true);
7242 rc = SUPSemEventSignal(pThis->aCts[i].pSupDrvSession, pThis->aCts[i].hAsyncIOSem);
7243 AssertRC(rc);
7244 rc = RTSemEventSignal(pThis->aCts[i].SuspendIOSem);
7245 AssertRC(rc);
7246 }
7247 }
7248
7249 /*
7250 * Wait for the threads to terminate before destroying their resources.
7251 */
7252 for (unsigned i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
7253 {
7254 if (pThis->aCts[i].AsyncIOThread != NIL_RTTHREAD)
7255 {
7256 rc = RTThreadWait(pThis->aCts[i].AsyncIOThread, 30000 /* 30 s*/, NULL);
7257 if (RT_SUCCESS(rc))
7258 pThis->aCts[i].AsyncIOThread = NIL_RTTHREAD;
7259 else
7260 LogRel(("PIIX3 ATA Dtor: Ctl#%u is still executing, DevSel=%d AIOIf=%d CmdIf0=%#04x CmdIf1=%#04x rc=%Rrc\n",
7261 i, pThis->aCts[i].iSelectedIf, pThis->aCts[i].iAIOIf,
7262 pThis->aCts[i].aIfs[0].uATARegCommand, pThis->aCts[i].aIfs[1].uATARegCommand, rc));
7263 }
7264 }
7265
7266 /*
7267 * Free resources.
7268 */
7269 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
7270 {
7271 if (PDMCritSectIsInitialized(&pThis->aCts[i].AsyncIORequestLock))
7272 PDMR3CritSectDelete(&pThis->aCts[i].AsyncIORequestLock);
7273 if (pThis->aCts[i].hAsyncIOSem != NIL_SUPSEMEVENT)
7274 {
7275 SUPSemEventClose(pThis->aCts[i].pSupDrvSession, pThis->aCts[i].hAsyncIOSem);
7276 pThis->aCts[i].hAsyncIOSem = NIL_SUPSEMEVENT;
7277 }
7278 if (pThis->aCts[i].SuspendIOSem != NIL_RTSEMEVENT)
7279 {
7280 RTSemEventDestroy(pThis->aCts[i].SuspendIOSem);
7281 pThis->aCts[i].SuspendIOSem = NIL_RTSEMEVENT;
7282 }
7283
7284 /* try one final time */
7285 if (pThis->aCts[i].AsyncIOThread != NIL_RTTHREAD)
7286 {
7287 rc = RTThreadWait(pThis->aCts[i].AsyncIOThread, 1 /*ms*/, NULL);
7288 if (RT_SUCCESS(rc))
7289 {
7290 pThis->aCts[i].AsyncIOThread = NIL_RTTHREAD;
7291 LogRel(("PIIX3 ATA Dtor: Ctl#%u actually completed.\n", i));
7292 }
7293 }
7294
7295 for (uint32_t iIf = 0; iIf < RT_ELEMENTS(pThis->aCts[i].aIfs); iIf++)
7296 {
7297 if (pThis->aCts[i].aIfs[iIf].pTrackList)
7298 {
7299 ATAPIPassthroughTrackListDestroy(pThis->aCts[i].aIfs[iIf].pTrackList);
7300 pThis->aCts[i].aIfs[iIf].pTrackList = NULL;
7301 }
7302 }
7303 }
7304
7305 return VINF_SUCCESS;
7306}
7307
7308/**
7309 * Convert config value to DEVPCBIOSBOOT.
7310 *
7311 * @returns VBox status code.
7312 * @param pDevIns The device instance data.
7313 * @param pCfg Configuration handle.
7314 * @param penmChipset Where to store the chipset type.
7315 */
7316static int ataR3ControllerFromCfg(PPDMDEVINS pDevIns, PCFGMNODE pCfg, CHIPSET *penmChipset)
7317{
7318 char szType[20];
7319
7320 int rc = CFGMR3QueryStringDef(pCfg, "Type", &szType[0], sizeof(szType), "PIIX4");
7321 if (RT_FAILURE(rc))
7322 return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS,
7323 N_("Configuration error: Querying \"Type\" as a string failed"));
7324 if (!strcmp(szType, "PIIX3"))
7325 *penmChipset = CHIPSET_PIIX3;
7326 else if (!strcmp(szType, "PIIX4"))
7327 *penmChipset = CHIPSET_PIIX4;
7328 else if (!strcmp(szType, "ICH6"))
7329 *penmChipset = CHIPSET_ICH6;
7330 else
7331 {
7332 PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS,
7333 N_("Configuration error: The \"Type\" value \"%s\" is unknown"),
7334 szType);
7335 rc = VERR_INTERNAL_ERROR;
7336 }
7337 return rc;
7338}
7339
7340/**
7341 * @interface_method_impl{PDMDEVREG,pfnConstruct}
7342 */
7343static DECLCALLBACK(int) ataR3Construct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfg)
7344{
7345 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
7346 PPDMIBASE pBase;
7347 int rc;
7348 bool fRCEnabled;
7349 bool fR0Enabled;
7350 uint32_t DelayIRQMillies;
7351
7352 Assert(iInstance == 0);
7353 PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
7354
7355 /*
7356 * Initialize NIL handle values (for the destructor).
7357 */
7358 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
7359 {
7360 pThis->aCts[i].hAsyncIOSem = NIL_SUPSEMEVENT;
7361 pThis->aCts[i].SuspendIOSem = NIL_RTSEMEVENT;
7362 pThis->aCts[i].AsyncIOThread = NIL_RTTHREAD;
7363 }
7364
7365 /*
7366 * Validate and read configuration.
7367 */
7368 if (!CFGMR3AreValuesValid(pCfg,
7369 "GCEnabled\0"
7370 "R0Enabled\0"
7371 "IRQDelay\0"
7372 "Type\0")
7373 /** @todo || invalid keys */)
7374 return PDMDEV_SET_ERROR(pDevIns, VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES,
7375 N_("PIIX3 configuration error: unknown option specified"));
7376
7377 rc = CFGMR3QueryBoolDef(pCfg, "GCEnabled", &fRCEnabled, true);
7378 if (RT_FAILURE(rc))
7379 return PDMDEV_SET_ERROR(pDevIns, rc,
7380 N_("PIIX3 configuration error: failed to read GCEnabled as boolean"));
7381 Log(("%s: fRCEnabled=%d\n", __FUNCTION__, fRCEnabled));
7382
7383 rc = CFGMR3QueryBoolDef(pCfg, "R0Enabled", &fR0Enabled, true);
7384 if (RT_FAILURE(rc))
7385 return PDMDEV_SET_ERROR(pDevIns, rc,
7386 N_("PIIX3 configuration error: failed to read R0Enabled as boolean"));
7387 Log(("%s: fR0Enabled=%d\n", __FUNCTION__, fR0Enabled));
7388
7389 rc = CFGMR3QueryU32Def(pCfg, "IRQDelay", &DelayIRQMillies, 0);
7390 if (RT_FAILURE(rc))
7391 return PDMDEV_SET_ERROR(pDevIns, rc,
7392 N_("PIIX3 configuration error: failed to read IRQDelay as integer"));
7393 Log(("%s: DelayIRQMillies=%d\n", __FUNCTION__, DelayIRQMillies));
7394 Assert(DelayIRQMillies < 50);
7395
7396 CHIPSET enmChipset = CHIPSET_PIIX3;
7397 rc = ataR3ControllerFromCfg(pDevIns, pCfg, &enmChipset);
7398 if (RT_FAILURE(rc))
7399 return rc;
7400 pThis->u8Type = (uint8_t)enmChipset;
7401
7402 /*
7403 * Initialize data (most of it anyway).
7404 */
7405 /* Status LUN. */
7406 pThis->IBase.pfnQueryInterface = ataR3Status_QueryInterface;
7407 pThis->ILeds.pfnQueryStatusLed = ataR3Status_QueryStatusLed;
7408
7409 /* PCI configuration space. */
7410 PCIDevSetVendorId(&pThis->dev, 0x8086); /* Intel */
7411
7412 /*
7413 * When adding more IDE chipsets, don't forget to update pci_bios_init_device()
7414 * as it explicitly checks for PCI id for IDE controllers.
7415 */
7416 switch (pThis->u8Type)
7417 {
7418 case CHIPSET_ICH6:
7419 PCIDevSetDeviceId(&pThis->dev, 0x269e); /* ICH6 IDE */
7420 /** @todo: do we need it? Do we need anything else? */
7421 pThis->dev.config[0x48] = 0x00; /* UDMACTL */
7422 pThis->dev.config[0x4A] = 0x00; /* UDMATIM */
7423 pThis->dev.config[0x4B] = 0x00;
7424 {
7425 /*
7426 * See www.intel.com/Assets/PDF/manual/298600.pdf p. 30
7427 * Report
7428 * WR_Ping-Pong_EN: must be set
7429 * PCR0, PCR1: 80-pin primary cable reporting for both disks
7430 * SCR0, SCR1: 80-pin secondary cable reporting for both disks
7431 */
7432 uint16_t u16Config = (1<<10) | (1<<7) | (1<<6) | (1<<5) | (1<<4) ;
7433 pThis->dev.config[0x54] = u16Config & 0xff;
7434 pThis->dev.config[0x55] = u16Config >> 8;
7435 }
7436 break;
7437 case CHIPSET_PIIX4:
7438 PCIDevSetDeviceId(&pThis->dev, 0x7111); /* PIIX4 IDE */
7439 PCIDevSetRevisionId(&pThis->dev, 0x01); /* PIIX4E */
7440 pThis->dev.config[0x48] = 0x00; /* UDMACTL */
7441 pThis->dev.config[0x4A] = 0x00; /* UDMATIM */
7442 pThis->dev.config[0x4B] = 0x00;
7443 break;
7444 case CHIPSET_PIIX3:
7445 PCIDevSetDeviceId(&pThis->dev, 0x7010); /* PIIX3 IDE */
7446 break;
7447 default:
7448 AssertMsgFailed(("Unsupported IDE chipset type: %d\n", pThis->u8Type));
7449 }
7450
7451 PCIDevSetCommand( &pThis->dev, PCI_COMMAND_IOACCESS | PCI_COMMAND_MEMACCESS | PCI_COMMAND_BUSMASTER);
7452 PCIDevSetClassProg( &pThis->dev, 0x8a); /* programming interface = PCI_IDE bus master is supported */
7453 PCIDevSetClassSub( &pThis->dev, 0x01); /* class_sub = PCI_IDE */
7454 PCIDevSetClassBase( &pThis->dev, 0x01); /* class_base = PCI_mass_storage */
7455 PCIDevSetHeaderType(&pThis->dev, 0x00);
7456
7457 pThis->pDevIns = pDevIns;
7458 pThis->fRCEnabled = fRCEnabled;
7459 pThis->fR0Enabled = fR0Enabled;
7460 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
7461 {
7462 pThis->aCts[i].pDevInsR3 = pDevIns;
7463 pThis->aCts[i].pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
7464 pThis->aCts[i].pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
7465 pThis->aCts[i].DelayIRQMillies = (uint32_t)DelayIRQMillies;
7466 for (uint32_t j = 0; j < RT_ELEMENTS(pThis->aCts[i].aIfs); j++)
7467 {
7468 ATADevState *pIf = &pThis->aCts[i].aIfs[j];
7469
7470 pIf->iLUN = i * RT_ELEMENTS(pThis->aCts) + j;
7471 pIf->pDevInsR3 = pDevIns;
7472 pIf->pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
7473 pIf->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
7474 pIf->pControllerR3 = &pThis->aCts[i];
7475 pIf->pControllerR0 = MMHyperR3ToR0(PDMDevHlpGetVM(pDevIns), &pThis->aCts[i]);
7476 pIf->pControllerRC = MMHyperR3ToRC(PDMDevHlpGetVM(pDevIns), &pThis->aCts[i]);
7477 pIf->IBase.pfnQueryInterface = ataR3QueryInterface;
7478 pIf->IMountNotify.pfnMountNotify = ataR3MountNotify;
7479 pIf->IMountNotify.pfnUnmountNotify = ataR3UnmountNotify;
7480 pIf->IPort.pfnQueryDeviceLocation = ataR3QueryDeviceLocation;
7481 pIf->Led.u32Magic = PDMLED_MAGIC;
7482 }
7483 }
7484
7485 Assert(RT_ELEMENTS(pThis->aCts) == 2);
7486 pThis->aCts[0].irq = 14;
7487 pThis->aCts[0].IOPortBase1 = 0x1f0;
7488 pThis->aCts[0].IOPortBase2 = 0x3f6;
7489 pThis->aCts[1].irq = 15;
7490 pThis->aCts[1].IOPortBase1 = 0x170;
7491 pThis->aCts[1].IOPortBase2 = 0x376;
7492
7493 /*
7494 * Set the default critical section to NOP as we lock on controller level.
7495 */
7496 rc = PDMDevHlpSetDeviceCritSect(pDevIns, PDMDevHlpCritSectGetNop(pDevIns));
7497 AssertRCReturn(rc, rc);
7498
7499 /*
7500 * Register the PCI device.
7501 * N.B. There's a hack in the PIIX3 PCI bridge device to assign this
7502 * device the slot next to itself.
7503 */
7504 rc = PDMDevHlpPCIRegister(pDevIns, &pThis->dev);
7505 if (RT_FAILURE(rc))
7506 return PDMDEV_SET_ERROR(pDevIns, rc,
7507 N_("PIIX3 cannot register PCI device"));
7508 //AssertMsg(pThis->dev.devfn == 9 || iInstance != 0, ("pThis->dev.devfn=%d\n", pThis->dev.devfn));
7509 rc = PDMDevHlpPCIIORegionRegister(pDevIns, 4, 0x10, PCI_ADDRESS_SPACE_IO, ataR3BMDMAIORangeMap);
7510 if (RT_FAILURE(rc))
7511 return PDMDEV_SET_ERROR(pDevIns, rc,
7512 N_("PIIX3 cannot register PCI I/O region for BMDMA"));
7513
7514 /*
7515 * Register the I/O ports.
7516 * The ports are all hardcoded and enforced by the PIIX3 host bridge controller.
7517 */
7518 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
7519 {
7520 rc = PDMDevHlpIOPortRegister(pDevIns, pThis->aCts[i].IOPortBase1, 1, (RTHCPTR)(uintptr_t)i,
7521 ataIOPortWrite1Data, ataIOPortRead1Data,
7522 ataIOPortWriteStr1Data, ataIOPortReadStr1Data, "ATA I/O Base 1 - Data");
7523 AssertLogRelRCReturn(rc, rc);
7524 rc = PDMDevHlpIOPortRegister(pDevIns, pThis->aCts[i].IOPortBase1 + 1, 7, (RTHCPTR)(uintptr_t)i,
7525 ataIOPortWrite1Other, ataIOPortRead1Other, NULL, NULL, "ATA I/O Base 1 - Other");
7526
7527 AssertLogRelRCReturn(rc, rc);
7528 if (fRCEnabled)
7529 {
7530 rc = PDMDevHlpIOPortRegisterRC(pDevIns, pThis->aCts[i].IOPortBase1, 1, (RTGCPTR)i,
7531 "ataIOPortWrite1Data", "ataIOPortRead1Data",
7532 "ataIOPortWriteStr1Data", "ataIOPortReadStr1Data", "ATA I/O Base 1 - Data");
7533 AssertLogRelRCReturn(rc, rc);
7534 rc = PDMDevHlpIOPortRegisterRC(pDevIns, pThis->aCts[i].IOPortBase1 + 1, 7, (RTGCPTR)i,
7535 "ataIOPortWrite1Other", "ataIOPortRead1Other", NULL, NULL, "ATA I/O Base 1 - Other");
7536 AssertLogRelRCReturn(rc, rc);
7537 }
7538
7539 if (fR0Enabled)
7540 {
7541#if 0
7542 rc = PDMDevHlpIOPortRegisterR0(pDevIns, pThis->aCts[i].IOPortBase1, 1, (RTR0PTR)i,
7543 "ataIOPortWrite1Data", "ataIOPortRead1Data", NULL, NULL, "ATA I/O Base 1 - Data");
7544#else
7545 rc = PDMDevHlpIOPortRegisterR0(pDevIns, pThis->aCts[i].IOPortBase1, 1, (RTR0PTR)i,
7546 "ataIOPortWrite1Data", "ataIOPortRead1Data",
7547 "ataIOPortWriteStr1Data", "ataIOPortReadStr1Data", "ATA I/O Base 1 - Data");
7548#endif
7549 AssertLogRelRCReturn(rc, rc);
7550 rc = PDMDevHlpIOPortRegisterR0(pDevIns, pThis->aCts[i].IOPortBase1 + 1, 7, (RTR0PTR)i,
7551 "ataIOPortWrite1Other", "ataIOPortRead1Other", NULL, NULL, "ATA I/O Base 1 - Other");
7552 AssertLogRelRCReturn(rc, rc);
7553 }
7554
7555 rc = PDMDevHlpIOPortRegister(pDevIns, pThis->aCts[i].IOPortBase2, 1, (RTHCPTR)(uintptr_t)i,
7556 ataIOPortWrite2, ataIOPortRead2, NULL, NULL, "ATA I/O Base 2");
7557 if (RT_FAILURE(rc))
7558 return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot register base2 I/O handlers"));
7559
7560 if (fRCEnabled)
7561 {
7562 rc = PDMDevHlpIOPortRegisterRC(pDevIns, pThis->aCts[i].IOPortBase2, 1, (RTGCPTR)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 (GC)"));
7566 }
7567 if (fR0Enabled)
7568 {
7569 rc = PDMDevHlpIOPortRegisterR0(pDevIns, pThis->aCts[i].IOPortBase2, 1, (RTR0PTR)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 (R0)"));
7573 }
7574
7575 for (uint32_t j = 0; j < RT_ELEMENTS(pThis->aCts[i].aIfs); j++)
7576 {
7577 ATADevState *pIf = &pThis->aCts[i].aIfs[j];
7578 PDMDevHlpSTAMRegisterF(pDevIns, &pIf->StatATADMA, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,
7579 "Number of ATA DMA transfers.", "/Devices/IDE%d/ATA%d/Unit%d/DMA", iInstance, i, j);
7580 PDMDevHlpSTAMRegisterF(pDevIns, &pIf->StatATAPIO, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,
7581 "Number of ATA PIO transfers.", "/Devices/IDE%d/ATA%d/Unit%d/PIO", iInstance, i, j);
7582 PDMDevHlpSTAMRegisterF(pDevIns, &pIf->StatATAPIDMA, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,
7583 "Number of ATAPI DMA transfers.", "/Devices/IDE%d/ATA%d/Unit%d/AtapiDMA", iInstance, i, j);
7584 PDMDevHlpSTAMRegisterF(pDevIns, &pIf->StatATAPIPIO, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,
7585 "Number of ATAPI PIO transfers.", "/Devices/IDE%d/ATA%d/Unit%d/AtapiPIO", iInstance, i, j);
7586#ifdef VBOX_WITH_STATISTICS /** @todo release too. */
7587 PDMDevHlpSTAMRegisterF(pDevIns, &pIf->StatReads, STAMTYPE_PROFILE_ADV, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL,
7588 "Profiling of the read operations.", "/Devices/IDE%d/ATA%d/Unit%d/Reads", iInstance, i, j);
7589#endif
7590 PDMDevHlpSTAMRegisterF(pDevIns, &pIf->StatBytesRead, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES,
7591 "Amount of data read.", "/Devices/IDE%d/ATA%d/Unit%d/ReadBytes", iInstance, i, j);
7592#ifdef VBOX_INSTRUMENT_DMA_WRITES
7593 PDMDevHlpSTAMRegisterF(pDevIns, &pIf->StatInstrVDWrites,STAMTYPE_PROFILE_ADV, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL,
7594 "Profiling of the VD DMA write operations.", "/Devices/IDE%d/ATA%d/Unit%d/InstrVDWrites", iInstance, i, j);
7595#endif
7596#ifdef VBOX_WITH_STATISTICS
7597 PDMDevHlpSTAMRegisterF(pDevIns, &pIf->StatWrites, STAMTYPE_PROFILE_ADV, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL,
7598 "Profiling of the write operations.", "/Devices/IDE%d/ATA%d/Unit%d/Writes", iInstance, i, j);
7599#endif
7600 PDMDevHlpSTAMRegisterF(pDevIns, &pIf->StatBytesWritten, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES,
7601 "Amount of data written.", "/Devices/IDE%d/ATA%d/Unit%d/WrittenBytes", iInstance, i, j);
7602#ifdef VBOX_WITH_STATISTICS
7603 PDMDevHlpSTAMRegisterF(pDevIns, &pIf->StatFlushes, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL,
7604 "Profiling of the flush operations.", "/Devices/IDE%d/ATA%d/Unit%d/Flushes", iInstance, i, j);
7605#endif
7606 }
7607#ifdef VBOX_WITH_STATISTICS /** @todo release too. */
7608 PDMDevHlpSTAMRegisterF(pDevIns, &pThis->aCts[i].StatAsyncOps, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,
7609 "The number of async operations.", "/Devices/IDE%d/ATA%d/Async/Operations", iInstance, i);
7610 /** @todo STAMUNIT_MICROSECS */
7611 PDMDevHlpSTAMRegisterF(pDevIns, &pThis->aCts[i].StatAsyncMinWait, STAMTYPE_U64_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_NONE,
7612 "Minimum wait in microseconds.", "/Devices/IDE%d/ATA%d/Async/MinWait", iInstance, i);
7613 PDMDevHlpSTAMRegisterF(pDevIns, &pThis->aCts[i].StatAsyncMaxWait, STAMTYPE_U64_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_NONE,
7614 "Maximum wait in microseconds.", "/Devices/IDE%d/ATA%d/Async/MaxWait", iInstance, i);
7615 PDMDevHlpSTAMRegisterF(pDevIns, &pThis->aCts[i].StatAsyncTimeUS, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_NONE,
7616 "Total time spent in microseconds.", "/Devices/IDE%d/ATA%d/Async/TotalTimeUS", iInstance, i);
7617 PDMDevHlpSTAMRegisterF(pDevIns, &pThis->aCts[i].StatAsyncTime, STAMTYPE_PROFILE_ADV, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL,
7618 "Profiling of async operations.", "/Devices/IDE%d/ATA%d/Async/Time", iInstance, i);
7619 PDMDevHlpSTAMRegisterF(pDevIns, &pThis->aCts[i].StatLockWait, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL,
7620 "Profiling of locks.", "/Devices/IDE%d/ATA%d/Async/LockWait", iInstance, i);
7621#endif /* VBOX_WITH_STATISTICS */
7622
7623 /* Initialize per-controller critical section. */
7624 rc = PDMDevHlpCritSectInit(pDevIns, &pThis->aCts[i].lock, RT_SRC_POS, "ATA#%u-Ctl", i);
7625 AssertLogRelRCReturn(rc, rc);
7626
7627 /* Initialize per-controller async I/O request critical section. */
7628 rc = PDMDevHlpCritSectInit(pDevIns, &pThis->aCts[i].AsyncIORequestLock, RT_SRC_POS, "ATA#%u-Req", i);
7629 AssertLogRelRCReturn(rc, rc);
7630 }
7631
7632 /*
7633 * Attach status driver (optional).
7634 */
7635 rc = PDMDevHlpDriverAttach(pDevIns, PDM_STATUS_LUN, &pThis->IBase, &pBase, "Status Port");
7636 if (RT_SUCCESS(rc))
7637 {
7638 pThis->pLedsConnector = PDMIBASE_QUERY_INTERFACE(pBase, PDMILEDCONNECTORS);
7639 pThis->pMediaNotify = PDMIBASE_QUERY_INTERFACE(pBase, PDMIMEDIANOTIFY);
7640 }
7641 else if (rc != VERR_PDM_NO_ATTACHED_DRIVER)
7642 {
7643 AssertMsgFailed(("Failed to attach to status driver. rc=%Rrc\n", rc));
7644 return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot attach to status driver"));
7645 }
7646
7647 /*
7648 * Attach the units.
7649 */
7650 uint32_t cbTotalBuffer = 0;
7651 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
7652 {
7653 PATACONTROLLER pCtl = &pThis->aCts[i];
7654
7655 /*
7656 * Start the worker thread.
7657 */
7658 pCtl->uAsyncIOState = ATA_AIO_NEW;
7659 pCtl->pSupDrvSession = PDMDevHlpGetSupDrvSession(pDevIns);
7660 rc = SUPSemEventCreate(pCtl->pSupDrvSession, &pCtl->hAsyncIOSem);
7661 AssertLogRelRCReturn(rc, rc);
7662 rc = RTSemEventCreate(&pCtl->SuspendIOSem);
7663 AssertLogRelRCReturn(rc, rc);
7664
7665 ataR3AsyncIOClearRequests(pCtl);
7666 rc = RTThreadCreateF(&pCtl->AsyncIOThread, ataR3AsyncIOThread, (void *)pCtl, 128*1024 /*cbStack*/,
7667 RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, "ATA-%u", i);
7668 AssertLogRelRCReturn(rc, rc);
7669 Assert( pCtl->AsyncIOThread != NIL_RTTHREAD && pCtl->hAsyncIOSem != NIL_SUPSEMEVENT
7670 && pCtl->SuspendIOSem != NIL_RTSEMEVENT && PDMCritSectIsInitialized(&pCtl->AsyncIORequestLock));
7671 Log(("%s: controller %d AIO thread id %#x; sem %p susp_sem %p\n", __FUNCTION__, i, pCtl->AsyncIOThread, pCtl->hAsyncIOSem, pCtl->SuspendIOSem));
7672
7673 for (uint32_t j = 0; j < RT_ELEMENTS(pCtl->aIfs); j++)
7674 {
7675 static const char *s_apszDescs[RT_ELEMENTS(pThis->aCts)][RT_ELEMENTS(pCtl->aIfs)] =
7676 {
7677 { "Primary Master", "Primary Slave" },
7678 { "Secondary Master", "Secondary Slave" }
7679 };
7680
7681 /*
7682 * Try attach the block device and get the interfaces,
7683 * required as well as optional.
7684 */
7685 ATADevState *pIf = &pCtl->aIfs[j];
7686
7687 rc = PDMDevHlpDriverAttach(pDevIns, pIf->iLUN, &pIf->IBase, &pIf->pDrvBase, s_apszDescs[i][j]);
7688 if (RT_SUCCESS(rc))
7689 {
7690 rc = ataR3ConfigLun(pDevIns, pIf);
7691 if (RT_SUCCESS(rc))
7692 {
7693 /*
7694 * Init vendor product data.
7695 */
7696 static const char *s_apszCFGMKeys[RT_ELEMENTS(pThis->aCts)][RT_ELEMENTS(pCtl->aIfs)] =
7697 {
7698 { "PrimaryMaster", "PrimarySlave" },
7699 { "SecondaryMaster", "SecondarySlave" }
7700 };
7701
7702 /* Generate a default serial number. */
7703 char szSerial[ATA_SERIAL_NUMBER_LENGTH+1];
7704 RTUUID Uuid;
7705 if (pIf->pDrvMedia)
7706 rc = pIf->pDrvMedia->pfnGetUuid(pIf->pDrvMedia, &Uuid);
7707 else
7708 RTUuidClear(&Uuid);
7709
7710 if (RT_FAILURE(rc) || RTUuidIsNull(&Uuid))
7711 {
7712 /* Generate a predictable serial for drives which don't have a UUID. */
7713 RTStrPrintf(szSerial, sizeof(szSerial), "VB%x-%04x%04x",
7714 pIf->iLUN + pDevIns->iInstance * 32,
7715 pThis->aCts[i].IOPortBase1, pThis->aCts[i].IOPortBase2);
7716 }
7717 else
7718 RTStrPrintf(szSerial, sizeof(szSerial), "VB%08x-%08x", Uuid.au32[0], Uuid.au32[3]);
7719
7720 /* Get user config if present using defaults otherwise. */
7721 PCFGMNODE pCfgNode = CFGMR3GetChild(pCfg, s_apszCFGMKeys[i][j]);
7722 rc = CFGMR3QueryStringDef(pCfgNode, "SerialNumber", pIf->szSerialNumber, sizeof(pIf->szSerialNumber),
7723 szSerial);
7724 if (RT_FAILURE(rc))
7725 {
7726 if (rc == VERR_CFGM_NOT_ENOUGH_SPACE)
7727 return PDMDEV_SET_ERROR(pDevIns, VERR_INVALID_PARAMETER,
7728 N_("PIIX3 configuration error: \"SerialNumber\" is longer than 20 bytes"));
7729 return PDMDEV_SET_ERROR(pDevIns, rc,
7730 N_("PIIX3 configuration error: failed to read \"SerialNumber\" as string"));
7731 }
7732
7733 rc = CFGMR3QueryStringDef(pCfgNode, "FirmwareRevision", pIf->szFirmwareRevision, sizeof(pIf->szFirmwareRevision),
7734 "1.0");
7735 if (RT_FAILURE(rc))
7736 {
7737 if (rc == VERR_CFGM_NOT_ENOUGH_SPACE)
7738 return PDMDEV_SET_ERROR(pDevIns, VERR_INVALID_PARAMETER,
7739 N_("PIIX3 configuration error: \"FirmwareRevision\" is longer than 8 bytes"));
7740 return PDMDEV_SET_ERROR(pDevIns, rc,
7741 N_("PIIX3 configuration error: failed to read \"FirmwareRevision\" as string"));
7742 }
7743
7744 rc = CFGMR3QueryStringDef(pCfgNode, "ModelNumber", pIf->szModelNumber, sizeof(pIf->szModelNumber),
7745 pIf->fATAPI ? "VBOX CD-ROM" : "VBOX HARDDISK");
7746 if (RT_FAILURE(rc))
7747 {
7748 if (rc == VERR_CFGM_NOT_ENOUGH_SPACE)
7749 return PDMDEV_SET_ERROR(pDevIns, VERR_INVALID_PARAMETER,
7750 N_("PIIX3 configuration error: \"ModelNumber\" is longer than 40 bytes"));
7751 return PDMDEV_SET_ERROR(pDevIns, rc,
7752 N_("PIIX3 configuration error: failed to read \"ModelNumber\" as string"));
7753 }
7754
7755 rc = CFGMR3QueryBoolDef(pCfgNode, "NonRotationalMedium", &pIf->fNonRotational, false);
7756 if (RT_FAILURE(rc))
7757 return PDMDEV_SET_ERROR(pDevIns, rc,
7758 N_("PIIX3 configuration error: failed to read \"NonRotationalMedium\" as boolean"));
7759
7760 /* There are three other identification strings for CD drives used for INQUIRY */
7761 if (pIf->fATAPI)
7762 {
7763 rc = CFGMR3QueryStringDef(pCfgNode, "ATAPIVendorId", pIf->szInquiryVendorId, sizeof(pIf->szInquiryVendorId),
7764 "VBOX");
7765 if (RT_FAILURE(rc))
7766 {
7767 if (rc == VERR_CFGM_NOT_ENOUGH_SPACE)
7768 return PDMDEV_SET_ERROR(pDevIns, VERR_INVALID_PARAMETER,
7769 N_("PIIX3 configuration error: \"ATAPIVendorId\" is longer than 16 bytes"));
7770 return PDMDEV_SET_ERROR(pDevIns, rc,
7771 N_("PIIX3 configuration error: failed to read \"ATAPIVendorId\" as string"));
7772 }
7773
7774 rc = CFGMR3QueryStringDef(pCfgNode, "ATAPIProductId", pIf->szInquiryProductId, sizeof(pIf->szInquiryProductId),
7775 "CD-ROM");
7776 if (RT_FAILURE(rc))
7777 {
7778 if (rc == VERR_CFGM_NOT_ENOUGH_SPACE)
7779 return PDMDEV_SET_ERROR(pDevIns, VERR_INVALID_PARAMETER,
7780 N_("PIIX3 configuration error: \"ATAPIProductId\" is longer than 16 bytes"));
7781 return PDMDEV_SET_ERROR(pDevIns, rc,
7782 N_("PIIX3 configuration error: failed to read \"ATAPIProductId\" as string"));
7783 }
7784
7785 rc = CFGMR3QueryStringDef(pCfgNode, "ATAPIRevision", pIf->szInquiryRevision, sizeof(pIf->szInquiryRevision),
7786 "1.0");
7787 if (RT_FAILURE(rc))
7788 {
7789 if (rc == VERR_CFGM_NOT_ENOUGH_SPACE)
7790 return PDMDEV_SET_ERROR(pDevIns, VERR_INVALID_PARAMETER,
7791 N_("PIIX3 configuration error: \"ATAPIRevision\" is longer than 4 bytes"));
7792 return PDMDEV_SET_ERROR(pDevIns, rc,
7793 N_("PIIX3 configuration error: failed to read \"ATAPIRevision\" as string"));
7794 }
7795
7796 rc = CFGMR3QueryBoolDef(pCfgNode, "OverwriteInquiry", &pIf->fOverwriteInquiry, true);
7797 if (RT_FAILURE(rc))
7798 return PDMDEV_SET_ERROR(pDevIns, rc,
7799 N_("PIIX3 configuration error: failed to read \"OverwriteInquiry\" as boolean"));
7800 }
7801 }
7802
7803 }
7804 else if (rc == VERR_PDM_NO_ATTACHED_DRIVER)
7805 {
7806 pIf->pDrvBase = NULL;
7807 pIf->pDrvMedia = NULL;
7808 pIf->cbIOBuffer = 0;
7809 pIf->pbIOBufferR3 = NULL;
7810 pIf->pbIOBufferR0 = NIL_RTR0PTR;
7811 pIf->pbIOBufferRC = NIL_RTGCPTR;
7812 LogRel(("PIIX3 ATA: LUN#%d: no unit\n", pIf->iLUN));
7813 }
7814 else
7815 {
7816 switch (rc)
7817 {
7818 case VERR_ACCESS_DENIED:
7819 /* Error already cached by DrvHostBase */
7820 return rc;
7821 default:
7822 return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS,
7823 N_("PIIX3 cannot attach drive to the %s"),
7824 s_apszDescs[i][j]);
7825 }
7826 }
7827 cbTotalBuffer += pIf->cbIOBuffer;
7828 }
7829 }
7830
7831 rc = PDMDevHlpSSMRegisterEx(pDevIns, ATA_SAVED_STATE_VERSION, sizeof(*pThis) + cbTotalBuffer, NULL,
7832 NULL, ataR3LiveExec, NULL,
7833 ataR3SaveLoadPrep, ataR3SaveExec, NULL,
7834 ataR3SaveLoadPrep, ataR3LoadExec, NULL);
7835 if (RT_FAILURE(rc))
7836 return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot register save state handlers"));
7837
7838 /*
7839 * Initialize the device state.
7840 */
7841 return ataR3ResetCommon(pDevIns, true /*fConstruct*/);
7842}
7843
7844
7845/**
7846 * The device registration structure.
7847 */
7848const PDMDEVREG g_DevicePIIX3IDE =
7849{
7850 /* u32Version */
7851 PDM_DEVREG_VERSION,
7852 /* szName */
7853 "piix3ide",
7854 /* szRCMod */
7855 "VBoxDDRC.rc",
7856 /* szR0Mod */
7857 "VBoxDDR0.r0",
7858 /* pszDescription */
7859 "Intel PIIX3 ATA controller.\n"
7860 " LUN #0 is primary master.\n"
7861 " LUN #1 is primary slave.\n"
7862 " LUN #2 is secondary master.\n"
7863 " LUN #3 is secondary slave.\n"
7864 " LUN #999 is the LED/Status connector.",
7865 /* fFlags */
7866 PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0 |
7867 PDM_DEVREG_FLAGS_FIRST_SUSPEND_NOTIFICATION | PDM_DEVREG_FLAGS_FIRST_POWEROFF_NOTIFICATION |
7868 PDM_DEVREG_FLAGS_FIRST_RESET_NOTIFICATION,
7869 /* fClass */
7870 PDM_DEVREG_CLASS_STORAGE,
7871 /* cMaxInstances */
7872 1,
7873 /* cbInstance */
7874 sizeof(PCIATAState),
7875 /* pfnConstruct */
7876 ataR3Construct,
7877 /* pfnDestruct */
7878 ataR3Destruct,
7879 /* pfnRelocate */
7880 ataR3Relocate,
7881 /* pfnMemSetup */
7882 NULL,
7883 /* pfnPowerOn */
7884 NULL,
7885 /* pfnReset */
7886 ataR3Reset,
7887 /* pfnSuspend */
7888 ataR3Suspend,
7889 /* pfnResume */
7890 ataR3Resume,
7891 /* pfnAttach */
7892 ataR3Attach,
7893 /* pfnDetach */
7894 ataR3Detach,
7895 /* pfnQueryInterface. */
7896 NULL,
7897 /* pfnInitComplete */
7898 NULL,
7899 /* pfnPowerOff */
7900 ataR3PowerOff,
7901 /* pfnSoftReset */
7902 NULL,
7903 /* u32VersionEnd */
7904 PDM_DEVREG_VERSION
7905};
7906#endif /* IN_RING3 */
7907#endif /* !VBOX_DEVICE_STRUCT_TESTCASE */
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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