VirtualBox

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

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

DevATA: Save and load+verify config. New saved state version.

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

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