VirtualBox

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

Last change on this file since 24741 was 24741, checked in by vboxsync, 15 years ago

DevATA: Use the async notification handling.

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