VirtualBox

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

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

Removed harmful Yield.

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

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