VirtualBox

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

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

64-bit alignment. Klaus, could you quickly verify that I didn't break anything in the saved state here...

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 218.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 request type of 0 or 1 only, and only starting feature 0. */
1927 if (((s->aATAPICmd[1] & 0x03) != 0 && (s->aATAPICmd[1] & 0x03) != 1) || 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, 12);
1934 ataH2BE_U16(pbBuf + 6, 8); /* current profile: cd-rom read-only */
1935
1936 ataH2BE_U16(pbBuf + 8, 0); /* feature 0: list of profiles supported */
1937 pbBuf[10] = (0 << 2) | (1 << 1) | (1 || 0); /* version 0, persistent, current */
1938 pbBuf[11] = 4; /* additional bytes for profiles */
1939 ataH2BE_U16(pbBuf + 12, 8); /* profile: cd-rom read-only */
1940 pbBuf[14] = (1 << 0); /* current profile */
1941 s->iSourceSink = ATAFN_SS_NULL;
1942 atapiCmdOK(s);
1943 return false;
1944}
1945
1946
1947static bool atapiInquirySS(ATADevState *s)
1948{
1949 uint8_t *pbBuf = s->CTXSUFF(pbIOBuffer);
1950
1951 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
1952 Assert(s->cbElementaryTransfer <= 36);
1953 pbBuf[0] = 0x05; /* CD-ROM */
1954 pbBuf[1] = 0x80; /* removable */
1955#if 1/*ndef VBOX*/ /** @todo implement MESN + AENC. (async notification on removal and stuff.) */
1956 pbBuf[2] = 0x00; /* ISO */
1957 pbBuf[3] = 0x21; /* ATAPI-2 (XXX: put ATAPI-4 ?) */
1958#else
1959 pbBuf[2] = 0x00; /* ISO */
1960 pbBuf[3] = 0x91; /* format 1, MESN=1, AENC=9 ??? */
1961#endif
1962 pbBuf[4] = 31; /* additional length */
1963 pbBuf[5] = 0; /* reserved */
1964 pbBuf[6] = 0; /* reserved */
1965 pbBuf[7] = 0; /* reserved */
1966 ataSCSIPadStr(pbBuf + 8, "VBOX", 8);
1967 ataSCSIPadStr(pbBuf + 16, "CD-ROM", 16);
1968 ataSCSIPadStr(pbBuf + 32, "1.0", 4);
1969 s->iSourceSink = ATAFN_SS_NULL;
1970 atapiCmdOK(s);
1971 return false;
1972}
1973
1974
1975static bool atapiModeSenseErrorRecoverySS(ATADevState *s)
1976{
1977 uint8_t *pbBuf = s->CTXSUFF(pbIOBuffer);
1978
1979 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
1980 Assert(s->cbElementaryTransfer <= 16);
1981 ataH2BE_U16(&pbBuf[0], 16 + 6);
1982 pbBuf[2] = 0x70;
1983 pbBuf[3] = 0;
1984 pbBuf[4] = 0;
1985 pbBuf[5] = 0;
1986 pbBuf[6] = 0;
1987 pbBuf[7] = 0;
1988
1989 pbBuf[8] = 0x01;
1990 pbBuf[9] = 0x06;
1991 pbBuf[10] = 0x00;
1992 pbBuf[11] = 0x05;
1993 pbBuf[12] = 0x00;
1994 pbBuf[13] = 0x00;
1995 pbBuf[14] = 0x00;
1996 pbBuf[15] = 0x00;
1997 s->iSourceSink = ATAFN_SS_NULL;
1998 atapiCmdOK(s);
1999 return false;
2000}
2001
2002
2003static bool atapiModeSenseCDStatusSS(ATADevState *s)
2004{
2005 uint8_t *pbBuf = s->CTXSUFF(pbIOBuffer);
2006
2007 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
2008 Assert(s->cbElementaryTransfer <= 40);
2009 ataH2BE_U16(&pbBuf[0], 38);
2010 pbBuf[2] = 0x70;
2011 pbBuf[3] = 0;
2012 pbBuf[4] = 0;
2013 pbBuf[5] = 0;
2014 pbBuf[6] = 0;
2015 pbBuf[7] = 0;
2016
2017 pbBuf[8] = 0x2a;
2018 pbBuf[9] = 30; /* page length */
2019 pbBuf[10] = 0x08; /* DVD-ROM read support */
2020 pbBuf[11] = 0x00; /* no write support */
2021 /* The following claims we support audio play. This is obviously false,
2022 * but the Linux generic CDROM support makes many features depend on this
2023 * capability. If it's not set, this causes many things to be disabled. */
2024 pbBuf[12] = 0x71; /* multisession support, mode 2 form 1/2 support, audio play */
2025 pbBuf[13] = 0x00; /* no subchannel reads supported */
2026 pbBuf[14] = (1 << 0) | (1 << 3) | (1 << 5); /* lock supported, eject supported, tray type loading mechanism */
2027 if (s->pDrvMount->pfnIsLocked(s->pDrvMount))
2028 pbBuf[14] |= 1 << 1; /* report lock state */
2029 pbBuf[15] = 0; /* no subchannel reads supported, no separate audio volume control, no changer etc. */
2030 ataH2BE_U16(&pbBuf[16], 5632); /* (obsolete) claim 32x speed support */
2031 ataH2BE_U16(&pbBuf[18], 2); /* number of audio volume levels */
2032 ataH2BE_U16(&pbBuf[20], s->cbIOBuffer / _1K); /* buffer size supported in Kbyte */
2033 ataH2BE_U16(&pbBuf[22], 5632); /* (obsolete) current read speed 32x */
2034 pbBuf[24] = 0; /* reserved */
2035 pbBuf[25] = 0; /* reserved for digital audio (see idx 15) */
2036 ataH2BE_U16(&pbBuf[26], 0); /* (obsolete) maximum write speed */
2037 ataH2BE_U16(&pbBuf[28], 0); /* (obsolete) current write speed */
2038 ataH2BE_U16(&pbBuf[30], 0); /* copy management revision supported 0=no CSS */
2039 pbBuf[32] = 0; /* reserved */
2040 pbBuf[33] = 0; /* reserved */
2041 pbBuf[34] = 0; /* reserved */
2042 pbBuf[35] = 1; /* rotation control CAV */
2043 ataH2BE_U16(&pbBuf[36], 0); /* current write speed */
2044 ataH2BE_U16(&pbBuf[38], 0); /* number of write speed performance descriptors */
2045 s->iSourceSink = ATAFN_SS_NULL;
2046 atapiCmdOK(s);
2047 return false;
2048}
2049
2050
2051static bool atapiRequestSenseSS(ATADevState *s)
2052{
2053 uint8_t *pbBuf = s->CTXSUFF(pbIOBuffer);
2054
2055 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
2056 Assert(s->cbElementaryTransfer <= 18);
2057 memset(pbBuf, 0, 18);
2058 pbBuf[0] = 0x70 | (1 << 7);
2059 pbBuf[2] = s->uATAPISenseKey;
2060 pbBuf[7] = 10;
2061 pbBuf[12] = s->uATAPIASC;
2062 s->iSourceSink = ATAFN_SS_NULL;
2063 atapiCmdOK(s);
2064 return false;
2065}
2066
2067
2068static bool atapiMechanismStatusSS(ATADevState *s)
2069{
2070 uint8_t *pbBuf = s->CTXSUFF(pbIOBuffer);
2071
2072 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
2073 Assert(s->cbElementaryTransfer <= 8);
2074 ataH2BE_U16(pbBuf, 0);
2075 /* no current LBA */
2076 pbBuf[2] = 0;
2077 pbBuf[3] = 0;
2078 pbBuf[4] = 0;
2079 pbBuf[5] = 1;
2080 ataH2BE_U16(pbBuf + 6, 0);
2081 s->iSourceSink = ATAFN_SS_NULL;
2082 atapiCmdOK(s);
2083 return false;
2084}
2085
2086
2087static bool atapiReadTOCNormalSS(ATADevState *s)
2088{
2089 uint8_t *pbBuf = s->CTXSUFF(pbIOBuffer), *q, iStartTrack;
2090 bool fMSF;
2091 uint32_t cbSize;
2092
2093 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
2094 fMSF = (s->aATAPICmd[1] >> 1) & 1;
2095 iStartTrack = s->aATAPICmd[6];
2096 if (iStartTrack > 1 && iStartTrack != 0xaa)
2097 {
2098 atapiCmdError(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INV_FIELD_IN_CMD_PACKET);
2099 return false;
2100 }
2101 q = pbBuf + 2;
2102 *q++ = 1; /* first session */
2103 *q++ = 1; /* last session */
2104 if (iStartTrack <= 1)
2105 {
2106 *q++ = 0; /* reserved */
2107 *q++ = 0x14; /* ADR, control */
2108 *q++ = 1; /* track number */
2109 *q++ = 0; /* reserved */
2110 if (fMSF)
2111 {
2112 *q++ = 0; /* reserved */
2113 ataLBA2MSF(q, 0);
2114 q += 3;
2115 }
2116 else
2117 {
2118 /* sector 0 */
2119 ataH2BE_U32(q, 0);
2120 q += 4;
2121 }
2122 }
2123 /* lead out track */
2124 *q++ = 0; /* reserved */
2125 *q++ = 0x14; /* ADR, control */
2126 *q++ = 0xaa; /* track number */
2127 *q++ = 0; /* reserved */
2128 if (fMSF)
2129 {
2130 *q++ = 0; /* reserved */
2131 ataLBA2MSF(q, s->cTotalSectors);
2132 q += 3;
2133 }
2134 else
2135 {
2136 ataH2BE_U32(q, s->cTotalSectors);
2137 q += 4;
2138 }
2139 cbSize = q - pbBuf;
2140 ataH2BE_U16(pbBuf, cbSize - 2);
2141 if (cbSize < s->cbTotalTransfer)
2142 s->cbTotalTransfer = cbSize;
2143 s->iSourceSink = ATAFN_SS_NULL;
2144 atapiCmdOK(s);
2145 return false;
2146}
2147
2148
2149static bool atapiReadTOCMultiSS(ATADevState *s)
2150{
2151 uint8_t *pbBuf = s->CTXSUFF(pbIOBuffer);
2152 bool fMSF;
2153
2154 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
2155 Assert(s->cbElementaryTransfer <= 12);
2156 fMSF = (s->aATAPICmd[1] >> 1) & 1;
2157 /* multi session: only a single session defined */
2158/** @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. */
2159 memset(pbBuf, 0, 12);
2160 pbBuf[1] = 0x0a;
2161 pbBuf[2] = 0x01;
2162 pbBuf[3] = 0x01;
2163 pbBuf[5] = 0x14; /* ADR, control */
2164 pbBuf[6] = 1; /* first track in last complete session */
2165 if (fMSF)
2166 {
2167 pbBuf[8] = 0; /* reserved */
2168 ataLBA2MSF(&pbBuf[9], 0);
2169 }
2170 else
2171 {
2172 /* sector 0 */
2173 ataH2BE_U32(pbBuf + 8, 0);
2174 }
2175 s->iSourceSink = ATAFN_SS_NULL;
2176 atapiCmdOK(s);
2177 return false;
2178}
2179
2180
2181static bool atapiReadTOCRawSS(ATADevState *s)
2182{
2183 uint8_t *pbBuf = s->CTXSUFF(pbIOBuffer), *q, iStartTrack;
2184 bool fMSF;
2185 uint32_t cbSize;
2186
2187 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
2188 fMSF = (s->aATAPICmd[1] >> 1) & 1;
2189 iStartTrack = s->aATAPICmd[6];
2190
2191 q = pbBuf + 2;
2192 *q++ = 1; /* first session */
2193 *q++ = 1; /* last session */
2194
2195 *q++ = 1; /* session number */
2196 *q++ = 0x14; /* data track */
2197 *q++ = 0; /* track number */
2198 *q++ = 0xa0; /* first track in program area */
2199 *q++ = 0; /* min */
2200 *q++ = 0; /* sec */
2201 *q++ = 0; /* frame */
2202 *q++ = 0;
2203 *q++ = 1; /* first track */
2204 *q++ = 0x00; /* disk type CD-DA or CD data */
2205 *q++ = 0;
2206
2207 *q++ = 1; /* session number */
2208 *q++ = 0x14; /* data track */
2209 *q++ = 0; /* track number */
2210 *q++ = 0xa1; /* last track in program area */
2211 *q++ = 0; /* min */
2212 *q++ = 0; /* sec */
2213 *q++ = 0; /* frame */
2214 *q++ = 0;
2215 *q++ = 1; /* last track */
2216 *q++ = 0;
2217 *q++ = 0;
2218
2219 *q++ = 1; /* session number */
2220 *q++ = 0x14; /* data track */
2221 *q++ = 0; /* track number */
2222 *q++ = 0xa2; /* lead-out */
2223 *q++ = 0; /* min */
2224 *q++ = 0; /* sec */
2225 *q++ = 0; /* frame */
2226 if (fMSF)
2227 {
2228 *q++ = 0; /* reserved */
2229 ataLBA2MSF(q, s->cTotalSectors);
2230 q += 3;
2231 }
2232 else
2233 {
2234 ataH2BE_U32(q, s->cTotalSectors);
2235 q += 4;
2236 }
2237
2238 *q++ = 1; /* session number */
2239 *q++ = 0x14; /* ADR, control */
2240 *q++ = 0; /* track number */
2241 *q++ = 1; /* point */
2242 *q++ = 0; /* min */
2243 *q++ = 0; /* sec */
2244 *q++ = 0; /* frame */
2245 if (fMSF)
2246 {
2247 *q++ = 0; /* reserved */
2248 ataLBA2MSF(q, 0);
2249 q += 3;
2250 }
2251 else
2252 {
2253 /* sector 0 */
2254 ataH2BE_U32(q, 0);
2255 q += 4;
2256 }
2257
2258 cbSize = q - pbBuf;
2259 ataH2BE_U16(pbBuf, cbSize - 2);
2260 if (cbSize < s->cbTotalTransfer)
2261 s->cbTotalTransfer = cbSize;
2262 s->iSourceSink = ATAFN_SS_NULL;
2263 atapiCmdOK(s);
2264 return false;
2265}
2266
2267
2268static void atapiParseCmdVirtualATAPI(ATADevState *s)
2269{
2270 const uint8_t *pbPacket;
2271 uint8_t *pbBuf;
2272 uint32_t cbMax;
2273
2274 pbPacket = s->aATAPICmd;
2275 pbBuf = s->CTXSUFF(pbIOBuffer);
2276 switch (pbPacket[0])
2277 {
2278 case SCSI_TEST_UNIT_READY:
2279 if (s->cNotifiedMediaChange > 0)
2280 {
2281 if (s->cNotifiedMediaChange-- > 2)
2282 atapiCmdError(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
2283 else
2284 atapiCmdError(s, SCSI_SENSE_UNIT_ATTENTION, SCSI_ASC_MEDIUM_MAY_HAVE_CHANGED); /* media changed */
2285 }
2286 else if (s->pDrvMount->pfnIsMounted(s->pDrvMount))
2287 atapiCmdOK(s);
2288 else
2289 atapiCmdError(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
2290 break;
2291 case SCSI_MODE_SENSE_10:
2292 {
2293 uint8_t uPageControl, uPageCode;
2294 cbMax = ataBE2H_U16(pbPacket + 7);
2295 uPageControl = pbPacket[2] >> 6;
2296 uPageCode = pbPacket[2] & 0x3f;
2297 switch (uPageControl)
2298 {
2299 case SCSI_PAGECONTROL_CURRENT:
2300 switch (uPageCode)
2301 {
2302 case SCSI_MODEPAGE_ERROR_RECOVERY:
2303 ataStartTransfer(s, RT_MIN(cbMax, 16), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_MODE_SENSE_ERROR_RECOVERY, true);
2304 break;
2305 case SCSI_MODEPAGE_CD_STATUS:
2306 ataStartTransfer(s, RT_MIN(cbMax, 40), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_MODE_SENSE_CD_STATUS, true);
2307 break;
2308 default:
2309 goto error_cmd;
2310 }
2311 break;
2312 case SCSI_PAGECONTROL_CHANGEABLE:
2313 goto error_cmd;
2314 case SCSI_PAGECONTROL_DEFAULT:
2315 goto error_cmd;
2316 default:
2317 case SCSI_PAGECONTROL_SAVED:
2318 atapiCmdError(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_SAVING_PARAMETERS_NOT_SUPPORTED);
2319 break;
2320 }
2321 }
2322 break;
2323 case SCSI_REQUEST_SENSE:
2324 cbMax = pbPacket[4];
2325 ataStartTransfer(s, RT_MIN(cbMax, 18), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_REQUEST_SENSE, true);
2326 break;
2327 case SCSI_PREVENT_ALLOW_MEDIUM_REMOVAL:
2328 if (s->pDrvMount->pfnIsMounted(s->pDrvMount))
2329 {
2330 if (pbPacket[4] & 1)
2331 s->pDrvMount->pfnLock(s->pDrvMount);
2332 else
2333 s->pDrvMount->pfnUnlock(s->pDrvMount);
2334 atapiCmdOK(s);
2335 }
2336 else
2337 atapiCmdError(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
2338 break;
2339 case SCSI_READ_10:
2340 case SCSI_READ_12:
2341 {
2342 uint32_t cSectors, iATAPILBA;
2343
2344 if (s->cNotifiedMediaChange > 0)
2345 {
2346 s->cNotifiedMediaChange-- ;
2347 atapiCmdError(s, SCSI_SENSE_UNIT_ATTENTION, SCSI_ASC_MEDIUM_MAY_HAVE_CHANGED); /* media changed */
2348 break;
2349 }
2350 else if (!s->pDrvMount->pfnIsMounted(s->pDrvMount))
2351 {
2352 atapiCmdError(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
2353 break;
2354 }
2355 if (pbPacket[0] == SCSI_READ_10)
2356 cSectors = ataBE2H_U16(pbPacket + 7);
2357 else
2358 cSectors = ataBE2H_U32(pbPacket + 6);
2359 iATAPILBA = ataBE2H_U32(pbPacket + 2);
2360 if (cSectors == 0)
2361 {
2362 atapiCmdOK(s);
2363 break;
2364 }
2365 if ((uint64_t)iATAPILBA + cSectors > s->cTotalSectors)
2366 {
2367 /* Rate limited logging, one log line per second. For
2368 * guests that insist on reading from places outside the
2369 * valid area this often generates too many release log
2370 * entries otherwise. */
2371 static uint64_t uLastLogTS = 0;
2372 if (RTTimeMilliTS() >= uLastLogTS + 1000)
2373 {
2374 LogRel(("PIIX3 ATA: LUN#%d: CD-ROM block number %Ld invalid (READ)\n", s->iLUN, (uint64_t)iATAPILBA + cSectors));
2375 uLastLogTS = RTTimeMilliTS();
2376 }
2377 atapiCmdError(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_LOGICAL_BLOCK_OOR);
2378 break;
2379 }
2380 atapiReadSectors(s, iATAPILBA, cSectors, 2048);
2381 }
2382 break;
2383 case SCSI_READ_CD:
2384 {
2385 uint32_t cSectors, iATAPILBA;
2386
2387 if (s->cNotifiedMediaChange > 0)
2388 {
2389 s->cNotifiedMediaChange-- ;
2390 atapiCmdError(s, SCSI_SENSE_UNIT_ATTENTION, SCSI_ASC_MEDIUM_MAY_HAVE_CHANGED); /* media changed */
2391 break;
2392 }
2393 else if (!s->pDrvMount->pfnIsMounted(s->pDrvMount))
2394 {
2395 atapiCmdError(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
2396 break;
2397 }
2398 cSectors = (pbPacket[6] << 16) | (pbPacket[7] << 8) | pbPacket[8];
2399 iATAPILBA = ataBE2H_U32(pbPacket + 2);
2400 if (cSectors == 0)
2401 {
2402 atapiCmdOK(s);
2403 break;
2404 }
2405 if ((uint64_t)iATAPILBA + cSectors > s->cTotalSectors)
2406 {
2407 /* Rate limited logging, one log line per second. For
2408 * guests that insist on reading from places outside the
2409 * valid area this often generates too many release log
2410 * entries otherwise. */
2411 static uint64_t uLastLogTS = 0;
2412 if (RTTimeMilliTS() >= uLastLogTS + 1000)
2413 {
2414 LogRel(("PIIX3 ATA: LUN#%d: CD-ROM block number %Ld invalid (READ CD)\n", s->iLUN, (uint64_t)iATAPILBA + cSectors));
2415 uLastLogTS = RTTimeMilliTS();
2416 }
2417 atapiCmdError(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_LOGICAL_BLOCK_OOR);
2418 break;
2419 }
2420 switch (pbPacket[9] & 0xf8)
2421 {
2422 case 0x00:
2423 /* nothing */
2424 atapiCmdOK(s);
2425 break;
2426 case 0x10:
2427 /* normal read */
2428 atapiReadSectors(s, iATAPILBA, cSectors, 2048);
2429 break;
2430 case 0xf8:
2431 /* read all data */
2432 atapiReadSectors(s, iATAPILBA, cSectors, 2352);
2433 break;
2434 default:
2435 LogRel(("PIIX3 ATA: LUN#%d: CD-ROM sector format not supported\n", s->iLUN));
2436 atapiCmdError(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INV_FIELD_IN_CMD_PACKET);
2437 break;
2438 }
2439 }
2440 break;
2441 case SCSI_SEEK_10:
2442 {
2443 uint32_t iATAPILBA;
2444 if (s->cNotifiedMediaChange > 0)
2445 {
2446 s->cNotifiedMediaChange-- ;
2447 atapiCmdError(s, SCSI_SENSE_UNIT_ATTENTION, SCSI_ASC_MEDIUM_MAY_HAVE_CHANGED); /* media changed */
2448 break;
2449 }
2450 else if (!s->pDrvMount->pfnIsMounted(s->pDrvMount))
2451 {
2452 atapiCmdError(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
2453 break;
2454 }
2455 iATAPILBA = ataBE2H_U32(pbPacket + 2);
2456 if (iATAPILBA > s->cTotalSectors)
2457 {
2458 /* Rate limited logging, one log line per second. For
2459 * guests that insist on seeking to places outside the
2460 * valid area this often generates too many release log
2461 * entries otherwise. */
2462 static uint64_t uLastLogTS = 0;
2463 if (RTTimeMilliTS() >= uLastLogTS + 1000)
2464 {
2465 LogRel(("PIIX3 ATA: LUN#%d: CD-ROM block number %Ld invalid (SEEK)\n", s->iLUN, (uint64_t)iATAPILBA));
2466 uLastLogTS = RTTimeMilliTS();
2467 }
2468 atapiCmdError(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_LOGICAL_BLOCK_OOR);
2469 break;
2470 }
2471 atapiCmdOK(s);
2472 ataSetStatus(s, ATA_STAT_SEEK); /* Linux expects this. */
2473 }
2474 break;
2475 case SCSI_START_STOP_UNIT:
2476 {
2477 int rc = VINF_SUCCESS;
2478 switch (pbPacket[4] & 3)
2479 {
2480 case 0: /* 00 - Stop motor */
2481 case 1: /* 01 - Start motor */
2482 break;
2483 case 2: /* 10 - Eject media */
2484 /* This must be done from EMT. */
2485 {
2486 PPDMDEVINS pDevIns = ATADEVSTATE_2_DEVINS(s);
2487 PVMREQ pReq;
2488 rc = VMR3ReqCall(PDMDevHlpGetVM(pDevIns), &pReq, RT_INDEFINITE_WAIT,
2489 (PFNRT)s->pDrvMount->pfnUnmount, 1, s->pDrvMount);
2490 AssertReleaseRC(rc);
2491 VMR3ReqFree(pReq);
2492 }
2493 break;
2494 case 3: /* 11 - Load media */
2495 /** @todo rc = s->pDrvMount->pfnLoadMedia(s->pDrvMount) */
2496 break;
2497 }
2498 if (VBOX_SUCCESS(rc))
2499 atapiCmdOK(s);
2500 else
2501 atapiCmdError(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIA_LOAD_OR_EJECT_FAILED);
2502 }
2503 break;
2504 case SCSI_MECHANISM_STATUS:
2505 {
2506 cbMax = ataBE2H_U16(pbPacket + 8);
2507 ataStartTransfer(s, RT_MIN(cbMax, 8), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_MECHANISM_STATUS, true);
2508 }
2509 break;
2510 case SCSI_READ_TOC_PMA_ATIP:
2511 {
2512 uint8_t format;
2513
2514 if (s->cNotifiedMediaChange > 0)
2515 {
2516 s->cNotifiedMediaChange-- ;
2517 atapiCmdError(s, SCSI_SENSE_UNIT_ATTENTION, SCSI_ASC_MEDIUM_MAY_HAVE_CHANGED); /* media changed */
2518 break;
2519 }
2520 else if (!s->pDrvMount->pfnIsMounted(s->pDrvMount))
2521 {
2522 atapiCmdError(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
2523 break;
2524 }
2525 cbMax = ataBE2H_U16(pbPacket + 7);
2526 /* SCSI MMC-3 spec says format is at offset 2 (lower 4 bits),
2527 * but Linux kernel uses offset 9 (topmost 2 bits). Hope that
2528 * the other field is clear... */
2529 format = (pbPacket[2] & 0xf) | (pbPacket[9] >> 6);
2530 switch (format)
2531 {
2532 case 0:
2533 ataStartTransfer(s, cbMax, PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_READ_TOC_NORMAL, true);
2534 break;
2535 case 1:
2536 ataStartTransfer(s, RT_MIN(cbMax, 12), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_READ_TOC_MULTI, true);
2537 break;
2538 case 2:
2539 ataStartTransfer(s, cbMax, PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_READ_TOC_RAW, true);
2540 break;
2541 default:
2542 error_cmd:
2543 atapiCmdError(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INV_FIELD_IN_CMD_PACKET);
2544 break;
2545 }
2546 }
2547 break;
2548 case SCSI_READ_CAPACITY:
2549 if (s->cNotifiedMediaChange > 0)
2550 {
2551 s->cNotifiedMediaChange-- ;
2552 atapiCmdError(s, SCSI_SENSE_UNIT_ATTENTION, SCSI_ASC_MEDIUM_MAY_HAVE_CHANGED); /* media changed */
2553 break;
2554 }
2555 else if (!s->pDrvMount->pfnIsMounted(s->pDrvMount))
2556 {
2557 atapiCmdError(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
2558 break;
2559 }
2560 ataStartTransfer(s, 8, PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_READ_CAPACITY, true);
2561 break;
2562 case SCSI_READ_DISC_INFORMATION:
2563 if (s->cNotifiedMediaChange > 0)
2564 {
2565 s->cNotifiedMediaChange-- ;
2566 atapiCmdError(s, SCSI_SENSE_UNIT_ATTENTION, SCSI_ASC_MEDIUM_MAY_HAVE_CHANGED); /* media changed */
2567 break;
2568 }
2569 else if (!s->pDrvMount->pfnIsMounted(s->pDrvMount))
2570 {
2571 atapiCmdError(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
2572 break;
2573 }
2574 cbMax = ataBE2H_U16(pbPacket + 7);
2575 ataStartTransfer(s, RT_MIN(cbMax, 34), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_READ_DISC_INFORMATION, true);
2576 break;
2577 case SCSI_READ_TRACK_INFORMATION:
2578 if (s->cNotifiedMediaChange > 0)
2579 {
2580 s->cNotifiedMediaChange-- ;
2581 atapiCmdError(s, SCSI_SENSE_UNIT_ATTENTION, SCSI_ASC_MEDIUM_MAY_HAVE_CHANGED); /* media changed */
2582 break;
2583 }
2584 else if (!s->pDrvMount->pfnIsMounted(s->pDrvMount))
2585 {
2586 atapiCmdError(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
2587 break;
2588 }
2589 cbMax = ataBE2H_U16(pbPacket + 7);
2590 ataStartTransfer(s, RT_MIN(cbMax, 36), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_READ_TRACK_INFORMATION, true);
2591 break;
2592 case SCSI_GET_CONFIGURATION:
2593 if (s->cNotifiedMediaChange > 0)
2594 {
2595 s->cNotifiedMediaChange-- ;
2596 atapiCmdError(s, SCSI_SENSE_UNIT_ATTENTION, SCSI_ASC_MEDIUM_MAY_HAVE_CHANGED); /* media changed */
2597 break;
2598 }
2599 else if (!s->pDrvMount->pfnIsMounted(s->pDrvMount))
2600 {
2601 atapiCmdError(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
2602 break;
2603 }
2604 cbMax = ataBE2H_U16(pbPacket + 7);
2605 ataStartTransfer(s, RT_MIN(cbMax, 32), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_GET_CONFIGURATION, true);
2606 break;
2607 case SCSI_INQUIRY:
2608 cbMax = pbPacket[4];
2609 ataStartTransfer(s, RT_MIN(cbMax, 36), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_INQUIRY, true);
2610 break;
2611 default:
2612 atapiCmdError(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_ILLEGAL_OPCODE);
2613 break;
2614 }
2615}
2616
2617
2618/*
2619 * Parse ATAPI commands, passing them directly to the CD/DVD drive.
2620 */
2621static void atapiParseCmdPassthrough(ATADevState *s)
2622{
2623 const uint8_t *pbPacket;
2624 uint8_t *pbBuf;
2625 uint32_t cSectors, iATAPILBA;
2626 uint32_t cbTransfer = 0;
2627 PDMBLOCKTXDIR uTxDir = PDMBLOCKTXDIR_NONE;
2628
2629 pbPacket = s->aATAPICmd;
2630 pbBuf = s->CTXSUFF(pbIOBuffer);
2631 switch (pbPacket[0])
2632 {
2633 case SCSI_BLANK:
2634 goto sendcmd;
2635 case SCSI_CLOSE_TRACK_SESSION:
2636 goto sendcmd;
2637 case SCSI_ERASE_10:
2638 iATAPILBA = ataBE2H_U32(pbPacket + 2);
2639 cbTransfer = ataBE2H_U16(pbPacket + 7);
2640 Log2(("ATAPI PT: lba %d\n", iATAPILBA));
2641 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
2642 goto sendcmd;
2643 case SCSI_FORMAT_UNIT:
2644 cbTransfer = s->uATARegLCyl | (s->uATARegHCyl << 8); /* use ATAPI transfer length */
2645 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
2646 goto sendcmd;
2647 case SCSI_GET_CONFIGURATION:
2648 cbTransfer = ataBE2H_U16(pbPacket + 7);
2649 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2650 goto sendcmd;
2651 case SCSI_GET_EVENT_STATUS_NOTIFICATION:
2652 cbTransfer = ataBE2H_U16(pbPacket + 7);
2653 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2654 goto sendcmd;
2655 case SCSI_GET_PERFORMANCE:
2656 cbTransfer = s->uATARegLCyl | (s->uATARegHCyl << 8); /* use ATAPI transfer length */
2657 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2658 goto sendcmd;
2659 case SCSI_INQUIRY:
2660 cbTransfer = pbPacket[4];
2661 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2662 goto sendcmd;
2663 case SCSI_LOAD_UNLOAD_MEDIUM:
2664 goto sendcmd;
2665 case SCSI_MECHANISM_STATUS:
2666 cbTransfer = ataBE2H_U16(pbPacket + 8);
2667 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2668 goto sendcmd;
2669 case SCSI_MODE_SELECT_10:
2670 cbTransfer = ataBE2H_U16(pbPacket + 7);
2671 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
2672 goto sendcmd;
2673 case SCSI_MODE_SENSE_10:
2674 cbTransfer = ataBE2H_U16(pbPacket + 7);
2675 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2676 goto sendcmd;
2677 case SCSI_PAUSE_RESUME:
2678 goto sendcmd;
2679 case SCSI_PLAY_AUDIO_10:
2680 goto sendcmd;
2681 case SCSI_PLAY_AUDIO_12:
2682 goto sendcmd;
2683 case SCSI_PLAY_AUDIO_MSF:
2684 goto sendcmd;
2685 case SCSI_PREVENT_ALLOW_MEDIUM_REMOVAL:
2686 /** @todo do not forget to unlock when a VM is shut down */
2687 goto sendcmd;
2688 case SCSI_READ_10:
2689 iATAPILBA = ataBE2H_U32(pbPacket + 2);
2690 cSectors = ataBE2H_U16(pbPacket + 7);
2691 Log2(("ATAPI PT: lba %d sectors %d\n", iATAPILBA, cSectors));
2692 s->cbATAPISector = 2048; /**< @todo this size is not always correct */
2693 cbTransfer = cSectors * s->cbATAPISector;
2694 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2695 goto sendcmd;
2696 case SCSI_READ_12:
2697 iATAPILBA = ataBE2H_U32(pbPacket + 2);
2698 cSectors = ataBE2H_U32(pbPacket + 6);
2699 Log2(("ATAPI PT: lba %d sectors %d\n", iATAPILBA, cSectors));
2700 s->cbATAPISector = 2048; /**< @todo this size is not always correct */
2701 cbTransfer = cSectors * s->cbATAPISector;
2702 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2703 goto sendcmd;
2704 case SCSI_READ_BUFFER:
2705 cbTransfer = ataBE2H_U24(pbPacket + 6);
2706 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2707 goto sendcmd;
2708 case SCSI_READ_BUFFER_CAPACITY:
2709 cbTransfer = ataBE2H_U16(pbPacket + 7);
2710 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2711 goto sendcmd;
2712 case SCSI_READ_CAPACITY:
2713 cbTransfer = 8;
2714 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2715 goto sendcmd;
2716 case SCSI_READ_CD:
2717 s->cbATAPISector = 2048; /**< @todo this size is not always correct */
2718 cbTransfer = ataBE2H_U24(pbPacket + 6) / s->cbATAPISector * s->cbATAPISector;
2719 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2720 goto sendcmd;
2721 case SCSI_READ_CD_MSF:
2722 cSectors = ataMSF2LBA(pbPacket + 6) - ataMSF2LBA(pbPacket + 3);
2723 if (cSectors > 32)
2724 cSectors = 32; /* Limit transfer size to 64~74K. Safety first. In any case this can only harm software doing CDDA extraction. */
2725 s->cbATAPISector = 2048; /**< @todo this size is not always correct */
2726 cbTransfer = cSectors * s->cbATAPISector;
2727 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2728 goto sendcmd;
2729 case SCSI_READ_DISC_INFORMATION:
2730 cbTransfer = ataBE2H_U16(pbPacket + 7);
2731 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2732 goto sendcmd;
2733 case SCSI_READ_DVD_STRUCTURE:
2734 cbTransfer = ataBE2H_U16(pbPacket + 8);
2735 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2736 goto sendcmd;
2737 case SCSI_READ_FORMAT_CAPACITIES:
2738 cbTransfer = ataBE2H_U16(pbPacket + 7);
2739 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2740 goto sendcmd;
2741 case SCSI_READ_SUBCHANNEL:
2742 cbTransfer = ataBE2H_U16(pbPacket + 7);
2743 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2744 goto sendcmd;
2745 case SCSI_READ_TOC_PMA_ATIP:
2746 cbTransfer = ataBE2H_U16(pbPacket + 7);
2747 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2748 goto sendcmd;
2749 case SCSI_READ_TRACK_INFORMATION:
2750 cbTransfer = ataBE2H_U16(pbPacket + 7);
2751 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2752 goto sendcmd;
2753 case SCSI_REPAIR_TRACK:
2754 goto sendcmd;
2755 case SCSI_REPORT_KEY:
2756 cbTransfer = ataBE2H_U16(pbPacket + 8);
2757 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2758 goto sendcmd;
2759 case SCSI_REQUEST_SENSE:
2760 cbTransfer = pbPacket[4];
2761 if (s->uATAPISenseKey != SCSI_SENSE_NONE)
2762 {
2763 ataStartTransfer(s, RT_MIN(cbTransfer, 18), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_REQUEST_SENSE, true);
2764 break;
2765 }
2766 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2767 goto sendcmd;
2768 case SCSI_RESERVE_TRACK:
2769 goto sendcmd;
2770 case SCSI_SCAN:
2771 goto sendcmd;
2772 case SCSI_SEEK_10:
2773 goto sendcmd;
2774 case SCSI_SEND_CUE_SHEET:
2775 cbTransfer = ataBE2H_U24(pbPacket + 6);
2776 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
2777 goto sendcmd;
2778 case SCSI_SEND_DVD_STRUCTURE:
2779 cbTransfer = ataBE2H_U16(pbPacket + 8);
2780 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
2781 goto sendcmd;
2782 case SCSI_SEND_EVENT:
2783 cbTransfer = ataBE2H_U16(pbPacket + 8);
2784 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
2785 goto sendcmd;
2786 case SCSI_SEND_KEY:
2787 cbTransfer = ataBE2H_U16(pbPacket + 8);
2788 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
2789 goto sendcmd;
2790 case SCSI_SEND_OPC_INFORMATION:
2791 cbTransfer = ataBE2H_U16(pbPacket + 7);
2792 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
2793 goto sendcmd;
2794 case SCSI_SET_CD_SPEED:
2795 goto sendcmd;
2796 case SCSI_SET_READ_AHEAD:
2797 goto sendcmd;
2798 case SCSI_SET_STREAMING:
2799 cbTransfer = ataBE2H_U16(pbPacket + 9);
2800 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
2801 goto sendcmd;
2802 case SCSI_START_STOP_UNIT:
2803 goto sendcmd;
2804 case SCSI_STOP_PLAY_SCAN:
2805 goto sendcmd;
2806 case SCSI_SYNCHRONIZE_CACHE:
2807 goto sendcmd;
2808 case SCSI_TEST_UNIT_READY:
2809 goto sendcmd;
2810 case SCSI_VERIFY_10:
2811 goto sendcmd;
2812 case SCSI_WRITE_10:
2813 iATAPILBA = ataBE2H_U32(pbPacket + 2);
2814 cSectors = ataBE2H_U16(pbPacket + 7);
2815 Log2(("ATAPI PT: lba %d sectors %d\n", iATAPILBA, cSectors));
2816#if 0
2817 /* The sector size is determined by the async I/O thread. */
2818 s->cbATAPISector = 0;
2819 /* Preliminary, will be corrected once the sector size is known. */
2820 cbTransfer = cSectors;
2821#else
2822 s->cbATAPISector = 2048; /**< @todo this size is not always correct */
2823 cbTransfer = cSectors * s->cbATAPISector;
2824#endif
2825 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
2826 goto sendcmd;
2827 case SCSI_WRITE_12:
2828 iATAPILBA = ataBE2H_U32(pbPacket + 2);
2829 cSectors = ataBE2H_U32(pbPacket + 6);
2830 Log2(("ATAPI PT: lba %d sectors %d\n", iATAPILBA, cSectors));
2831#if 0
2832 /* The sector size is determined by the async I/O thread. */
2833 s->cbATAPISector = 0;
2834 /* Preliminary, will be corrected once the sector size is known. */
2835 cbTransfer = cSectors;
2836#else
2837 s->cbATAPISector = 2048; /**< @todo this size is not always correct */
2838 cbTransfer = cSectors * s->cbATAPISector;
2839#endif
2840 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
2841 goto sendcmd;
2842 case SCSI_WRITE_AND_VERIFY_10:
2843 iATAPILBA = ataBE2H_U32(pbPacket + 2);
2844 cSectors = ataBE2H_U16(pbPacket + 7);
2845 Log2(("ATAPI PT: lba %d sectors %d\n", iATAPILBA, cSectors));
2846 /* The sector size is determined by the async I/O thread. */
2847 s->cbATAPISector = 0;
2848 /* Preliminary, will be corrected once the sector size is known. */
2849 cbTransfer = cSectors;
2850 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
2851 goto sendcmd;
2852 case SCSI_WRITE_BUFFER:
2853 switch (pbPacket[1] & 0x1f)
2854 {
2855 case 0x04: /* download microcode */
2856 case 0x05: /* download microcode and save */
2857 case 0x06: /* download microcode with offsets */
2858 case 0x07: /* download microcode with offsets and save */
2859 case 0x0e: /* download microcode with offsets and defer activation */
2860 case 0x0f: /* activate deferred microcode */
2861 LogRel(("PIIX3 ATA: LUN#%d: CD-ROM passthrough command attempted to update firmware, blocked\n", s->iLUN));
2862 atapiCmdError(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INV_FIELD_IN_CMD_PACKET);
2863 break;
2864 default:
2865 cbTransfer = ataBE2H_U16(pbPacket + 6);
2866 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
2867 goto sendcmd;
2868 }
2869 break;
2870 case SCSI_REPORT_LUNS: /* Not part of MMC-3, but used by Windows. */
2871 cbTransfer = ataBE2H_U32(pbPacket + 6);
2872 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2873 goto sendcmd;
2874 case SCSI_REZERO_UNIT:
2875 /* Obsolete command used by cdrecord. What else would one expect?
2876 * This command is not sent to the drive, it is handled internally,
2877 * as the Linux kernel doesn't like it (message "scsi: unknown
2878 * opcode 0x01" in syslog) and replies with a sense code of 0,
2879 * which sends cdrecord to an endless loop. */
2880 atapiCmdError(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_ILLEGAL_OPCODE);
2881 break;
2882 default:
2883 LogRel(("PIIX3 ATA: LUN#%d: passthrough unimplemented for command %#x\n", s->iLUN, pbPacket[0]));
2884 atapiCmdError(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_ILLEGAL_OPCODE);
2885 break;
2886 sendcmd:
2887 /* Send a command to the drive, passing data in/out as required. */
2888 Log2(("ATAPI PT: max size %d\n", cbTransfer));
2889 Assert(cbTransfer <= s->cbIOBuffer);
2890 if (cbTransfer == 0)
2891 uTxDir = PDMBLOCKTXDIR_NONE;
2892 ataStartTransfer(s, cbTransfer, uTxDir, ATAFN_BT_ATAPI_PASSTHROUGH_CMD, ATAFN_SS_ATAPI_PASSTHROUGH, true);
2893 }
2894}
2895
2896
2897static void atapiParseCmd(ATADevState *s)
2898{
2899 const uint8_t *pbPacket;
2900
2901 pbPacket = s->aATAPICmd;
2902#ifdef DEBUG
2903 Log(("%s: LUN#%d DMA=%d CMD=%#04x \"%s\"\n", __FUNCTION__, s->iLUN, s->fDMA, pbPacket[0], g_apszSCSICmdNames[pbPacket[0]]));
2904#else /* !DEBUG */
2905 Log(("%s: LUN#%d DMA=%d CMD=%#04x\n", __FUNCTION__, s->iLUN, s->fDMA, pbPacket[0]));
2906#endif /* !DEBUG */
2907 Log2(("%s: limit=%#x packet: %.*Vhxs\n", __FUNCTION__, s->uATARegLCyl | (s->uATARegHCyl << 8), ATAPI_PACKET_SIZE, pbPacket));
2908
2909 if (s->fATAPIPassthrough)
2910 atapiParseCmdPassthrough(s);
2911 else
2912 atapiParseCmdVirtualATAPI(s);
2913}
2914
2915
2916static bool ataPacketSS(ATADevState *s)
2917{
2918 s->fDMA = !!(s->uATARegFeature & 1);
2919 memcpy(s->aATAPICmd, s->CTXSUFF(pbIOBuffer), ATAPI_PACKET_SIZE);
2920 s->uTxDir = PDMBLOCKTXDIR_NONE;
2921 s->cbTotalTransfer = 0;
2922 s->cbElementaryTransfer = 0;
2923 atapiParseCmd(s);
2924 return false;
2925}
2926
2927
2928/**
2929 * Called when a media is mounted.
2930 *
2931 * @param pInterface Pointer to the interface structure containing the called function pointer.
2932 */
2933static DECLCALLBACK(void) ataMountNotify(PPDMIMOUNTNOTIFY pInterface)
2934{
2935 ATADevState *pIf = PDMIMOUNTNOTIFY_2_ATASTATE(pInterface);
2936 Log(("%s: changing LUN#%d\n", __FUNCTION__, pIf->iLUN));
2937
2938 /* Ignore the call if we're called while being attached. */
2939 if (!pIf->pDrvBlock)
2940 return;
2941
2942 if (pIf->fATAPI)
2943 pIf->cTotalSectors = pIf->pDrvBlock->pfnGetSize(pIf->pDrvBlock) / 2048;
2944 else
2945 pIf->cTotalSectors = pIf->pDrvBlock->pfnGetSize(pIf->pDrvBlock) / 512;
2946
2947 /* Report media changed in TEST UNIT and other (probably incorrect) places. */
2948 if (pIf->cNotifiedMediaChange < 2)
2949 pIf->cNotifiedMediaChange = 2;
2950}
2951
2952/**
2953 * Called when a media is unmounted
2954 * @param pInterface Pointer to the interface structure containing the called function pointer.
2955 */
2956static DECLCALLBACK(void) ataUnmountNotify(PPDMIMOUNTNOTIFY pInterface)
2957{
2958 ATADevState *pIf = PDMIMOUNTNOTIFY_2_ATASTATE(pInterface);
2959 Log(("%s:\n", __FUNCTION__));
2960 pIf->cTotalSectors = 0;
2961
2962 /*
2963 * Whatever I do, XP will not use the GET MEDIA STATUS nor the EVENT stuff.
2964 * However, it will respond to TEST UNIT with a 0x6 0x28 (media changed) sense code.
2965 * So, we'll give it 4 TEST UNIT command to catch up, two which the media is not
2966 * present and 2 in which it is changed.
2967 */
2968 pIf->cNotifiedMediaChange = 4;
2969}
2970
2971static void ataPacketBT(ATADevState *s)
2972{
2973 s->cbElementaryTransfer = s->cbTotalTransfer;
2974 s->uATARegNSector = (s->uATARegNSector & ~7) | ATAPI_INT_REASON_CD;
2975 Log2(("%s: interrupt reason %#04x\n", __FUNCTION__, s->uATARegNSector));
2976 ataSetStatusValue(s, ATA_STAT_READY);
2977}
2978
2979
2980static void ataResetDevice(ATADevState *s)
2981{
2982 s->cMultSectors = ATA_MAX_MULT_SECTORS;
2983 s->cNotifiedMediaChange = 0;
2984 s->fIrqPending = true; /* Ensure that the interrupt is unset. */
2985 ataUnsetIRQ(s);
2986
2987 s->uATARegSelect = 0x20;
2988 ataSetStatusValue(s, ATA_STAT_READY);
2989 ataSetSignature(s);
2990 s->cbTotalTransfer = 0;
2991 s->cbElementaryTransfer = 0;
2992 s->iIOBufferPIODataStart = 0;
2993 s->iIOBufferPIODataEnd = 0;
2994 s->iBeginTransfer = ATAFN_BT_NULL;
2995 s->iSourceSink = ATAFN_SS_NULL;
2996 s->fATAPITransfer = false;
2997 s->uATATransferMode = ATA_MODE_UDMA | 2; /* PIIX3 supports only up to UDMA2 */
2998
2999 s->uATARegFeature = 0;
3000}
3001
3002
3003static bool ataExecuteDeviceDiagnosticSS(ATADevState *s)
3004{
3005 ataSetSignature(s);
3006 ataSetStatusValue(s, 0); /* NOTE: READY is _not_ set */
3007 s->uATARegError = 0x01;
3008 return false;
3009}
3010
3011
3012static void ataParseCmd(ATADevState *s, uint8_t cmd)
3013{
3014#ifdef DEBUG
3015 Log(("%s: LUN#%d CMD=%#04x \"%s\"\n", __FUNCTION__, s->iLUN, cmd, g_apszATACmdNames[cmd]));
3016#else /* !DEBUG */
3017 Log(("%s: LUN#%d CMD=%#04x\n", __FUNCTION__, s->iLUN, cmd));
3018#endif /* !DEBUG */
3019 s->fLBA48 = false;
3020 s->fDMA = false;
3021 s->uATARegCommand = cmd;
3022 switch (cmd)
3023 {
3024 case ATA_IDENTIFY_DEVICE:
3025 if (s->pDrvBlock && !s->fATAPI)
3026 ataStartTransfer(s, 512, PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_NULL, ATAFN_SS_IDENTIFY, false);
3027 else
3028 {
3029 if (s->fATAPI)
3030 ataSetSignature(s);
3031 ataCmdError(s, ABRT_ERR);
3032 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
3033 }
3034 break;
3035 case ATA_INITIALIZE_DEVICE_PARAMETERS:
3036 case ATA_RECALIBRATE:
3037 ataCmdOK(s, ATA_STAT_SEEK);
3038 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
3039 break;
3040 case ATA_SET_MULTIPLE_MODE:
3041 if (s->uATARegNSector > ATA_MAX_MULT_SECTORS ||
3042 s->uATARegNSector == 0 ||
3043 (s->uATARegNSector & (s->uATARegNSector - 1)) != 0)
3044 {
3045 ataCmdError(s, ABRT_ERR);
3046 }
3047 else
3048 {
3049 Log2(("%s: set multi sector count to %d\n", __FUNCTION__, s->uATARegNSector));
3050 s->cMultSectors = s->uATARegNSector;
3051 ataCmdOK(s, 0);
3052 }
3053 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
3054 break;
3055 case ATA_READ_VERIFY_SECTORS_EXT:
3056 s->fLBA48 = true;
3057 case ATA_READ_VERIFY_SECTORS:
3058 case ATA_READ_VERIFY_SECTORS_WITHOUT_RETRIES:
3059 /* do sector number check ? */
3060 ataCmdOK(s, 0);
3061 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
3062 break;
3063 case ATA_READ_SECTORS_EXT:
3064 s->fLBA48 = true;
3065 case ATA_READ_SECTORS:
3066 case ATA_READ_SECTORS_WITHOUT_RETRIES:
3067 if (!s->pDrvBlock)
3068 goto abort_cmd;
3069 s->cSectorsPerIRQ = 1;
3070 ataStartTransfer(s, ataGetNSectors(s) * 512, PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_READ_WRITE_SECTORS, ATAFN_SS_READ_SECTORS, false);
3071 break;
3072 case ATA_WRITE_SECTORS_EXT:
3073 s->fLBA48 = true;
3074 case ATA_WRITE_SECTORS:
3075 case ATA_WRITE_SECTORS_WITHOUT_RETRIES:
3076 s->cSectorsPerIRQ = 1;
3077 ataStartTransfer(s, ataGetNSectors(s) * 512, PDMBLOCKTXDIR_TO_DEVICE, ATAFN_BT_READ_WRITE_SECTORS, ATAFN_SS_WRITE_SECTORS, false);
3078 break;
3079 case ATA_READ_MULTIPLE_EXT:
3080 s->fLBA48 = true;
3081 case ATA_READ_MULTIPLE:
3082 if (!s->cMultSectors)
3083 goto abort_cmd;
3084 s->cSectorsPerIRQ = s->cMultSectors;
3085 ataStartTransfer(s, ataGetNSectors(s) * 512, PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_READ_WRITE_SECTORS, ATAFN_SS_READ_SECTORS, false);
3086 break;
3087 case ATA_WRITE_MULTIPLE_EXT:
3088 s->fLBA48 = true;
3089 case ATA_WRITE_MULTIPLE:
3090 if (!s->cMultSectors)
3091 goto abort_cmd;
3092 s->cSectorsPerIRQ = s->cMultSectors;
3093 ataStartTransfer(s, ataGetNSectors(s) * 512, PDMBLOCKTXDIR_TO_DEVICE, ATAFN_BT_READ_WRITE_SECTORS, ATAFN_SS_WRITE_SECTORS, false);
3094 break;
3095 case ATA_READ_DMA_EXT:
3096 s->fLBA48 = true;
3097 case ATA_READ_DMA:
3098 case ATA_READ_DMA_WITHOUT_RETRIES:
3099 if (!s->pDrvBlock)
3100 goto abort_cmd;
3101 s->cSectorsPerIRQ = ATA_MAX_MULT_SECTORS;
3102 s->fDMA = true;
3103 ataStartTransfer(s, ataGetNSectors(s) * 512, PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_READ_WRITE_SECTORS, ATAFN_SS_READ_SECTORS, false);
3104 break;
3105 case ATA_WRITE_DMA_EXT:
3106 s->fLBA48 = true;
3107 case ATA_WRITE_DMA:
3108 case ATA_WRITE_DMA_WITHOUT_RETRIES:
3109 if (!s->pDrvBlock)
3110 goto abort_cmd;
3111 s->cSectorsPerIRQ = ATA_MAX_MULT_SECTORS;
3112 s->fDMA = true;
3113 ataStartTransfer(s, ataGetNSectors(s) * 512, PDMBLOCKTXDIR_TO_DEVICE, ATAFN_BT_READ_WRITE_SECTORS, ATAFN_SS_WRITE_SECTORS, false);
3114 break;
3115 case ATA_READ_NATIVE_MAX_ADDRESS_EXT:
3116 s->fLBA48 = true;
3117 ataSetSector(s, s->cTotalSectors - 1);
3118 ataCmdOK(s, 0);
3119 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
3120 break;
3121 case ATA_READ_NATIVE_MAX_ADDRESS:
3122 ataSetSector(s, RT_MIN(s->cTotalSectors, 1 << 28) - 1);
3123 ataCmdOK(s, 0);
3124 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
3125 break;
3126 case ATA_CHECK_POWER_MODE:
3127 s->uATARegNSector = 0xff; /* drive active or idle */
3128 ataCmdOK(s, 0);
3129 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
3130 break;
3131 case ATA_SET_FEATURES:
3132 Log2(("%s: feature=%#x\n", __FUNCTION__, s->uATARegFeature));
3133 if (!s->pDrvBlock)
3134 goto abort_cmd;
3135 switch (s->uATARegFeature)
3136 {
3137 case 0x02: /* write cache enable */
3138 Log2(("%s: write cache enable\n", __FUNCTION__));
3139 ataCmdOK(s, ATA_STAT_SEEK);
3140 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
3141 break;
3142 case 0xaa: /* read look-ahead enable */
3143 Log2(("%s: read look-ahead enable\n", __FUNCTION__));
3144 ataCmdOK(s, ATA_STAT_SEEK);
3145 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
3146 break;
3147 case 0x55: /* read look-ahead disable */
3148 Log2(("%s: read look-ahead disable\n", __FUNCTION__));
3149 ataCmdOK(s, ATA_STAT_SEEK);
3150 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
3151 break;
3152 case 0x82: /* write cache disable */
3153 Log2(("%s: write cache disable\n", __FUNCTION__));
3154 /* As per the ATA/ATAPI-6 specs, a write cache disable
3155 * command MUST flush the write buffers to disc. */
3156 ataStartTransfer(s, 0, PDMBLOCKTXDIR_NONE, ATAFN_BT_NULL, ATAFN_SS_FLUSH, false);
3157 break;
3158 case 0x03: { /* set transfer mode */
3159 Log2(("%s: transfer mode %#04x\n", __FUNCTION__, s->uATARegNSector));
3160 switch (s->uATARegNSector & 0xf8)
3161 {
3162 case 0x00: /* PIO default */
3163 case 0x08: /* PIO mode */
3164 break;
3165 case ATA_MODE_MDMA: /* MDMA mode */
3166 s->uATATransferMode = (s->uATARegNSector & 0xf8) | RT_MIN(s->uATARegNSector & 0x07, ATA_MDMA_MODE_MAX);
3167 break;
3168 case ATA_MODE_UDMA: /* UDMA mode */
3169 s->uATATransferMode = (s->uATARegNSector & 0xf8) | RT_MIN(s->uATARegNSector & 0x07, ATA_UDMA_MODE_MAX);
3170 break;
3171 default:
3172 goto abort_cmd;
3173 }
3174 ataCmdOK(s, ATA_STAT_SEEK);
3175 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
3176 break;
3177 }
3178 default:
3179 goto abort_cmd;
3180 }
3181 /*
3182 * OS/2 workarond:
3183 * The OS/2 IDE driver from MCP2 appears to rely on the feature register being
3184 * reset here. According to the specification, this is a driver bug as the register
3185 * contents are undefined after the call. This means we can just as well reset it.
3186 */
3187 s->uATARegFeature = 0;
3188 break;
3189 case ATA_FLUSH_CACHE_EXT:
3190 case ATA_FLUSH_CACHE:
3191 if (!s->pDrvBlock || s->fATAPI)
3192 goto abort_cmd;
3193 ataStartTransfer(s, 0, PDMBLOCKTXDIR_NONE, ATAFN_BT_NULL, ATAFN_SS_FLUSH, false);
3194 break;
3195 case ATA_STANDBY_IMMEDIATE:
3196 ataCmdOK(s, 0);
3197 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
3198 break;
3199 case ATA_IDLE_IMMEDIATE:
3200 ataAbortCurrentCommand(s, false);
3201 break;
3202 /* ATAPI commands */
3203 case ATA_IDENTIFY_PACKET_DEVICE:
3204 if (s->fATAPI)
3205 ataStartTransfer(s, 512, PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_NULL, ATAFN_SS_ATAPI_IDENTIFY, false);
3206 else
3207 {
3208 ataCmdError(s, ABRT_ERR);
3209 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
3210 }
3211 break;
3212 case ATA_EXECUTE_DEVICE_DIAGNOSTIC:
3213 ataStartTransfer(s, 0, PDMBLOCKTXDIR_NONE, ATAFN_BT_NULL, ATAFN_SS_EXECUTE_DEVICE_DIAGNOSTIC, false);
3214 break;
3215 case ATA_DEVICE_RESET:
3216 if (!s->fATAPI)
3217 goto abort_cmd;
3218 ataAbortCurrentCommand(s, true);
3219 break;
3220 case ATA_PACKET:
3221 if (!s->fATAPI)
3222 goto abort_cmd;
3223 /* overlapping commands not supported */
3224 if (s->uATARegFeature & 0x02)
3225 goto abort_cmd;
3226 ataStartTransfer(s, ATAPI_PACKET_SIZE, PDMBLOCKTXDIR_TO_DEVICE, ATAFN_BT_PACKET, ATAFN_SS_PACKET, false);
3227 break;
3228 default:
3229 abort_cmd:
3230 ataCmdError(s, ABRT_ERR);
3231 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
3232 break;
3233 }
3234}
3235
3236
3237/**
3238 * Waits for a particular async I/O thread to complete whatever it
3239 * is doing at the moment.
3240 *
3241 * @returns true on success.
3242 * @returns false when the thread is still processing.
3243 * @param pData Pointer to the controller data.
3244 * @param cMillies How long to wait (total).
3245 */
3246static bool ataWaitForAsyncIOIsIdle(PATACONTROLLER pCtl, unsigned cMillies)
3247{
3248 uint64_t u64Start;
3249
3250 /*
3251 * Wait for any pending async operation to finish
3252 */
3253 u64Start = RTTimeMilliTS();
3254 for (;;)
3255 {
3256 if (ataAsyncIOIsIdle(pCtl, false))
3257 return true;
3258 if (RTTimeMilliTS() - u64Start >= cMillies)
3259 break;
3260
3261 /* Sleep for a bit. */
3262 RTThreadSleep(100);
3263 }
3264
3265 return false;
3266}
3267
3268#endif /* IN_RING3 */
3269
3270static int ataIOPortWriteU8(PATACONTROLLER pCtl, uint32_t addr, uint32_t val)
3271{
3272 Log2(("%s: write addr=%#x val=%#04x\n", __FUNCTION__, addr, val));
3273 addr &= 7;
3274 switch (addr)
3275 {
3276 case 0:
3277 break;
3278 case 1: /* feature register */
3279 /* NOTE: data is written to the two drives */
3280 pCtl->aIfs[0].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
3281 pCtl->aIfs[1].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
3282 pCtl->aIfs[0].uATARegFeatureHOB = pCtl->aIfs[0].uATARegFeature;
3283 pCtl->aIfs[1].uATARegFeatureHOB = pCtl->aIfs[1].uATARegFeature;
3284 pCtl->aIfs[0].uATARegFeature = val;
3285 pCtl->aIfs[1].uATARegFeature = val;
3286 break;
3287 case 2: /* sector count */
3288 pCtl->aIfs[0].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
3289 pCtl->aIfs[1].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
3290 pCtl->aIfs[0].uATARegNSectorHOB = pCtl->aIfs[0].uATARegNSector;
3291 pCtl->aIfs[1].uATARegNSectorHOB = pCtl->aIfs[1].uATARegNSector;
3292 pCtl->aIfs[0].uATARegNSector = val;
3293 pCtl->aIfs[1].uATARegNSector = val;
3294 break;
3295 case 3: /* sector number */
3296 pCtl->aIfs[0].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
3297 pCtl->aIfs[1].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
3298 pCtl->aIfs[0].uATARegSectorHOB = pCtl->aIfs[0].uATARegSector;
3299 pCtl->aIfs[1].uATARegSectorHOB = pCtl->aIfs[1].uATARegSector;
3300 pCtl->aIfs[0].uATARegSector = val;
3301 pCtl->aIfs[1].uATARegSector = val;
3302 break;
3303 case 4: /* cylinder low */
3304 pCtl->aIfs[0].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
3305 pCtl->aIfs[1].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
3306 pCtl->aIfs[0].uATARegLCylHOB = pCtl->aIfs[0].uATARegLCyl;
3307 pCtl->aIfs[1].uATARegLCylHOB = pCtl->aIfs[1].uATARegLCyl;
3308 pCtl->aIfs[0].uATARegLCyl = val;
3309 pCtl->aIfs[1].uATARegLCyl = val;
3310 break;
3311 case 5: /* cylinder high */
3312 pCtl->aIfs[0].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
3313 pCtl->aIfs[1].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
3314 pCtl->aIfs[0].uATARegHCylHOB = pCtl->aIfs[0].uATARegHCyl;
3315 pCtl->aIfs[1].uATARegHCylHOB = pCtl->aIfs[1].uATARegHCyl;
3316 pCtl->aIfs[0].uATARegHCyl = val;
3317 pCtl->aIfs[1].uATARegHCyl = val;
3318 break;
3319 case 6: /* drive/head */
3320 pCtl->aIfs[0].uATARegSelect = (val & ~0x10) | 0xa0;
3321 pCtl->aIfs[1].uATARegSelect = (val | 0x10) | 0xa0;
3322 if ((((val >> 4)) & 1) != pCtl->iSelectedIf)
3323 {
3324 PPDMDEVINS pDevIns = CONTROLLER_2_DEVINS(pCtl);
3325
3326 /* select another drive */
3327 pCtl->iSelectedIf = (val >> 4) & 1;
3328 /* The IRQ line is multiplexed between the two drives, so
3329 * update the state when switching to another drive. */
3330 if (pCtl->aIfs[pCtl->iSelectedIf].fIrqPending)
3331 {
3332 if (pCtl->irq == 16)
3333 PDMDevHlpPCISetIrqNoWait(pDevIns, 0, 1);
3334 else
3335 PDMDevHlpISASetIrqNoWait(pDevIns, pCtl->irq, 1);
3336 }
3337 else
3338 {
3339 if (pCtl->irq == 16)
3340 PDMDevHlpPCISetIrqNoWait(pDevIns, 0, 0);
3341 else
3342 PDMDevHlpISASetIrqNoWait(pDevIns, pCtl->irq, 0);
3343 }
3344 }
3345 break;
3346 default:
3347 case 7: /* command */
3348 /* ignore commands to non existant slave */
3349 if (pCtl->iSelectedIf && !pCtl->aIfs[pCtl->iSelectedIf].pDrvBlock)
3350 break;
3351#ifndef IN_RING3
3352 /* Don't do anything complicated in GC */
3353 return VINF_IOM_HC_IOPORT_WRITE;
3354#else /* IN_RING3 */
3355 ataParseCmd(&pCtl->aIfs[pCtl->iSelectedIf], val);
3356#endif /* !IN_RING3 */
3357 }
3358 return VINF_SUCCESS;
3359}
3360
3361
3362static void ataIOPortReadU8(PATACONTROLLER pCtl, uint32_t addr, uint32_t *pu32)
3363{
3364 ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf];
3365 uint32_t val;
3366 bool fHOB;
3367
3368 fHOB = !!(s->uATARegDevCtl & (1 << 7));
3369 switch (addr & 7)
3370 {
3371 case 0: /* data register */
3372 val = 0xff;
3373 break;
3374 case 1: /* error register */
3375 /* The ATA specification is very terse when it comes to specifying
3376 * the precise effects of reading back the error/feature register.
3377 * The error register (read-only) shares the register number with
3378 * the feature register (write-only), so it seems that it's not
3379 * necessary to support the usual HOB readback here. */
3380 if (!s->pDrvBlock)
3381 val = 0;
3382 else
3383 val = s->uATARegError;
3384 break;
3385 case 2: /* sector count */
3386 if (!s->pDrvBlock)
3387 val = 0;
3388 else if (fHOB)
3389 val = s->uATARegNSectorHOB;
3390 else
3391 val = s->uATARegNSector;
3392 break;
3393 case 3: /* sector number */
3394 if (!s->pDrvBlock)
3395 val = 0;
3396 else if (fHOB)
3397 val = s->uATARegSectorHOB;
3398 else
3399 val = s->uATARegSector;
3400 break;
3401 case 4: /* cylinder low */
3402 if (!s->pDrvBlock)
3403 val = 0;
3404 else if (fHOB)
3405 val = s->uATARegLCylHOB;
3406 else
3407 val = s->uATARegLCyl;
3408 break;
3409 case 5: /* cylinder high */
3410 if (!s->pDrvBlock)
3411 val = 0;
3412 else if (fHOB)
3413 val = s->uATARegHCylHOB;
3414 else
3415 val = s->uATARegHCyl;
3416 break;
3417 case 6: /* drive/head */
3418 /* This register must always work as long as there is at least
3419 * one drive attached to the controller. It is common between
3420 * both drives anyway (completely identical content). */
3421 if (!pCtl->aIfs[0].pDrvBlock && !pCtl->aIfs[1].pDrvBlock)
3422 val = 0;
3423 else
3424 val = s->uATARegSelect;
3425 break;
3426 default:
3427 case 7: /* primary status */
3428 {
3429 if (!s->pDrvBlock)
3430 val = 0;
3431 else
3432 val = s->uATARegStatus;
3433 ataUnsetIRQ(s);
3434#ifdef IN_RING3
3435 /* Give the async I/O thread an opportunity to make progress,
3436 * don't let it starve by guests polling frequently. EMT has a
3437 * lower priority than the async I/O thread, but sometimes the
3438 * host OS doesn't care. With some guests we are only allowed to
3439 * be busy for about 5 milliseconds in some situations. */
3440 if (val & ATA_STAT_BUSY)
3441 {
3442 PDMCritSectLeave(&pCtl->lock);
3443
3444 RTThreadYield();
3445
3446 {
3447 STAM_PROFILE_START(&pCtl->StatLockWait, a);
3448 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
3449 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
3450 }
3451
3452 val = s->uATARegStatus;
3453 }
3454#endif
3455 break;
3456 }
3457 }
3458 Log2(("%s: addr=%#x val=%#04x\n", __FUNCTION__, addr, val));
3459 *pu32 = val;
3460}
3461
3462
3463static uint32_t ataStatusRead(PATACONTROLLER pCtl, uint32_t addr)
3464{
3465 ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf];
3466 uint32_t val;
3467
3468 if ((!pCtl->aIfs[0].pDrvBlock && !pCtl->aIfs[1].pDrvBlock) ||
3469 (pCtl->iSelectedIf == 1 && !s->pDrvBlock))
3470 val = 0;
3471 else
3472 val = s->uATARegStatus;
3473 Log2(("%s: addr=%#x val=%#04x\n", __FUNCTION__, addr, val));
3474 return val;
3475}
3476
3477static int ataControlWrite(PATACONTROLLER pCtl, uint32_t addr, uint32_t val)
3478{
3479#ifndef IN_RING3
3480 if ((val ^ pCtl->aIfs[0].uATARegDevCtl) & ATA_DEVCTL_RESET)
3481 return VINF_IOM_HC_IOPORT_WRITE; /* The RESET stuff is too complicated for GC. */
3482#endif /* !IN_RING3 */
3483
3484 Log2(("%s: addr=%#x val=%#04x\n", __FUNCTION__, addr, val));
3485 /* RESET is common for both drives attached to a controller. */
3486 if (!(pCtl->aIfs[0].uATARegDevCtl & ATA_DEVCTL_RESET) &&
3487 (val & ATA_DEVCTL_RESET))
3488 {
3489#ifdef IN_RING3
3490 /* Software RESET low to high */
3491 LogRel(("PIIX3 ATA: Ctl#%d: RESET, DevSel=%d AIOIf=%d CmdIf0=%#04x CmdIf1=%#04x\n",
3492 ATACONTROLLER_IDX(pCtl), pCtl->iSelectedIf, pCtl->iAIOIf,
3493 pCtl->aIfs[0].uATARegCommand, pCtl->aIfs[1].uATARegCommand));
3494 pCtl->fReset = true;
3495 /* Everything must be done after the reset flag is set, otherwise
3496 * there are unavoidable races with the currently executing request
3497 * (which might just finish in the mean time). */
3498 pCtl->fChainedTransfer = false;
3499 for (uint32_t i = 0; i < RT_ELEMENTS(pCtl->aIfs); i++)
3500 {
3501 ataResetDevice(&pCtl->aIfs[i]);
3502 /* The following cannot be done using ataSetStatusValue() since the
3503 * reset flag is already set, which suppresses all status changes. */
3504 pCtl->aIfs[i].uATARegStatus = ATA_STAT_BUSY | ATA_STAT_SEEK;
3505 Log2(("%s: LUN#%d status %#04x\n", __FUNCTION__, pCtl->aIfs[i].iLUN, pCtl->aIfs[i].uATARegStatus));
3506 pCtl->aIfs[i].uATARegError = 0x01;
3507 }
3508 ataAsyncIOClearRequests(pCtl);
3509 Log2(("%s: Ctl#%d: message to async I/O thread, resetA\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
3510 if (val & ATA_DEVCTL_HOB)
3511 {
3512 val &= ~ATA_DEVCTL_HOB;
3513 Log2(("%s: ignored setting HOB\n", __FUNCTION__));
3514 }
3515 ataAsyncIOPutRequest(pCtl, &ataResetARequest);
3516#else /* !IN_RING3 */
3517 AssertMsgFailed(("RESET handling is too complicated for GC\n"));
3518#endif /* IN_RING3 */
3519 }
3520 else if ((pCtl->aIfs[0].uATARegDevCtl & ATA_DEVCTL_RESET) &&
3521 !(val & ATA_DEVCTL_RESET))
3522 {
3523#ifdef IN_RING3
3524 /* Software RESET high to low */
3525 Log(("%s: deasserting RESET\n", __FUNCTION__));
3526 Log2(("%s: Ctl#%d: message to async I/O thread, resetC\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
3527 if (val & ATA_DEVCTL_HOB)
3528 {
3529 val &= ~ATA_DEVCTL_HOB;
3530 Log2(("%s: ignored setting HOB\n", __FUNCTION__));
3531 }
3532 ataAsyncIOPutRequest(pCtl, &ataResetCRequest);
3533#else /* !IN_RING3 */
3534 AssertMsgFailed(("RESET handling is too complicated for GC\n"));
3535#endif /* IN_RING3 */
3536 }
3537
3538 if (val & ATA_DEVCTL_HOB)
3539 Log2(("%s: set HOB\n", __FUNCTION__));
3540
3541 pCtl->aIfs[0].uATARegDevCtl = val;
3542 pCtl->aIfs[1].uATARegDevCtl = val;
3543
3544 return VINF_SUCCESS;
3545}
3546
3547#ifdef IN_RING3
3548
3549DECLINLINE(void) ataPIOTransferFinish(PATACONTROLLER pCtl, ATADevState *s)
3550{
3551 /* Do not interfere with RESET processing if the PIO transfer finishes
3552 * while the RESET line is asserted. */
3553 if (pCtl->fReset)
3554 {
3555 Log2(("%s: Ctl#%d: suppressed continuing PIO transfer as RESET is active\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
3556 return;
3557 }
3558
3559 ataUnsetStatus(s, ATA_STAT_READY | ATA_STAT_DRQ);
3560 ataSetStatus(s, ATA_STAT_BUSY);
3561
3562 Log2(("%s: Ctl#%d: message to async I/O thread, continuing PIO transfer\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
3563 ataAsyncIOPutRequest(pCtl, &ataPIORequest);
3564}
3565
3566#endif /* IN_RING3 */
3567
3568static int ataDataWrite(PATACONTROLLER pCtl, uint32_t addr, uint32_t cbSize, const uint8_t *pbBuf)
3569{
3570 ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf];
3571 uint8_t *p;
3572
3573 if (s->iIOBufferPIODataStart < s->iIOBufferPIODataEnd)
3574 {
3575 Assert(s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE);
3576 p = s->CTXSUFF(pbIOBuffer) + s->iIOBufferPIODataStart;
3577#ifndef IN_RING3
3578 /* All but the last transfer unit is simple enough for GC, but
3579 * sending a request to the async IO thread is too complicated. */
3580 if (s->iIOBufferPIODataStart + cbSize < s->iIOBufferPIODataEnd)
3581 {
3582 memcpy(p, pbBuf, cbSize);
3583 s->iIOBufferPIODataStart += cbSize;
3584 }
3585 else
3586 return VINF_IOM_HC_IOPORT_WRITE;
3587#else /* IN_RING3 */
3588 memcpy(p, pbBuf, cbSize);
3589 s->iIOBufferPIODataStart += cbSize;
3590 if (s->iIOBufferPIODataStart >= s->iIOBufferPIODataEnd)
3591 ataPIOTransferFinish(pCtl, s);
3592#endif /* !IN_RING3 */
3593 }
3594 else
3595 Log2(("%s: DUMMY data\n", __FUNCTION__));
3596 Log3(("%s: addr=%#x val=%.*Vhxs\n", __FUNCTION__, addr, cbSize, pbBuf));
3597 return VINF_SUCCESS;
3598}
3599
3600static int ataDataRead(PATACONTROLLER pCtl, uint32_t addr, uint32_t cbSize, uint8_t *pbBuf)
3601{
3602 ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf];
3603 uint8_t *p;
3604
3605 if (s->iIOBufferPIODataStart < s->iIOBufferPIODataEnd)
3606 {
3607 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
3608 p = s->CTXSUFF(pbIOBuffer) + s->iIOBufferPIODataStart;
3609#ifndef IN_RING3
3610 /* All but the last transfer unit is simple enough for GC, but
3611 * sending a request to the async IO thread is too complicated. */
3612 if (s->iIOBufferPIODataStart + cbSize < s->iIOBufferPIODataEnd)
3613 {
3614 memcpy(pbBuf, p, cbSize);
3615 s->iIOBufferPIODataStart += cbSize;
3616 }
3617 else
3618 return VINF_IOM_HC_IOPORT_READ;
3619#else /* IN_RING3 */
3620 memcpy(pbBuf, p, cbSize);
3621 s->iIOBufferPIODataStart += cbSize;
3622 if (s->iIOBufferPIODataStart >= s->iIOBufferPIODataEnd)
3623 ataPIOTransferFinish(pCtl, s);
3624#endif /* !IN_RING3 */
3625 }
3626 else
3627 {
3628 Log2(("%s: DUMMY data\n", __FUNCTION__));
3629 memset(pbBuf, '\xff', cbSize);
3630 }
3631 Log3(("%s: addr=%#x val=%.*Vhxs\n", __FUNCTION__, addr, cbSize, pbBuf));
3632 return VINF_SUCCESS;
3633}
3634
3635#ifdef IN_RING3
3636
3637/* Attempt to guess the LCHS disk geometry from the MS-DOS master boot
3638 * record (partition table). */
3639static int ataGuessDiskLCHS(ATADevState *s, uint32_t *pcCylinders, uint32_t *pcHeads, uint32_t *pcSectors)
3640{
3641 uint8_t aMBR[512], *p;
3642 int rc;
3643 uint32_t iEndHead, iEndSector, cCHSCylinders, cCHSHeads, cCHSSectors;
3644
3645 if (s->fATAPI || !s->pDrvBlock)
3646 return VERR_INVALID_PARAMETER;
3647 rc = s->pDrvBlock->pfnRead(s->pDrvBlock, 0, aMBR, 1 * 512);
3648 if (VBOX_FAILURE(rc))
3649 return rc;
3650 /* Test MBR magic number. */
3651 if (aMBR[510] != 0x55 || aMBR[511] != 0xaa)
3652 return VERR_INVALID_PARAMETER;
3653 for (uint32_t i = 0; i < 4; i++)
3654 {
3655 /* Figure out the start of a partition table entry. */
3656 p = &aMBR[0x1be + i * 16];
3657 iEndHead = p[5];
3658 iEndSector = p[6] & 63;
3659 if ((p[12] | p[13] | p[14] | p[15]) && iEndSector & iEndHead)
3660 {
3661 /* Assumption: partition terminates on a cylinder boundary. */
3662 cCHSHeads = iEndHead + 1;
3663 cCHSSectors = iEndSector;
3664 cCHSCylinders = s->cTotalSectors / (cCHSHeads * cCHSSectors);
3665 if (cCHSCylinders >= 1 && cCHSCylinders <= 16383)
3666 {
3667 *pcHeads = cCHSHeads;
3668 *pcSectors = cCHSSectors;
3669 *pcCylinders = cCHSCylinders;
3670 Log(("%s: LCHS=%d %d %d\n", __FUNCTION__, cCHSCylinders, cCHSHeads, cCHSSectors));
3671 return VINF_SUCCESS;
3672 }
3673 }
3674 }
3675 return VERR_INVALID_PARAMETER;
3676}
3677
3678
3679static void ataDMATransferStop(ATADevState *s)
3680{
3681 s->cbTotalTransfer = 0;
3682 s->cbElementaryTransfer = 0;
3683 s->iBeginTransfer = ATAFN_BT_NULL;
3684 s->iSourceSink = ATAFN_SS_NULL;
3685}
3686
3687
3688/**
3689 * Perform the entire DMA transfer in one go (unless a source/sink operation
3690 * has to be redone or a RESET comes in between). Unlike the PIO counterpart
3691 * this function cannot handle empty transfers.
3692 *
3693 * @param pCtl Controller for which to perform the transfer.
3694 */
3695static void ataDMATransfer(PATACONTROLLER pCtl)
3696{
3697 PPDMDEVINS pDevIns = CONTROLLER_2_DEVINS(pCtl);
3698 ATADevState *s = &pCtl->aIfs[pCtl->iAIOIf];
3699 bool fRedo;
3700 RTGCPHYS pDesc;
3701 uint32_t cbTotalTransfer, cbElementaryTransfer;
3702 uint32_t iIOBufferCur, iIOBufferEnd;
3703 uint32_t dmalen;
3704 PDMBLOCKTXDIR uTxDir;
3705 bool fLastDesc = false;
3706
3707 Assert(sizeof(BMDMADesc) == 8);
3708
3709 fRedo = pCtl->fRedo;
3710 if (RT_LIKELY(!fRedo))
3711 Assert(s->cbTotalTransfer);
3712 uTxDir = (PDMBLOCKTXDIR)s->uTxDir;
3713 cbTotalTransfer = s->cbTotalTransfer;
3714 cbElementaryTransfer = s->cbElementaryTransfer;
3715 iIOBufferCur = s->iIOBufferCur;
3716 iIOBufferEnd = s->iIOBufferEnd;
3717
3718 /* The DMA loop is designed to hold the lock only when absolutely
3719 * necessary. This avoids long freezes should the guest access the
3720 * ATA registers etc. for some reason. */
3721 PDMCritSectLeave(&pCtl->lock);
3722
3723 Log2(("%s: %s tx_size=%d elem_tx_size=%d index=%d end=%d\n",
3724 __FUNCTION__, uTxDir == PDMBLOCKTXDIR_FROM_DEVICE ? "T2I" : "I2T",
3725 cbTotalTransfer, cbElementaryTransfer,
3726 iIOBufferCur, iIOBufferEnd));
3727 for (pDesc = pCtl->pFirstDMADesc; pDesc <= pCtl->pLastDMADesc; pDesc += sizeof(BMDMADesc))
3728 {
3729 BMDMADesc DMADesc;
3730 RTGCPHYS pBuffer;
3731 uint32_t cbBuffer;
3732
3733 if (RT_UNLIKELY(fRedo))
3734 {
3735 pBuffer = pCtl->pRedoDMABuffer;
3736 cbBuffer = pCtl->cbRedoDMABuffer;
3737 fLastDesc = pCtl->fRedoDMALastDesc;
3738 }
3739 else
3740 {
3741 PDMDevHlpPhysRead(pDevIns, pDesc, &DMADesc, sizeof(BMDMADesc));
3742 pBuffer = RT_LE2H_U32(DMADesc.pBuffer);
3743 cbBuffer = RT_LE2H_U32(DMADesc.cbBuffer);
3744 fLastDesc = !!(cbBuffer & 0x80000000);
3745 cbBuffer &= 0xfffe;
3746 if (cbBuffer == 0)
3747 cbBuffer = 0x10000;
3748 if (cbBuffer > cbTotalTransfer)
3749 cbBuffer = cbTotalTransfer;
3750 }
3751
3752 while (RT_UNLIKELY(fRedo) || (cbBuffer && cbTotalTransfer))
3753 {
3754 if (RT_LIKELY(!fRedo))
3755 {
3756 dmalen = RT_MIN(cbBuffer, iIOBufferEnd - iIOBufferCur);
3757 Log2(("%s: DMA desc %#010x: addr=%#010x size=%#010x\n", __FUNCTION__,
3758 (int)pDesc, pBuffer, cbBuffer));
3759 if (uTxDir == PDMBLOCKTXDIR_FROM_DEVICE)
3760 PDMDevHlpPhysWrite(pDevIns, pBuffer, s->CTXSUFF(pbIOBuffer) + iIOBufferCur, dmalen);
3761 else
3762 PDMDevHlpPhysRead(pDevIns, pBuffer, s->CTXSUFF(pbIOBuffer) + iIOBufferCur, dmalen);
3763 iIOBufferCur += dmalen;
3764 cbTotalTransfer -= dmalen;
3765 cbBuffer -= dmalen;
3766 pBuffer += dmalen;
3767 }
3768 if ( iIOBufferCur == iIOBufferEnd
3769 && (uTxDir == PDMBLOCKTXDIR_TO_DEVICE || cbTotalTransfer))
3770 {
3771 if (uTxDir == PDMBLOCKTXDIR_FROM_DEVICE && cbElementaryTransfer > cbTotalTransfer)
3772 cbElementaryTransfer = cbTotalTransfer;
3773
3774 {
3775 STAM_PROFILE_START(&pCtl->StatLockWait, a);
3776 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
3777 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
3778 }
3779
3780 /* The RESET handler could have cleared the DMA transfer
3781 * state (since we didn't hold the lock until just now
3782 * the guest can continue in parallel). If so, the state
3783 * is already set up so the loop is exited immediately. */
3784 if (s->iSourceSink != ATAFN_SS_NULL)
3785 {
3786 s->iIOBufferCur = iIOBufferCur;
3787 s->iIOBufferEnd = iIOBufferEnd;
3788 s->cbElementaryTransfer = cbElementaryTransfer;
3789 s->cbTotalTransfer = cbTotalTransfer;
3790 Log2(("%s: calling source/sink function\n", __FUNCTION__));
3791 fRedo = g_apfnSourceSinkFuncs[s->iSourceSink](s);
3792 if (RT_UNLIKELY(fRedo))
3793 {
3794 pCtl->pFirstDMADesc = pDesc;
3795 pCtl->pRedoDMABuffer = pBuffer;
3796 pCtl->cbRedoDMABuffer = cbBuffer;
3797 pCtl->fRedoDMALastDesc = fLastDesc;
3798 }
3799 else
3800 {
3801 cbTotalTransfer = s->cbTotalTransfer;
3802 cbElementaryTransfer = s->cbElementaryTransfer;
3803
3804 if (uTxDir == PDMBLOCKTXDIR_TO_DEVICE && cbElementaryTransfer > cbTotalTransfer)
3805 cbElementaryTransfer = cbTotalTransfer;
3806 iIOBufferCur = 0;
3807 iIOBufferEnd = cbElementaryTransfer;
3808 }
3809 pCtl->fRedo = fRedo;
3810 }
3811 else
3812 {
3813 /* This forces the loop to exit immediately. */
3814 pDesc = pCtl->pLastDMADesc + 1;
3815 }
3816
3817 PDMCritSectLeave(&pCtl->lock);
3818 if (RT_UNLIKELY(fRedo))
3819 break;
3820 }
3821 }
3822
3823 if (RT_UNLIKELY(fRedo))
3824 break;
3825
3826 /* end of transfer */
3827 if (!cbTotalTransfer || fLastDesc)
3828 break;
3829
3830 {
3831 STAM_PROFILE_START(&pCtl->StatLockWait, a);
3832 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
3833 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
3834 }
3835
3836 if (!(pCtl->BmDma.u8Cmd & BM_CMD_START) || pCtl->fReset)
3837 {
3838 LogRel(("PIIX3 ATA: Ctl#%d: ABORT DMA%s\n", ATACONTROLLER_IDX(pCtl), pCtl->fReset ? " due to RESET" : ""));
3839 if (!pCtl->fReset)
3840 ataDMATransferStop(s);
3841 /* This forces the loop to exit immediately. */
3842 pDesc = pCtl->pLastDMADesc + 1;
3843 }
3844
3845 PDMCritSectLeave(&pCtl->lock);
3846 }
3847
3848 {
3849 STAM_PROFILE_START(&pCtl->StatLockWait, a);
3850 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
3851 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
3852 }
3853
3854 if (RT_UNLIKELY(fRedo))
3855 return;
3856
3857 if (fLastDesc)
3858 pCtl->BmDma.u8Status &= ~BM_STATUS_DMAING;
3859 s->cbTotalTransfer = cbTotalTransfer;
3860 s->cbElementaryTransfer = cbElementaryTransfer;
3861 s->iIOBufferCur = iIOBufferCur;
3862 s->iIOBufferEnd = iIOBufferEnd;
3863}
3864
3865
3866static void ataPIOTransfer(PATACONTROLLER pCtl)
3867{
3868 ATADevState *s;
3869
3870 s = &pCtl->aIfs[pCtl->iAIOIf];
3871 Log3(("%s: if=%p\n", __FUNCTION__, s));
3872
3873 if (s->cbTotalTransfer && s->iIOBufferCur > s->iIOBufferEnd)
3874 {
3875 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"));
3876 /* Any guest OS that triggers this case has a pathetic ATA driver.
3877 * In a real system it would block the CPU via IORDY, here we do it
3878 * very similarly by not continuing with the current instruction
3879 * until the transfer to/from the storage medium is completed. */
3880 if (s->iSourceSink != ATAFN_SS_NULL)
3881 {
3882 bool fRedo;
3883 uint8_t status = s->uATARegStatus;
3884 ataSetStatusValue(s, ATA_STAT_BUSY);
3885 Log2(("%s: calling source/sink function\n", __FUNCTION__));
3886 fRedo = g_apfnSourceSinkFuncs[s->iSourceSink](s);
3887 pCtl->fRedo = fRedo;
3888 if (RT_UNLIKELY(fRedo))
3889 return;
3890 ataSetStatusValue(s, status);
3891 s->iIOBufferCur = 0;
3892 s->iIOBufferEnd = s->cbElementaryTransfer;
3893 }
3894 }
3895 if (s->cbTotalTransfer)
3896 {
3897 if (s->fATAPITransfer)
3898 ataPIOTransferLimitATAPI(s);
3899
3900 if (s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE && s->cbElementaryTransfer > s->cbTotalTransfer)
3901 s->cbElementaryTransfer = s->cbTotalTransfer;
3902
3903 Log2(("%s: %s tx_size=%d elem_tx_size=%d index=%d end=%d\n",
3904 __FUNCTION__, s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE ? "T2I" : "I2T",
3905 s->cbTotalTransfer, s->cbElementaryTransfer,
3906 s->iIOBufferCur, s->iIOBufferEnd));
3907 ataPIOTransferStart(s, s->iIOBufferCur, s->cbElementaryTransfer);
3908 s->cbTotalTransfer -= s->cbElementaryTransfer;
3909 s->iIOBufferCur += s->cbElementaryTransfer;
3910
3911 if (s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE && s->cbElementaryTransfer > s->cbTotalTransfer)
3912 s->cbElementaryTransfer = s->cbTotalTransfer;
3913 }
3914 else
3915 ataPIOTransferStop(s);
3916}
3917
3918
3919/**
3920 * Suspend I/O operations on a controller. Also suspends EMT, because it's
3921 * waiting for I/O to make progress. The next attempt to perform an I/O
3922 * operation will be made when EMT is resumed up again (as the resume
3923 * callback below restarts I/O).
3924 *
3925 * @param pCtl Controller for which to suspend I/O.
3926 */
3927static void ataSuspendRedo(PATACONTROLLER pCtl)
3928{
3929 PPDMDEVINS pDevIns = CONTROLLER_2_DEVINS(pCtl);
3930 PVMREQ pReq;
3931 int rc;
3932
3933 pCtl->fRedoIdle = true;
3934 rc = VMR3ReqCall(PDMDevHlpGetVM(pDevIns), &pReq, RT_INDEFINITE_WAIT,
3935 (PFNRT)pDevIns->pDevHlp->pfnVMSuspend, 1, pDevIns);
3936 AssertReleaseRC(rc);
3937 VMR3ReqFree(pReq);
3938}
3939
3940/** Asynch I/O thread for an interface. Once upon a time this was readable
3941 * code with several loops and a different semaphore for each purpose. But
3942 * then came the "how can one save the state in the middle of a PIO transfer"
3943 * question. The solution was to use an ASM, which is what's there now. */
3944static DECLCALLBACK(int) ataAsyncIOLoop(RTTHREAD ThreadSelf, void *pvUser)
3945{
3946 const ATARequest *pReq;
3947 uint64_t u64TS = 0; /* shut up gcc */
3948 uint64_t uWait;
3949 int rc = VINF_SUCCESS;
3950 PATACONTROLLER pCtl = (PATACONTROLLER)pvUser;
3951 ATADevState *s;
3952
3953 pReq = NULL;
3954 pCtl->fChainedTransfer = false;
3955 while (!pCtl->fShutdown)
3956 {
3957 /* Keep this thread from doing anything as long as EMT is suspended. */
3958 while (pCtl->fRedoIdle)
3959 {
3960 rc = RTSemEventWait(pCtl->SuspendIOSem, RT_INDEFINITE_WAIT);
3961 if (VBOX_FAILURE(rc) || pCtl->fShutdown)
3962 break;
3963
3964 pCtl->fRedoIdle = false;
3965 }
3966
3967 /* Wait for work. */
3968 if (pReq == NULL)
3969 {
3970 rc = RTSemEventWait(pCtl->AsyncIOSem, RT_INDEFINITE_WAIT);
3971 if (VBOX_FAILURE(rc) || pCtl->fShutdown)
3972 break;
3973
3974 pReq = ataAsyncIOGetCurrentRequest(pCtl);
3975 }
3976
3977 if (pReq == NULL)
3978 continue;
3979
3980 ATAAIO ReqType = pReq->ReqType;
3981
3982 Log2(("%s: Ctl#%d: state=%d, req=%d\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl), pCtl->uAsyncIOState, ReqType));
3983 if (pCtl->uAsyncIOState != ReqType)
3984 {
3985 /* The new state is not the state that was expected by the normal
3986 * state changes. This is either a RESET/ABORT or there's something
3987 * really strange going on. */
3988 if ( (pCtl->uAsyncIOState == ATA_AIO_PIO || pCtl->uAsyncIOState == ATA_AIO_DMA)
3989 && (ReqType == ATA_AIO_PIO || ReqType == ATA_AIO_DMA))
3990 {
3991 /* Incorrect sequence of PIO/DMA states. Dump request queue. */
3992 ataAsyncIODumpRequests(pCtl);
3993 }
3994 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));
3995 }
3996
3997 /* Do our work. */
3998 {
3999 STAM_PROFILE_START(&pCtl->StatLockWait, a);
4000 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
4001 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
4002 }
4003
4004 if (pCtl->uAsyncIOState == ATA_AIO_NEW && !pCtl->fChainedTransfer)
4005 {
4006 u64TS = RTTimeNanoTS();
4007#if defined(DEBUG) || defined(VBOX_WITH_STATISTICS)
4008 STAM_PROFILE_ADV_START(&pCtl->StatAsyncTime, a);
4009#endif /* DEBUG || VBOX_WITH_STATISTICS */
4010 }
4011
4012 switch (ReqType)
4013 {
4014 case ATA_AIO_NEW:
4015
4016 pCtl->iAIOIf = pReq->u.t.iIf;
4017 s = &pCtl->aIfs[pCtl->iAIOIf];
4018 s->cbTotalTransfer = pReq->u.t.cbTotalTransfer;
4019 s->uTxDir = pReq->u.t.uTxDir;
4020 s->iBeginTransfer = pReq->u.t.iBeginTransfer;
4021 s->iSourceSink = pReq->u.t.iSourceSink;
4022 s->iIOBufferEnd = 0;
4023
4024 pCtl->fChainedTransfer = false;
4025
4026 if (s->iBeginTransfer != ATAFN_BT_NULL)
4027 {
4028 Log2(("%s: Ctl#%d: calling begin transfer function\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
4029 g_apfnBeginTransFuncs[s->iBeginTransfer](s);
4030 s->iBeginTransfer = ATAFN_BT_NULL;
4031 if (s->uTxDir != PDMBLOCKTXDIR_FROM_DEVICE)
4032 s->iIOBufferEnd = s->cbElementaryTransfer;
4033 }
4034 else
4035 {
4036 s->cbElementaryTransfer = s->cbTotalTransfer;
4037 s->iIOBufferEnd = s->cbTotalTransfer;
4038 }
4039 s->iIOBufferCur = 0;
4040
4041 if (s->uTxDir != PDMBLOCKTXDIR_TO_DEVICE)
4042 {
4043 if (s->iSourceSink != ATAFN_SS_NULL)
4044 {
4045 bool fRedo;
4046 Log2(("%s: Ctl#%d: calling source/sink function\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
4047 fRedo = g_apfnSourceSinkFuncs[s->iSourceSink](s);
4048 pCtl->fRedo = fRedo;
4049 if (RT_UNLIKELY(fRedo))
4050 {
4051 /* Operation failed at the initial transfer, restart
4052 * everything from scratch by resending the current
4053 * request. Occurs very rarely, not worth optimizing. */
4054 LogRel(("%s: Ctl#%d: redo entire operation\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
4055 ataAsyncIOPutRequest(pCtl, pReq);
4056 ataSuspendRedo(pCtl);
4057 break;
4058 }
4059 }
4060 else
4061 ataCmdOK(s, 0);
4062 s->iIOBufferEnd = s->cbElementaryTransfer;
4063
4064 }
4065
4066 /* Do not go into the transfer phase if RESET is asserted.
4067 * The CritSect is released while waiting for the host OS
4068 * to finish the I/O, thus RESET is possible here. Most
4069 * important: do not change uAsyncIOState. */
4070 if (pCtl->fReset)
4071 break;
4072
4073 if (s->fDMA)
4074 {
4075 if (s->cbTotalTransfer)
4076 {
4077 ataSetStatus(s, ATA_STAT_DRQ);
4078
4079 pCtl->uAsyncIOState = ATA_AIO_DMA;
4080 /* If BMDMA is already started, do the transfer now. */
4081 if (pCtl->BmDma.u8Cmd & BM_CMD_START)
4082 {
4083 Log2(("%s: Ctl#%d: message to async I/O thread, continuing DMA transfer immediately\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
4084 ataAsyncIOPutRequest(pCtl, &ataDMARequest);
4085 }
4086 }
4087 else
4088 {
4089 Assert(s->uTxDir == PDMBLOCKTXDIR_NONE); /* Any transfer which has an initial transfer size of 0 must be marked as such. */
4090 /* Finish DMA transfer. */
4091 ataDMATransferStop(s);
4092 ataSetIRQ(s);
4093 pCtl->uAsyncIOState = ATA_AIO_NEW;
4094 }
4095 }
4096 else
4097 {
4098 if (s->cbTotalTransfer)
4099 {
4100 ataPIOTransfer(pCtl);
4101 Assert(!pCtl->fRedo);
4102 if (s->fATAPITransfer || s->uTxDir != PDMBLOCKTXDIR_TO_DEVICE)
4103 ataSetIRQ(s);
4104
4105 pCtl->uAsyncIOState = ATA_AIO_PIO;
4106 }
4107 else
4108 {
4109 Assert(s->uTxDir == PDMBLOCKTXDIR_NONE); /* Any transfer which has an initial transfer size of 0 must be marked as such. */
4110 /* Finish PIO transfer. */
4111 ataPIOTransfer(pCtl);
4112 Assert(!pCtl->fRedo);
4113 if (!s->fATAPITransfer)
4114 ataSetIRQ(s);
4115 pCtl->uAsyncIOState = ATA_AIO_NEW;
4116 }
4117 }
4118 break;
4119
4120 case ATA_AIO_DMA:
4121 {
4122 BMDMAState *bm = &pCtl->BmDma;
4123 s = &pCtl->aIfs[pCtl->iAIOIf]; /* Do not remove or there's an instant crash after loading the saved state */
4124 ATAFNSS iOriginalSourceSink = (ATAFNSS)s->iSourceSink; /* Used by the hack below, but gets reset by then. */
4125
4126 if (s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE)
4127 AssertRelease(bm->u8Cmd & BM_CMD_WRITE);
4128 else
4129 AssertRelease(!(bm->u8Cmd & BM_CMD_WRITE));
4130
4131 if (RT_LIKELY(!pCtl->fRedo))
4132 {
4133 /* The specs say that the descriptor table must not cross a
4134 * 4K boundary. */
4135 pCtl->pFirstDMADesc = bm->pvAddr;
4136 pCtl->pLastDMADesc = RT_ALIGN_32(bm->pvAddr + 1, _4K) - sizeof(BMDMADesc);
4137 }
4138 ataDMATransfer(pCtl);
4139
4140 if (RT_UNLIKELY(pCtl->fRedo))
4141 {
4142 LogRel(("PIIX3 ATA: Ctl#%d: redo DMA operation\n", ATACONTROLLER_IDX(pCtl)));
4143 ataAsyncIOPutRequest(pCtl, &ataDMARequest);
4144 ataSuspendRedo(pCtl);
4145 break;
4146 }
4147
4148 /* The infamous delay IRQ hack. */
4149 if ( iOriginalSourceSink == ATAFN_SS_WRITE_SECTORS
4150 && s->cbTotalTransfer == 0
4151 && pCtl->DelayIRQMillies)
4152 {
4153 /* Delay IRQ for writing. Required to get the Win2K
4154 * installation work reliably (otherwise it crashes,
4155 * usually during component install). So far no better
4156 * solution has been found. */
4157 Log(("%s: delay IRQ hack\n", __FUNCTION__));
4158 PDMCritSectLeave(&pCtl->lock);
4159 RTThreadSleep(pCtl->DelayIRQMillies);
4160 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
4161 }
4162
4163 ataUnsetStatus(s, ATA_STAT_DRQ);
4164 Assert(!pCtl->fChainedTransfer);
4165 Assert(s->iSourceSink == ATAFN_SS_NULL);
4166 if (s->fATAPITransfer)
4167 {
4168 s->uATARegNSector = (s->uATARegNSector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
4169 Log2(("%s: Ctl#%d: interrupt reason %#04x\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl), s->uATARegNSector));
4170 s->fATAPITransfer = false;
4171 }
4172 ataSetIRQ(s);
4173 pCtl->uAsyncIOState = ATA_AIO_NEW;
4174 break;
4175 }
4176
4177 case ATA_AIO_PIO:
4178 s = &pCtl->aIfs[pCtl->iAIOIf]; /* Do not remove or there's an instant crash after loading the saved state */
4179
4180 if (s->iSourceSink != ATAFN_SS_NULL)
4181 {
4182 bool fRedo;
4183 Log2(("%s: Ctl#%d: calling source/sink function\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
4184 fRedo = g_apfnSourceSinkFuncs[s->iSourceSink](s);
4185 pCtl->fRedo = fRedo;
4186 if (RT_UNLIKELY(fRedo))
4187 {
4188 LogRel(("PIIX3 ATA: Ctl#%d: redo PIO operation\n", ATACONTROLLER_IDX(pCtl)));
4189 ataAsyncIOPutRequest(pCtl, &ataPIORequest);
4190 ataSuspendRedo(pCtl);
4191 break;
4192 }
4193 s->iIOBufferCur = 0;
4194 s->iIOBufferEnd = s->cbElementaryTransfer;
4195 }
4196 else
4197 {
4198 /* Continue a previously started transfer. */
4199 ataUnsetStatus(s, ATA_STAT_BUSY);
4200 ataSetStatus(s, ATA_STAT_READY);
4201 }
4202
4203 /* It is possible that the drives on this controller get RESET
4204 * during the above call to the source/sink function. If that's
4205 * the case, don't restart the transfer and don't finish it the
4206 * usual way. RESET handling took care of all that already.
4207 * Most important: do not change uAsyncIOState. */
4208 if (pCtl->fReset)
4209 break;
4210
4211 if (s->cbTotalTransfer)
4212 {
4213 ataPIOTransfer(pCtl);
4214 ataSetIRQ(s);
4215
4216 pCtl->uAsyncIOState = ATA_AIO_PIO;
4217 }
4218 else
4219 {
4220 /* Finish PIO transfer. */
4221 ataPIOTransfer(pCtl);
4222 pCtl->uAsyncIOState = ATA_AIO_NEW;
4223 if (!pCtl->fChainedTransfer)
4224 {
4225 if (!s->fATAPITransfer && s->uTxDir != PDMBLOCKTXDIR_FROM_DEVICE)
4226 ataSetIRQ(s);
4227 }
4228 }
4229 break;
4230
4231 case ATA_AIO_RESET_ASSERTED:
4232 pCtl->uAsyncIOState = ATA_AIO_RESET_CLEARED;
4233 ataPIOTransferStop(&pCtl->aIfs[0]);
4234 ataPIOTransferStop(&pCtl->aIfs[1]);
4235 /* Do not change the DMA registers, they are not affected by the
4236 * ATA controller reset logic. It should be sufficient to issue a
4237 * new command, which is now possible as the state is cleared. */
4238 break;
4239
4240 case ATA_AIO_RESET_CLEARED:
4241 pCtl->uAsyncIOState = ATA_AIO_NEW;
4242 pCtl->fReset = false;
4243 for (uint32_t i = 0; i < RT_ELEMENTS(pCtl->aIfs); i++)
4244 {
4245 if (pCtl->aIfs[i].fATAPI)
4246 ataSetStatusValue(&pCtl->aIfs[i], 0); /* NOTE: READY is _not_ set */
4247 else
4248 ataSetStatusValue(&pCtl->aIfs[i], ATA_STAT_READY | ATA_STAT_SEEK);
4249 ataSetSignature(&pCtl->aIfs[i]);
4250 }
4251 break;
4252
4253 case ATA_AIO_ABORT:
4254 /* Abort the current command only if it operates on the same interface. */
4255 if (pCtl->iAIOIf == pReq->u.a.iIf)
4256 {
4257 s = &pCtl->aIfs[pCtl->iAIOIf];
4258
4259 pCtl->uAsyncIOState = ATA_AIO_NEW;
4260 /* Do not change the DMA registers, they are not affected by the
4261 * ATA controller reset logic. It should be sufficient to issue a
4262 * new command, which is now possible as the state is cleared. */
4263 if (pReq->u.a.fResetDrive)
4264 {
4265 ataResetDevice(s);
4266 ataExecuteDeviceDiagnosticSS(s);
4267 }
4268 else
4269 {
4270 ataPIOTransferStop(s);
4271 ataUnsetStatus(s, ATA_STAT_BUSY | ATA_STAT_DRQ | ATA_STAT_SEEK | ATA_STAT_ERR);
4272 ataSetStatus(s, ATA_STAT_READY);
4273 ataSetIRQ(s);
4274 }
4275 }
4276 break;
4277
4278 default:
4279 AssertMsgFailed(("Undefined async I/O state %d\n", pCtl->uAsyncIOState));
4280 }
4281
4282 ataAsyncIORemoveCurrentRequest(pCtl, ReqType);
4283 pReq = ataAsyncIOGetCurrentRequest(pCtl);
4284
4285 if (pCtl->uAsyncIOState == ATA_AIO_NEW && !pCtl->fChainedTransfer)
4286 {
4287#if defined(DEBUG) || defined(VBOX_WITH_STATISTICS)
4288 STAM_PROFILE_ADV_STOP(&pCtl->StatAsyncTime, a);
4289#endif /* DEBUG || VBOX_WITH_STATISTICS */
4290
4291 u64TS = RTTimeNanoTS() - u64TS;
4292 uWait = u64TS / 1000;
4293 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)));
4294
4295 /*
4296 * Release logging of command execution times depends on the
4297 * command type. ATAPI commands often take longer (due to CD/DVD
4298 * spin up time etc.) so the threshold is different.
4299 */
4300 if (pCtl->aIfs[pCtl->iAIOIf].uATARegCommand != ATA_PACKET)
4301 {
4302 if (uWait > 10 * 1000 * 1000)
4303 {
4304 /*
4305 * Command took longer than 10 seconds. This is close
4306 * enough or over the guest's command timeout, so place
4307 * an entry in the release log to allow tracking such
4308 * timing errors (which are often caused by the host).
4309 */
4310 LogRel(("PIIX3 ATA: execution time for ATA command %#04x was %d seconds\n", pCtl->aIfs[pCtl->iAIOIf].uATARegCommand, uWait / (1000 * 1000)));
4311 }
4312 }
4313 else
4314 {
4315 if (uWait > 20 * 1000 * 1000)
4316 {
4317 /*
4318 * Command took longer than 20 seconds. This is close
4319 * enough or over the guest's command timeout, so place
4320 * an entry in the release log to allow tracking such
4321 * timing errors (which are often caused by the host).
4322 */
4323 LogRel(("PIIX3 ATA: execution time for ATAPI command %#04x was %d seconds\n", pCtl->aIfs[pCtl->iAIOIf].aATAPICmd[0], uWait / (1000 * 1000)));
4324 }
4325 }
4326
4327#if defined(DEBUG) || defined(VBOX_WITH_STATISTICS)
4328 if (uWait < pCtl->StatAsyncMinWait || !pCtl->StatAsyncMinWait)
4329 pCtl->StatAsyncMinWait = uWait;
4330 if (uWait > pCtl->StatAsyncMaxWait)
4331 pCtl->StatAsyncMaxWait = uWait;
4332
4333 STAM_COUNTER_ADD(&pCtl->StatAsyncTimeUS, uWait);
4334 STAM_COUNTER_INC(&pCtl->StatAsyncOps);
4335#endif /* DEBUG || VBOX_WITH_STATISTICS */
4336 }
4337
4338 PDMCritSectLeave(&pCtl->lock);
4339 }
4340
4341 /* Cleanup the state. */
4342 if (pCtl->AsyncIOSem)
4343 {
4344 RTSemEventDestroy(pCtl->AsyncIOSem);
4345 pCtl->AsyncIOSem = NIL_RTSEMEVENT;
4346 }
4347 if (pCtl->SuspendIOSem)
4348 {
4349 RTSemEventDestroy(pCtl->SuspendIOSem);
4350 pCtl->SuspendIOSem = NIL_RTSEMEVENT;
4351 }
4352 /* Do not destroy request mutex yet, still needed for proper shutdown. */
4353 pCtl->fShutdown = false;
4354 /* This must be last, as it also signals thread exit to EMT. */
4355 pCtl->AsyncIOThread = NIL_RTTHREAD;
4356
4357 Log2(("%s: Ctl#%d: return %Vrc\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl), rc));
4358 return rc;
4359}
4360
4361#endif /* IN_RING3 */
4362
4363static uint32_t ataBMDMACmdReadB(PATACONTROLLER pCtl, uint32_t addr)
4364{
4365 uint32_t val = pCtl->BmDma.u8Cmd;
4366 Log2(("%s: addr=%#06x val=%#04x\n", __FUNCTION__, addr, val));
4367 return val;
4368}
4369
4370
4371static void ataBMDMACmdWriteB(PATACONTROLLER pCtl, uint32_t addr, uint32_t val)
4372{
4373 Log2(("%s: addr=%#06x val=%#04x\n", __FUNCTION__, addr, val));
4374 if (!(val & BM_CMD_START))
4375 {
4376 pCtl->BmDma.u8Status &= ~BM_STATUS_DMAING;
4377 pCtl->BmDma.u8Cmd = val & (BM_CMD_START | BM_CMD_WRITE);
4378 }
4379 else
4380 {
4381#ifdef IN_RING3
4382 /* Check whether the guest OS wants to change DMA direction in
4383 * mid-flight. Not allowed, according to the PIIX3 specs. */
4384 Assert(!(pCtl->BmDma.u8Status & BM_STATUS_DMAING) || !((val ^ pCtl->BmDma.u8Cmd) & 0x04));
4385 pCtl->BmDma.u8Status |= BM_STATUS_DMAING;
4386 pCtl->BmDma.u8Cmd = val & (BM_CMD_START | BM_CMD_WRITE);
4387
4388 /* Do not continue DMA transfers while the RESET line is asserted. */
4389 if (pCtl->fReset)
4390 {
4391 Log2(("%s: Ctl#%d: suppressed continuing DMA transfer as RESET is active\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
4392 return;
4393 }
4394
4395 /* Do not start DMA transfers if there's a PIO transfer going on. */
4396 if (!pCtl->aIfs[pCtl->iSelectedIf].fDMA)
4397 return;
4398
4399 if (pCtl->aIfs[pCtl->iAIOIf].uATARegStatus & ATA_STAT_DRQ)
4400 {
4401 Log2(("%s: Ctl#%d: message to async I/O thread, continuing DMA transfer\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
4402 ataAsyncIOPutRequest(pCtl, &ataDMARequest);
4403 }
4404#else /* !IN_RING3 */
4405 AssertMsgFailed(("DMA START handling is too complicated for GC\n"));
4406#endif /* IN_RING3 */
4407 }
4408}
4409
4410static uint32_t ataBMDMAStatusReadB(PATACONTROLLER pCtl, uint32_t addr)
4411{
4412 uint32_t val = pCtl->BmDma.u8Status;
4413 Log2(("%s: addr=%#06x val=%#04x\n", __FUNCTION__, addr, val));
4414 return val;
4415}
4416
4417static void ataBMDMAStatusWriteB(PATACONTROLLER pCtl, uint32_t addr, uint32_t val)
4418{
4419 Log2(("%s: addr=%#06x val=%#04x\n", __FUNCTION__, addr, val));
4420 pCtl->BmDma.u8Status = (val & (BM_STATUS_D0DMA | BM_STATUS_D1DMA))
4421 | (pCtl->BmDma.u8Status & BM_STATUS_DMAING)
4422 | (pCtl->BmDma.u8Status & ~val & (BM_STATUS_ERROR | BM_STATUS_INT));
4423}
4424
4425static uint32_t ataBMDMAAddrReadL(PATACONTROLLER pCtl, uint32_t addr)
4426{
4427 uint32_t val = (uint32_t)pCtl->BmDma.pvAddr;
4428 Log2(("%s: addr=%#06x val=%#010x\n", __FUNCTION__, addr, val));
4429 return val;
4430}
4431
4432static void ataBMDMAAddrWriteL(PATACONTROLLER pCtl, uint32_t addr, uint32_t val)
4433{
4434 Log2(("%s: addr=%#06x val=%#010x\n", __FUNCTION__, addr, val));
4435 pCtl->BmDma.pvAddr = val & ~3;
4436}
4437
4438static void ataBMDMAAddrWriteLowWord(PATACONTROLLER pCtl, uint32_t addr, uint32_t val)
4439{
4440 Log2(("%s: addr=%#06x val=%#010x\n", __FUNCTION__, addr, val));
4441 pCtl->BmDma.pvAddr = (pCtl->BmDma.pvAddr & 0xFFFF0000) | RT_LOWORD(val & ~3);
4442
4443}
4444
4445static void ataBMDMAAddrWriteHighWord(PATACONTROLLER pCtl, uint32_t addr, uint32_t val)
4446{
4447 Log2(("%s: addr=%#06x val=%#010x\n", __FUNCTION__, addr, val));
4448 pCtl->BmDma.pvAddr = (RT_LOWORD(val) << 16) | RT_LOWORD(pCtl->BmDma.pvAddr);
4449}
4450
4451#define VAL(port, size) ( ((port) & 7) | ((size) << 3) )
4452
4453/**
4454 * Port I/O Handler for bus master DMA IN operations.
4455 * @see FNIOMIOPORTIN for details.
4456 */
4457PDMBOTHCBDECL(int) ataBMDMAIOPortRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
4458{
4459 uint32_t i = (uint32_t)(uintptr_t)pvUser;
4460 PCIATAState *pData = PDMINS2DATA(pDevIns, PCIATAState *);
4461 PATACONTROLLER pCtl = &pData->aCts[i];
4462 int rc;
4463
4464 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_HC_IOPORT_READ);
4465 if (rc != VINF_SUCCESS)
4466 return rc;
4467 switch (VAL(Port, cb))
4468 {
4469 case VAL(0, 1): *pu32 = ataBMDMACmdReadB(pCtl, Port); break;
4470 case VAL(0, 2): *pu32 = ataBMDMACmdReadB(pCtl, Port); break;
4471 case VAL(2, 1): *pu32 = ataBMDMAStatusReadB(pCtl, Port); break;
4472 case VAL(2, 2): *pu32 = ataBMDMAStatusReadB(pCtl, Port); break;
4473 case VAL(4, 4): *pu32 = ataBMDMAAddrReadL(pCtl, Port); break;
4474 default:
4475 AssertMsgFailed(("%s: Unsupported read from port %x size=%d\n", __FUNCTION__, Port, cb));
4476 PDMCritSectLeave(&pCtl->lock);
4477 return VERR_IOM_IOPORT_UNUSED;
4478 }
4479 PDMCritSectLeave(&pCtl->lock);
4480 return rc;
4481}
4482
4483/**
4484 * Port I/O Handler for bus master DMA OUT operations.
4485 * @see FNIOMIOPORTOUT for details.
4486 */
4487PDMBOTHCBDECL(int) ataBMDMAIOPortWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
4488{
4489 uint32_t i = (uint32_t)(uintptr_t)pvUser;
4490 PCIATAState *pData = PDMINS2DATA(pDevIns, PCIATAState *);
4491 PATACONTROLLER pCtl = &pData->aCts[i];
4492 int rc;
4493
4494 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_HC_IOPORT_WRITE);
4495 if (rc != VINF_SUCCESS)
4496 return rc;
4497 switch (VAL(Port, cb))
4498 {
4499 case VAL(0, 1):
4500#ifndef IN_RING3
4501 if (u32 & BM_CMD_START)
4502 {
4503 rc = VINF_IOM_HC_IOPORT_WRITE;
4504 break;
4505 }
4506#endif /* !IN_RING3 */
4507 ataBMDMACmdWriteB(pCtl, Port, u32);
4508 break;
4509 case VAL(2, 1): ataBMDMAStatusWriteB(pCtl, Port, u32); break;
4510 case VAL(4, 4): ataBMDMAAddrWriteL(pCtl, Port, u32); break;
4511 case VAL(4, 2): ataBMDMAAddrWriteLowWord(pCtl, Port, u32); break;
4512 case VAL(6, 2): ataBMDMAAddrWriteHighWord(pCtl, Port, u32); break;
4513 default: AssertMsgFailed(("%s: Unsupported write to port %x size=%d val=%x\n", __FUNCTION__, Port, cb, u32)); break;
4514 }
4515 PDMCritSectLeave(&pCtl->lock);
4516 return rc;
4517}
4518
4519#undef VAL
4520
4521#ifdef IN_RING3
4522
4523/**
4524 * Callback function for mapping an PCI I/O region.
4525 *
4526 * @return VBox status code.
4527 * @param pPciDev Pointer to PCI device. Use pPciDev->pDevIns to get the device instance.
4528 * @param iRegion The region number.
4529 * @param GCPhysAddress Physical address of the region. If iType is PCI_ADDRESS_SPACE_IO, this is an
4530 * I/O port, else it's a physical address.
4531 * This address is *NOT* relative to pci_mem_base like earlier!
4532 * @param enmType One of the PCI_ADDRESS_SPACE_* values.
4533 */
4534static DECLCALLBACK(int) ataBMDMAIORangeMap(PPCIDEVICE pPciDev, /*unsigned*/ int iRegion, RTGCPHYS GCPhysAddress, uint32_t cb, PCIADDRESSSPACE enmType)
4535{
4536 PCIATAState *pData = PCIDEV_2_PCIATASTATE(pPciDev);
4537 int rc = VINF_SUCCESS;
4538 Assert(enmType == PCI_ADDRESS_SPACE_IO);
4539 Assert(iRegion == 4);
4540 AssertMsg(RT_ALIGN(GCPhysAddress, 8) == GCPhysAddress, ("Expected 8 byte alignment. GCPhysAddress=%#x\n", GCPhysAddress));
4541
4542 /* Register the port range. */
4543 for (uint32_t i = 0; i < RT_ELEMENTS(pData->aCts); i++)
4544 {
4545 int rc2 = PDMDevHlpIOPortRegister(pPciDev->pDevIns, (RTIOPORT)GCPhysAddress + i * 8, 8,
4546 (RTHCPTR)i, ataBMDMAIOPortWrite, ataBMDMAIOPortRead, NULL, NULL, "ATA Bus Master DMA");
4547 AssertRC(rc2);
4548 if (rc2 < rc)
4549 rc = rc2;
4550
4551 if (pData->fGCEnabled)
4552 {
4553 rc2 = PDMDevHlpIOPortRegisterGC(pPciDev->pDevIns, (RTIOPORT)GCPhysAddress + i * 8, 8,
4554 (RTGCPTR)i, "ataBMDMAIOPortWrite", "ataBMDMAIOPortRead", NULL, NULL, "ATA Bus Master DMA");
4555 AssertRC(rc2);
4556 if (rc2 < rc)
4557 rc = rc2;
4558 }
4559 if (pData->fR0Enabled)
4560 {
4561 rc2 = PDMDevHlpIOPortRegisterR0(pPciDev->pDevIns, (RTIOPORT)GCPhysAddress + i * 8, 8,
4562 (RTHCPTR)i, "ataBMDMAIOPortWrite", "ataBMDMAIOPortRead", NULL, NULL, "ATA Bus Master DMA");
4563 AssertRC(rc2);
4564 if (rc2 < rc)
4565 rc = rc2;
4566 }
4567 }
4568 return rc;
4569}
4570
4571
4572/**
4573 * Reset notification.
4574 *
4575 * @returns VBox status.
4576 * @param pDevIns The device instance data.
4577 */
4578static DECLCALLBACK(void) ataReset(PPDMDEVINS pDevIns)
4579{
4580 PCIATAState *pData = PDMINS2DATA(pDevIns, PCIATAState *);
4581
4582 for (uint32_t i = 0; i < RT_ELEMENTS(pData->aCts); i++)
4583 {
4584 pData->aCts[i].iSelectedIf = 0;
4585 pData->aCts[i].iAIOIf = 0;
4586 pData->aCts[i].BmDma.u8Cmd = 0;
4587 /* Report that both drives present on the bus are in DMA mode. This
4588 * pretends that there is a BIOS that has set it up. Normal reset
4589 * default is 0x00. */
4590 pData->aCts[i].BmDma.u8Status = (pData->aCts[i].aIfs[0].pDrvBase != NULL ? BM_STATUS_D0DMA : 0)
4591 | (pData->aCts[i].aIfs[1].pDrvBase != NULL ? BM_STATUS_D1DMA : 0);
4592 pData->aCts[i].BmDma.pvAddr = 0;
4593
4594 pData->aCts[i].fReset = true;
4595 pData->aCts[i].fRedo = false;
4596 pData->aCts[i].fRedoIdle = false;
4597 ataAsyncIOClearRequests(&pData->aCts[i]);
4598 Log2(("%s: Ctl#%d: message to async I/O thread, reset controller\n", __FUNCTION__, i));
4599 ataAsyncIOPutRequest(&pData->aCts[i], &ataResetARequest);
4600 ataAsyncIOPutRequest(&pData->aCts[i], &ataResetCRequest);
4601 if (!ataWaitForAsyncIOIsIdle(&pData->aCts[i], 30000))
4602 AssertReleaseMsgFailed(("Async I/O thread busy after reset\n"));
4603
4604 for (uint32_t j = 0; j < RT_ELEMENTS(pData->aCts[i].aIfs); j++)
4605 ataResetDevice(&pData->aCts[i].aIfs[j]);
4606 }
4607}
4608
4609
4610/* -=-=-=-=-=- PCIATAState::IBase -=-=-=-=-=- */
4611
4612/**
4613 * Queries an interface to the driver.
4614 *
4615 * @returns Pointer to interface.
4616 * @returns NULL if the interface was not supported by the device.
4617 * @param pInterface Pointer to ATADevState::IBase.
4618 * @param enmInterface The requested interface identification.
4619 */
4620static DECLCALLBACK(void *) ataStatus_QueryInterface(PPDMIBASE pInterface, PDMINTERFACE enmInterface)
4621{
4622 PCIATAState *pData = PDMIBASE_2_PCIATASTATE(pInterface);
4623 switch (enmInterface)
4624 {
4625 case PDMINTERFACE_BASE:
4626 return &pData->IBase;
4627 case PDMINTERFACE_LED_PORTS:
4628 return &pData->ILeds;
4629 default:
4630 return NULL;
4631 }
4632}
4633
4634
4635/* -=-=-=-=-=- PCIATAState::ILeds -=-=-=-=-=- */
4636
4637/**
4638 * Gets the pointer to the status LED of a unit.
4639 *
4640 * @returns VBox status code.
4641 * @param pInterface Pointer to the interface structure containing the called function pointer.
4642 * @param iLUN The unit which status LED we desire.
4643 * @param ppLed Where to store the LED pointer.
4644 */
4645static DECLCALLBACK(int) ataStatus_QueryStatusLed(PPDMILEDPORTS pInterface, unsigned iLUN, PPDMLED *ppLed)
4646{
4647 PCIATAState *pData = PDMILEDPORTS_2_PCIATASTATE(pInterface);
4648 if (iLUN >= 0 && iLUN <= 4)
4649 {
4650 switch (iLUN)
4651 {
4652 case 0: *ppLed = &pData->aCts[0].aIfs[0].Led; break;
4653 case 1: *ppLed = &pData->aCts[0].aIfs[1].Led; break;
4654 case 2: *ppLed = &pData->aCts[1].aIfs[0].Led; break;
4655 case 3: *ppLed = &pData->aCts[1].aIfs[1].Led; break;
4656 }
4657 Assert((*ppLed)->u32Magic == PDMLED_MAGIC);
4658 return VINF_SUCCESS;
4659 }
4660 return VERR_PDM_LUN_NOT_FOUND;
4661}
4662
4663
4664/* -=-=-=-=-=- ATADevState::IBase -=-=-=-=-=- */
4665
4666/**
4667 * Queries an interface to the driver.
4668 *
4669 * @returns Pointer to interface.
4670 * @returns NULL if the interface was not supported by the device.
4671 * @param pInterface Pointer to ATADevState::IBase.
4672 * @param enmInterface The requested interface identification.
4673 */
4674static DECLCALLBACK(void *) ataQueryInterface(PPDMIBASE pInterface, PDMINTERFACE enmInterface)
4675{
4676 ATADevState *pIf = PDMIBASE_2_ATASTATE(pInterface);
4677 switch (enmInterface)
4678 {
4679 case PDMINTERFACE_BASE:
4680 return &pIf->IBase;
4681 case PDMINTERFACE_BLOCK_PORT:
4682 return &pIf->IPort;
4683 case PDMINTERFACE_MOUNT_NOTIFY:
4684 return &pIf->IMountNotify;
4685 default:
4686 return NULL;
4687 }
4688}
4689
4690#endif /* IN_RING3 */
4691
4692
4693/* -=-=-=-=-=- Wrappers -=-=-=-=-=- */
4694
4695/**
4696 * Port I/O Handler for primary port range OUT operations.
4697 * @see FNIOMIOPORTOUT for details.
4698 */
4699PDMBOTHCBDECL(int) ataIOPortWrite1(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
4700{
4701 uint32_t i = (uint32_t)(uintptr_t)pvUser;
4702 PCIATAState *pData = PDMINS2DATA(pDevIns, PCIATAState *);
4703 PATACONTROLLER pCtl = &pData->aCts[i];
4704 int rc = VINF_SUCCESS;
4705
4706 Assert(i < 2);
4707
4708 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_HC_IOPORT_WRITE);
4709 if (rc != VINF_SUCCESS)
4710 return rc;
4711 if (cb == 1)
4712 rc = ataIOPortWriteU8(pCtl, Port, u32);
4713 else if (Port == pCtl->IOPortBase1)
4714 {
4715 Assert(cb == 2 || cb == 4);
4716 rc = ataDataWrite(pCtl, Port, cb, (const uint8_t *)&u32);
4717 }
4718 else
4719 AssertMsgFailed(("ataIOPortWrite1: unsupported write to port %x val=%x size=%d\n", Port, u32, cb));
4720 PDMCritSectLeave(&pCtl->lock);
4721 return rc;
4722}
4723
4724
4725/**
4726 * Port I/O Handler for primary port range IN operations.
4727 * @see FNIOMIOPORTIN for details.
4728 */
4729PDMBOTHCBDECL(int) ataIOPortRead1(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
4730{
4731 uint32_t i = (uint32_t)(uintptr_t)pvUser;
4732 PCIATAState *pData = PDMINS2DATA(pDevIns, PCIATAState *);
4733 PATACONTROLLER pCtl = &pData->aCts[i];
4734 int rc = VINF_SUCCESS;
4735
4736 Assert(i < 2);
4737
4738 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_HC_IOPORT_READ);
4739 if (rc != VINF_SUCCESS)
4740 return rc;
4741 if (cb == 1)
4742 {
4743 ataIOPortReadU8(pCtl, Port, pu32);
4744 rc = VINF_SUCCESS;
4745 }
4746 else if (Port == pCtl->IOPortBase1)
4747 {
4748 Assert(cb == 2 || cb == 4);
4749 rc = ataDataRead(pCtl, Port, cb, (uint8_t *)pu32);
4750 if (cb == 2)
4751 *pu32 &= 0xffff;
4752 }
4753 else
4754 {
4755 AssertMsgFailed(("ataIOPortRead1: unsupported read from port %x size=%d\n", Port, cb));
4756 rc = VERR_IOM_IOPORT_UNUSED;
4757 }
4758 PDMCritSectLeave(&pCtl->lock);
4759 return rc;
4760}
4761
4762#ifndef IN_RING0
4763/**
4764 * Port I/O Handler for primary port range IN string operations.
4765 * @see FNIOMIOPORTINSTRING for details.
4766 */
4767PDMBOTHCBDECL(int) ataIOPortReadStr1(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, RTGCPTR *pGCPtrDst, unsigned *pcTransfer, unsigned cb)
4768{
4769 uint32_t i = (uint32_t)(uintptr_t)pvUser;
4770 PCIATAState *pData = PDMINS2DATA(pDevIns, PCIATAState *);
4771 PATACONTROLLER pCtl = &pData->aCts[i];
4772 int rc = VINF_SUCCESS;
4773
4774 Assert(i < 2);
4775
4776 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_HC_IOPORT_READ);
4777 if (rc != VINF_SUCCESS)
4778 return rc;
4779 if (Port == pCtl->IOPortBase1)
4780 {
4781 uint32_t cTransAvailable, cTransfer = *pcTransfer, cbTransfer;
4782 RTGCPTR GCDst = *pGCPtrDst;
4783 ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf];
4784 Assert(cb == 2 || cb == 4);
4785
4786 cTransAvailable = (s->iIOBufferPIODataEnd - s->iIOBufferPIODataStart) / cb;
4787#ifndef IN_RING3
4788 /* The last transfer unit cannot be handled in GC, as it involves thread communication. */
4789 cTransAvailable--;
4790#endif /* !IN_RING3 */
4791 /* Do not handle the dummy transfer stuff here, leave it to the single-word transfers.
4792 * They are not performance-critical and generally shouldn't occur at all. */
4793 if (cTransAvailable > cTransfer)
4794 cTransAvailable = cTransfer;
4795 cbTransfer = cTransAvailable * cb;
4796
4797#ifdef IN_GC
4798 for (uint32_t i = 0; i < cbTransfer; i += cb)
4799 MMGCRamWriteNoTrapHandler((char *)GCDst + i, s->CTXSUFF(pbIOBuffer) + s->iIOBufferPIODataStart + i, cb);
4800#else /* !IN_GC */
4801 rc = PGMPhysWriteGCPtrDirty(PDMDevHlpGetVM(pDevIns), GCDst, s->CTXSUFF(pbIOBuffer) + s->iIOBufferPIODataStart, cbTransfer);
4802 Assert(rc == VINF_SUCCESS);
4803#endif /* IN_GC */
4804
4805 if (cbTransfer)
4806 Log3(("%s: addr=%#x val=%.*Vhxs\n", __FUNCTION__, Port, cbTransfer, s->CTXSUFF(pbIOBuffer) + s->iIOBufferPIODataStart));
4807 s->iIOBufferPIODataStart += cbTransfer;
4808 *pGCPtrDst = (RTGCPTR)((RTGCUINTPTR)GCDst + cbTransfer);
4809 *pcTransfer = cTransfer - cTransAvailable;
4810#ifdef IN_RING3
4811 if (s->iIOBufferPIODataStart >= s->iIOBufferPIODataEnd)
4812 ataPIOTransferFinish(pCtl, s);
4813#endif /* IN_RING3 */
4814 }
4815 PDMCritSectLeave(&pCtl->lock);
4816 return rc;
4817}
4818
4819
4820/**
4821 * Port I/O Handler for primary port range OUT string operations.
4822 * @see FNIOMIOPORTOUTSTRING for details.
4823 */
4824PDMBOTHCBDECL(int) ataIOPortWriteStr1(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, RTGCPTR *pGCPtrSrc, unsigned *pcTransfer, unsigned cb)
4825{
4826 uint32_t i = (uint32_t)(uintptr_t)pvUser;
4827 PCIATAState *pData = PDMINS2DATA(pDevIns, PCIATAState *);
4828 PATACONTROLLER pCtl = &pData->aCts[i];
4829 int rc;
4830
4831 Assert(i < 2);
4832
4833 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_HC_IOPORT_WRITE);
4834 if (rc != VINF_SUCCESS)
4835 return rc;
4836 if (Port == pCtl->IOPortBase1)
4837 {
4838 uint32_t cTransAvailable, cTransfer = *pcTransfer, cbTransfer;
4839 RTGCPTR GCSrc = *pGCPtrSrc;
4840 ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf];
4841 Assert(cb == 2 || cb == 4);
4842
4843 cTransAvailable = (s->iIOBufferPIODataEnd - s->iIOBufferPIODataStart) / cb;
4844#ifndef IN_RING3
4845 /* The last transfer unit cannot be handled in GC, as it involves thread communication. */
4846 cTransAvailable--;
4847#endif /* !IN_RING3 */
4848 /* Do not handle the dummy transfer stuff here, leave it to the single-word transfers.
4849 * They are not performance-critical and generally shouldn't occur at all. */
4850 if (cTransAvailable > cTransfer)
4851 cTransAvailable = cTransfer;
4852 cbTransfer = cTransAvailable * cb;
4853
4854#ifdef IN_GC
4855 for (uint32_t i = 0; i < cbTransfer; i += cb)
4856 MMGCRamReadNoTrapHandler(s->CTXSUFF(pbIOBuffer) + s->iIOBufferPIODataStart + i, (char *)GCSrc + i, cb);
4857#else /* !IN_GC */
4858 rc = PGMPhysReadGCPtr(PDMDevHlpGetVM(pDevIns), s->CTXSUFF(pbIOBuffer) + s->iIOBufferPIODataStart, GCSrc, cbTransfer);
4859 Assert(rc == VINF_SUCCESS);
4860#endif /* IN_GC */
4861
4862 if (cbTransfer)
4863 Log3(("%s: addr=%#x val=%.*Vhxs\n", __FUNCTION__, Port, cbTransfer, s->CTXSUFF(pbIOBuffer) + s->iIOBufferPIODataStart));
4864 s->iIOBufferPIODataStart += cbTransfer;
4865 *pGCPtrSrc = (RTGCPTR)((RTGCUINTPTR)GCSrc + cbTransfer);
4866 *pcTransfer = cTransfer - cTransAvailable;
4867#ifdef IN_RING3
4868 if (s->iIOBufferPIODataStart >= s->iIOBufferPIODataEnd)
4869 ataPIOTransferFinish(pCtl, s);
4870#endif /* IN_RING3 */
4871 }
4872 PDMCritSectLeave(&pCtl->lock);
4873 return rc;
4874}
4875#endif /* !IN_RING0 */
4876
4877/**
4878 * Port I/O Handler for secondary port range OUT operations.
4879 * @see FNIOMIOPORTOUT for details.
4880 */
4881PDMBOTHCBDECL(int) ataIOPortWrite2(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
4882{
4883 uint32_t i = (uint32_t)(uintptr_t)pvUser;
4884 PCIATAState *pData = PDMINS2DATA(pDevIns, PCIATAState *);
4885 PATACONTROLLER pCtl = &pData->aCts[i];
4886 int rc;
4887
4888 Assert(i < 2);
4889
4890 if (cb != 1)
4891 return VINF_SUCCESS;
4892 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_HC_IOPORT_WRITE);
4893 if (rc != VINF_SUCCESS)
4894 return rc;
4895 rc = ataControlWrite(pCtl, Port, u32);
4896 PDMCritSectLeave(&pCtl->lock);
4897 return rc;
4898}
4899
4900
4901/**
4902 * Port I/O Handler for secondary port range IN operations.
4903 * @see FNIOMIOPORTIN for details.
4904 */
4905PDMBOTHCBDECL(int) ataIOPortRead2(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
4906{
4907 uint32_t i = (uint32_t)(uintptr_t)pvUser;
4908 PCIATAState *pData = PDMINS2DATA(pDevIns, PCIATAState *);
4909 PATACONTROLLER pCtl = &pData->aCts[i];
4910 int rc;
4911
4912 Assert(i < 2);
4913
4914 if (cb != 1)
4915 return VERR_IOM_IOPORT_UNUSED;
4916
4917 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_HC_IOPORT_READ);
4918 if (rc != VINF_SUCCESS)
4919 return rc;
4920 *pu32 = ataStatusRead(pCtl, Port);
4921 PDMCritSectLeave(&pCtl->lock);
4922 return VINF_SUCCESS;
4923}
4924
4925#ifdef IN_RING3
4926
4927/**
4928 * Waits for all async I/O threads to complete whatever they
4929 * are doing at the moment.
4930 *
4931 * @returns true on success.
4932 * @returns false when one or more threads is still processing.
4933 * @param pData Pointer to the instance data.
4934 * @param cMillies How long to wait (total).
4935 */
4936static bool ataWaitForAllAsyncIOIsIdle(PPDMDEVINS pDevIns, unsigned cMillies)
4937{
4938 PCIATAState *pData = PDMINS2DATA(pDevIns, PCIATAState *);
4939 bool fVMLocked;
4940 uint64_t u64Start;
4941 bool fAllIdle = false;
4942
4943 /* The only way to deal cleanly with the VM lock is to check whether
4944 * it is owned now (it always is owned by EMT, which is the current
4945 * thread). Since this function is called several times during VM
4946 * shutdown, and the VM lock is only held for the first call (which
4947 * can be either from ataPowerOff or ataSuspend), there is no other
4948 * reasonable solution. */
4949 fVMLocked = VMMR3LockIsOwner(PDMDevHlpGetVM(pDevIns));
4950
4951 if (fVMLocked)
4952 pDevIns->pDevHlp->pfnUnlockVM(pDevIns);
4953 /*
4954 * Wait for any pending async operation to finish
4955 */
4956 u64Start = RTTimeMilliTS();
4957 for (;;)
4958 {
4959 /* Check all async I/O threads. */
4960 fAllIdle = true;
4961 for (uint32_t i = 0; i < RT_ELEMENTS(pData->aCts); i++)
4962 {
4963 fAllIdle &= ataAsyncIOIsIdle(&pData->aCts[i], false);
4964 if (!fAllIdle)
4965 break;
4966 }
4967 if ( fAllIdle
4968 || RTTimeMilliTS() - u64Start >= cMillies)
4969 break;
4970
4971 /* Sleep for a bit. */
4972 RTThreadSleep(100);
4973 }
4974
4975 if (fVMLocked)
4976 pDevIns->pDevHlp->pfnLockVM(pDevIns);
4977
4978 return fAllIdle;
4979}
4980
4981
4982DECLINLINE(void) ataRelocBuffer(PPDMDEVINS pDevIns, ATADevState *s)
4983{
4984 if (s->pbIOBufferHC)
4985 s->pbIOBufferGC = MMHyperHC2GC(PDMDevHlpGetVM(pDevIns), s->pbIOBufferHC);
4986}
4987
4988
4989/**
4990 * @copydoc FNPDMDEVRELOCATE
4991 */
4992static DECLCALLBACK(void) ataRelocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta)
4993{
4994 PCIATAState *pData = PDMINS2DATA(pDevIns, PCIATAState *);
4995
4996 for (uint32_t i = 0; i < RT_ELEMENTS(pData->aCts); i++)
4997 {
4998 pData->aCts[i].pDevInsGC += offDelta;
4999 pData->aCts[i].aIfs[0].pDevInsGC += offDelta;
5000 pData->aCts[i].aIfs[0].pControllerGC += offDelta;
5001 ataRelocBuffer(pDevIns, &pData->aCts[i].aIfs[0]);
5002 pData->aCts[i].aIfs[1].pDevInsGC += offDelta;
5003 pData->aCts[i].aIfs[1].pControllerGC += offDelta;
5004 ataRelocBuffer(pDevIns, &pData->aCts[i].aIfs[1]);
5005 }
5006}
5007
5008
5009/**
5010 * Destroy a driver instance.
5011 *
5012 * Most VM resources are freed by the VM. This callback is provided so that any non-VM
5013 * resources can be freed correctly.
5014 *
5015 * @param pDrvIns The driver instance data.
5016 */
5017static DECLCALLBACK(int) ataDestruct(PPDMDEVINS pDevIns)
5018{
5019 PCIATAState *pData = PDMINS2DATA(pDevIns, PCIATAState *);
5020 int rc;
5021
5022 Log(("%s:\n", __FUNCTION__));
5023
5024 /*
5025 * Terminate all async helper threads
5026 */
5027 for (uint32_t i = 0; i < RT_ELEMENTS(pData->aCts); i++)
5028 {
5029 if (pData->aCts[i].AsyncIOThread != NIL_RTTHREAD)
5030 {
5031 ASMAtomicXchgU32(&pData->aCts[i].fShutdown, true);
5032 rc = RTSemEventSignal(pData->aCts[i].AsyncIOSem);
5033 AssertRC(rc);
5034 }
5035 }
5036
5037 /*
5038 * Wait for them to complete whatever they are doing and then
5039 * for them to terminate.
5040 */
5041 if (ataWaitForAllAsyncIOIsIdle(pDevIns, 20000))
5042 {
5043 uint64_t u64Start = RTTimeMilliTS();
5044 bool fAllDone;
5045 for (;;)
5046 {
5047 /* check */
5048 fAllDone = true;
5049 for (uint32_t i = 0; i < RT_ELEMENTS(pData->aCts) && fAllDone; i++)
5050 fAllDone &= (pData->aCts[i].AsyncIOThread == NIL_RTTHREAD);
5051
5052 if ( fAllDone
5053 || RTTimeMilliTS() - u64Start >= 500)
5054 break;
5055
5056 /* Sleep for a bit. */
5057 RTThreadSleep(100);
5058 }
5059 AssertMsg(fAllDone, ("Some of the async I/O threads are still running!\n"));
5060 }
5061 else
5062 AssertMsgFailed(("Async I/O is still busy!\n"));
5063
5064 /*
5065 * Now the request mutexes are no longer needed. Free resources.
5066 */
5067 for (uint32_t i = 0; i < RT_ELEMENTS(pData->aCts); i++)
5068 {
5069 if (pData->aCts[i].AsyncIORequestMutex)
5070 {
5071 RTSemMutexDestroy(pData->aCts[i].AsyncIORequestMutex);
5072 pData->aCts[i].AsyncIORequestMutex = NIL_RTSEMEVENT;
5073 }
5074 }
5075 return VINF_SUCCESS;
5076}
5077
5078
5079/**
5080 * Detach notification.
5081 *
5082 * The DVD drive has been unplugged.
5083 *
5084 * @param pDevIns The device instance.
5085 * @param iLUN The logical unit which is being detached.
5086 */
5087static DECLCALLBACK(void) ataDetach(PPDMDEVINS pDevIns, unsigned iLUN)
5088{
5089 PCIATAState *pThis = PDMINS2DATA(pDevIns, PCIATAState *);
5090 PATACONTROLLER pCtl;
5091 ATADevState *pIf;
5092 unsigned iController;
5093 unsigned iInterface;
5094
5095 /*
5096 * Locate the controller and stuff.
5097 */
5098 iController = iLUN / RT_ELEMENTS(pThis->aCts[0].aIfs);
5099 AssertReleaseMsg(iController < RT_ELEMENTS(pThis->aCts), ("iController=%d iLUN=%d\n", iController, iLUN));
5100 pCtl = &pThis->aCts[iController];
5101
5102 iInterface = iLUN % RT_ELEMENTS(pThis->aCts[0].aIfs);
5103 pIf = &pCtl->aIfs[iInterface];
5104
5105 /*
5106 * Zero some important members.
5107 */
5108 pIf->pDrvBase = NULL;
5109 pIf->pDrvBlock = NULL;
5110 pIf->pDrvBlockBios = NULL;
5111 pIf->pDrvMount = NULL;
5112}
5113
5114
5115/**
5116 * Configure a LUN.
5117 *
5118 * @returns VBox status code.
5119 * @param pDevIns The device instance.
5120 * @param pIf The ATA unit state.
5121 */
5122static int ataConfigLun(PPDMDEVINS pDevIns, ATADevState *pIf)
5123{
5124 int rc;
5125 PDMBLOCKTYPE enmType;
5126
5127 /*
5128 * Query Block, Bios and Mount interfaces.
5129 */
5130 pIf->pDrvBlock = (PDMIBLOCK *)pIf->pDrvBase->pfnQueryInterface(pIf->pDrvBase, PDMINTERFACE_BLOCK);
5131 if (!pIf->pDrvBlock)
5132 {
5133 AssertMsgFailed(("Configuration error: LUN#%d hasn't a block interface!\n", pIf->iLUN));
5134 return VERR_PDM_MISSING_INTERFACE;
5135 }
5136
5137 /** @todo implement the BIOS invisible code path. */
5138 pIf->pDrvBlockBios = (PDMIBLOCKBIOS *)pIf->pDrvBase->pfnQueryInterface(pIf->pDrvBase, PDMINTERFACE_BLOCK_BIOS);
5139 if (!pIf->pDrvBlockBios)
5140 {
5141 AssertMsgFailed(("Configuration error: LUN#%d hasn't a block BIOS interface!\n", pIf->iLUN));
5142 return VERR_PDM_MISSING_INTERFACE;
5143 }
5144 pIf->pDrvMount = (PDMIMOUNT *)pIf->pDrvBase->pfnQueryInterface(pIf->pDrvBase, PDMINTERFACE_MOUNT);
5145
5146 /*
5147 * Validate type.
5148 */
5149 enmType = pIf->pDrvBlock->pfnGetType(pIf->pDrvBlock);
5150 if ( enmType != PDMBLOCKTYPE_CDROM
5151 && enmType != PDMBLOCKTYPE_DVD
5152 && enmType != PDMBLOCKTYPE_HARD_DISK)
5153 {
5154 AssertMsgFailed(("Configuration error: LUN#%d isn't a disk or cd/dvd-rom. enmType=%d\n", pIf->iLUN, enmType));
5155 return VERR_PDM_UNSUPPORTED_BLOCK_TYPE;
5156 }
5157 if ( ( enmType == PDMBLOCKTYPE_DVD
5158 || enmType == PDMBLOCKTYPE_CDROM)
5159 && !pIf->pDrvMount)
5160 {
5161 AssertMsgFailed(("Internal error: cdrom without a mountable interface, WTF???!\n"));
5162 return VERR_INTERNAL_ERROR;
5163 }
5164 pIf->fATAPI = enmType == PDMBLOCKTYPE_DVD || enmType == PDMBLOCKTYPE_CDROM;
5165 pIf->fATAPIPassthrough = pIf->fATAPI ? (pIf->pDrvBlock->pfnSendCmd != NULL) : false;
5166
5167 /*
5168 * Allocate I/O buffer.
5169 */
5170 PVM pVM = PDMDevHlpGetVM(pDevIns);
5171 if (pIf->cbIOBuffer)
5172 {
5173 /* Buffer is (probably) already allocated. Validate the fields,
5174 * because memory corruption can also overwrite pIf->cbIOBuffer. */
5175 if (pIf->fATAPI)
5176 AssertRelease(pIf->cbIOBuffer == _128K);
5177 else
5178 AssertRelease(pIf->cbIOBuffer == ATA_MAX_MULT_SECTORS * 512);
5179 Assert(pIf->pbIOBufferHC);
5180 Assert(pIf->pbIOBufferGC == MMHyperHC2GC(pVM, pIf->pbIOBufferHC));
5181 }
5182 else
5183 {
5184 if (pIf->fATAPI)
5185 pIf->cbIOBuffer = _128K;
5186 else
5187 pIf->cbIOBuffer = ATA_MAX_MULT_SECTORS * 512;
5188 Assert(!pIf->pbIOBufferHC);
5189 rc = MMHyperAlloc(pVM, pIf->cbIOBuffer, 1, MM_TAG_PDM_DEVICE_USER, (void **)&pIf->pbIOBufferHC);
5190 if (VBOX_FAILURE(rc))
5191 return VERR_NO_MEMORY;
5192 pIf->pbIOBufferGC = MMHyperHC2GC(pVM, pIf->pbIOBufferHC);
5193 }
5194
5195 /*
5196 * Init geometry.
5197 */
5198 if (pIf->fATAPI)
5199 {
5200 pIf->cTotalSectors = pIf->pDrvBlock->pfnGetSize(pIf->pDrvBlock) / 2048;
5201 rc = pIf->pDrvBlockBios->pfnGetGeometry(pIf->pDrvBlockBios, &pIf->cCHSCylinders, &pIf->cCHSHeads, &pIf->cCHSSectors);
5202 pIf->cCHSCylinders = 0; /* dummy */
5203 pIf->cCHSHeads = 0; /* dummy */
5204 pIf->cCHSSectors = 0; /* dummy */
5205 if (rc != VERR_PDM_MEDIA_NOT_MOUNTED)
5206 {
5207 pIf->pDrvBlockBios->pfnSetTranslation(pIf->pDrvBlockBios, PDMBIOSTRANSLATION_NONE);
5208 pIf->pDrvBlockBios->pfnSetGeometry(pIf->pDrvBlockBios, pIf->cCHSCylinders, pIf->cCHSHeads, pIf->cCHSSectors);
5209 }
5210 LogRel(("PIIX3 ATA: LUN#%d: CD/DVD, total number of sectors %Ld, passthrough %s\n", pIf->iLUN, pIf->cTotalSectors, (pIf->fATAPIPassthrough ? "enabled" : "disabled")));
5211 }
5212 else
5213 {
5214 pIf->cTotalSectors = pIf->pDrvBlock->pfnGetSize(pIf->pDrvBlock) / 512;
5215 rc = pIf->pDrvBlockBios->pfnGetGeometry(pIf->pDrvBlockBios, &pIf->cCHSCylinders, &pIf->cCHSHeads, &pIf->cCHSSectors);
5216 if (rc == VERR_PDM_MEDIA_NOT_MOUNTED)
5217 {
5218 pIf->cCHSCylinders = 0;
5219 pIf->cCHSHeads = 16; /*??*/
5220 pIf->cCHSSectors = 63; /*??*/
5221 }
5222 else if (VBOX_FAILURE(rc))
5223 {
5224 rc = ataGuessDiskLCHS(pIf, &pIf->cCHSCylinders, &pIf->cCHSHeads, &pIf->cCHSSectors);
5225 if (VBOX_SUCCESS(rc) && pIf->cCHSHeads <= 16 /* if cCHSHeads > 16, it means that a BIOS LBA translation was active, so the default hardware geometry is OK. */
5226 )
5227 {
5228 /* Disable any translation to be in sync with the logical geometry */
5229 PDMBIOSTRANSLATION enmTranslation;
5230 rc = pIf->pDrvBlockBios->pfnGetTranslation(pIf->pDrvBlockBios, &enmTranslation);
5231 if (VBOX_FAILURE(rc) || enmTranslation == PDMBIOSTRANSLATION_AUTO)
5232 pIf->pDrvBlockBios->pfnSetTranslation(pIf->pDrvBlockBios, PDMBIOSTRANSLATION_NONE);
5233 }
5234 else
5235 {
5236 /* If no geometry, use a standard physical disk geometry. */
5237 uint64_t cCHSCylinders = pIf->cTotalSectors / (16 * 63);
5238 pIf->cCHSCylinders = (uint32_t)RT_MIN(RT_MAX(cCHSCylinders, 2), 16383);
5239 pIf->cCHSHeads = 16;
5240 pIf->cCHSSectors = 63;
5241 }
5242 pIf->pDrvBlockBios->pfnSetGeometry(pIf->pDrvBlockBios, pIf->cCHSCylinders, pIf->cCHSHeads, pIf->cCHSSectors);
5243 }
5244 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));
5245 }
5246 return VINF_SUCCESS;
5247}
5248
5249
5250/**
5251 * Attach command.
5252 *
5253 * This is called when we change block driver for the DVD drive.
5254 *
5255 * @returns VBox status code.
5256 * @param pDevIns The device instance.
5257 * @param iLUN The logical unit which is being detached.
5258 */
5259static DECLCALLBACK(int) ataAttach(PPDMDEVINS pDevIns, unsigned iLUN)
5260{
5261 PCIATAState *pThis = PDMINS2DATA(pDevIns, PCIATAState *);
5262 PATACONTROLLER pCtl;
5263 ATADevState *pIf;
5264 int rc;
5265 unsigned iController;
5266 unsigned iInterface;
5267
5268 /*
5269 * Locate the controller and stuff.
5270 */
5271 iController = iLUN / RT_ELEMENTS(pThis->aCts[0].aIfs);
5272 AssertReleaseMsg(iController < RT_ELEMENTS(pThis->aCts), ("iController=%d iLUN=%d\n", iController, iLUN));
5273 pCtl = &pThis->aCts[iController];
5274
5275 iInterface = iLUN % RT_ELEMENTS(pThis->aCts[0].aIfs);
5276 pIf = &pCtl->aIfs[iInterface];
5277
5278 /* the usual paranoia */
5279 AssertRelease(!pIf->pDrvBase);
5280 AssertRelease(!pIf->pDrvBlock);
5281 Assert(ATADEVSTATE_2_CONTROLLER(pIf) == pCtl);
5282 Assert(pIf->iLUN == iLUN);
5283
5284 /*
5285 * Try attach the block device and get the interfaces,
5286 * required as well as optional.
5287 */
5288 rc = PDMDevHlpDriverAttach(pDevIns, pIf->iLUN, &pIf->IBase, &pIf->pDrvBase, NULL);
5289 if (VBOX_SUCCESS(rc))
5290 rc = ataConfigLun(pDevIns, pIf);
5291 else
5292 AssertMsgFailed(("Failed to attach LUN#%d. rc=%Vrc\n", pIf->iLUN, rc));
5293
5294 if (VBOX_FAILURE(rc))
5295 {
5296 pIf->pDrvBase = NULL;
5297 pIf->pDrvBlock = NULL;
5298 }
5299 return rc;
5300}
5301
5302
5303/**
5304 * Suspend notification.
5305 *
5306 * @returns VBox status.
5307 * @param pDrvIns The driver instance data.
5308 */
5309static DECLCALLBACK(void) ataSuspend(PPDMDEVINS pDevIns)
5310{
5311 Log(("%s:\n", __FUNCTION__));
5312 if (!ataWaitForAllAsyncIOIsIdle(pDevIns, 20000))
5313 AssertMsgFailed(("Async I/O didn't stop in 20 seconds!\n"));
5314 return;
5315}
5316
5317
5318/**
5319 * Resume notification.
5320 *
5321 * @returns VBox status.
5322 * @param pDrvIns The driver instance data.
5323 */
5324static DECLCALLBACK(void) ataResume(PPDMDEVINS pDevIns)
5325{
5326 PCIATAState *pData = PDMINS2DATA(pDevIns, PCIATAState *);
5327 int rc;
5328
5329 Log(("%s:\n", __FUNCTION__));
5330 for (uint32_t i = 0; i < RT_ELEMENTS(pData->aCts); i++)
5331 {
5332 if (pData->aCts[i].fRedo && pData->aCts[i].fRedoIdle)
5333 {
5334 rc = RTSemEventSignal(pData->aCts[i].SuspendIOSem);
5335 AssertRC(rc);
5336 }
5337 }
5338 return;
5339}
5340
5341
5342/**
5343 * Power Off notification.
5344 *
5345 * @returns VBox status.
5346 * @param pDrvIns The driver instance data.
5347 */
5348static DECLCALLBACK(void) ataPowerOff(PPDMDEVINS pDevIns)
5349{
5350 Log(("%s:\n", __FUNCTION__));
5351 if (!ataWaitForAllAsyncIOIsIdle(pDevIns, 20000))
5352 AssertMsgFailed(("Async I/O didn't stop in 20 seconds!\n"));
5353 return;
5354}
5355
5356
5357/**
5358 * Prepare state save and load operation.
5359 *
5360 * @returns VBox status code.
5361 * @param pDevIns Device instance of the device which registered the data unit.
5362 * @param pSSM SSM operation handle.
5363 */
5364static DECLCALLBACK(int) ataSaveLoadPrep(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
5365{
5366 PCIATAState *pData = PDMINS2DATA(pDevIns, PCIATAState *);
5367
5368 /* sanity - the suspend notification will wait on the async stuff. */
5369 for (uint32_t i = 0; i < RT_ELEMENTS(pData->aCts); i++)
5370 {
5371 Assert(ataAsyncIOIsIdle(&pData->aCts[i], false));
5372 if (!ataAsyncIOIsIdle(&pData->aCts[i], false))
5373 return VERR_SSM_IDE_ASYNC_TIMEOUT;
5374 }
5375 return VINF_SUCCESS;
5376}
5377
5378
5379/**
5380 * Saves a state of the ATA device.
5381 *
5382 * @returns VBox status code.
5383 * @param pDevIns The device instance.
5384 * @param pSSMHandle The handle to save the state to.
5385 */
5386static DECLCALLBACK(int) ataSaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSMHandle)
5387{
5388 PCIATAState *pData = PDMINS2DATA(pDevIns, PCIATAState *);
5389
5390 for (uint32_t i = 0; i < RT_ELEMENTS(pData->aCts); i++)
5391 {
5392 SSMR3PutU8(pSSMHandle, pData->aCts[i].iSelectedIf);
5393 SSMR3PutU8(pSSMHandle, pData->aCts[i].iAIOIf);
5394 SSMR3PutU8(pSSMHandle, pData->aCts[i].uAsyncIOState);
5395 SSMR3PutBool(pSSMHandle, pData->aCts[i].fChainedTransfer);
5396 SSMR3PutBool(pSSMHandle, pData->aCts[i].fReset);
5397 SSMR3PutBool(pSSMHandle, pData->aCts[i].fRedo);
5398 SSMR3PutBool(pSSMHandle, pData->aCts[i].fRedoIdle);
5399 SSMR3PutBool(pSSMHandle, pData->aCts[i].fRedoDMALastDesc);
5400 SSMR3PutMem(pSSMHandle, &pData->aCts[i].BmDma, sizeof(pData->aCts[i].BmDma));
5401 SSMR3PutGCPhys(pSSMHandle, pData->aCts[i].pFirstDMADesc);
5402 SSMR3PutGCPhys(pSSMHandle, pData->aCts[i].pLastDMADesc);
5403 SSMR3PutGCPhys(pSSMHandle, pData->aCts[i].pRedoDMABuffer);
5404 SSMR3PutU32(pSSMHandle, pData->aCts[i].cbRedoDMABuffer);
5405
5406 for (uint32_t j = 0; j < RT_ELEMENTS(pData->aCts[i].aIfs); j++)
5407 {
5408 SSMR3PutBool(pSSMHandle, pData->aCts[i].aIfs[j].fLBA48);
5409 SSMR3PutBool(pSSMHandle, pData->aCts[i].aIfs[j].fATAPI);
5410 SSMR3PutBool(pSSMHandle, pData->aCts[i].aIfs[j].fIrqPending);
5411 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].cMultSectors);
5412 SSMR3PutU32(pSSMHandle, pData->aCts[i].aIfs[j].cCHSCylinders);
5413 SSMR3PutU32(pSSMHandle, pData->aCts[i].aIfs[j].cCHSHeads);
5414 SSMR3PutU32(pSSMHandle, pData->aCts[i].aIfs[j].cCHSSectors);
5415 SSMR3PutU32(pSSMHandle, pData->aCts[i].aIfs[j].cSectorsPerIRQ);
5416 SSMR3PutU64(pSSMHandle, pData->aCts[i].aIfs[j].cTotalSectors);
5417 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].uATARegFeature);
5418 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].uATARegFeatureHOB);
5419 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].uATARegError);
5420 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].uATARegNSector);
5421 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].uATARegNSectorHOB);
5422 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].uATARegSector);
5423 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].uATARegSectorHOB);
5424 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].uATARegLCyl);
5425 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].uATARegLCylHOB);
5426 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].uATARegHCyl);
5427 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].uATARegHCylHOB);
5428 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].uATARegSelect);
5429 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].uATARegStatus);
5430 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].uATARegCommand);
5431 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].uATARegDevCtl);
5432 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].uATATransferMode);
5433 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].uTxDir);
5434 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].iBeginTransfer);
5435 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].iSourceSink);
5436 SSMR3PutBool(pSSMHandle, pData->aCts[i].aIfs[j].fDMA);
5437 SSMR3PutBool(pSSMHandle, pData->aCts[i].aIfs[j].fATAPITransfer);
5438 SSMR3PutU32(pSSMHandle, pData->aCts[i].aIfs[j].cbTotalTransfer);
5439 SSMR3PutU32(pSSMHandle, pData->aCts[i].aIfs[j].cbElementaryTransfer);
5440 SSMR3PutU32(pSSMHandle, pData->aCts[i].aIfs[j].iIOBufferCur);
5441 SSMR3PutU32(pSSMHandle, pData->aCts[i].aIfs[j].iIOBufferEnd);
5442 SSMR3PutU32(pSSMHandle, pData->aCts[i].aIfs[j].iIOBufferPIODataStart);
5443 SSMR3PutU32(pSSMHandle, pData->aCts[i].aIfs[j].iIOBufferPIODataEnd);
5444 SSMR3PutU32(pSSMHandle, pData->aCts[i].aIfs[j].iATAPILBA);
5445 SSMR3PutU32(pSSMHandle, pData->aCts[i].aIfs[j].cbATAPISector);
5446 SSMR3PutMem(pSSMHandle, &pData->aCts[i].aIfs[j].aATAPICmd, sizeof(pData->aCts[i].aIfs[j].aATAPICmd));
5447 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].uATAPISenseKey);
5448 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].uATAPIASC);
5449 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].cNotifiedMediaChange);
5450 SSMR3PutMem(pSSMHandle, &pData->aCts[i].aIfs[j].Led, sizeof(pData->aCts[i].aIfs[j].Led));
5451 SSMR3PutU32(pSSMHandle, pData->aCts[i].aIfs[j].cbIOBuffer);
5452 if (pData->aCts[i].aIfs[j].cbIOBuffer)
5453 SSMR3PutMem(pSSMHandle, pData->aCts[i].aIfs[j].CTXSUFF(pbIOBuffer), pData->aCts[i].aIfs[j].cbIOBuffer);
5454 else
5455 Assert(pData->aCts[i].aIfs[j].CTXSUFF(pbIOBuffer) == NULL);
5456 }
5457 }
5458
5459 return SSMR3PutU32(pSSMHandle, ~0); /* sanity/terminator */
5460}
5461
5462
5463/**
5464 * Loads a saved ATA device state.
5465 *
5466 * @returns VBox status code.
5467 * @param pDevIns The device instance.
5468 * @param pSSMHandle The handle to the saved state.
5469 * @param u32Version The data unit version number.
5470 */
5471static DECLCALLBACK(int) ataLoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSMHandle, uint32_t u32Version)
5472{
5473 PCIATAState *pData = PDMINS2DATA(pDevIns, PCIATAState *);
5474 int rc;
5475 uint32_t u32;
5476
5477 if (u32Version != ATA_SAVED_STATE_VERSION)
5478 {
5479 AssertMsgFailed(("u32Version=%d\n", u32Version));
5480 return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
5481 }
5482
5483 /*
5484 * Restore valid parts of the PCIATAState structure
5485 */
5486 for (uint32_t i = 0; i < RT_ELEMENTS(pData->aCts); i++)
5487 {
5488 /* integrity check */
5489 if (!ataAsyncIOIsIdle(&pData->aCts[i], false))
5490 {
5491 AssertMsgFailed(("Async I/O for controller %d is active\n", i));
5492 rc = VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
5493 return rc;
5494 }
5495
5496 SSMR3GetU8(pSSMHandle, &pData->aCts[i].iSelectedIf);
5497 SSMR3GetU8(pSSMHandle, &pData->aCts[i].iAIOIf);
5498 SSMR3GetU8(pSSMHandle, &pData->aCts[i].uAsyncIOState);
5499 SSMR3GetBool(pSSMHandle, &pData->aCts[i].fChainedTransfer);
5500 SSMR3GetBool(pSSMHandle, (bool *)&pData->aCts[i].fReset);
5501 SSMR3GetBool(pSSMHandle, (bool *)&pData->aCts[i].fRedo);
5502 SSMR3GetBool(pSSMHandle, (bool *)&pData->aCts[i].fRedoIdle);
5503 SSMR3GetBool(pSSMHandle, (bool *)&pData->aCts[i].fRedoDMALastDesc);
5504 SSMR3GetMem(pSSMHandle, &pData->aCts[i].BmDma, sizeof(pData->aCts[i].BmDma));
5505 SSMR3GetGCPhys(pSSMHandle, &pData->aCts[i].pFirstDMADesc);
5506 SSMR3GetGCPhys(pSSMHandle, &pData->aCts[i].pLastDMADesc);
5507 SSMR3GetGCPhys(pSSMHandle, &pData->aCts[i].pRedoDMABuffer);
5508 SSMR3GetU32(pSSMHandle, &pData->aCts[i].cbRedoDMABuffer);
5509
5510 for (uint32_t j = 0; j < RT_ELEMENTS(pData->aCts[i].aIfs); j++)
5511 {
5512 SSMR3GetBool(pSSMHandle, &pData->aCts[i].aIfs[j].fLBA48);
5513 SSMR3GetBool(pSSMHandle, &pData->aCts[i].aIfs[j].fATAPI);
5514 SSMR3GetBool(pSSMHandle, &pData->aCts[i].aIfs[j].fIrqPending);
5515 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].cMultSectors);
5516 SSMR3GetU32(pSSMHandle, &pData->aCts[i].aIfs[j].cCHSCylinders);
5517 SSMR3GetU32(pSSMHandle, &pData->aCts[i].aIfs[j].cCHSHeads);
5518 SSMR3GetU32(pSSMHandle, &pData->aCts[i].aIfs[j].cCHSSectors);
5519 SSMR3GetU32(pSSMHandle, &pData->aCts[i].aIfs[j].cSectorsPerIRQ);
5520 SSMR3GetU64(pSSMHandle, &pData->aCts[i].aIfs[j].cTotalSectors);
5521 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].uATARegFeature);
5522 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].uATARegFeatureHOB);
5523 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].uATARegError);
5524 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].uATARegNSector);
5525 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].uATARegNSectorHOB);
5526 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].uATARegSector);
5527 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].uATARegSectorHOB);
5528 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].uATARegLCyl);
5529 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].uATARegLCylHOB);
5530 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].uATARegHCyl);
5531 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].uATARegHCylHOB);
5532 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].uATARegSelect);
5533 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].uATARegStatus);
5534 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].uATARegCommand);
5535 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].uATARegDevCtl);
5536 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].uATATransferMode);
5537 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].uTxDir);
5538 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].iBeginTransfer);
5539 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].iSourceSink);
5540 SSMR3GetBool(pSSMHandle, &pData->aCts[i].aIfs[j].fDMA);
5541 SSMR3GetBool(pSSMHandle, &pData->aCts[i].aIfs[j].fATAPITransfer);
5542 SSMR3GetU32(pSSMHandle, &pData->aCts[i].aIfs[j].cbTotalTransfer);
5543 SSMR3GetU32(pSSMHandle, &pData->aCts[i].aIfs[j].cbElementaryTransfer);
5544 SSMR3GetU32(pSSMHandle, &pData->aCts[i].aIfs[j].iIOBufferCur);
5545 SSMR3GetU32(pSSMHandle, &pData->aCts[i].aIfs[j].iIOBufferEnd);
5546 SSMR3GetU32(pSSMHandle, &pData->aCts[i].aIfs[j].iIOBufferPIODataStart);
5547 SSMR3GetU32(pSSMHandle, &pData->aCts[i].aIfs[j].iIOBufferPIODataEnd);
5548 SSMR3GetU32(pSSMHandle, &pData->aCts[i].aIfs[j].iATAPILBA);
5549 SSMR3GetU32(pSSMHandle, &pData->aCts[i].aIfs[j].cbATAPISector);
5550 SSMR3GetMem(pSSMHandle, &pData->aCts[i].aIfs[j].aATAPICmd, sizeof(pData->aCts[i].aIfs[j].aATAPICmd));
5551 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].uATAPISenseKey);
5552 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].uATAPIASC);
5553 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].cNotifiedMediaChange);
5554 SSMR3GetMem(pSSMHandle, &pData->aCts[i].aIfs[j].Led, sizeof(pData->aCts[i].aIfs[j].Led));
5555 SSMR3GetU32(pSSMHandle, &pData->aCts[i].aIfs[j].cbIOBuffer);
5556 if (pData->aCts[i].aIfs[j].cbIOBuffer)
5557 SSMR3GetMem(pSSMHandle, pData->aCts[i].aIfs[j].CTXSUFF(pbIOBuffer), pData->aCts[i].aIfs[j].cbIOBuffer);
5558 else
5559 Assert(pData->aCts[i].aIfs[j].CTXSUFF(pbIOBuffer) == NULL);
5560 }
5561 }
5562
5563 rc = SSMR3GetU32(pSSMHandle, &u32);
5564 if (VBOX_FAILURE(rc))
5565 return rc;
5566 if (u32 != ~0U)
5567 {
5568 AssertMsgFailed(("u32=%#x expected ~0\n", u32));
5569 rc = VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
5570 return rc;
5571 }
5572
5573 return VINF_SUCCESS;
5574}
5575
5576
5577/**
5578 * Construct a device instance for a VM.
5579 *
5580 * @returns VBox status.
5581 * @param pDevIns The device instance data.
5582 * If the registration structure is needed, pDevIns->pDevReg points to it.
5583 * @param iInstance Instance number. Use this to figure out which registers and such to use.
5584 * The device number is also found in pDevIns->iInstance, but since it's
5585 * likely to be freqently used PDM passes it as parameter.
5586 * @param pCfgHandle Configuration node handle for the device. Use this to obtain the configuration
5587 * of the device instance. It's also found in pDevIns->pCfgHandle, but like
5588 * iInstance it's expected to be used a bit in this function.
5589 */
5590static DECLCALLBACK(int) ataConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfgHandle)
5591{
5592 PCIATAState *pData = PDMINS2DATA(pDevIns, PCIATAState *);
5593 PPDMIBASE pBase;
5594 int rc;
5595 bool fGCEnabled;
5596 bool fR0Enabled;
5597 uint32_t DelayIRQMillies;
5598
5599 Assert(iInstance == 0);
5600
5601 /*
5602 * Validate and read configuration.
5603 */
5604 if (!CFGMR3AreValuesValid(pCfgHandle, "GCEnabled\0IRQDelay\0R0Enabled"))
5605 return PDMDEV_SET_ERROR(pDevIns, VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES,
5606 N_("PIIX3 configuration error: unknown option specified."));
5607
5608 rc = CFGMR3QueryBool(pCfgHandle, "GCEnabled", &fGCEnabled);
5609 if (rc == VERR_CFGM_VALUE_NOT_FOUND)
5610 fGCEnabled = true;
5611 else if (VBOX_FAILURE(rc))
5612 return PDMDEV_SET_ERROR(pDevIns, rc,
5613 N_("PIIX3 configuration error: failed to read GCEnabled as boolean."));
5614 Log(("%s: fGCEnabled=%d\n", __FUNCTION__, fGCEnabled));
5615
5616 rc = CFGMR3QueryBool(pCfgHandle, "R0Enabled", &fR0Enabled);
5617 if (rc == VERR_CFGM_VALUE_NOT_FOUND)
5618 fR0Enabled = true;
5619 else if (VBOX_FAILURE(rc))
5620 return PDMDEV_SET_ERROR(pDevIns, rc,
5621 N_("PIIX3 configuration error: failed to read R0Enabled as boolean."));
5622 Log(("%s: fR0Enabled=%d\n", __FUNCTION__, fR0Enabled));
5623
5624 rc = CFGMR3QueryU32(pCfgHandle, "IRQDelay", &DelayIRQMillies);
5625 if (rc == VERR_CFGM_VALUE_NOT_FOUND)
5626 DelayIRQMillies = 0;
5627 else if (VBOX_FAILURE(rc))
5628 return PDMDEV_SET_ERROR(pDevIns, rc,
5629 N_("PIIX3 configuration error: failed to read IRQDelay as integer."));
5630 Log(("%s: DelayIRQMillies=%d\n", __FUNCTION__, DelayIRQMillies));
5631 Assert(DelayIRQMillies < 50);
5632
5633 /*
5634 * Initialize data (most of it anyway).
5635 */
5636 /* Status LUN. */
5637 pData->IBase.pfnQueryInterface = ataStatus_QueryInterface;
5638 pData->ILeds.pfnQueryStatusLed = ataStatus_QueryStatusLed;
5639
5640 /* pci */
5641 pData->dev.config[0x00] = 0x86; /* Vendor: Intel */
5642 pData->dev.config[0x01] = 0x80;
5643 pData->dev.config[0x02] = 0x10; /* Device: PIIX3 IDE */
5644 pData->dev.config[0x03] = 0x70;
5645 pData->dev.config[0x04] = PCI_COMMAND_IOACCESS | PCI_COMMAND_MEMACCESS | PCI_COMMAND_BUSMASTER;
5646 pData->dev.config[0x09] = 0x8a; /* programming interface = PCI_IDE bus master is supported */
5647 pData->dev.config[0x0a] = 0x01; /* class_sub = PCI_IDE */
5648 pData->dev.config[0x0b] = 0x01; /* class_base = PCI_mass_storage */
5649 pData->dev.config[0x0e] = 0x00; /* header_type */
5650
5651 pData->pDevIns = pDevIns;
5652 pData->fGCEnabled = fGCEnabled;
5653 pData->fR0Enabled = fR0Enabled;
5654 for (uint32_t i = 0; i < RT_ELEMENTS(pData->aCts); i++)
5655 {
5656 pData->aCts[i].pDevInsHC = pDevIns;
5657 pData->aCts[i].pDevInsGC = PDMDEVINS_2_GCPTR(pDevIns);
5658 pData->aCts[i].DelayIRQMillies = (uint32_t)DelayIRQMillies;
5659 for (uint32_t j = 0; j < RT_ELEMENTS(pData->aCts[i].aIfs); j++)
5660 {
5661 pData->aCts[i].aIfs[j].iLUN = i * RT_ELEMENTS(pData->aCts) + j;
5662 pData->aCts[i].aIfs[j].pDevInsHC = pDevIns;
5663 pData->aCts[i].aIfs[j].pDevInsGC = PDMDEVINS_2_GCPTR(pDevIns);
5664 pData->aCts[i].aIfs[j].pControllerHC = &pData->aCts[i];
5665 pData->aCts[i].aIfs[j].pControllerGC = MMHyperHC2GC(PDMDevHlpGetVM(pDevIns), &pData->aCts[i]);
5666 pData->aCts[i].aIfs[j].IBase.pfnQueryInterface = ataQueryInterface;
5667 pData->aCts[i].aIfs[j].IMountNotify.pfnMountNotify = ataMountNotify;
5668 pData->aCts[i].aIfs[j].IMountNotify.pfnUnmountNotify = ataUnmountNotify;
5669 pData->aCts[i].aIfs[j].Led.u32Magic = PDMLED_MAGIC;
5670 }
5671 }
5672
5673 Assert(RT_ELEMENTS(pData->aCts) == 2);
5674 pData->aCts[0].irq = 14;
5675 pData->aCts[0].IOPortBase1 = 0x1f0;
5676 pData->aCts[0].IOPortBase2 = 0x3f6;
5677 pData->aCts[1].irq = 15;
5678 pData->aCts[1].IOPortBase1 = 0x170;
5679 pData->aCts[1].IOPortBase2 = 0x376;
5680
5681 /*
5682 * Register the PCI device.
5683 * N.B. There's a hack in the PIIX3 PCI bridge device to assign this
5684 * device the slot next to itself.
5685 */
5686 rc = PDMDevHlpPCIRegister(pDevIns, &pData->dev);
5687 if (VBOX_FAILURE(rc))
5688 return PDMDEV_SET_ERROR(pDevIns, rc,
5689 N_("PIIX3 cannot register PCI device."));
5690 AssertMsg(pData->dev.devfn == 9 || iInstance != 0, ("pData->dev.devfn=%d\n", pData->dev.devfn));
5691 rc = PDMDevHlpPCIIORegionRegister(pDevIns, 4, 0x10, PCI_ADDRESS_SPACE_IO, ataBMDMAIORangeMap);
5692 if (VBOX_FAILURE(rc))
5693 return PDMDEV_SET_ERROR(pDevIns, rc,
5694 N_("PIIX3 cannot register PCI I/O region for BMDMA."));
5695
5696 /*
5697 * Register the I/O ports.
5698 * The ports are all hardcoded and enforced by the PIIX3 host bridge controller.
5699 */
5700 for (uint32_t i = 0; i < RT_ELEMENTS(pData->aCts); i++)
5701 {
5702 rc = PDMDevHlpIOPortRegister(pDevIns, pData->aCts[i].IOPortBase1, 8, (RTHCPTR)i,
5703 ataIOPortWrite1, ataIOPortRead1, ataIOPortWriteStr1, ataIOPortReadStr1, "ATA I/O Base 1");
5704 if (VBOX_FAILURE(rc))
5705 return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot register I/O handlers."));
5706
5707 if (fGCEnabled)
5708 {
5709 rc = PDMDevHlpIOPortRegisterGC(pDevIns, pData->aCts[i].IOPortBase1, 8, (RTGCPTR)i,
5710 "ataIOPortWrite1", "ataIOPortRead1", "ataIOPortWriteStr1", "ataIOPortReadStr1", "ATA I/O Base 1");
5711 if (VBOX_FAILURE(rc))
5712 return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot register I/O handlers (GC)."));
5713 }
5714
5715 if (fR0Enabled)
5716 {
5717#if 1
5718 rc = PDMDevHlpIOPortRegisterR0(pDevIns, pData->aCts[i].IOPortBase1, 8, (RTHCPTR)i,
5719 "ataIOPortWrite1", "ataIOPortRead1", NULL, NULL, "ATA I/O Base 1");
5720#else
5721 rc = PDMDevHlpIOPortRegisterR0(pDevIns, pData->aCts[i].IOPortBase1, 8, (RTHCPTR)i,
5722 "ataIOPortWrite1", "ataIOPortRead1", "ataIOPortWriteStr1", "ataIOPortReadStr1", "ATA I/O Base 1");
5723#endif
5724 if (VBOX_FAILURE(rc))
5725 return PDMDEV_SET_ERROR(pDevIns, rc, "PIIX3 cannot register I/O handlers (R0).");
5726 }
5727
5728 rc = PDMDevHlpIOPortRegister(pDevIns, pData->aCts[i].IOPortBase2, 1, (RTHCPTR)i,
5729 ataIOPortWrite2, ataIOPortRead2, NULL, NULL, "ATA I/O Base 2");
5730 if (VBOX_FAILURE(rc))
5731 return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot register base2 I/O handlers."));
5732
5733 if (fGCEnabled)
5734 {
5735 rc = PDMDevHlpIOPortRegisterGC(pDevIns, pData->aCts[i].IOPortBase2, 1, (RTGCPTR)i,
5736 "ataIOPortWrite2", "ataIOPortRead2", NULL, NULL, "ATA I/O Base 2");
5737 if (VBOX_FAILURE(rc))
5738 return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot register base2 I/O handlers (GC)."));
5739 }
5740 if (fR0Enabled)
5741 {
5742 rc = PDMDevHlpIOPortRegisterR0(pDevIns, pData->aCts[i].IOPortBase2, 1, (RTHCPTR)i,
5743 "ataIOPortWrite2", "ataIOPortRead2", NULL, NULL, "ATA I/O Base 2");
5744 if (VBOX_FAILURE(rc))
5745 return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot register base2 I/O handlers (R0)."));
5746 }
5747
5748#ifdef VBOX_WITH_STATISTICS /** @todo release too. */
5749 for (uint32_t j = 0; j < RT_ELEMENTS(pData->aCts[i].aIfs); j++)
5750 {
5751 ATADevState *pIf = &pData->aCts[i].aIfs[j];
5752 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);
5753 PDMDevHlpSTAMRegisterF(pDevIns, &pIf->StatBytesRead, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES, "Amount of data read.", "/Devices/ATA%d/Unit%d/ReadBytes", i, j);
5754 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);
5755 PDMDevHlpSTAMRegisterF(pDevIns, &pIf->StatBytesWritten, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES, "Amount of data written.", "/Devices/ATA%d/Unit%d/WrittenBytes", i, j);
5756 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);
5757 }
5758 PDMDevHlpSTAMRegisterF(pDevIns, &pData->aCts[i].StatAsyncOps, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "The number of async operations.", "/Devices/ATA%d/Async/Operations", i);
5759 /** @todo STAMUNIT_MICROSECS */
5760 PDMDevHlpSTAMRegisterF(pDevIns, &pData->aCts[i].StatAsyncMinWait, STAMTYPE_U64_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_NONE, "Minimum wait in microseconds.", "/Devices/ATA%d/Async/MinWait", i);
5761 PDMDevHlpSTAMRegisterF(pDevIns, &pData->aCts[i].StatAsyncMaxWait, STAMTYPE_U64_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_NONE, "Maximum wait in microseconds.", "/Devices/ATA%d/Async/MaxWait", i);
5762 PDMDevHlpSTAMRegisterF(pDevIns, &pData->aCts[i].StatAsyncTimeUS, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_NONE, "Total time spent in microseconds.","/Devices/ATA%d/Async/TotalTimeUS", i);
5763 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);
5764 PDMDevHlpSTAMRegisterF(pDevIns, &pData->aCts[i].StatLockWait, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling of locks.", "/Devices/ATA%d/Async/LockWait", i);
5765#endif /* VBOX_WITH_STATISTICS */
5766
5767 /* Initialize per-controller critical section */
5768 char szName[24];
5769 RTStrPrintf(szName, sizeof(szName), "ATA%d", i);
5770 rc = PDMDevHlpCritSectInit(pDevIns, &pData->aCts[i].lock, szName);
5771 if (VBOX_FAILURE(rc))
5772 return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot initialize critical section."));
5773 }
5774
5775 /*
5776 * Attach status driver (optional).
5777 */
5778 rc = PDMDevHlpDriverAttach(pDevIns, PDM_STATUS_LUN, &pData->IBase, &pBase, "Status Port");
5779 if (VBOX_SUCCESS(rc))
5780 pData->pLedsConnector = (PDMILEDCONNECTORS *)pBase->pfnQueryInterface(pBase, PDMINTERFACE_LED_CONNECTORS);
5781 else if (rc != VERR_PDM_NO_ATTACHED_DRIVER)
5782 {
5783 AssertMsgFailed(("Failed to attach to status driver. rc=%Vrc\n", rc));
5784 return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot attach to status driver."));
5785 }
5786
5787 /*
5788 * Attach the units.
5789 */
5790 uint32_t cbTotalBuffer = 0;
5791 for (uint32_t i = 0; i < RT_ELEMENTS(pData->aCts); i++)
5792 {
5793 PATACONTROLLER pCtl = &pData->aCts[i];
5794
5795 /*
5796 * Start the worker thread.
5797 */
5798 pCtl->uAsyncIOState = ATA_AIO_NEW;
5799 rc = RTSemEventCreate(&pCtl->AsyncIOSem);
5800 AssertRC(rc);
5801 rc = RTSemEventCreate(&pCtl->SuspendIOSem);
5802 AssertRC(rc);
5803 rc = RTSemMutexCreate(&pCtl->AsyncIORequestMutex);
5804 AssertRC(rc);
5805 ataAsyncIOClearRequests(pCtl);
5806 rc = RTThreadCreate(&pCtl->AsyncIOThread, ataAsyncIOLoop, (void *)pCtl, 128*1024, RTTHREADTYPE_IO, 0, "ATA");
5807 AssertRC(rc);
5808 Assert(pCtl->AsyncIOThread != NIL_RTTHREAD && pCtl->AsyncIOSem != NIL_RTSEMEVENT && pCtl->SuspendIOSem != NIL_RTSEMEVENT && pCtl->AsyncIORequestMutex != NIL_RTSEMMUTEX);
5809 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));
5810
5811 for (uint32_t j = 0; j < RT_ELEMENTS(pCtl->aIfs); j++)
5812 {
5813 static const char *s_apszDescs[RT_ELEMENTS(pData->aCts)][RT_ELEMENTS(pCtl->aIfs)] =
5814 {
5815 { "Primary Master", "Primary Slave" },
5816 { "Secondary Master", "Secondary Slave" }
5817 };
5818
5819 /*
5820 * Try attach the block device and get the interfaces,
5821 * required as well as optional.
5822 */
5823 ATADevState *pIf = &pCtl->aIfs[j];
5824
5825 rc = PDMDevHlpDriverAttach(pDevIns, pIf->iLUN, &pIf->IBase, &pIf->pDrvBase, s_apszDescs[i][j]);
5826 if (VBOX_SUCCESS(rc))
5827 rc = ataConfigLun(pDevIns, pIf);
5828 else if (rc == VERR_PDM_NO_ATTACHED_DRIVER)
5829 {
5830 pIf->pDrvBase = NULL;
5831 pIf->pDrvBlock = NULL;
5832 pIf->cbIOBuffer = 0;
5833 pIf->pbIOBufferHC = NULL;
5834 pIf->pbIOBufferGC = NIL_RTGCPHYS;
5835 LogRel(("PIIX3 ATA: LUN#%d: no unit\n", pIf->iLUN));
5836 }
5837 else
5838 {
5839 AssertMsgFailed(("Failed to attach LUN#%d. rc=%Vrc\n", pIf->iLUN, rc));
5840 switch (rc)
5841 {
5842 case VERR_ACCESS_DENIED:
5843 /* Error already catched by DrvHostBase */
5844 return rc;
5845 default:
5846 return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS, N_(
5847 "PIIX3 cannot attach drive to the %s"), s_apszDescs[i][j]);
5848 }
5849 }
5850 cbTotalBuffer += pIf->cbIOBuffer;
5851 }
5852 }
5853
5854 rc = PDMDevHlpSSMRegister(pDevIns, pDevIns->pDevReg->szDeviceName, iInstance,
5855 ATA_SAVED_STATE_VERSION, sizeof(*pData) + cbTotalBuffer,
5856 ataSaveLoadPrep, ataSaveExec, NULL,
5857 ataSaveLoadPrep, ataLoadExec, NULL);
5858 if (VBOX_FAILURE(rc))
5859 return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot register save state handlers."));
5860
5861 /*
5862 * Initialize the device state.
5863 */
5864 ataReset(pDevIns);
5865
5866 return VINF_SUCCESS;
5867}
5868
5869
5870/**
5871 * The device registration structure.
5872 */
5873const PDMDEVREG g_DevicePIIX3IDE =
5874{
5875 /* u32Version */
5876 PDM_DEVREG_VERSION,
5877 /* szDeviceName */
5878 "piix3ide",
5879 /* szGCMod */
5880 "VBoxDDGC.gc",
5881 /* szR0Mod */
5882 "VBoxDDR0.r0",
5883 /* pszDescription */
5884 "Intel PIIX3 ATA controller.\n"
5885 " LUN #0 is primary master.\n"
5886 " LUN #1 is primary slave.\n"
5887 " LUN #2 is secondary master.\n"
5888 " LUN #3 is secondary slave.\n"
5889 " LUN #999 is the LED/Status connector.",
5890 /* fFlags */
5891 PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT | PDM_DEVREG_FLAGS_GUEST_BITS_DEFAULT | PDM_DEVREG_FLAGS_GC | PDM_DEVREG_FLAGS_R0,
5892 /* fClass */
5893 PDM_DEVREG_CLASS_STORAGE,
5894 /* cMaxInstances */
5895 1,
5896 /* cbInstance */
5897 sizeof(PCIATAState),
5898 /* pfnConstruct */
5899 ataConstruct,
5900 /* pfnDestruct */
5901 ataDestruct,
5902 /* pfnRelocate */
5903 ataRelocate,
5904 /* pfnIOCtl */
5905 NULL,
5906 /* pfnPowerOn */
5907 NULL,
5908 /* pfnReset */
5909 ataReset,
5910 /* pfnSuspend */
5911 ataSuspend,
5912 /* pfnResume */
5913 ataResume,
5914 /* pfnAttach */
5915 ataAttach,
5916 /* pfnDetach */
5917 ataDetach,
5918 /* pfnQueryInterface. */
5919 NULL,
5920 /* pfnInitComplete */
5921 NULL,
5922 /* pfnPowerOff */
5923 ataPowerOff
5924};
5925#endif /* IN_RING3 */
5926#endif /* !VBOX_DEVICE_STRUCT_TESTCASE */
5927
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