VirtualBox

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

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

Handle EFBIG on Linux correctly (and try to detect the same situation on
Windows). Provide separate runtime error message, because disk full
doesn't describe the problem (file size limit exceeded). Happens mostly
if people store VDIs on FAT32 partitions.

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

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