VirtualBox

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

Last change on this file since 2833 was 2826, checked in by vboxsync, 18 years ago

Yield CPU on drive busy, even in guest context. This reduces the CPU
load, but doesn't really solve any timing problems.

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

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