VirtualBox

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

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

Only detect geometry via the partition table if invalid CHS is set.

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

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