VirtualBox

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

Last change on this file since 6062 was 6062, checked in by vboxsync, 17 years ago

ATA: Fix status value for EXECUTE DEVICE DIAGNOSTICS command, should
mark drive as ready for non-ATAPI devices.

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