VirtualBox

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

Last change on this file since 59248 was 59248, checked in by vboxsync, 9 years ago

Storage: Get rid of the block driver and merge the the little extra functionality it had into the VD driver. Enables us to get rid of PDMIBLOCK which is basically a subset of PDMIMEDIA and makes changes to the latter interface tedious because it had to be replicated in the former. (bugref:4114)

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

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