VirtualBox

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

Last change on this file since 17995 was 17947, checked in by vboxsync, 16 years ago

ATA: create correct header for raw sector, according to the spec, fixed writing behind buffer boundaries.

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