VirtualBox

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

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

Backed out [20718] as it broke vmdk image support.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 222.0 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(RT_MIN(s->cCHSCylinders, 16383));
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(RT_MIN(s->cCHSCylinders, 16383));
1078 p[55] = RT_H2LE_U16(s->cCHSHeads);
1079 p[56] = RT_H2LE_U16(s->cCHSSectors);
1080 p[57] = RT_H2LE_U16(RT_MIN(s->cCHSCylinders, 16383) * s->cCHSHeads * s->cCHSSectors);
1081 p[58] = RT_H2LE_U16(RT_MIN(s->cCHSCylinders, 16383) * 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 != 0
3061 && ( s->uATARegNSector > ATA_MAX_MULT_SECTORS
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 0xcc: /* reverting to power-on defaults enable */
3172 Log2(("%s: revert to power-on defaults enable\n", __FUNCTION__));
3173 ataCmdOK(s, ATA_STAT_SEEK);
3174 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
3175 break;
3176 case 0x66: /* reverting to power-on defaults disable */
3177 Log2(("%s: revert to power-on defaults disable\n", __FUNCTION__));
3178 ataCmdOK(s, ATA_STAT_SEEK);
3179 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
3180 break;
3181 case 0x82: /* write cache disable */
3182 Log2(("%s: write cache disable\n", __FUNCTION__));
3183 /* As per the ATA/ATAPI-6 specs, a write cache disable
3184 * command MUST flush the write buffers to disc. */
3185 ataStartTransfer(s, 0, PDMBLOCKTXDIR_NONE, ATAFN_BT_NULL, ATAFN_SS_FLUSH, false);
3186 break;
3187 case 0x03: { /* set transfer mode */
3188 Log2(("%s: transfer mode %#04x\n", __FUNCTION__, s->uATARegNSector));
3189 switch (s->uATARegNSector & 0xf8)
3190 {
3191 case 0x00: /* PIO default */
3192 case 0x08: /* PIO mode */
3193 break;
3194 case ATA_MODE_MDMA: /* MDMA mode */
3195 s->uATATransferMode = (s->uATARegNSector & 0xf8) | RT_MIN(s->uATARegNSector & 0x07, ATA_MDMA_MODE_MAX);
3196 break;
3197 case ATA_MODE_UDMA: /* UDMA mode */
3198 s->uATATransferMode = (s->uATARegNSector & 0xf8) | RT_MIN(s->uATARegNSector & 0x07, ATA_UDMA_MODE_MAX);
3199 break;
3200 default:
3201 goto abort_cmd;
3202 }
3203 ataCmdOK(s, ATA_STAT_SEEK);
3204 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
3205 break;
3206 }
3207 default:
3208 goto abort_cmd;
3209 }
3210 /*
3211 * OS/2 workarond:
3212 * The OS/2 IDE driver from MCP2 appears to rely on the feature register being
3213 * reset here. According to the specification, this is a driver bug as the register
3214 * contents are undefined after the call. This means we can just as well reset it.
3215 */
3216 s->uATARegFeature = 0;
3217 break;
3218 case ATA_FLUSH_CACHE_EXT:
3219 case ATA_FLUSH_CACHE:
3220 if (!s->pDrvBlock || s->fATAPI)
3221 goto abort_cmd;
3222 ataStartTransfer(s, 0, PDMBLOCKTXDIR_NONE, ATAFN_BT_NULL, ATAFN_SS_FLUSH, false);
3223 break;
3224 case ATA_STANDBY_IMMEDIATE:
3225 ataCmdOK(s, 0);
3226 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
3227 break;
3228 case ATA_IDLE_IMMEDIATE:
3229 ataAbortCurrentCommand(s, false);
3230 break;
3231 /* ATAPI commands */
3232 case ATA_IDENTIFY_PACKET_DEVICE:
3233 if (s->fATAPI)
3234 ataStartTransfer(s, 512, PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_NULL, ATAFN_SS_ATAPI_IDENTIFY, false);
3235 else
3236 {
3237 ataCmdError(s, ABRT_ERR);
3238 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
3239 }
3240 break;
3241 case ATA_EXECUTE_DEVICE_DIAGNOSTIC:
3242 ataStartTransfer(s, 0, PDMBLOCKTXDIR_NONE, ATAFN_BT_NULL, ATAFN_SS_EXECUTE_DEVICE_DIAGNOSTIC, false);
3243 break;
3244 case ATA_DEVICE_RESET:
3245 if (!s->fATAPI)
3246 goto abort_cmd;
3247 ataAbortCurrentCommand(s, true);
3248 break;
3249 case ATA_PACKET:
3250 if (!s->fATAPI)
3251 goto abort_cmd;
3252 /* overlapping commands not supported */
3253 if (s->uATARegFeature & 0x02)
3254 goto abort_cmd;
3255 ataStartTransfer(s, ATAPI_PACKET_SIZE, PDMBLOCKTXDIR_TO_DEVICE, ATAFN_BT_PACKET, ATAFN_SS_PACKET, false);
3256 break;
3257 default:
3258 abort_cmd:
3259 ataCmdError(s, ABRT_ERR);
3260 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
3261 break;
3262 }
3263}
3264
3265
3266/**
3267 * Waits for a particular async I/O thread to complete whatever it
3268 * is doing at the moment.
3269 *
3270 * @returns true on success.
3271 * @returns false when the thread is still processing.
3272 * @param pData Pointer to the controller data.
3273 * @param cMillies How long to wait (total).
3274 */
3275static bool ataWaitForAsyncIOIsIdle(PATACONTROLLER pCtl, unsigned cMillies)
3276{
3277 uint64_t u64Start;
3278
3279 /*
3280 * Wait for any pending async operation to finish
3281 */
3282 u64Start = RTTimeMilliTS();
3283 for (;;)
3284 {
3285 if (ataAsyncIOIsIdle(pCtl, false))
3286 return true;
3287 if (RTTimeMilliTS() - u64Start >= cMillies)
3288 break;
3289
3290 /* Sleep for a bit. */
3291 RTThreadSleep(100);
3292 }
3293
3294 return false;
3295}
3296
3297#endif /* IN_RING3 */
3298
3299static int ataIOPortWriteU8(PATACONTROLLER pCtl, uint32_t addr, uint32_t val)
3300{
3301 Log2(("%s: write addr=%#x val=%#04x\n", __FUNCTION__, addr, val));
3302 addr &= 7;
3303 switch (addr)
3304 {
3305 case 0:
3306 break;
3307 case 1: /* feature register */
3308 /* NOTE: data is written to the two drives */
3309 pCtl->aIfs[0].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
3310 pCtl->aIfs[1].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
3311 pCtl->aIfs[0].uATARegFeatureHOB = pCtl->aIfs[0].uATARegFeature;
3312 pCtl->aIfs[1].uATARegFeatureHOB = pCtl->aIfs[1].uATARegFeature;
3313 pCtl->aIfs[0].uATARegFeature = val;
3314 pCtl->aIfs[1].uATARegFeature = val;
3315 break;
3316 case 2: /* sector count */
3317 pCtl->aIfs[0].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
3318 pCtl->aIfs[1].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
3319 pCtl->aIfs[0].uATARegNSectorHOB = pCtl->aIfs[0].uATARegNSector;
3320 pCtl->aIfs[1].uATARegNSectorHOB = pCtl->aIfs[1].uATARegNSector;
3321 pCtl->aIfs[0].uATARegNSector = val;
3322 pCtl->aIfs[1].uATARegNSector = val;
3323 break;
3324 case 3: /* sector number */
3325 pCtl->aIfs[0].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
3326 pCtl->aIfs[1].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
3327 pCtl->aIfs[0].uATARegSectorHOB = pCtl->aIfs[0].uATARegSector;
3328 pCtl->aIfs[1].uATARegSectorHOB = pCtl->aIfs[1].uATARegSector;
3329 pCtl->aIfs[0].uATARegSector = val;
3330 pCtl->aIfs[1].uATARegSector = val;
3331 break;
3332 case 4: /* cylinder low */
3333 pCtl->aIfs[0].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
3334 pCtl->aIfs[1].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
3335 pCtl->aIfs[0].uATARegLCylHOB = pCtl->aIfs[0].uATARegLCyl;
3336 pCtl->aIfs[1].uATARegLCylHOB = pCtl->aIfs[1].uATARegLCyl;
3337 pCtl->aIfs[0].uATARegLCyl = val;
3338 pCtl->aIfs[1].uATARegLCyl = val;
3339 break;
3340 case 5: /* cylinder high */
3341 pCtl->aIfs[0].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
3342 pCtl->aIfs[1].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
3343 pCtl->aIfs[0].uATARegHCylHOB = pCtl->aIfs[0].uATARegHCyl;
3344 pCtl->aIfs[1].uATARegHCylHOB = pCtl->aIfs[1].uATARegHCyl;
3345 pCtl->aIfs[0].uATARegHCyl = val;
3346 pCtl->aIfs[1].uATARegHCyl = val;
3347 break;
3348 case 6: /* drive/head */
3349 pCtl->aIfs[0].uATARegSelect = (val & ~0x10) | 0xa0;
3350 pCtl->aIfs[1].uATARegSelect = (val | 0x10) | 0xa0;
3351 if ((((val >> 4)) & 1) != pCtl->iSelectedIf)
3352 {
3353 PPDMDEVINS pDevIns = CONTROLLER_2_DEVINS(pCtl);
3354
3355 /* select another drive */
3356 pCtl->iSelectedIf = (val >> 4) & 1;
3357 /* The IRQ line is multiplexed between the two drives, so
3358 * update the state when switching to another drive. */
3359 if (pCtl->aIfs[pCtl->iSelectedIf].fIrqPending)
3360 {
3361 if (pCtl->irq == 16)
3362 PDMDevHlpPCISetIrqNoWait(pDevIns, 0, 1);
3363 else
3364 PDMDevHlpISASetIrqNoWait(pDevIns, pCtl->irq, 1);
3365 }
3366 else
3367 {
3368 if (pCtl->irq == 16)
3369 PDMDevHlpPCISetIrqNoWait(pDevIns, 0, 0);
3370 else
3371 PDMDevHlpISASetIrqNoWait(pDevIns, pCtl->irq, 0);
3372 }
3373 }
3374 break;
3375 default:
3376 case 7: /* command */
3377 /* ignore commands to non existant slave */
3378 if (pCtl->iSelectedIf && !pCtl->aIfs[pCtl->iSelectedIf].pDrvBlock)
3379 break;
3380#ifndef IN_RING3
3381 /* Don't do anything complicated in GC */
3382 return VINF_IOM_HC_IOPORT_WRITE;
3383#else /* IN_RING3 */
3384 ataParseCmd(&pCtl->aIfs[pCtl->iSelectedIf], val);
3385#endif /* !IN_RING3 */
3386 }
3387 return VINF_SUCCESS;
3388}
3389
3390
3391static void ataIOPortReadU8(PATACONTROLLER pCtl, uint32_t addr, uint32_t *pu32)
3392{
3393 ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf];
3394 uint32_t val;
3395 bool fHOB;
3396
3397 fHOB = !!(s->uATARegDevCtl & (1 << 7));
3398 switch (addr & 7)
3399 {
3400 case 0: /* data register */
3401 val = 0xff;
3402 break;
3403 case 1: /* error register */
3404 /* The ATA specification is very terse when it comes to specifying
3405 * the precise effects of reading back the error/feature register.
3406 * The error register (read-only) shares the register number with
3407 * the feature register (write-only), so it seems that it's not
3408 * necessary to support the usual HOB readback here. */
3409 if (!s->pDrvBlock)
3410 val = 0;
3411 else
3412 val = s->uATARegError;
3413 break;
3414 case 2: /* sector count */
3415 if (!s->pDrvBlock)
3416 val = 0;
3417 else if (fHOB)
3418 val = s->uATARegNSectorHOB;
3419 else
3420 val = s->uATARegNSector;
3421 break;
3422 case 3: /* sector number */
3423 if (!s->pDrvBlock)
3424 val = 0;
3425 else if (fHOB)
3426 val = s->uATARegSectorHOB;
3427 else
3428 val = s->uATARegSector;
3429 break;
3430 case 4: /* cylinder low */
3431 if (!s->pDrvBlock)
3432 val = 0;
3433 else if (fHOB)
3434 val = s->uATARegLCylHOB;
3435 else
3436 val = s->uATARegLCyl;
3437 break;
3438 case 5: /* cylinder high */
3439 if (!s->pDrvBlock)
3440 val = 0;
3441 else if (fHOB)
3442 val = s->uATARegHCylHOB;
3443 else
3444 val = s->uATARegHCyl;
3445 break;
3446 case 6: /* drive/head */
3447 /* This register must always work as long as there is at least
3448 * one drive attached to the controller. It is common between
3449 * both drives anyway (completely identical content). */
3450 if (!pCtl->aIfs[0].pDrvBlock && !pCtl->aIfs[1].pDrvBlock)
3451 val = 0;
3452 else
3453 val = s->uATARegSelect;
3454 break;
3455 default:
3456 case 7: /* primary status */
3457 {
3458 if (!s->pDrvBlock)
3459 val = 0;
3460 else
3461 val = s->uATARegStatus;
3462 ataUnsetIRQ(s);
3463#ifdef IN_RING3
3464 /* Give the async I/O thread an opportunity to make progress,
3465 * don't let it starve by guests polling frequently. EMT has a
3466 * lower priority than the async I/O thread, but sometimes the
3467 * host OS doesn't care. With some guests we are only allowed to
3468 * be busy for about 5 milliseconds in some situations. */
3469 if (val & ATA_STAT_BUSY)
3470 {
3471 PDMCritSectLeave(&pCtl->lock);
3472
3473 RTThreadYield();
3474
3475 {
3476 STAM_PROFILE_START(&pCtl->StatLockWait, a);
3477 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
3478 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
3479 }
3480
3481 val = s->uATARegStatus;
3482 }
3483#endif
3484 break;
3485 }
3486 }
3487 Log2(("%s: addr=%#x val=%#04x\n", __FUNCTION__, addr, val));
3488 *pu32 = val;
3489}
3490
3491
3492static uint32_t ataStatusRead(PATACONTROLLER pCtl, uint32_t addr)
3493{
3494 ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf];
3495 uint32_t val;
3496
3497 if ((!pCtl->aIfs[0].pDrvBlock && !pCtl->aIfs[1].pDrvBlock) ||
3498 (pCtl->iSelectedIf == 1 && !s->pDrvBlock))
3499 val = 0;
3500 else
3501 val = s->uATARegStatus;
3502 Log2(("%s: addr=%#x val=%#04x\n", __FUNCTION__, addr, val));
3503 return val;
3504}
3505
3506static int ataControlWrite(PATACONTROLLER pCtl, uint32_t addr, uint32_t val)
3507{
3508#ifndef IN_RING3
3509 if ((val ^ pCtl->aIfs[0].uATARegDevCtl) & ATA_DEVCTL_RESET)
3510 return VINF_IOM_HC_IOPORT_WRITE; /* The RESET stuff is too complicated for GC. */
3511#endif /* !IN_RING3 */
3512
3513 Log2(("%s: addr=%#x val=%#04x\n", __FUNCTION__, addr, val));
3514 /* RESET is common for both drives attached to a controller. */
3515 if (!(pCtl->aIfs[0].uATARegDevCtl & ATA_DEVCTL_RESET) &&
3516 (val & ATA_DEVCTL_RESET))
3517 {
3518#ifdef IN_RING3
3519 /* Software RESET low to high */
3520 LogRel(("PIIX3 ATA: Ctl#%d: RESET, DevSel=%d AIOIf=%d CmdIf0=%#04x CmdIf1=%#04x\n",
3521 ATACONTROLLER_IDX(pCtl), pCtl->iSelectedIf, pCtl->iAIOIf,
3522 pCtl->aIfs[0].uATARegCommand, pCtl->aIfs[1].uATARegCommand));
3523 pCtl->fReset = true;
3524 /* Everything must be done after the reset flag is set, otherwise
3525 * there are unavoidable races with the currently executing request
3526 * (which might just finish in the mean time). */
3527 pCtl->fChainedTransfer = false;
3528 for (uint32_t i = 0; i < RT_ELEMENTS(pCtl->aIfs); i++)
3529 {
3530 ataResetDevice(&pCtl->aIfs[i]);
3531 /* The following cannot be done using ataSetStatusValue() since the
3532 * reset flag is already set, which suppresses all status changes. */
3533 pCtl->aIfs[i].uATARegStatus = ATA_STAT_BUSY | ATA_STAT_SEEK;
3534 Log2(("%s: LUN#%d status %#04x\n", __FUNCTION__, pCtl->aIfs[i].iLUN, pCtl->aIfs[i].uATARegStatus));
3535 pCtl->aIfs[i].uATARegError = 0x01;
3536 }
3537 ataAsyncIOClearRequests(pCtl);
3538 Log2(("%s: Ctl#%d: message to async I/O thread, resetA\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
3539 if (val & ATA_DEVCTL_HOB)
3540 {
3541 val &= ~ATA_DEVCTL_HOB;
3542 Log2(("%s: ignored setting HOB\n", __FUNCTION__));
3543 }
3544 ataAsyncIOPutRequest(pCtl, &ataResetARequest);
3545#else /* !IN_RING3 */
3546 AssertMsgFailed(("RESET handling is too complicated for GC\n"));
3547#endif /* IN_RING3 */
3548 }
3549 else if ((pCtl->aIfs[0].uATARegDevCtl & ATA_DEVCTL_RESET) &&
3550 !(val & ATA_DEVCTL_RESET))
3551 {
3552#ifdef IN_RING3
3553 /* Software RESET high to low */
3554 Log(("%s: deasserting RESET\n", __FUNCTION__));
3555 Log2(("%s: Ctl#%d: message to async I/O thread, resetC\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
3556 if (val & ATA_DEVCTL_HOB)
3557 {
3558 val &= ~ATA_DEVCTL_HOB;
3559 Log2(("%s: ignored setting HOB\n", __FUNCTION__));
3560 }
3561 ataAsyncIOPutRequest(pCtl, &ataResetCRequest);
3562#else /* !IN_RING3 */
3563 AssertMsgFailed(("RESET handling is too complicated for GC\n"));
3564#endif /* IN_RING3 */
3565 }
3566
3567 if (val & ATA_DEVCTL_HOB)
3568 Log2(("%s: set HOB\n", __FUNCTION__));
3569
3570 pCtl->aIfs[0].uATARegDevCtl = val;
3571 pCtl->aIfs[1].uATARegDevCtl = val;
3572
3573 return VINF_SUCCESS;
3574}
3575
3576#ifdef IN_RING3
3577
3578DECLINLINE(void) ataPIOTransferFinish(PATACONTROLLER pCtl, ATADevState *s)
3579{
3580 /* Do not interfere with RESET processing if the PIO transfer finishes
3581 * while the RESET line is asserted. */
3582 if (pCtl->fReset)
3583 {
3584 Log2(("%s: Ctl#%d: suppressed continuing PIO transfer as RESET is active\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
3585 return;
3586 }
3587
3588 ataUnsetStatus(s, ATA_STAT_READY | ATA_STAT_DRQ);
3589 ataSetStatus(s, ATA_STAT_BUSY);
3590
3591 Log2(("%s: Ctl#%d: message to async I/O thread, continuing PIO transfer\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
3592 ataAsyncIOPutRequest(pCtl, &ataPIORequest);
3593}
3594
3595#endif /* IN_RING3 */
3596
3597static int ataDataWrite(PATACONTROLLER pCtl, uint32_t addr, uint32_t cbSize, const uint8_t *pbBuf)
3598{
3599 ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf];
3600 uint8_t *p;
3601
3602 if (s->iIOBufferPIODataStart < s->iIOBufferPIODataEnd)
3603 {
3604 Assert(s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE);
3605 p = s->CTXSUFF(pbIOBuffer) + s->iIOBufferPIODataStart;
3606#ifndef IN_RING3
3607 /* All but the last transfer unit is simple enough for GC, but
3608 * sending a request to the async IO thread is too complicated. */
3609 if (s->iIOBufferPIODataStart + cbSize < s->iIOBufferPIODataEnd)
3610 {
3611 memcpy(p, pbBuf, cbSize);
3612 s->iIOBufferPIODataStart += cbSize;
3613 }
3614 else
3615 return VINF_IOM_HC_IOPORT_WRITE;
3616#else /* IN_RING3 */
3617 memcpy(p, pbBuf, cbSize);
3618 s->iIOBufferPIODataStart += cbSize;
3619 if (s->iIOBufferPIODataStart >= s->iIOBufferPIODataEnd)
3620 ataPIOTransferFinish(pCtl, s);
3621#endif /* !IN_RING3 */
3622 }
3623 else
3624 Log2(("%s: DUMMY data\n", __FUNCTION__));
3625 Log3(("%s: addr=%#x val=%.*Vhxs\n", __FUNCTION__, addr, cbSize, pbBuf));
3626 return VINF_SUCCESS;
3627}
3628
3629static int ataDataRead(PATACONTROLLER pCtl, uint32_t addr, uint32_t cbSize, uint8_t *pbBuf)
3630{
3631 ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf];
3632 uint8_t *p;
3633
3634 if (s->iIOBufferPIODataStart < s->iIOBufferPIODataEnd)
3635 {
3636 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
3637 p = s->CTXSUFF(pbIOBuffer) + s->iIOBufferPIODataStart;
3638#ifndef IN_RING3
3639 /* All but the last transfer unit is simple enough for GC, but
3640 * sending a request to the async IO thread is too complicated. */
3641 if (s->iIOBufferPIODataStart + cbSize < s->iIOBufferPIODataEnd)
3642 {
3643 memcpy(pbBuf, p, cbSize);
3644 s->iIOBufferPIODataStart += cbSize;
3645 }
3646 else
3647 return VINF_IOM_HC_IOPORT_READ;
3648#else /* IN_RING3 */
3649 memcpy(pbBuf, p, cbSize);
3650 s->iIOBufferPIODataStart += cbSize;
3651 if (s->iIOBufferPIODataStart >= s->iIOBufferPIODataEnd)
3652 ataPIOTransferFinish(pCtl, s);
3653#endif /* !IN_RING3 */
3654 }
3655 else
3656 {
3657 Log2(("%s: DUMMY data\n", __FUNCTION__));
3658 memset(pbBuf, '\xff', cbSize);
3659 }
3660 Log3(("%s: addr=%#x val=%.*Vhxs\n", __FUNCTION__, addr, cbSize, pbBuf));
3661 return VINF_SUCCESS;
3662}
3663
3664#ifdef IN_RING3
3665
3666/* Attempt to guess the LCHS disk geometry from the MS-DOS master boot
3667 * record (partition table). */
3668static int ataGuessDiskLCHS(ATADevState *s, uint32_t *pcCylinders, uint32_t *pcHeads, uint32_t *pcSectors)
3669{
3670 uint8_t aMBR[512], *p;
3671 int rc;
3672 uint32_t iEndHead, iEndSector, cCHSCylinders, cCHSHeads, cCHSSectors;
3673
3674 if (s->fATAPI || !s->pDrvBlock)
3675 return VERR_INVALID_PARAMETER;
3676 rc = s->pDrvBlock->pfnRead(s->pDrvBlock, 0, aMBR, 1 * 512);
3677 if (VBOX_FAILURE(rc))
3678 return rc;
3679 /* Test MBR magic number. */
3680 if (aMBR[510] != 0x55 || aMBR[511] != 0xaa)
3681 return VERR_INVALID_PARAMETER;
3682 for (uint32_t i = 0; i < 4; i++)
3683 {
3684 /* Figure out the start of a partition table entry. */
3685 p = &aMBR[0x1be + i * 16];
3686 iEndHead = p[5];
3687 iEndSector = p[6] & 63;
3688 if ((p[12] | p[13] | p[14] | p[15]) && iEndSector & iEndHead)
3689 {
3690 /* Assumption: partition terminates on a cylinder boundary. */
3691 cCHSHeads = iEndHead + 1;
3692 cCHSSectors = iEndSector;
3693 cCHSCylinders = s->cTotalSectors / (cCHSHeads * cCHSSectors);
3694 if (cCHSCylinders >= 1)
3695 {
3696 *pcHeads = cCHSHeads;
3697 *pcSectors = cCHSSectors;
3698 *pcCylinders = cCHSCylinders;
3699 Log(("%s: LCHS=%d %d %d\n", __FUNCTION__, cCHSCylinders, cCHSHeads, cCHSSectors));
3700 return VINF_SUCCESS;
3701 }
3702 }
3703 }
3704 return VERR_INVALID_PARAMETER;
3705}
3706
3707
3708static void ataDMATransferStop(ATADevState *s)
3709{
3710 s->cbTotalTransfer = 0;
3711 s->cbElementaryTransfer = 0;
3712 s->iBeginTransfer = ATAFN_BT_NULL;
3713 s->iSourceSink = ATAFN_SS_NULL;
3714}
3715
3716
3717/**
3718 * Perform the entire DMA transfer in one go (unless a source/sink operation
3719 * has to be redone or a RESET comes in between). Unlike the PIO counterpart
3720 * this function cannot handle empty transfers.
3721 *
3722 * @param pCtl Controller for which to perform the transfer.
3723 */
3724static void ataDMATransfer(PATACONTROLLER pCtl)
3725{
3726 PPDMDEVINS pDevIns = CONTROLLER_2_DEVINS(pCtl);
3727 ATADevState *s = &pCtl->aIfs[pCtl->iAIOIf];
3728 bool fRedo;
3729 RTGCPHYS pDesc;
3730 uint32_t cbTotalTransfer, cbElementaryTransfer;
3731 uint32_t iIOBufferCur, iIOBufferEnd;
3732 uint32_t dmalen;
3733 PDMBLOCKTXDIR uTxDir;
3734 bool fLastDesc = false;
3735
3736 Assert(sizeof(BMDMADesc) == 8);
3737
3738 fRedo = pCtl->fRedo;
3739 if (RT_LIKELY(!fRedo))
3740 Assert(s->cbTotalTransfer);
3741 uTxDir = (PDMBLOCKTXDIR)s->uTxDir;
3742 cbTotalTransfer = s->cbTotalTransfer;
3743 cbElementaryTransfer = s->cbElementaryTransfer;
3744 iIOBufferCur = s->iIOBufferCur;
3745 iIOBufferEnd = s->iIOBufferEnd;
3746
3747 /* The DMA loop is designed to hold the lock only when absolutely
3748 * necessary. This avoids long freezes should the guest access the
3749 * ATA registers etc. for some reason. */
3750 PDMCritSectLeave(&pCtl->lock);
3751
3752 Log2(("%s: %s tx_size=%d elem_tx_size=%d index=%d end=%d\n",
3753 __FUNCTION__, uTxDir == PDMBLOCKTXDIR_FROM_DEVICE ? "T2I" : "I2T",
3754 cbTotalTransfer, cbElementaryTransfer,
3755 iIOBufferCur, iIOBufferEnd));
3756 for (pDesc = pCtl->pFirstDMADesc; pDesc <= pCtl->pLastDMADesc; pDesc += sizeof(BMDMADesc))
3757 {
3758 BMDMADesc DMADesc;
3759 RTGCPHYS pBuffer;
3760 uint32_t cbBuffer;
3761
3762 if (RT_UNLIKELY(fRedo))
3763 {
3764 pBuffer = pCtl->pRedoDMABuffer;
3765 cbBuffer = pCtl->cbRedoDMABuffer;
3766 fLastDesc = pCtl->fRedoDMALastDesc;
3767 }
3768 else
3769 {
3770 PDMDevHlpPhysRead(pDevIns, pDesc, &DMADesc, sizeof(BMDMADesc));
3771 pBuffer = RT_LE2H_U32(DMADesc.pBuffer);
3772 cbBuffer = RT_LE2H_U32(DMADesc.cbBuffer);
3773 fLastDesc = !!(cbBuffer & 0x80000000);
3774 cbBuffer &= 0xfffe;
3775 if (cbBuffer == 0)
3776 cbBuffer = 0x10000;
3777 if (cbBuffer > cbTotalTransfer)
3778 cbBuffer = cbTotalTransfer;
3779 }
3780
3781 while (RT_UNLIKELY(fRedo) || (cbBuffer && cbTotalTransfer))
3782 {
3783 if (RT_LIKELY(!fRedo))
3784 {
3785 dmalen = RT_MIN(cbBuffer, iIOBufferEnd - iIOBufferCur);
3786 Log2(("%s: DMA desc %#010x: addr=%#010x size=%#010x\n", __FUNCTION__,
3787 (int)pDesc, pBuffer, cbBuffer));
3788 if (uTxDir == PDMBLOCKTXDIR_FROM_DEVICE)
3789 PDMDevHlpPhysWrite(pDevIns, pBuffer, s->CTXSUFF(pbIOBuffer) + iIOBufferCur, dmalen);
3790 else
3791 PDMDevHlpPhysRead(pDevIns, pBuffer, s->CTXSUFF(pbIOBuffer) + iIOBufferCur, dmalen);
3792 iIOBufferCur += dmalen;
3793 cbTotalTransfer -= dmalen;
3794 cbBuffer -= dmalen;
3795 pBuffer += dmalen;
3796 }
3797 if ( iIOBufferCur == iIOBufferEnd
3798 && (uTxDir == PDMBLOCKTXDIR_TO_DEVICE || cbTotalTransfer))
3799 {
3800 if (uTxDir == PDMBLOCKTXDIR_FROM_DEVICE && cbElementaryTransfer > cbTotalTransfer)
3801 cbElementaryTransfer = cbTotalTransfer;
3802
3803 {
3804 STAM_PROFILE_START(&pCtl->StatLockWait, a);
3805 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
3806 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
3807 }
3808
3809 /* The RESET handler could have cleared the DMA transfer
3810 * state (since we didn't hold the lock until just now
3811 * the guest can continue in parallel). If so, the state
3812 * is already set up so the loop is exited immediately. */
3813 if (s->iSourceSink != ATAFN_SS_NULL)
3814 {
3815 s->iIOBufferCur = iIOBufferCur;
3816 s->iIOBufferEnd = iIOBufferEnd;
3817 s->cbElementaryTransfer = cbElementaryTransfer;
3818 s->cbTotalTransfer = cbTotalTransfer;
3819 Log2(("%s: calling source/sink function\n", __FUNCTION__));
3820 fRedo = g_apfnSourceSinkFuncs[s->iSourceSink](s);
3821 if (RT_UNLIKELY(fRedo))
3822 {
3823 pCtl->pFirstDMADesc = pDesc;
3824 pCtl->pRedoDMABuffer = pBuffer;
3825 pCtl->cbRedoDMABuffer = cbBuffer;
3826 pCtl->fRedoDMALastDesc = fLastDesc;
3827 }
3828 else
3829 {
3830 cbTotalTransfer = s->cbTotalTransfer;
3831 cbElementaryTransfer = s->cbElementaryTransfer;
3832
3833 if (uTxDir == PDMBLOCKTXDIR_TO_DEVICE && cbElementaryTransfer > cbTotalTransfer)
3834 cbElementaryTransfer = cbTotalTransfer;
3835 iIOBufferCur = 0;
3836 iIOBufferEnd = cbElementaryTransfer;
3837 }
3838 pCtl->fRedo = fRedo;
3839 }
3840 else
3841 {
3842 /* This forces the loop to exit immediately. */
3843 pDesc = pCtl->pLastDMADesc + 1;
3844 }
3845
3846 PDMCritSectLeave(&pCtl->lock);
3847 if (RT_UNLIKELY(fRedo))
3848 break;
3849 }
3850 }
3851
3852 if (RT_UNLIKELY(fRedo))
3853 break;
3854
3855 /* end of transfer */
3856 if (!cbTotalTransfer || fLastDesc)
3857 break;
3858
3859 {
3860 STAM_PROFILE_START(&pCtl->StatLockWait, a);
3861 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
3862 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
3863 }
3864
3865 if (!(pCtl->BmDma.u8Cmd & BM_CMD_START) || pCtl->fReset)
3866 {
3867 LogRel(("PIIX3 ATA: Ctl#%d: ABORT DMA%s\n", ATACONTROLLER_IDX(pCtl), pCtl->fReset ? " due to RESET" : ""));
3868 if (!pCtl->fReset)
3869 ataDMATransferStop(s);
3870 /* This forces the loop to exit immediately. */
3871 pDesc = pCtl->pLastDMADesc + 1;
3872 }
3873
3874 PDMCritSectLeave(&pCtl->lock);
3875 }
3876
3877 {
3878 STAM_PROFILE_START(&pCtl->StatLockWait, a);
3879 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
3880 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
3881 }
3882
3883 if (RT_UNLIKELY(fRedo))
3884 return;
3885
3886 if (fLastDesc)
3887 pCtl->BmDma.u8Status &= ~BM_STATUS_DMAING;
3888 s->cbTotalTransfer = cbTotalTransfer;
3889 s->cbElementaryTransfer = cbElementaryTransfer;
3890 s->iIOBufferCur = iIOBufferCur;
3891 s->iIOBufferEnd = iIOBufferEnd;
3892}
3893
3894
3895static void ataPIOTransfer(PATACONTROLLER pCtl)
3896{
3897 ATADevState *s;
3898
3899 s = &pCtl->aIfs[pCtl->iAIOIf];
3900 Log3(("%s: if=%p\n", __FUNCTION__, s));
3901
3902 if (s->cbTotalTransfer && s->iIOBufferCur > s->iIOBufferEnd)
3903 {
3904 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"));
3905 /* Any guest OS that triggers this case has a pathetic ATA driver.
3906 * In a real system it would block the CPU via IORDY, here we do it
3907 * very similarly by not continuing with the current instruction
3908 * until the transfer to/from the storage medium is completed. */
3909 if (s->iSourceSink != ATAFN_SS_NULL)
3910 {
3911 bool fRedo;
3912 uint8_t status = s->uATARegStatus;
3913 ataSetStatusValue(s, ATA_STAT_BUSY);
3914 Log2(("%s: calling source/sink function\n", __FUNCTION__));
3915 fRedo = g_apfnSourceSinkFuncs[s->iSourceSink](s);
3916 pCtl->fRedo = fRedo;
3917 if (RT_UNLIKELY(fRedo))
3918 return;
3919 ataSetStatusValue(s, status);
3920 s->iIOBufferCur = 0;
3921 s->iIOBufferEnd = s->cbElementaryTransfer;
3922 }
3923 }
3924 if (s->cbTotalTransfer)
3925 {
3926 if (s->fATAPITransfer)
3927 ataPIOTransferLimitATAPI(s);
3928
3929 if (s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE && s->cbElementaryTransfer > s->cbTotalTransfer)
3930 s->cbElementaryTransfer = s->cbTotalTransfer;
3931
3932 Log2(("%s: %s tx_size=%d elem_tx_size=%d index=%d end=%d\n",
3933 __FUNCTION__, s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE ? "T2I" : "I2T",
3934 s->cbTotalTransfer, s->cbElementaryTransfer,
3935 s->iIOBufferCur, s->iIOBufferEnd));
3936 ataPIOTransferStart(s, s->iIOBufferCur, s->cbElementaryTransfer);
3937 s->cbTotalTransfer -= s->cbElementaryTransfer;
3938 s->iIOBufferCur += s->cbElementaryTransfer;
3939
3940 if (s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE && s->cbElementaryTransfer > s->cbTotalTransfer)
3941 s->cbElementaryTransfer = s->cbTotalTransfer;
3942 }
3943 else
3944 ataPIOTransferStop(s);
3945}
3946
3947
3948/**
3949 * Suspend I/O operations on a controller. Also suspends EMT, because it's
3950 * waiting for I/O to make progress. The next attempt to perform an I/O
3951 * operation will be made when EMT is resumed up again (as the resume
3952 * callback below restarts I/O).
3953 *
3954 * @param pCtl Controller for which to suspend I/O.
3955 */
3956static void ataSuspendRedo(PATACONTROLLER pCtl)
3957{
3958 PPDMDEVINS pDevIns = CONTROLLER_2_DEVINS(pCtl);
3959 PVMREQ pReq;
3960 int rc;
3961
3962 pCtl->fRedoIdle = true;
3963 rc = VMR3ReqCall(PDMDevHlpGetVM(pDevIns), &pReq, RT_INDEFINITE_WAIT,
3964 (PFNRT)pDevIns->pDevHlp->pfnVMSuspend, 1, pDevIns);
3965 AssertReleaseRC(rc);
3966 VMR3ReqFree(pReq);
3967}
3968
3969/** Asynch I/O thread for an interface. Once upon a time this was readable
3970 * code with several loops and a different semaphore for each purpose. But
3971 * then came the "how can one save the state in the middle of a PIO transfer"
3972 * question. The solution was to use an ASM, which is what's there now. */
3973static DECLCALLBACK(int) ataAsyncIOLoop(RTTHREAD ThreadSelf, void *pvUser)
3974{
3975 const ATARequest *pReq;
3976 uint64_t u64TS = 0; /* shut up gcc */
3977 uint64_t uWait;
3978 int rc = VINF_SUCCESS;
3979 PATACONTROLLER pCtl = (PATACONTROLLER)pvUser;
3980 ATADevState *s;
3981
3982 pReq = NULL;
3983 pCtl->fChainedTransfer = false;
3984 while (!pCtl->fShutdown)
3985 {
3986 /* Keep this thread from doing anything as long as EMT is suspended. */
3987 while (pCtl->fRedoIdle)
3988 {
3989 rc = RTSemEventWait(pCtl->SuspendIOSem, RT_INDEFINITE_WAIT);
3990 if (VBOX_FAILURE(rc) || pCtl->fShutdown)
3991 break;
3992
3993 pCtl->fRedoIdle = false;
3994 }
3995
3996 /* Wait for work. */
3997 if (pReq == NULL)
3998 {
3999 rc = RTSemEventWait(pCtl->AsyncIOSem, RT_INDEFINITE_WAIT);
4000 if (VBOX_FAILURE(rc) || pCtl->fShutdown)
4001 break;
4002
4003 pReq = ataAsyncIOGetCurrentRequest(pCtl);
4004 }
4005
4006 if (pReq == NULL)
4007 continue;
4008
4009 ATAAIO ReqType = pReq->ReqType;
4010
4011 Log2(("%s: Ctl#%d: state=%d, req=%d\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl), pCtl->uAsyncIOState, ReqType));
4012 if (pCtl->uAsyncIOState != ReqType)
4013 {
4014 /* The new state is not the state that was expected by the normal
4015 * state changes. This is either a RESET/ABORT or there's something
4016 * really strange going on. */
4017 if ( (pCtl->uAsyncIOState == ATA_AIO_PIO || pCtl->uAsyncIOState == ATA_AIO_DMA)
4018 && (ReqType == ATA_AIO_PIO || ReqType == ATA_AIO_DMA))
4019 {
4020 /* Incorrect sequence of PIO/DMA states. Dump request queue. */
4021 ataAsyncIODumpRequests(pCtl);
4022 }
4023 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));
4024 }
4025
4026 /* Do our work. */
4027 {
4028 STAM_PROFILE_START(&pCtl->StatLockWait, a);
4029 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
4030 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
4031 }
4032
4033 if (pCtl->uAsyncIOState == ATA_AIO_NEW && !pCtl->fChainedTransfer)
4034 {
4035 u64TS = RTTimeNanoTS();
4036#if defined(DEBUG) || defined(VBOX_WITH_STATISTICS)
4037 STAM_PROFILE_ADV_START(&pCtl->StatAsyncTime, a);
4038#endif /* DEBUG || VBOX_WITH_STATISTICS */
4039 }
4040
4041 switch (ReqType)
4042 {
4043 case ATA_AIO_NEW:
4044
4045 pCtl->iAIOIf = pReq->u.t.iIf;
4046 s = &pCtl->aIfs[pCtl->iAIOIf];
4047 s->cbTotalTransfer = pReq->u.t.cbTotalTransfer;
4048 s->uTxDir = pReq->u.t.uTxDir;
4049 s->iBeginTransfer = pReq->u.t.iBeginTransfer;
4050 s->iSourceSink = pReq->u.t.iSourceSink;
4051 s->iIOBufferEnd = 0;
4052
4053 pCtl->fChainedTransfer = false;
4054
4055 if (s->iBeginTransfer != ATAFN_BT_NULL)
4056 {
4057 Log2(("%s: Ctl#%d: calling begin transfer function\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
4058 g_apfnBeginTransFuncs[s->iBeginTransfer](s);
4059 s->iBeginTransfer = ATAFN_BT_NULL;
4060 if (s->uTxDir != PDMBLOCKTXDIR_FROM_DEVICE)
4061 s->iIOBufferEnd = s->cbElementaryTransfer;
4062 }
4063 else
4064 {
4065 s->cbElementaryTransfer = s->cbTotalTransfer;
4066 s->iIOBufferEnd = s->cbTotalTransfer;
4067 }
4068 s->iIOBufferCur = 0;
4069
4070 if (s->uTxDir != PDMBLOCKTXDIR_TO_DEVICE)
4071 {
4072 if (s->iSourceSink != ATAFN_SS_NULL)
4073 {
4074 bool fRedo;
4075 Log2(("%s: Ctl#%d: calling source/sink function\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
4076 fRedo = g_apfnSourceSinkFuncs[s->iSourceSink](s);
4077 pCtl->fRedo = fRedo;
4078 if (RT_UNLIKELY(fRedo))
4079 {
4080 /* Operation failed at the initial transfer, restart
4081 * everything from scratch by resending the current
4082 * request. Occurs very rarely, not worth optimizing. */
4083 LogRel(("%s: Ctl#%d: redo entire operation\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
4084 ataAsyncIOPutRequest(pCtl, pReq);
4085 ataSuspendRedo(pCtl);
4086 break;
4087 }
4088 }
4089 else
4090 ataCmdOK(s, 0);
4091 s->iIOBufferEnd = s->cbElementaryTransfer;
4092
4093 }
4094
4095 /* Do not go into the transfer phase if RESET is asserted.
4096 * The CritSect is released while waiting for the host OS
4097 * to finish the I/O, thus RESET is possible here. Most
4098 * important: do not change uAsyncIOState. */
4099 if (pCtl->fReset)
4100 break;
4101
4102 if (s->fDMA)
4103 {
4104 if (s->cbTotalTransfer)
4105 {
4106 ataSetStatus(s, ATA_STAT_DRQ);
4107
4108 pCtl->uAsyncIOState = ATA_AIO_DMA;
4109 /* If BMDMA is already started, do the transfer now. */
4110 if (pCtl->BmDma.u8Cmd & BM_CMD_START)
4111 {
4112 Log2(("%s: Ctl#%d: message to async I/O thread, continuing DMA transfer immediately\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
4113 ataAsyncIOPutRequest(pCtl, &ataDMARequest);
4114 }
4115 }
4116 else
4117 {
4118 Assert(s->uTxDir == PDMBLOCKTXDIR_NONE); /* Any transfer which has an initial transfer size of 0 must be marked as such. */
4119 /* Finish DMA transfer. */
4120 ataDMATransferStop(s);
4121 ataSetIRQ(s);
4122 pCtl->uAsyncIOState = ATA_AIO_NEW;
4123 }
4124 }
4125 else
4126 {
4127 if (s->cbTotalTransfer)
4128 {
4129 ataPIOTransfer(pCtl);
4130 Assert(!pCtl->fRedo);
4131 if (s->fATAPITransfer || s->uTxDir != PDMBLOCKTXDIR_TO_DEVICE)
4132 ataSetIRQ(s);
4133
4134 pCtl->uAsyncIOState = ATA_AIO_PIO;
4135 }
4136 else
4137 {
4138 Assert(s->uTxDir == PDMBLOCKTXDIR_NONE); /* Any transfer which has an initial transfer size of 0 must be marked as such. */
4139 /* Finish PIO transfer. */
4140 ataPIOTransfer(pCtl);
4141 Assert(!pCtl->fRedo);
4142 if (!s->fATAPITransfer)
4143 ataSetIRQ(s);
4144 pCtl->uAsyncIOState = ATA_AIO_NEW;
4145 }
4146 }
4147 break;
4148
4149 case ATA_AIO_DMA:
4150 {
4151 BMDMAState *bm = &pCtl->BmDma;
4152 s = &pCtl->aIfs[pCtl->iAIOIf]; /* Do not remove or there's an instant crash after loading the saved state */
4153 ATAFNSS iOriginalSourceSink = (ATAFNSS)s->iSourceSink; /* Used by the hack below, but gets reset by then. */
4154
4155 if (s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE)
4156 AssertRelease(bm->u8Cmd & BM_CMD_WRITE);
4157 else
4158 AssertRelease(!(bm->u8Cmd & BM_CMD_WRITE));
4159
4160 if (RT_LIKELY(!pCtl->fRedo))
4161 {
4162 /* The specs say that the descriptor table must not cross a
4163 * 4K boundary. */
4164 pCtl->pFirstDMADesc = bm->pvAddr;
4165 pCtl->pLastDMADesc = RT_ALIGN_32(bm->pvAddr + 1, _4K) - sizeof(BMDMADesc);
4166 }
4167 ataDMATransfer(pCtl);
4168
4169 if (RT_UNLIKELY(pCtl->fRedo))
4170 {
4171 LogRel(("PIIX3 ATA: Ctl#%d: redo DMA operation\n", ATACONTROLLER_IDX(pCtl)));
4172 ataAsyncIOPutRequest(pCtl, &ataDMARequest);
4173 ataSuspendRedo(pCtl);
4174 break;
4175 }
4176
4177 /* The infamous delay IRQ hack. */
4178 if ( iOriginalSourceSink == ATAFN_SS_WRITE_SECTORS
4179 && s->cbTotalTransfer == 0
4180 && pCtl->DelayIRQMillies)
4181 {
4182 /* Delay IRQ for writing. Required to get the Win2K
4183 * installation work reliably (otherwise it crashes,
4184 * usually during component install). So far no better
4185 * solution has been found. */
4186 Log(("%s: delay IRQ hack\n", __FUNCTION__));
4187 PDMCritSectLeave(&pCtl->lock);
4188 RTThreadSleep(pCtl->DelayIRQMillies);
4189 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
4190 }
4191
4192 ataUnsetStatus(s, ATA_STAT_DRQ);
4193 Assert(!pCtl->fChainedTransfer);
4194 Assert(s->iSourceSink == ATAFN_SS_NULL);
4195 if (s->fATAPITransfer)
4196 {
4197 s->uATARegNSector = (s->uATARegNSector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
4198 Log2(("%s: Ctl#%d: interrupt reason %#04x\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl), s->uATARegNSector));
4199 s->fATAPITransfer = false;
4200 }
4201 ataSetIRQ(s);
4202 pCtl->uAsyncIOState = ATA_AIO_NEW;
4203 break;
4204 }
4205
4206 case ATA_AIO_PIO:
4207 s = &pCtl->aIfs[pCtl->iAIOIf]; /* Do not remove or there's an instant crash after loading the saved state */
4208
4209 if (s->iSourceSink != ATAFN_SS_NULL)
4210 {
4211 bool fRedo;
4212 Log2(("%s: Ctl#%d: calling source/sink function\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
4213 fRedo = g_apfnSourceSinkFuncs[s->iSourceSink](s);
4214 pCtl->fRedo = fRedo;
4215 if (RT_UNLIKELY(fRedo))
4216 {
4217 LogRel(("PIIX3 ATA: Ctl#%d: redo PIO operation\n", ATACONTROLLER_IDX(pCtl)));
4218 ataAsyncIOPutRequest(pCtl, &ataPIORequest);
4219 ataSuspendRedo(pCtl);
4220 break;
4221 }
4222 s->iIOBufferCur = 0;
4223 s->iIOBufferEnd = s->cbElementaryTransfer;
4224 }
4225 else
4226 {
4227 /* Continue a previously started transfer. */
4228 ataUnsetStatus(s, ATA_STAT_BUSY);
4229 ataSetStatus(s, ATA_STAT_READY);
4230 }
4231
4232 /* It is possible that the drives on this controller get RESET
4233 * during the above call to the source/sink function. If that's
4234 * the case, don't restart the transfer and don't finish it the
4235 * usual way. RESET handling took care of all that already.
4236 * Most important: do not change uAsyncIOState. */
4237 if (pCtl->fReset)
4238 break;
4239
4240 if (s->cbTotalTransfer)
4241 {
4242 ataPIOTransfer(pCtl);
4243 ataSetIRQ(s);
4244
4245 pCtl->uAsyncIOState = ATA_AIO_PIO;
4246 }
4247 else
4248 {
4249 /* Finish PIO transfer. */
4250 ataPIOTransfer(pCtl);
4251 pCtl->uAsyncIOState = ATA_AIO_NEW;
4252 if (!pCtl->fChainedTransfer)
4253 {
4254 if (!s->fATAPITransfer && s->uTxDir != PDMBLOCKTXDIR_FROM_DEVICE)
4255 ataSetIRQ(s);
4256 }
4257 }
4258 break;
4259
4260 case ATA_AIO_RESET_ASSERTED:
4261 pCtl->uAsyncIOState = ATA_AIO_RESET_CLEARED;
4262 ataPIOTransferStop(&pCtl->aIfs[0]);
4263 ataPIOTransferStop(&pCtl->aIfs[1]);
4264 /* Do not change the DMA registers, they are not affected by the
4265 * ATA controller reset logic. It should be sufficient to issue a
4266 * new command, which is now possible as the state is cleared. */
4267 break;
4268
4269 case ATA_AIO_RESET_CLEARED:
4270 pCtl->uAsyncIOState = ATA_AIO_NEW;
4271 pCtl->fReset = false;
4272 for (uint32_t i = 0; i < RT_ELEMENTS(pCtl->aIfs); i++)
4273 {
4274 if (pCtl->aIfs[i].fATAPI)
4275 ataSetStatusValue(&pCtl->aIfs[i], 0); /* NOTE: READY is _not_ set */
4276 else
4277 ataSetStatusValue(&pCtl->aIfs[i], ATA_STAT_READY | ATA_STAT_SEEK);
4278 ataSetSignature(&pCtl->aIfs[i]);
4279 }
4280 break;
4281
4282 case ATA_AIO_ABORT:
4283 /* Abort the current command only if it operates on the same interface. */
4284 if (pCtl->iAIOIf == pReq->u.a.iIf)
4285 {
4286 s = &pCtl->aIfs[pCtl->iAIOIf];
4287
4288 pCtl->uAsyncIOState = ATA_AIO_NEW;
4289 /* Do not change the DMA registers, they are not affected by the
4290 * ATA controller reset logic. It should be sufficient to issue a
4291 * new command, which is now possible as the state is cleared. */
4292 if (pReq->u.a.fResetDrive)
4293 {
4294 ataResetDevice(s);
4295 ataExecuteDeviceDiagnosticSS(s);
4296 }
4297 else
4298 {
4299 ataPIOTransferStop(s);
4300 ataUnsetStatus(s, ATA_STAT_BUSY | ATA_STAT_DRQ | ATA_STAT_SEEK | ATA_STAT_ERR);
4301 ataSetStatus(s, ATA_STAT_READY);
4302 ataSetIRQ(s);
4303 }
4304 }
4305 break;
4306
4307 default:
4308 AssertMsgFailed(("Undefined async I/O state %d\n", pCtl->uAsyncIOState));
4309 }
4310
4311 ataAsyncIORemoveCurrentRequest(pCtl, ReqType);
4312 pReq = ataAsyncIOGetCurrentRequest(pCtl);
4313
4314 if (pCtl->uAsyncIOState == ATA_AIO_NEW && !pCtl->fChainedTransfer)
4315 {
4316#if defined(DEBUG) || defined(VBOX_WITH_STATISTICS)
4317 STAM_PROFILE_ADV_STOP(&pCtl->StatAsyncTime, a);
4318#endif /* DEBUG || VBOX_WITH_STATISTICS */
4319
4320 u64TS = RTTimeNanoTS() - u64TS;
4321 uWait = u64TS / 1000;
4322 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)));
4323
4324 /*
4325 * Release logging of command execution times depends on the
4326 * command type. ATAPI commands often take longer (due to CD/DVD
4327 * spin up time etc.) so the threshold is different.
4328 */
4329 if (pCtl->aIfs[pCtl->iAIOIf].uATARegCommand != ATA_PACKET)
4330 {
4331 if (uWait > 10 * 1000 * 1000)
4332 {
4333 /*
4334 * Command took longer than 10 seconds. This is close
4335 * enough or over the guest's command timeout, so place
4336 * an entry in the release log to allow tracking such
4337 * timing errors (which are often caused by the host).
4338 */
4339 LogRel(("PIIX3 ATA: execution time for ATA command %#04x was %d seconds\n", pCtl->aIfs[pCtl->iAIOIf].uATARegCommand, uWait / (1000 * 1000)));
4340 }
4341 }
4342 else
4343 {
4344 if (uWait > 20 * 1000 * 1000)
4345 {
4346 /*
4347 * Command took longer than 20 seconds. This is close
4348 * enough or over the guest's command timeout, so place
4349 * an entry in the release log to allow tracking such
4350 * timing errors (which are often caused by the host).
4351 */
4352 LogRel(("PIIX3 ATA: execution time for ATAPI command %#04x was %d seconds\n", pCtl->aIfs[pCtl->iAIOIf].aATAPICmd[0], uWait / (1000 * 1000)));
4353 }
4354 }
4355
4356#if defined(DEBUG) || defined(VBOX_WITH_STATISTICS)
4357 if (uWait < pCtl->StatAsyncMinWait || !pCtl->StatAsyncMinWait)
4358 pCtl->StatAsyncMinWait = uWait;
4359 if (uWait > pCtl->StatAsyncMaxWait)
4360 pCtl->StatAsyncMaxWait = uWait;
4361
4362 STAM_COUNTER_ADD(&pCtl->StatAsyncTimeUS, uWait);
4363 STAM_COUNTER_INC(&pCtl->StatAsyncOps);
4364#endif /* DEBUG || VBOX_WITH_STATISTICS */
4365 }
4366
4367 PDMCritSectLeave(&pCtl->lock);
4368 }
4369
4370 /* Cleanup the state. */
4371 if (pCtl->AsyncIOSem)
4372 {
4373 RTSemEventDestroy(pCtl->AsyncIOSem);
4374 pCtl->AsyncIOSem = NIL_RTSEMEVENT;
4375 }
4376 if (pCtl->SuspendIOSem)
4377 {
4378 RTSemEventDestroy(pCtl->SuspendIOSem);
4379 pCtl->SuspendIOSem = NIL_RTSEMEVENT;
4380 }
4381 /* Do not destroy request mutex yet, still needed for proper shutdown. */
4382 pCtl->fShutdown = false;
4383 /* This must be last, as it also signals thread exit to EMT. */
4384 pCtl->AsyncIOThread = NIL_RTTHREAD;
4385
4386 Log2(("%s: Ctl#%d: return %Vrc\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl), rc));
4387 return rc;
4388}
4389
4390#endif /* IN_RING3 */
4391
4392static uint32_t ataBMDMACmdReadB(PATACONTROLLER pCtl, uint32_t addr)
4393{
4394 uint32_t val = pCtl->BmDma.u8Cmd;
4395 Log2(("%s: addr=%#06x val=%#04x\n", __FUNCTION__, addr, val));
4396 return val;
4397}
4398
4399
4400static void ataBMDMACmdWriteB(PATACONTROLLER pCtl, uint32_t addr, uint32_t val)
4401{
4402 Log2(("%s: addr=%#06x val=%#04x\n", __FUNCTION__, addr, val));
4403 if (!(val & BM_CMD_START))
4404 {
4405 pCtl->BmDma.u8Status &= ~BM_STATUS_DMAING;
4406 pCtl->BmDma.u8Cmd = val & (BM_CMD_START | BM_CMD_WRITE);
4407 }
4408 else
4409 {
4410#ifdef IN_RING3
4411 /* Check whether the guest OS wants to change DMA direction in
4412 * mid-flight. Not allowed, according to the PIIX3 specs. */
4413 Assert(!(pCtl->BmDma.u8Status & BM_STATUS_DMAING) || !((val ^ pCtl->BmDma.u8Cmd) & 0x04));
4414 pCtl->BmDma.u8Status |= BM_STATUS_DMAING;
4415 pCtl->BmDma.u8Cmd = val & (BM_CMD_START | BM_CMD_WRITE);
4416
4417 /* Do not continue DMA transfers while the RESET line is asserted. */
4418 if (pCtl->fReset)
4419 {
4420 Log2(("%s: Ctl#%d: suppressed continuing DMA transfer as RESET is active\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
4421 return;
4422 }
4423
4424 /* Do not start DMA transfers if there's a PIO transfer going on. */
4425 if (!pCtl->aIfs[pCtl->iSelectedIf].fDMA)
4426 return;
4427
4428 if (pCtl->aIfs[pCtl->iAIOIf].uATARegStatus & ATA_STAT_DRQ)
4429 {
4430 Log2(("%s: Ctl#%d: message to async I/O thread, continuing DMA transfer\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
4431 ataAsyncIOPutRequest(pCtl, &ataDMARequest);
4432 }
4433#else /* !IN_RING3 */
4434 AssertMsgFailed(("DMA START handling is too complicated for GC\n"));
4435#endif /* IN_RING3 */
4436 }
4437}
4438
4439static uint32_t ataBMDMAStatusReadB(PATACONTROLLER pCtl, uint32_t addr)
4440{
4441 uint32_t val = pCtl->BmDma.u8Status;
4442 Log2(("%s: addr=%#06x val=%#04x\n", __FUNCTION__, addr, val));
4443 return val;
4444}
4445
4446static void ataBMDMAStatusWriteB(PATACONTROLLER pCtl, uint32_t addr, uint32_t val)
4447{
4448 Log2(("%s: addr=%#06x val=%#04x\n", __FUNCTION__, addr, val));
4449 pCtl->BmDma.u8Status = (val & (BM_STATUS_D0DMA | BM_STATUS_D1DMA))
4450 | (pCtl->BmDma.u8Status & BM_STATUS_DMAING)
4451 | (pCtl->BmDma.u8Status & ~val & (BM_STATUS_ERROR | BM_STATUS_INT));
4452}
4453
4454static uint32_t ataBMDMAAddrReadL(PATACONTROLLER pCtl, uint32_t addr)
4455{
4456 uint32_t val = (uint32_t)pCtl->BmDma.pvAddr;
4457 Log2(("%s: addr=%#06x val=%#010x\n", __FUNCTION__, addr, val));
4458 return val;
4459}
4460
4461static void ataBMDMAAddrWriteL(PATACONTROLLER pCtl, uint32_t addr, uint32_t val)
4462{
4463 Log2(("%s: addr=%#06x val=%#010x\n", __FUNCTION__, addr, val));
4464 pCtl->BmDma.pvAddr = val & ~3;
4465}
4466
4467static void ataBMDMAAddrWriteLowWord(PATACONTROLLER pCtl, uint32_t addr, uint32_t val)
4468{
4469 Log2(("%s: addr=%#06x val=%#010x\n", __FUNCTION__, addr, val));
4470 pCtl->BmDma.pvAddr = (pCtl->BmDma.pvAddr & 0xFFFF0000) | RT_LOWORD(val & ~3);
4471
4472}
4473
4474static void ataBMDMAAddrWriteHighWord(PATACONTROLLER pCtl, uint32_t addr, uint32_t val)
4475{
4476 Log2(("%s: addr=%#06x val=%#010x\n", __FUNCTION__, addr, val));
4477 pCtl->BmDma.pvAddr = (RT_LOWORD(val) << 16) | RT_LOWORD(pCtl->BmDma.pvAddr);
4478}
4479
4480#define VAL(port, size) ( ((port) & 7) | ((size) << 3) )
4481
4482/**
4483 * Port I/O Handler for bus master DMA IN operations.
4484 * @see FNIOMIOPORTIN for details.
4485 */
4486PDMBOTHCBDECL(int) ataBMDMAIOPortRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
4487{
4488 uint32_t i = (uint32_t)(uintptr_t)pvUser;
4489 PCIATAState *pData = PDMINS2DATA(pDevIns, PCIATAState *);
4490 PATACONTROLLER pCtl = &pData->aCts[i];
4491 int rc;
4492
4493 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_HC_IOPORT_READ);
4494 if (rc != VINF_SUCCESS)
4495 return rc;
4496 switch (VAL(Port, cb))
4497 {
4498 case VAL(0, 1): *pu32 = ataBMDMACmdReadB(pCtl, Port); break;
4499 case VAL(0, 2): *pu32 = ataBMDMACmdReadB(pCtl, Port); break;
4500 case VAL(2, 1): *pu32 = ataBMDMAStatusReadB(pCtl, Port); break;
4501 case VAL(2, 2): *pu32 = ataBMDMAStatusReadB(pCtl, Port); break;
4502 case VAL(4, 4): *pu32 = ataBMDMAAddrReadL(pCtl, Port); break;
4503 default:
4504 AssertMsgFailed(("%s: Unsupported read from port %x size=%d\n", __FUNCTION__, Port, cb));
4505 PDMCritSectLeave(&pCtl->lock);
4506 return VERR_IOM_IOPORT_UNUSED;
4507 }
4508 PDMCritSectLeave(&pCtl->lock);
4509 return rc;
4510}
4511
4512/**
4513 * Port I/O Handler for bus master DMA OUT operations.
4514 * @see FNIOMIOPORTOUT for details.
4515 */
4516PDMBOTHCBDECL(int) ataBMDMAIOPortWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
4517{
4518 uint32_t i = (uint32_t)(uintptr_t)pvUser;
4519 PCIATAState *pData = PDMINS2DATA(pDevIns, PCIATAState *);
4520 PATACONTROLLER pCtl = &pData->aCts[i];
4521 int rc;
4522
4523 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_HC_IOPORT_WRITE);
4524 if (rc != VINF_SUCCESS)
4525 return rc;
4526 switch (VAL(Port, cb))
4527 {
4528 case VAL(0, 1):
4529#ifndef IN_RING3
4530 if (u32 & BM_CMD_START)
4531 {
4532 rc = VINF_IOM_HC_IOPORT_WRITE;
4533 break;
4534 }
4535#endif /* !IN_RING3 */
4536 ataBMDMACmdWriteB(pCtl, Port, u32);
4537 break;
4538 case VAL(2, 1): ataBMDMAStatusWriteB(pCtl, Port, u32); break;
4539 case VAL(4, 4): ataBMDMAAddrWriteL(pCtl, Port, u32); break;
4540 case VAL(4, 2): ataBMDMAAddrWriteLowWord(pCtl, Port, u32); break;
4541 case VAL(6, 2): ataBMDMAAddrWriteHighWord(pCtl, Port, u32); break;
4542 default: AssertMsgFailed(("%s: Unsupported write to port %x size=%d val=%x\n", __FUNCTION__, Port, cb, u32)); break;
4543 }
4544 PDMCritSectLeave(&pCtl->lock);
4545 return rc;
4546}
4547
4548#undef VAL
4549
4550#ifdef IN_RING3
4551
4552/**
4553 * Callback function for mapping an PCI I/O region.
4554 *
4555 * @return VBox status code.
4556 * @param pPciDev Pointer to PCI device. Use pPciDev->pDevIns to get the device instance.
4557 * @param iRegion The region number.
4558 * @param GCPhysAddress Physical address of the region. If iType is PCI_ADDRESS_SPACE_IO, this is an
4559 * I/O port, else it's a physical address.
4560 * This address is *NOT* relative to pci_mem_base like earlier!
4561 * @param enmType One of the PCI_ADDRESS_SPACE_* values.
4562 */
4563static DECLCALLBACK(int) ataBMDMAIORangeMap(PPCIDEVICE pPciDev, /*unsigned*/ int iRegion, RTGCPHYS GCPhysAddress, uint32_t cb, PCIADDRESSSPACE enmType)
4564{
4565 PCIATAState *pData = PCIDEV_2_PCIATASTATE(pPciDev);
4566 int rc = VINF_SUCCESS;
4567 Assert(enmType == PCI_ADDRESS_SPACE_IO);
4568 Assert(iRegion == 4);
4569 AssertMsg(RT_ALIGN(GCPhysAddress, 8) == GCPhysAddress, ("Expected 8 byte alignment. GCPhysAddress=%#x\n", GCPhysAddress));
4570
4571 /* Register the port range. */
4572 for (uint32_t i = 0; i < RT_ELEMENTS(pData->aCts); i++)
4573 {
4574 int rc2 = PDMDevHlpIOPortRegister(pPciDev->pDevIns, (RTIOPORT)GCPhysAddress + i * 8, 8,
4575 (RTHCPTR)i, ataBMDMAIOPortWrite, ataBMDMAIOPortRead, NULL, NULL, "ATA Bus Master DMA");
4576 AssertRC(rc2);
4577 if (rc2 < rc)
4578 rc = rc2;
4579
4580 if (pData->fGCEnabled)
4581 {
4582 rc2 = PDMDevHlpIOPortRegisterGC(pPciDev->pDevIns, (RTIOPORT)GCPhysAddress + i * 8, 8,
4583 (RTGCPTR)i, "ataBMDMAIOPortWrite", "ataBMDMAIOPortRead", NULL, NULL, "ATA Bus Master DMA");
4584 AssertRC(rc2);
4585 if (rc2 < rc)
4586 rc = rc2;
4587 }
4588 if (pData->fR0Enabled)
4589 {
4590 rc2 = PDMDevHlpIOPortRegisterR0(pPciDev->pDevIns, (RTIOPORT)GCPhysAddress + i * 8, 8,
4591 (RTR0PTR)i, "ataBMDMAIOPortWrite", "ataBMDMAIOPortRead", NULL, NULL, "ATA Bus Master DMA");
4592 AssertRC(rc2);
4593 if (rc2 < rc)
4594 rc = rc2;
4595 }
4596 }
4597 return rc;
4598}
4599
4600
4601/**
4602 * Reset notification.
4603 *
4604 * @returns VBox status.
4605 * @param pDevIns The device instance data.
4606 */
4607static DECLCALLBACK(void) ataReset(PPDMDEVINS pDevIns)
4608{
4609 PCIATAState *pData = PDMINS2DATA(pDevIns, PCIATAState *);
4610
4611 for (uint32_t i = 0; i < RT_ELEMENTS(pData->aCts); i++)
4612 {
4613 pData->aCts[i].iSelectedIf = 0;
4614 pData->aCts[i].iAIOIf = 0;
4615 pData->aCts[i].BmDma.u8Cmd = 0;
4616 /* Report that both drives present on the bus are in DMA mode. This
4617 * pretends that there is a BIOS that has set it up. Normal reset
4618 * default is 0x00. */
4619 pData->aCts[i].BmDma.u8Status = (pData->aCts[i].aIfs[0].pDrvBase != NULL ? BM_STATUS_D0DMA : 0)
4620 | (pData->aCts[i].aIfs[1].pDrvBase != NULL ? BM_STATUS_D1DMA : 0);
4621 pData->aCts[i].BmDma.pvAddr = 0;
4622
4623 pData->aCts[i].fReset = true;
4624 pData->aCts[i].fRedo = false;
4625 pData->aCts[i].fRedoIdle = false;
4626 ataAsyncIOClearRequests(&pData->aCts[i]);
4627 Log2(("%s: Ctl#%d: message to async I/O thread, reset controller\n", __FUNCTION__, i));
4628 ataAsyncIOPutRequest(&pData->aCts[i], &ataResetARequest);
4629 ataAsyncIOPutRequest(&pData->aCts[i], &ataResetCRequest);
4630 if (!ataWaitForAsyncIOIsIdle(&pData->aCts[i], 30000))
4631 AssertReleaseMsgFailed(("Async I/O thread busy after reset\n"));
4632
4633 for (uint32_t j = 0; j < RT_ELEMENTS(pData->aCts[i].aIfs); j++)
4634 ataResetDevice(&pData->aCts[i].aIfs[j]);
4635 }
4636}
4637
4638
4639/* -=-=-=-=-=- PCIATAState::IBase -=-=-=-=-=- */
4640
4641/**
4642 * Queries an interface to the driver.
4643 *
4644 * @returns Pointer to interface.
4645 * @returns NULL if the interface was not supported by the device.
4646 * @param pInterface Pointer to ATADevState::IBase.
4647 * @param enmInterface The requested interface identification.
4648 */
4649static DECLCALLBACK(void *) ataStatus_QueryInterface(PPDMIBASE pInterface, PDMINTERFACE enmInterface)
4650{
4651 PCIATAState *pData = PDMIBASE_2_PCIATASTATE(pInterface);
4652 switch (enmInterface)
4653 {
4654 case PDMINTERFACE_BASE:
4655 return &pData->IBase;
4656 case PDMINTERFACE_LED_PORTS:
4657 return &pData->ILeds;
4658 default:
4659 return NULL;
4660 }
4661}
4662
4663
4664/* -=-=-=-=-=- PCIATAState::ILeds -=-=-=-=-=- */
4665
4666/**
4667 * Gets the pointer to the status LED of a unit.
4668 *
4669 * @returns VBox status code.
4670 * @param pInterface Pointer to the interface structure containing the called function pointer.
4671 * @param iLUN The unit which status LED we desire.
4672 * @param ppLed Where to store the LED pointer.
4673 */
4674static DECLCALLBACK(int) ataStatus_QueryStatusLed(PPDMILEDPORTS pInterface, unsigned iLUN, PPDMLED *ppLed)
4675{
4676 PCIATAState *pData = PDMILEDPORTS_2_PCIATASTATE(pInterface);
4677 if (iLUN >= 0 && iLUN <= 4)
4678 {
4679 switch (iLUN)
4680 {
4681 case 0: *ppLed = &pData->aCts[0].aIfs[0].Led; break;
4682 case 1: *ppLed = &pData->aCts[0].aIfs[1].Led; break;
4683 case 2: *ppLed = &pData->aCts[1].aIfs[0].Led; break;
4684 case 3: *ppLed = &pData->aCts[1].aIfs[1].Led; break;
4685 }
4686 Assert((*ppLed)->u32Magic == PDMLED_MAGIC);
4687 return VINF_SUCCESS;
4688 }
4689 return VERR_PDM_LUN_NOT_FOUND;
4690}
4691
4692
4693/* -=-=-=-=-=- ATADevState::IBase -=-=-=-=-=- */
4694
4695/**
4696 * Queries an interface to the driver.
4697 *
4698 * @returns Pointer to interface.
4699 * @returns NULL if the interface was not supported by the device.
4700 * @param pInterface Pointer to ATADevState::IBase.
4701 * @param enmInterface The requested interface identification.
4702 */
4703static DECLCALLBACK(void *) ataQueryInterface(PPDMIBASE pInterface, PDMINTERFACE enmInterface)
4704{
4705 ATADevState *pIf = PDMIBASE_2_ATASTATE(pInterface);
4706 switch (enmInterface)
4707 {
4708 case PDMINTERFACE_BASE:
4709 return &pIf->IBase;
4710 case PDMINTERFACE_BLOCK_PORT:
4711 return &pIf->IPort;
4712 case PDMINTERFACE_MOUNT_NOTIFY:
4713 return &pIf->IMountNotify;
4714 default:
4715 return NULL;
4716 }
4717}
4718
4719#endif /* IN_RING3 */
4720
4721
4722/* -=-=-=-=-=- Wrappers -=-=-=-=-=- */
4723
4724/**
4725 * Port I/O Handler for primary port range OUT operations.
4726 * @see FNIOMIOPORTOUT for details.
4727 */
4728PDMBOTHCBDECL(int) ataIOPortWrite1(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
4729{
4730 uint32_t i = (uint32_t)(uintptr_t)pvUser;
4731 PCIATAState *pData = PDMINS2DATA(pDevIns, PCIATAState *);
4732 PATACONTROLLER pCtl = &pData->aCts[i];
4733 int rc = VINF_SUCCESS;
4734
4735 Assert(i < 2);
4736
4737 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_HC_IOPORT_WRITE);
4738 if (rc != VINF_SUCCESS)
4739 return rc;
4740 if (cb == 1)
4741 rc = ataIOPortWriteU8(pCtl, Port, u32);
4742 else if (Port == pCtl->IOPortBase1)
4743 {
4744 Assert(cb == 2 || cb == 4);
4745 rc = ataDataWrite(pCtl, Port, cb, (const uint8_t *)&u32);
4746 }
4747 else
4748 AssertMsgFailed(("ataIOPortWrite1: unsupported write to port %x val=%x size=%d\n", Port, u32, cb));
4749 PDMCritSectLeave(&pCtl->lock);
4750 return rc;
4751}
4752
4753
4754/**
4755 * Port I/O Handler for primary port range IN operations.
4756 * @see FNIOMIOPORTIN for details.
4757 */
4758PDMBOTHCBDECL(int) ataIOPortRead1(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
4759{
4760 uint32_t i = (uint32_t)(uintptr_t)pvUser;
4761 PCIATAState *pData = PDMINS2DATA(pDevIns, PCIATAState *);
4762 PATACONTROLLER pCtl = &pData->aCts[i];
4763 int rc = VINF_SUCCESS;
4764
4765 Assert(i < 2);
4766
4767 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_HC_IOPORT_READ);
4768 if (rc != VINF_SUCCESS)
4769 return rc;
4770 if (cb == 1)
4771 {
4772 ataIOPortReadU8(pCtl, Port, pu32);
4773 rc = VINF_SUCCESS;
4774 }
4775 else if (Port == pCtl->IOPortBase1)
4776 {
4777 Assert(cb == 2 || cb == 4);
4778 rc = ataDataRead(pCtl, Port, cb, (uint8_t *)pu32);
4779 if (cb == 2)
4780 *pu32 &= 0xffff;
4781 }
4782 else
4783 {
4784 AssertMsgFailed(("ataIOPortRead1: unsupported read from port %x size=%d\n", Port, cb));
4785 rc = VERR_IOM_IOPORT_UNUSED;
4786 }
4787 PDMCritSectLeave(&pCtl->lock);
4788 return rc;
4789}
4790
4791#ifndef IN_RING0
4792/**
4793 * Port I/O Handler for primary port range IN string operations.
4794 * @see FNIOMIOPORTINSTRING for details.
4795 */
4796PDMBOTHCBDECL(int) ataIOPortReadStr1(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, RTGCPTR *pGCPtrDst, unsigned *pcTransfer, unsigned cb)
4797{
4798 uint32_t i = (uint32_t)(uintptr_t)pvUser;
4799 PCIATAState *pData = PDMINS2DATA(pDevIns, PCIATAState *);
4800 PATACONTROLLER pCtl = &pData->aCts[i];
4801 int rc = VINF_SUCCESS;
4802
4803 Assert(i < 2);
4804
4805 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_HC_IOPORT_READ);
4806 if (rc != VINF_SUCCESS)
4807 return rc;
4808 if (Port == pCtl->IOPortBase1)
4809 {
4810 uint32_t cTransAvailable, cTransfer = *pcTransfer, cbTransfer;
4811 RTGCPTR GCDst = *pGCPtrDst;
4812 ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf];
4813 Assert(cb == 2 || cb == 4);
4814
4815 cTransAvailable = (s->iIOBufferPIODataEnd - s->iIOBufferPIODataStart) / cb;
4816#ifndef IN_RING3
4817 /* The last transfer unit cannot be handled in GC, as it involves thread communication. */
4818 cTransAvailable--;
4819#endif /* !IN_RING3 */
4820 /* Do not handle the dummy transfer stuff here, leave it to the single-word transfers.
4821 * They are not performance-critical and generally shouldn't occur at all. */
4822 if (cTransAvailable > cTransfer)
4823 cTransAvailable = cTransfer;
4824 cbTransfer = cTransAvailable * cb;
4825
4826#ifdef IN_GC
4827 for (uint32_t i = 0; i < cbTransfer; i += cb)
4828 MMGCRamWriteNoTrapHandler((char *)GCDst + i, s->CTXSUFF(pbIOBuffer) + s->iIOBufferPIODataStart + i, cb);
4829#else /* !IN_GC */
4830 rc = PGMPhysWriteGCPtrDirty(PDMDevHlpGetVM(pDevIns), GCDst, s->CTXSUFF(pbIOBuffer) + s->iIOBufferPIODataStart, cbTransfer);
4831 Assert(rc == VINF_SUCCESS);
4832#endif /* IN_GC */
4833
4834 if (cbTransfer)
4835 Log3(("%s: addr=%#x val=%.*Vhxs\n", __FUNCTION__, Port, cbTransfer, s->CTXSUFF(pbIOBuffer) + s->iIOBufferPIODataStart));
4836 s->iIOBufferPIODataStart += cbTransfer;
4837 *pGCPtrDst = (RTGCPTR)((RTGCUINTPTR)GCDst + cbTransfer);
4838 *pcTransfer = cTransfer - cTransAvailable;
4839#ifdef IN_RING3
4840 if (s->iIOBufferPIODataStart >= s->iIOBufferPIODataEnd)
4841 ataPIOTransferFinish(pCtl, s);
4842#endif /* IN_RING3 */
4843 }
4844 PDMCritSectLeave(&pCtl->lock);
4845 return rc;
4846}
4847
4848
4849/**
4850 * Port I/O Handler for primary port range OUT string operations.
4851 * @see FNIOMIOPORTOUTSTRING for details.
4852 */
4853PDMBOTHCBDECL(int) ataIOPortWriteStr1(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, RTGCPTR *pGCPtrSrc, unsigned *pcTransfer, unsigned cb)
4854{
4855 uint32_t i = (uint32_t)(uintptr_t)pvUser;
4856 PCIATAState *pData = PDMINS2DATA(pDevIns, PCIATAState *);
4857 PATACONTROLLER pCtl = &pData->aCts[i];
4858 int rc;
4859
4860 Assert(i < 2);
4861
4862 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_HC_IOPORT_WRITE);
4863 if (rc != VINF_SUCCESS)
4864 return rc;
4865 if (Port == pCtl->IOPortBase1)
4866 {
4867 uint32_t cTransAvailable, cTransfer = *pcTransfer, cbTransfer;
4868 RTGCPTR GCSrc = *pGCPtrSrc;
4869 ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf];
4870 Assert(cb == 2 || cb == 4);
4871
4872 cTransAvailable = (s->iIOBufferPIODataEnd - s->iIOBufferPIODataStart) / cb;
4873#ifndef IN_RING3
4874 /* The last transfer unit cannot be handled in GC, as it involves thread communication. */
4875 cTransAvailable--;
4876#endif /* !IN_RING3 */
4877 /* Do not handle the dummy transfer stuff here, leave it to the single-word transfers.
4878 * They are not performance-critical and generally shouldn't occur at all. */
4879 if (cTransAvailable > cTransfer)
4880 cTransAvailable = cTransfer;
4881 cbTransfer = cTransAvailable * cb;
4882
4883#ifdef IN_GC
4884 for (uint32_t i = 0; i < cbTransfer; i += cb)
4885 MMGCRamReadNoTrapHandler(s->CTXSUFF(pbIOBuffer) + s->iIOBufferPIODataStart + i, (char *)GCSrc + i, cb);
4886#else /* !IN_GC */
4887 rc = PGMPhysReadGCPtr(PDMDevHlpGetVM(pDevIns), s->CTXSUFF(pbIOBuffer) + s->iIOBufferPIODataStart, GCSrc, cbTransfer);
4888 Assert(rc == VINF_SUCCESS);
4889#endif /* IN_GC */
4890
4891 if (cbTransfer)
4892 Log3(("%s: addr=%#x val=%.*Vhxs\n", __FUNCTION__, Port, cbTransfer, s->CTXSUFF(pbIOBuffer) + s->iIOBufferPIODataStart));
4893 s->iIOBufferPIODataStart += cbTransfer;
4894 *pGCPtrSrc = (RTGCPTR)((RTGCUINTPTR)GCSrc + cbTransfer);
4895 *pcTransfer = cTransfer - cTransAvailable;
4896#ifdef IN_RING3
4897 if (s->iIOBufferPIODataStart >= s->iIOBufferPIODataEnd)
4898 ataPIOTransferFinish(pCtl, s);
4899#endif /* IN_RING3 */
4900 }
4901 PDMCritSectLeave(&pCtl->lock);
4902 return rc;
4903}
4904#endif /* !IN_RING0 */
4905
4906/**
4907 * Port I/O Handler for secondary port range OUT operations.
4908 * @see FNIOMIOPORTOUT for details.
4909 */
4910PDMBOTHCBDECL(int) ataIOPortWrite2(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
4911{
4912 uint32_t i = (uint32_t)(uintptr_t)pvUser;
4913 PCIATAState *pData = PDMINS2DATA(pDevIns, PCIATAState *);
4914 PATACONTROLLER pCtl = &pData->aCts[i];
4915 int rc;
4916
4917 Assert(i < 2);
4918
4919 if (cb != 1)
4920 return VINF_SUCCESS;
4921 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_HC_IOPORT_WRITE);
4922 if (rc != VINF_SUCCESS)
4923 return rc;
4924 rc = ataControlWrite(pCtl, Port, u32);
4925 PDMCritSectLeave(&pCtl->lock);
4926 return rc;
4927}
4928
4929
4930/**
4931 * Port I/O Handler for secondary port range IN operations.
4932 * @see FNIOMIOPORTIN for details.
4933 */
4934PDMBOTHCBDECL(int) ataIOPortRead2(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
4935{
4936 uint32_t i = (uint32_t)(uintptr_t)pvUser;
4937 PCIATAState *pData = PDMINS2DATA(pDevIns, PCIATAState *);
4938 PATACONTROLLER pCtl = &pData->aCts[i];
4939 int rc;
4940
4941 Assert(i < 2);
4942
4943 if (cb != 1)
4944 return VERR_IOM_IOPORT_UNUSED;
4945
4946 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_HC_IOPORT_READ);
4947 if (rc != VINF_SUCCESS)
4948 return rc;
4949 *pu32 = ataStatusRead(pCtl, Port);
4950 PDMCritSectLeave(&pCtl->lock);
4951 return VINF_SUCCESS;
4952}
4953
4954#ifdef IN_RING3
4955
4956/**
4957 * Waits for all async I/O threads to complete whatever they
4958 * are doing at the moment.
4959 *
4960 * @returns true on success.
4961 * @returns false when one or more threads is still processing.
4962 * @param pData Pointer to the instance data.
4963 * @param cMillies How long to wait (total).
4964 */
4965static bool ataWaitForAllAsyncIOIsIdle(PPDMDEVINS pDevIns, unsigned cMillies)
4966{
4967 PCIATAState *pData = PDMINS2DATA(pDevIns, PCIATAState *);
4968 bool fVMLocked;
4969 uint64_t u64Start;
4970 bool fAllIdle = false;
4971
4972 /* The only way to deal cleanly with the VM lock is to check whether
4973 * it is owned now (it always is owned by EMT, which is the current
4974 * thread). Since this function is called several times during VM
4975 * shutdown, and the VM lock is only held for the first call (which
4976 * can be either from ataPowerOff or ataSuspend), there is no other
4977 * reasonable solution. */
4978 fVMLocked = VMMR3LockIsOwner(PDMDevHlpGetVM(pDevIns));
4979
4980 if (fVMLocked)
4981 pDevIns->pDevHlp->pfnUnlockVM(pDevIns);
4982 /*
4983 * Wait for any pending async operation to finish
4984 */
4985 u64Start = RTTimeMilliTS();
4986 for (;;)
4987 {
4988 /* Check all async I/O threads. */
4989 fAllIdle = true;
4990 for (uint32_t i = 0; i < RT_ELEMENTS(pData->aCts); i++)
4991 {
4992 fAllIdle &= ataAsyncIOIsIdle(&pData->aCts[i], false);
4993 if (!fAllIdle)
4994 break;
4995 }
4996 if ( fAllIdle
4997 || RTTimeMilliTS() - u64Start >= cMillies)
4998 break;
4999
5000 /* Sleep for a bit. */
5001 RTThreadSleep(100);
5002 }
5003
5004 if (fVMLocked)
5005 pDevIns->pDevHlp->pfnLockVM(pDevIns);
5006
5007 return fAllIdle;
5008}
5009
5010
5011DECLINLINE(void) ataRelocBuffer(PPDMDEVINS pDevIns, ATADevState *s)
5012{
5013 if (s->pbIOBufferHC)
5014 s->pbIOBufferGC = MMHyperHC2GC(PDMDevHlpGetVM(pDevIns), s->pbIOBufferHC);
5015}
5016
5017
5018/**
5019 * @copydoc FNPDMDEVRELOCATE
5020 */
5021static DECLCALLBACK(void) ataRelocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta)
5022{
5023 PCIATAState *pData = PDMINS2DATA(pDevIns, PCIATAState *);
5024
5025 for (uint32_t i = 0; i < RT_ELEMENTS(pData->aCts); i++)
5026 {
5027 pData->aCts[i].pDevInsGC += offDelta;
5028 pData->aCts[i].aIfs[0].pDevInsGC += offDelta;
5029 pData->aCts[i].aIfs[0].pControllerGC += offDelta;
5030 ataRelocBuffer(pDevIns, &pData->aCts[i].aIfs[0]);
5031 pData->aCts[i].aIfs[1].pDevInsGC += offDelta;
5032 pData->aCts[i].aIfs[1].pControllerGC += offDelta;
5033 ataRelocBuffer(pDevIns, &pData->aCts[i].aIfs[1]);
5034 }
5035}
5036
5037
5038/**
5039 * Destroy a driver instance.
5040 *
5041 * Most VM resources are freed by the VM. This callback is provided so that any non-VM
5042 * resources can be freed correctly.
5043 *
5044 * @param pDrvIns The driver instance data.
5045 */
5046static DECLCALLBACK(int) ataDestruct(PPDMDEVINS pDevIns)
5047{
5048 PCIATAState *pData = PDMINS2DATA(pDevIns, PCIATAState *);
5049 int rc;
5050
5051 Log(("%s:\n", __FUNCTION__));
5052
5053 /*
5054 * Terminate all async helper threads
5055 */
5056 for (uint32_t i = 0; i < RT_ELEMENTS(pData->aCts); i++)
5057 {
5058 if (pData->aCts[i].AsyncIOThread != NIL_RTTHREAD)
5059 {
5060 ASMAtomicXchgU32(&pData->aCts[i].fShutdown, true);
5061 rc = RTSemEventSignal(pData->aCts[i].AsyncIOSem);
5062 AssertRC(rc);
5063 }
5064 }
5065
5066 /*
5067 * Wait for them to complete whatever they are doing and then
5068 * for them to terminate.
5069 */
5070 if (ataWaitForAllAsyncIOIsIdle(pDevIns, 20000))
5071 {
5072 uint64_t u64Start = RTTimeMilliTS();
5073 bool fAllDone;
5074 for (;;)
5075 {
5076 /* check */
5077 fAllDone = true;
5078 for (uint32_t i = 0; i < RT_ELEMENTS(pData->aCts) && fAllDone; i++)
5079 fAllDone &= (pData->aCts[i].AsyncIOThread == NIL_RTTHREAD);
5080
5081 if ( fAllDone
5082 || RTTimeMilliTS() - u64Start >= 500)
5083 break;
5084
5085 /* Sleep for a bit. */
5086 RTThreadSleep(100);
5087 }
5088 AssertMsg(fAllDone, ("Some of the async I/O threads are still running!\n"));
5089 }
5090 else
5091 AssertMsgFailed(("Async I/O is still busy!\n"));
5092
5093 /*
5094 * Now the request mutexes are no longer needed. Free resources.
5095 */
5096 for (uint32_t i = 0; i < RT_ELEMENTS(pData->aCts); i++)
5097 {
5098 if (pData->aCts[i].AsyncIORequestMutex)
5099 {
5100 RTSemMutexDestroy(pData->aCts[i].AsyncIORequestMutex);
5101 pData->aCts[i].AsyncIORequestMutex = NIL_RTSEMEVENT;
5102 }
5103 }
5104 return VINF_SUCCESS;
5105}
5106
5107
5108/**
5109 * Detach notification.
5110 *
5111 * The DVD drive has been unplugged.
5112 *
5113 * @param pDevIns The device instance.
5114 * @param iLUN The logical unit which is being detached.
5115 */
5116static DECLCALLBACK(void) ataDetach(PPDMDEVINS pDevIns, unsigned iLUN)
5117{
5118 PCIATAState *pThis = PDMINS2DATA(pDevIns, PCIATAState *);
5119 PATACONTROLLER pCtl;
5120 ATADevState *pIf;
5121 unsigned iController;
5122 unsigned iInterface;
5123
5124 /*
5125 * Locate the controller and stuff.
5126 */
5127 iController = iLUN / RT_ELEMENTS(pThis->aCts[0].aIfs);
5128 AssertReleaseMsg(iController < RT_ELEMENTS(pThis->aCts), ("iController=%d iLUN=%d\n", iController, iLUN));
5129 pCtl = &pThis->aCts[iController];
5130
5131 iInterface = iLUN % RT_ELEMENTS(pThis->aCts[0].aIfs);
5132 pIf = &pCtl->aIfs[iInterface];
5133
5134 /*
5135 * Zero some important members.
5136 */
5137 pIf->pDrvBase = NULL;
5138 pIf->pDrvBlock = NULL;
5139 pIf->pDrvBlockBios = NULL;
5140 pIf->pDrvMount = NULL;
5141}
5142
5143
5144/**
5145 * Configure a LUN.
5146 *
5147 * @returns VBox status code.
5148 * @param pDevIns The device instance.
5149 * @param pIf The ATA unit state.
5150 */
5151static int ataConfigLun(PPDMDEVINS pDevIns, ATADevState *pIf)
5152{
5153 int rc;
5154 PDMBLOCKTYPE enmType;
5155
5156 /*
5157 * Query Block, Bios and Mount interfaces.
5158 */
5159 pIf->pDrvBlock = (PDMIBLOCK *)pIf->pDrvBase->pfnQueryInterface(pIf->pDrvBase, PDMINTERFACE_BLOCK);
5160 if (!pIf->pDrvBlock)
5161 {
5162 AssertMsgFailed(("Configuration error: LUN#%d hasn't a block interface!\n", pIf->iLUN));
5163 return VERR_PDM_MISSING_INTERFACE;
5164 }
5165
5166 /** @todo implement the BIOS invisible code path. */
5167 pIf->pDrvBlockBios = (PDMIBLOCKBIOS *)pIf->pDrvBase->pfnQueryInterface(pIf->pDrvBase, PDMINTERFACE_BLOCK_BIOS);
5168 if (!pIf->pDrvBlockBios)
5169 {
5170 AssertMsgFailed(("Configuration error: LUN#%d hasn't a block BIOS interface!\n", pIf->iLUN));
5171 return VERR_PDM_MISSING_INTERFACE;
5172 }
5173 pIf->pDrvMount = (PDMIMOUNT *)pIf->pDrvBase->pfnQueryInterface(pIf->pDrvBase, PDMINTERFACE_MOUNT);
5174
5175 /*
5176 * Validate type.
5177 */
5178 enmType = pIf->pDrvBlock->pfnGetType(pIf->pDrvBlock);
5179 if ( enmType != PDMBLOCKTYPE_CDROM
5180 && enmType != PDMBLOCKTYPE_DVD
5181 && enmType != PDMBLOCKTYPE_HARD_DISK)
5182 {
5183 AssertMsgFailed(("Configuration error: LUN#%d isn't a disk or cd/dvd-rom. enmType=%d\n", pIf->iLUN, enmType));
5184 return VERR_PDM_UNSUPPORTED_BLOCK_TYPE;
5185 }
5186 if ( ( enmType == PDMBLOCKTYPE_DVD
5187 || enmType == PDMBLOCKTYPE_CDROM)
5188 && !pIf->pDrvMount)
5189 {
5190 AssertMsgFailed(("Internal error: cdrom without a mountable interface, WTF???!\n"));
5191 return VERR_INTERNAL_ERROR;
5192 }
5193 pIf->fATAPI = enmType == PDMBLOCKTYPE_DVD || enmType == PDMBLOCKTYPE_CDROM;
5194 pIf->fATAPIPassthrough = pIf->fATAPI ? (pIf->pDrvBlock->pfnSendCmd != NULL) : false;
5195
5196 /*
5197 * Allocate I/O buffer.
5198 */
5199 PVM pVM = PDMDevHlpGetVM(pDevIns);
5200 if (pIf->cbIOBuffer)
5201 {
5202 /* Buffer is (probably) already allocated. Validate the fields,
5203 * because memory corruption can also overwrite pIf->cbIOBuffer. */
5204 if (pIf->fATAPI)
5205 AssertRelease(pIf->cbIOBuffer == _128K);
5206 else
5207 AssertRelease(pIf->cbIOBuffer == ATA_MAX_MULT_SECTORS * 512);
5208 Assert(pIf->pbIOBufferHC);
5209 Assert(pIf->pbIOBufferGC == MMHyperHC2GC(pVM, pIf->pbIOBufferHC));
5210 }
5211 else
5212 {
5213 if (pIf->fATAPI)
5214 pIf->cbIOBuffer = _128K;
5215 else
5216 pIf->cbIOBuffer = ATA_MAX_MULT_SECTORS * 512;
5217 Assert(!pIf->pbIOBufferHC);
5218 rc = MMHyperAlloc(pVM, pIf->cbIOBuffer, 1, MM_TAG_PDM_DEVICE_USER, (void **)&pIf->pbIOBufferHC);
5219 if (VBOX_FAILURE(rc))
5220 return VERR_NO_MEMORY;
5221 pIf->pbIOBufferGC = MMHyperHC2GC(pVM, pIf->pbIOBufferHC);
5222 }
5223
5224 /*
5225 * Init geometry.
5226 */
5227 if (pIf->fATAPI)
5228 {
5229 pIf->cTotalSectors = pIf->pDrvBlock->pfnGetSize(pIf->pDrvBlock) / 2048;
5230 rc = pIf->pDrvBlockBios->pfnGetGeometry(pIf->pDrvBlockBios, &pIf->cCHSCylinders, &pIf->cCHSHeads, &pIf->cCHSSectors);
5231 pIf->cCHSCylinders = 0; /* dummy */
5232 pIf->cCHSHeads = 0; /* dummy */
5233 pIf->cCHSSectors = 0; /* dummy */
5234 if (rc != VERR_PDM_MEDIA_NOT_MOUNTED)
5235 {
5236 pIf->pDrvBlockBios->pfnSetTranslation(pIf->pDrvBlockBios, PDMBIOSTRANSLATION_NONE);
5237 pIf->pDrvBlockBios->pfnSetGeometry(pIf->pDrvBlockBios, pIf->cCHSCylinders, pIf->cCHSHeads, pIf->cCHSSectors);
5238 }
5239 LogRel(("PIIX3 ATA: LUN#%d: CD/DVD, total number of sectors %Ld, passthrough %s\n", pIf->iLUN, pIf->cTotalSectors, (pIf->fATAPIPassthrough ? "enabled" : "disabled")));
5240 }
5241 else
5242 {
5243 pIf->cTotalSectors = pIf->pDrvBlock->pfnGetSize(pIf->pDrvBlock) / 512;
5244 rc = pIf->pDrvBlockBios->pfnGetGeometry(pIf->pDrvBlockBios, &pIf->cCHSCylinders, &pIf->cCHSHeads, &pIf->cCHSSectors);
5245 if (rc == VERR_PDM_MEDIA_NOT_MOUNTED)
5246 {
5247 pIf->cCHSCylinders = 0;
5248 pIf->cCHSHeads = 16; /*??*/
5249 pIf->cCHSSectors = 63; /*??*/
5250 }
5251 else if (VBOX_FAILURE(rc))
5252 {
5253 PDMBIOSTRANSLATION enmTranslation;
5254 rc = pIf->pDrvBlockBios->pfnGetTranslation(pIf->pDrvBlockBios, &enmTranslation);
5255 if (rc == VERR_PDM_TRANSLATION_NOT_SET)
5256 {
5257 enmTranslation = PDMBIOSTRANSLATION_AUTO;
5258 pIf->cCHSCylinders = 0;
5259 rc = VINF_SUCCESS;
5260 }
5261 AssertRC(rc);
5262
5263 if ( enmTranslation == PDMBIOSTRANSLATION_AUTO
5264 && ( pIf->cCHSCylinders == 0
5265 || pIf->cCHSHeads == 0
5266 || pIf->cCHSSectors == 0
5267 )
5268 )
5269 {
5270 /* Image contains no geometry information, detect geometry. */
5271 rc = ataGuessDiskLCHS(pIf, &pIf->cCHSCylinders, &pIf->cCHSHeads, &pIf->cCHSSectors);
5272 if (VBOX_SUCCESS(rc))
5273 {
5274 /* Caution: the above function returns LCHS, but the
5275 * disk must report proper PCHS values for disks bigger
5276 * than approximately 512MB. */
5277 if (pIf->cCHSSectors == 63 && (pIf->cCHSHeads != 16 || pIf->cCHSCylinders >= 1024))
5278 {
5279 pIf->cCHSCylinders = pIf->cTotalSectors / 63 / 16;
5280 pIf->cCHSHeads = 16;
5281 pIf->cCHSSectors = 63;
5282 /* Set the disk CHS translation mode. */
5283 pIf->pDrvBlockBios->pfnSetTranslation(pIf->pDrvBlockBios, PDMBIOSTRANSLATION_LBA);
5284 }
5285 /* Set the disk geometry information. */
5286 rc = pIf->pDrvBlockBios->pfnSetGeometry(pIf->pDrvBlockBios, pIf->cCHSCylinders, pIf->cCHSHeads, pIf->cCHSSectors);
5287 }
5288 else
5289 {
5290 /* Flag geometry as invalid, will be replaced below by the
5291 * default geometry. */
5292 pIf->cCHSCylinders = 0;
5293 }
5294 }
5295 /* If there is no geometry, use standard physical disk geometry.
5296 * This uses LCHS to LBA translation in the BIOS (which selects
5297 * the logical sector count 63 and the logical head count to be
5298 * the smallest of 16,32,64,128,255 which makes the logical
5299 * cylinder count smaller than 1024 - if that's not possible, it
5300 * uses 255 heads, so up to about 8 GByte maximum with the
5301 * standard int13 interface, which supports 1024 cylinders). */
5302 if (!pIf->cCHSCylinders)
5303 {
5304 uint64_t cCHSCylinders = pIf->cTotalSectors / (16 * 63);
5305 pIf->cCHSCylinders = (uint32_t)RT_MAX(cCHSCylinders, 1);
5306 pIf->cCHSHeads = 16;
5307 pIf->cCHSSectors = 63;
5308 /* Set the disk geometry information. */
5309 rc = pIf->pDrvBlockBios->pfnSetGeometry(pIf->pDrvBlockBios, pIf->cCHSCylinders, pIf->cCHSHeads, pIf->cCHSSectors);
5310 }
5311 }
5312 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));
5313 }
5314 return VINF_SUCCESS;
5315}
5316
5317
5318/**
5319 * Attach command.
5320 *
5321 * This is called when we change block driver for the DVD drive.
5322 *
5323 * @returns VBox status code.
5324 * @param pDevIns The device instance.
5325 * @param iLUN The logical unit which is being detached.
5326 */
5327static DECLCALLBACK(int) ataAttach(PPDMDEVINS pDevIns, unsigned iLUN)
5328{
5329 PCIATAState *pThis = PDMINS2DATA(pDevIns, PCIATAState *);
5330 PATACONTROLLER pCtl;
5331 ATADevState *pIf;
5332 int rc;
5333 unsigned iController;
5334 unsigned iInterface;
5335
5336 /*
5337 * Locate the controller and stuff.
5338 */
5339 iController = iLUN / RT_ELEMENTS(pThis->aCts[0].aIfs);
5340 AssertReleaseMsg(iController < RT_ELEMENTS(pThis->aCts), ("iController=%d iLUN=%d\n", iController, iLUN));
5341 pCtl = &pThis->aCts[iController];
5342
5343 iInterface = iLUN % RT_ELEMENTS(pThis->aCts[0].aIfs);
5344 pIf = &pCtl->aIfs[iInterface];
5345
5346 /* the usual paranoia */
5347 AssertRelease(!pIf->pDrvBase);
5348 AssertRelease(!pIf->pDrvBlock);
5349 Assert(ATADEVSTATE_2_CONTROLLER(pIf) == pCtl);
5350 Assert(pIf->iLUN == iLUN);
5351
5352 /*
5353 * Try attach the block device and get the interfaces,
5354 * required as well as optional.
5355 */
5356 rc = PDMDevHlpDriverAttach(pDevIns, pIf->iLUN, &pIf->IBase, &pIf->pDrvBase, NULL);
5357 if (VBOX_SUCCESS(rc))
5358 rc = ataConfigLun(pDevIns, pIf);
5359 else
5360 AssertMsgFailed(("Failed to attach LUN#%d. rc=%Vrc\n", pIf->iLUN, rc));
5361
5362 if (VBOX_FAILURE(rc))
5363 {
5364 pIf->pDrvBase = NULL;
5365 pIf->pDrvBlock = NULL;
5366 }
5367 return rc;
5368}
5369
5370
5371/**
5372 * Suspend notification.
5373 *
5374 * @returns VBox status.
5375 * @param pDrvIns The driver instance data.
5376 */
5377static DECLCALLBACK(void) ataSuspend(PPDMDEVINS pDevIns)
5378{
5379 Log(("%s:\n", __FUNCTION__));
5380 if (!ataWaitForAllAsyncIOIsIdle(pDevIns, 20000))
5381 AssertMsgFailed(("Async I/O didn't stop in 20 seconds!\n"));
5382 return;
5383}
5384
5385
5386/**
5387 * Resume notification.
5388 *
5389 * @returns VBox status.
5390 * @param pDrvIns The driver instance data.
5391 */
5392static DECLCALLBACK(void) ataResume(PPDMDEVINS pDevIns)
5393{
5394 PCIATAState *pData = PDMINS2DATA(pDevIns, PCIATAState *);
5395 int rc;
5396
5397 Log(("%s:\n", __FUNCTION__));
5398 for (uint32_t i = 0; i < RT_ELEMENTS(pData->aCts); i++)
5399 {
5400 if (pData->aCts[i].fRedo && pData->aCts[i].fRedoIdle)
5401 {
5402 rc = RTSemEventSignal(pData->aCts[i].SuspendIOSem);
5403 AssertRC(rc);
5404 }
5405 }
5406 return;
5407}
5408
5409
5410/**
5411 * Power Off notification.
5412 *
5413 * @returns VBox status.
5414 * @param pDrvIns The driver instance data.
5415 */
5416static DECLCALLBACK(void) ataPowerOff(PPDMDEVINS pDevIns)
5417{
5418 Log(("%s:\n", __FUNCTION__));
5419 if (!ataWaitForAllAsyncIOIsIdle(pDevIns, 20000))
5420 AssertMsgFailed(("Async I/O didn't stop in 20 seconds!\n"));
5421 return;
5422}
5423
5424
5425/**
5426 * Prepare state save and load operation.
5427 *
5428 * @returns VBox status code.
5429 * @param pDevIns Device instance of the device which registered the data unit.
5430 * @param pSSM SSM operation handle.
5431 */
5432static DECLCALLBACK(int) ataSaveLoadPrep(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
5433{
5434 PCIATAState *pData = PDMINS2DATA(pDevIns, PCIATAState *);
5435
5436 /* sanity - the suspend notification will wait on the async stuff. */
5437 for (uint32_t i = 0; i < RT_ELEMENTS(pData->aCts); i++)
5438 {
5439 Assert(ataAsyncIOIsIdle(&pData->aCts[i], false));
5440 if (!ataAsyncIOIsIdle(&pData->aCts[i], false))
5441 return VERR_SSM_IDE_ASYNC_TIMEOUT;
5442 }
5443 return VINF_SUCCESS;
5444}
5445
5446
5447/**
5448 * Saves a state of the ATA device.
5449 *
5450 * @returns VBox status code.
5451 * @param pDevIns The device instance.
5452 * @param pSSMHandle The handle to save the state to.
5453 */
5454static DECLCALLBACK(int) ataSaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSMHandle)
5455{
5456 PCIATAState *pData = PDMINS2DATA(pDevIns, PCIATAState *);
5457
5458 for (uint32_t i = 0; i < RT_ELEMENTS(pData->aCts); i++)
5459 {
5460 SSMR3PutU8(pSSMHandle, pData->aCts[i].iSelectedIf);
5461 SSMR3PutU8(pSSMHandle, pData->aCts[i].iAIOIf);
5462 SSMR3PutU8(pSSMHandle, pData->aCts[i].uAsyncIOState);
5463 SSMR3PutBool(pSSMHandle, pData->aCts[i].fChainedTransfer);
5464 SSMR3PutBool(pSSMHandle, pData->aCts[i].fReset);
5465 SSMR3PutBool(pSSMHandle, pData->aCts[i].fRedo);
5466 SSMR3PutBool(pSSMHandle, pData->aCts[i].fRedoIdle);
5467 SSMR3PutBool(pSSMHandle, pData->aCts[i].fRedoDMALastDesc);
5468 SSMR3PutMem(pSSMHandle, &pData->aCts[i].BmDma, sizeof(pData->aCts[i].BmDma));
5469 SSMR3PutGCPhys(pSSMHandle, pData->aCts[i].pFirstDMADesc);
5470 SSMR3PutGCPhys(pSSMHandle, pData->aCts[i].pLastDMADesc);
5471 SSMR3PutGCPhys(pSSMHandle, pData->aCts[i].pRedoDMABuffer);
5472 SSMR3PutU32(pSSMHandle, pData->aCts[i].cbRedoDMABuffer);
5473
5474 for (uint32_t j = 0; j < RT_ELEMENTS(pData->aCts[i].aIfs); j++)
5475 {
5476 SSMR3PutBool(pSSMHandle, pData->aCts[i].aIfs[j].fLBA48);
5477 SSMR3PutBool(pSSMHandle, pData->aCts[i].aIfs[j].fATAPI);
5478 SSMR3PutBool(pSSMHandle, pData->aCts[i].aIfs[j].fIrqPending);
5479 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].cMultSectors);
5480 SSMR3PutU32(pSSMHandle, pData->aCts[i].aIfs[j].cCHSCylinders);
5481 SSMR3PutU32(pSSMHandle, pData->aCts[i].aIfs[j].cCHSHeads);
5482 SSMR3PutU32(pSSMHandle, pData->aCts[i].aIfs[j].cCHSSectors);
5483 SSMR3PutU32(pSSMHandle, pData->aCts[i].aIfs[j].cSectorsPerIRQ);
5484 SSMR3PutU64(pSSMHandle, pData->aCts[i].aIfs[j].cTotalSectors);
5485 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].uATARegFeature);
5486 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].uATARegFeatureHOB);
5487 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].uATARegError);
5488 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].uATARegNSector);
5489 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].uATARegNSectorHOB);
5490 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].uATARegSector);
5491 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].uATARegSectorHOB);
5492 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].uATARegLCyl);
5493 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].uATARegLCylHOB);
5494 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].uATARegHCyl);
5495 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].uATARegHCylHOB);
5496 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].uATARegSelect);
5497 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].uATARegStatus);
5498 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].uATARegCommand);
5499 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].uATARegDevCtl);
5500 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].uATATransferMode);
5501 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].uTxDir);
5502 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].iBeginTransfer);
5503 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].iSourceSink);
5504 SSMR3PutBool(pSSMHandle, pData->aCts[i].aIfs[j].fDMA);
5505 SSMR3PutBool(pSSMHandle, pData->aCts[i].aIfs[j].fATAPITransfer);
5506 SSMR3PutU32(pSSMHandle, pData->aCts[i].aIfs[j].cbTotalTransfer);
5507 SSMR3PutU32(pSSMHandle, pData->aCts[i].aIfs[j].cbElementaryTransfer);
5508 SSMR3PutU32(pSSMHandle, pData->aCts[i].aIfs[j].iIOBufferCur);
5509 SSMR3PutU32(pSSMHandle, pData->aCts[i].aIfs[j].iIOBufferEnd);
5510 SSMR3PutU32(pSSMHandle, pData->aCts[i].aIfs[j].iIOBufferPIODataStart);
5511 SSMR3PutU32(pSSMHandle, pData->aCts[i].aIfs[j].iIOBufferPIODataEnd);
5512 SSMR3PutU32(pSSMHandle, pData->aCts[i].aIfs[j].iATAPILBA);
5513 SSMR3PutU32(pSSMHandle, pData->aCts[i].aIfs[j].cbATAPISector);
5514 SSMR3PutMem(pSSMHandle, &pData->aCts[i].aIfs[j].aATAPICmd, sizeof(pData->aCts[i].aIfs[j].aATAPICmd));
5515 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].uATAPISenseKey);
5516 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].uATAPIASC);
5517 SSMR3PutU8(pSSMHandle, pData->aCts[i].aIfs[j].cNotifiedMediaChange);
5518 SSMR3PutMem(pSSMHandle, &pData->aCts[i].aIfs[j].Led, sizeof(pData->aCts[i].aIfs[j].Led));
5519 SSMR3PutU32(pSSMHandle, pData->aCts[i].aIfs[j].cbIOBuffer);
5520 if (pData->aCts[i].aIfs[j].cbIOBuffer)
5521 SSMR3PutMem(pSSMHandle, pData->aCts[i].aIfs[j].CTXSUFF(pbIOBuffer), pData->aCts[i].aIfs[j].cbIOBuffer);
5522 else
5523 Assert(pData->aCts[i].aIfs[j].CTXSUFF(pbIOBuffer) == NULL);
5524 }
5525 }
5526
5527 return SSMR3PutU32(pSSMHandle, ~0); /* sanity/terminator */
5528}
5529
5530
5531/**
5532 * Loads a saved ATA device state.
5533 *
5534 * @returns VBox status code.
5535 * @param pDevIns The device instance.
5536 * @param pSSMHandle The handle to the saved state.
5537 * @param u32Version The data unit version number.
5538 */
5539static DECLCALLBACK(int) ataLoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSMHandle, uint32_t u32Version)
5540{
5541 PCIATAState *pData = PDMINS2DATA(pDevIns, PCIATAState *);
5542 int rc;
5543 uint32_t u32;
5544
5545 if (u32Version != ATA_SAVED_STATE_VERSION)
5546 {
5547 AssertMsgFailed(("u32Version=%d\n", u32Version));
5548 return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
5549 }
5550
5551 /*
5552 * Restore valid parts of the PCIATAState structure
5553 */
5554 for (uint32_t i = 0; i < RT_ELEMENTS(pData->aCts); i++)
5555 {
5556 /* integrity check */
5557 if (!ataAsyncIOIsIdle(&pData->aCts[i], false))
5558 {
5559 AssertMsgFailed(("Async I/O for controller %d is active\n", i));
5560 rc = VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
5561 return rc;
5562 }
5563
5564 SSMR3GetU8(pSSMHandle, &pData->aCts[i].iSelectedIf);
5565 SSMR3GetU8(pSSMHandle, &pData->aCts[i].iAIOIf);
5566 SSMR3GetU8(pSSMHandle, &pData->aCts[i].uAsyncIOState);
5567 SSMR3GetBool(pSSMHandle, &pData->aCts[i].fChainedTransfer);
5568 SSMR3GetBool(pSSMHandle, (bool *)&pData->aCts[i].fReset);
5569 SSMR3GetBool(pSSMHandle, (bool *)&pData->aCts[i].fRedo);
5570 SSMR3GetBool(pSSMHandle, (bool *)&pData->aCts[i].fRedoIdle);
5571 SSMR3GetBool(pSSMHandle, (bool *)&pData->aCts[i].fRedoDMALastDesc);
5572 SSMR3GetMem(pSSMHandle, &pData->aCts[i].BmDma, sizeof(pData->aCts[i].BmDma));
5573 SSMR3GetGCPhys(pSSMHandle, &pData->aCts[i].pFirstDMADesc);
5574 SSMR3GetGCPhys(pSSMHandle, &pData->aCts[i].pLastDMADesc);
5575 SSMR3GetGCPhys(pSSMHandle, &pData->aCts[i].pRedoDMABuffer);
5576 SSMR3GetU32(pSSMHandle, &pData->aCts[i].cbRedoDMABuffer);
5577
5578 for (uint32_t j = 0; j < RT_ELEMENTS(pData->aCts[i].aIfs); j++)
5579 {
5580 SSMR3GetBool(pSSMHandle, &pData->aCts[i].aIfs[j].fLBA48);
5581 SSMR3GetBool(pSSMHandle, &pData->aCts[i].aIfs[j].fATAPI);
5582 SSMR3GetBool(pSSMHandle, &pData->aCts[i].aIfs[j].fIrqPending);
5583 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].cMultSectors);
5584 SSMR3GetU32(pSSMHandle, &pData->aCts[i].aIfs[j].cCHSCylinders);
5585 SSMR3GetU32(pSSMHandle, &pData->aCts[i].aIfs[j].cCHSHeads);
5586 SSMR3GetU32(pSSMHandle, &pData->aCts[i].aIfs[j].cCHSSectors);
5587 SSMR3GetU32(pSSMHandle, &pData->aCts[i].aIfs[j].cSectorsPerIRQ);
5588 SSMR3GetU64(pSSMHandle, &pData->aCts[i].aIfs[j].cTotalSectors);
5589 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].uATARegFeature);
5590 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].uATARegFeatureHOB);
5591 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].uATARegError);
5592 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].uATARegNSector);
5593 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].uATARegNSectorHOB);
5594 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].uATARegSector);
5595 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].uATARegSectorHOB);
5596 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].uATARegLCyl);
5597 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].uATARegLCylHOB);
5598 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].uATARegHCyl);
5599 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].uATARegHCylHOB);
5600 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].uATARegSelect);
5601 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].uATARegStatus);
5602 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].uATARegCommand);
5603 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].uATARegDevCtl);
5604 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].uATATransferMode);
5605 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].uTxDir);
5606 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].iBeginTransfer);
5607 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].iSourceSink);
5608 SSMR3GetBool(pSSMHandle, &pData->aCts[i].aIfs[j].fDMA);
5609 SSMR3GetBool(pSSMHandle, &pData->aCts[i].aIfs[j].fATAPITransfer);
5610 SSMR3GetU32(pSSMHandle, &pData->aCts[i].aIfs[j].cbTotalTransfer);
5611 SSMR3GetU32(pSSMHandle, &pData->aCts[i].aIfs[j].cbElementaryTransfer);
5612 SSMR3GetU32(pSSMHandle, &pData->aCts[i].aIfs[j].iIOBufferCur);
5613 SSMR3GetU32(pSSMHandle, &pData->aCts[i].aIfs[j].iIOBufferEnd);
5614 SSMR3GetU32(pSSMHandle, &pData->aCts[i].aIfs[j].iIOBufferPIODataStart);
5615 SSMR3GetU32(pSSMHandle, &pData->aCts[i].aIfs[j].iIOBufferPIODataEnd);
5616 SSMR3GetU32(pSSMHandle, &pData->aCts[i].aIfs[j].iATAPILBA);
5617 SSMR3GetU32(pSSMHandle, &pData->aCts[i].aIfs[j].cbATAPISector);
5618 SSMR3GetMem(pSSMHandle, &pData->aCts[i].aIfs[j].aATAPICmd, sizeof(pData->aCts[i].aIfs[j].aATAPICmd));
5619 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].uATAPISenseKey);
5620 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].uATAPIASC);
5621 SSMR3GetU8(pSSMHandle, &pData->aCts[i].aIfs[j].cNotifiedMediaChange);
5622 SSMR3GetMem(pSSMHandle, &pData->aCts[i].aIfs[j].Led, sizeof(pData->aCts[i].aIfs[j].Led));
5623 SSMR3GetU32(pSSMHandle, &pData->aCts[i].aIfs[j].cbIOBuffer);
5624 if (pData->aCts[i].aIfs[j].cbIOBuffer)
5625 SSMR3GetMem(pSSMHandle, pData->aCts[i].aIfs[j].CTXSUFF(pbIOBuffer), pData->aCts[i].aIfs[j].cbIOBuffer);
5626 else
5627 Assert(pData->aCts[i].aIfs[j].CTXSUFF(pbIOBuffer) == NULL);
5628 }
5629 }
5630
5631 rc = SSMR3GetU32(pSSMHandle, &u32);
5632 if (VBOX_FAILURE(rc))
5633 return rc;
5634 if (u32 != ~0U)
5635 {
5636 AssertMsgFailed(("u32=%#x expected ~0\n", u32));
5637 rc = VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
5638 return rc;
5639 }
5640
5641 return VINF_SUCCESS;
5642}
5643
5644
5645/**
5646 * Construct a device instance for a VM.
5647 *
5648 * @returns VBox status.
5649 * @param pDevIns The device instance data.
5650 * If the registration structure is needed, pDevIns->pDevReg points to it.
5651 * @param iInstance Instance number. Use this to figure out which registers and such to use.
5652 * The device number is also found in pDevIns->iInstance, but since it's
5653 * likely to be freqently used PDM passes it as parameter.
5654 * @param pCfgHandle Configuration node handle for the device. Use this to obtain the configuration
5655 * of the device instance. It's also found in pDevIns->pCfgHandle, but like
5656 * iInstance it's expected to be used a bit in this function.
5657 */
5658static DECLCALLBACK(int) ataConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfgHandle)
5659{
5660 PCIATAState *pData = PDMINS2DATA(pDevIns, PCIATAState *);
5661 PPDMIBASE pBase;
5662 int rc;
5663 bool fGCEnabled;
5664 bool fR0Enabled;
5665 uint32_t DelayIRQMillies;
5666
5667 Assert(iInstance == 0);
5668
5669 /*
5670 * Validate and read configuration.
5671 */
5672 if (!CFGMR3AreValuesValid(pCfgHandle, "GCEnabled\0IRQDelay\0R0Enabled"))
5673 return PDMDEV_SET_ERROR(pDevIns, VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES,
5674 N_("PIIX3 configuration error: unknown option specified."));
5675
5676 rc = CFGMR3QueryBool(pCfgHandle, "GCEnabled", &fGCEnabled);
5677 if (rc == VERR_CFGM_VALUE_NOT_FOUND)
5678 fGCEnabled = true;
5679 else if (VBOX_FAILURE(rc))
5680 return PDMDEV_SET_ERROR(pDevIns, rc,
5681 N_("PIIX3 configuration error: failed to read GCEnabled as boolean."));
5682 Log(("%s: fGCEnabled=%d\n", __FUNCTION__, fGCEnabled));
5683
5684 rc = CFGMR3QueryBool(pCfgHandle, "R0Enabled", &fR0Enabled);
5685 if (rc == VERR_CFGM_VALUE_NOT_FOUND)
5686 fR0Enabled = true;
5687 else if (VBOX_FAILURE(rc))
5688 return PDMDEV_SET_ERROR(pDevIns, rc,
5689 N_("PIIX3 configuration error: failed to read R0Enabled as boolean."));
5690 Log(("%s: fR0Enabled=%d\n", __FUNCTION__, fR0Enabled));
5691
5692 rc = CFGMR3QueryU32(pCfgHandle, "IRQDelay", &DelayIRQMillies);
5693 if (rc == VERR_CFGM_VALUE_NOT_FOUND)
5694 DelayIRQMillies = 0;
5695 else if (VBOX_FAILURE(rc))
5696 return PDMDEV_SET_ERROR(pDevIns, rc,
5697 N_("PIIX3 configuration error: failed to read IRQDelay as integer."));
5698 Log(("%s: DelayIRQMillies=%d\n", __FUNCTION__, DelayIRQMillies));
5699 Assert(DelayIRQMillies < 50);
5700
5701 /*
5702 * Initialize data (most of it anyway).
5703 */
5704 /* Status LUN. */
5705 pData->IBase.pfnQueryInterface = ataStatus_QueryInterface;
5706 pData->ILeds.pfnQueryStatusLed = ataStatus_QueryStatusLed;
5707
5708 /* pci */
5709 pData->dev.config[0x00] = 0x86; /* Vendor: Intel */
5710 pData->dev.config[0x01] = 0x80;
5711 pData->dev.config[0x02] = 0x10; /* Device: PIIX3 IDE */
5712 pData->dev.config[0x03] = 0x70;
5713 pData->dev.config[0x04] = PCI_COMMAND_IOACCESS | PCI_COMMAND_MEMACCESS | PCI_COMMAND_BUSMASTER;
5714 pData->dev.config[0x09] = 0x8a; /* programming interface = PCI_IDE bus master is supported */
5715 pData->dev.config[0x0a] = 0x01; /* class_sub = PCI_IDE */
5716 pData->dev.config[0x0b] = 0x01; /* class_base = PCI_mass_storage */
5717 pData->dev.config[0x0e] = 0x00; /* header_type */
5718
5719 pData->pDevIns = pDevIns;
5720 pData->fGCEnabled = fGCEnabled;
5721 pData->fR0Enabled = fR0Enabled;
5722 for (uint32_t i = 0; i < RT_ELEMENTS(pData->aCts); i++)
5723 {
5724 pData->aCts[i].pDevInsHC = pDevIns;
5725 pData->aCts[i].pDevInsGC = PDMDEVINS_2_GCPTR(pDevIns);
5726 pData->aCts[i].DelayIRQMillies = (uint32_t)DelayIRQMillies;
5727 for (uint32_t j = 0; j < RT_ELEMENTS(pData->aCts[i].aIfs); j++)
5728 {
5729 pData->aCts[i].aIfs[j].iLUN = i * RT_ELEMENTS(pData->aCts) + j;
5730 pData->aCts[i].aIfs[j].pDevInsHC = pDevIns;
5731 pData->aCts[i].aIfs[j].pDevInsGC = PDMDEVINS_2_GCPTR(pDevIns);
5732 pData->aCts[i].aIfs[j].pControllerHC = &pData->aCts[i];
5733 pData->aCts[i].aIfs[j].pControllerGC = MMHyperHC2GC(PDMDevHlpGetVM(pDevIns), &pData->aCts[i]);
5734 pData->aCts[i].aIfs[j].IBase.pfnQueryInterface = ataQueryInterface;
5735 pData->aCts[i].aIfs[j].IMountNotify.pfnMountNotify = ataMountNotify;
5736 pData->aCts[i].aIfs[j].IMountNotify.pfnUnmountNotify = ataUnmountNotify;
5737 pData->aCts[i].aIfs[j].Led.u32Magic = PDMLED_MAGIC;
5738 }
5739 }
5740
5741 Assert(RT_ELEMENTS(pData->aCts) == 2);
5742 pData->aCts[0].irq = 14;
5743 pData->aCts[0].IOPortBase1 = 0x1f0;
5744 pData->aCts[0].IOPortBase2 = 0x3f6;
5745 pData->aCts[1].irq = 15;
5746 pData->aCts[1].IOPortBase1 = 0x170;
5747 pData->aCts[1].IOPortBase2 = 0x376;
5748
5749 /*
5750 * Register the PCI device.
5751 * N.B. There's a hack in the PIIX3 PCI bridge device to assign this
5752 * device the slot next to itself.
5753 */
5754 rc = PDMDevHlpPCIRegister(pDevIns, &pData->dev);
5755 if (VBOX_FAILURE(rc))
5756 return PDMDEV_SET_ERROR(pDevIns, rc,
5757 N_("PIIX3 cannot register PCI device."));
5758 AssertMsg(pData->dev.devfn == 9 || iInstance != 0, ("pData->dev.devfn=%d\n", pData->dev.devfn));
5759 rc = PDMDevHlpPCIIORegionRegister(pDevIns, 4, 0x10, PCI_ADDRESS_SPACE_IO, ataBMDMAIORangeMap);
5760 if (VBOX_FAILURE(rc))
5761 return PDMDEV_SET_ERROR(pDevIns, rc,
5762 N_("PIIX3 cannot register PCI I/O region for BMDMA."));
5763
5764 /*
5765 * Register the I/O ports.
5766 * The ports are all hardcoded and enforced by the PIIX3 host bridge controller.
5767 */
5768 for (uint32_t i = 0; i < RT_ELEMENTS(pData->aCts); i++)
5769 {
5770 rc = PDMDevHlpIOPortRegister(pDevIns, pData->aCts[i].IOPortBase1, 8, (RTHCPTR)i,
5771 ataIOPortWrite1, ataIOPortRead1, ataIOPortWriteStr1, ataIOPortReadStr1, "ATA I/O Base 1");
5772 if (VBOX_FAILURE(rc))
5773 return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot register I/O handlers."));
5774
5775 if (fGCEnabled)
5776 {
5777 rc = PDMDevHlpIOPortRegisterGC(pDevIns, pData->aCts[i].IOPortBase1, 8, (RTGCPTR)i,
5778 "ataIOPortWrite1", "ataIOPortRead1", "ataIOPortWriteStr1", "ataIOPortReadStr1", "ATA I/O Base 1");
5779 if (VBOX_FAILURE(rc))
5780 return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot register I/O handlers (GC)."));
5781 }
5782
5783 if (fR0Enabled)
5784 {
5785#if 1
5786 rc = PDMDevHlpIOPortRegisterR0(pDevIns, pData->aCts[i].IOPortBase1, 8, (RTR0PTR)i,
5787 "ataIOPortWrite1", "ataIOPortRead1", NULL, NULL, "ATA I/O Base 1");
5788#else
5789 rc = PDMDevHlpIOPortRegisterR0(pDevIns, pData->aCts[i].IOPortBase1, 8, (RTR0PTR)i,
5790 "ataIOPortWrite1", "ataIOPortRead1", "ataIOPortWriteStr1", "ataIOPortReadStr1", "ATA I/O Base 1");
5791#endif
5792 if (VBOX_FAILURE(rc))
5793 return PDMDEV_SET_ERROR(pDevIns, rc, "PIIX3 cannot register I/O handlers (R0).");
5794 }
5795
5796 rc = PDMDevHlpIOPortRegister(pDevIns, pData->aCts[i].IOPortBase2, 1, (RTHCPTR)i,
5797 ataIOPortWrite2, ataIOPortRead2, NULL, NULL, "ATA I/O Base 2");
5798 if (VBOX_FAILURE(rc))
5799 return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot register base2 I/O handlers."));
5800
5801 if (fGCEnabled)
5802 {
5803 rc = PDMDevHlpIOPortRegisterGC(pDevIns, pData->aCts[i].IOPortBase2, 1, (RTGCPTR)i,
5804 "ataIOPortWrite2", "ataIOPortRead2", NULL, NULL, "ATA I/O Base 2");
5805 if (VBOX_FAILURE(rc))
5806 return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot register base2 I/O handlers (GC)."));
5807 }
5808 if (fR0Enabled)
5809 {
5810 rc = PDMDevHlpIOPortRegisterR0(pDevIns, pData->aCts[i].IOPortBase2, 1, (RTR0PTR)i,
5811 "ataIOPortWrite2", "ataIOPortRead2", NULL, NULL, "ATA I/O Base 2");
5812 if (VBOX_FAILURE(rc))
5813 return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot register base2 I/O handlers (R0)."));
5814 }
5815
5816#ifdef VBOX_WITH_STATISTICS /** @todo release too. */
5817 for (uint32_t j = 0; j < RT_ELEMENTS(pData->aCts[i].aIfs); j++)
5818 {
5819 ATADevState *pIf = &pData->aCts[i].aIfs[j];
5820 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);
5821 PDMDevHlpSTAMRegisterF(pDevIns, &pIf->StatBytesRead, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES, "Amount of data read.", "/Devices/ATA%d/Unit%d/ReadBytes", i, j);
5822 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);
5823 PDMDevHlpSTAMRegisterF(pDevIns, &pIf->StatBytesWritten, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES, "Amount of data written.", "/Devices/ATA%d/Unit%d/WrittenBytes", i, j);
5824 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);
5825 }
5826 PDMDevHlpSTAMRegisterF(pDevIns, &pData->aCts[i].StatAsyncOps, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "The number of async operations.", "/Devices/ATA%d/Async/Operations", i);
5827 /** @todo STAMUNIT_MICROSECS */
5828 PDMDevHlpSTAMRegisterF(pDevIns, &pData->aCts[i].StatAsyncMinWait, STAMTYPE_U64_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_NONE, "Minimum wait in microseconds.", "/Devices/ATA%d/Async/MinWait", i);
5829 PDMDevHlpSTAMRegisterF(pDevIns, &pData->aCts[i].StatAsyncMaxWait, STAMTYPE_U64_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_NONE, "Maximum wait in microseconds.", "/Devices/ATA%d/Async/MaxWait", i);
5830 PDMDevHlpSTAMRegisterF(pDevIns, &pData->aCts[i].StatAsyncTimeUS, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_NONE, "Total time spent in microseconds.","/Devices/ATA%d/Async/TotalTimeUS", i);
5831 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);
5832 PDMDevHlpSTAMRegisterF(pDevIns, &pData->aCts[i].StatLockWait, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling of locks.", "/Devices/ATA%d/Async/LockWait", i);
5833#endif /* VBOX_WITH_STATISTICS */
5834
5835 /* Initialize per-controller critical section */
5836 char szName[24];
5837 RTStrPrintf(szName, sizeof(szName), "ATA%d", i);
5838 rc = PDMDevHlpCritSectInit(pDevIns, &pData->aCts[i].lock, szName);
5839 if (VBOX_FAILURE(rc))
5840 return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot initialize critical section."));
5841 }
5842
5843 /*
5844 * Attach status driver (optional).
5845 */
5846 rc = PDMDevHlpDriverAttach(pDevIns, PDM_STATUS_LUN, &pData->IBase, &pBase, "Status Port");
5847 if (VBOX_SUCCESS(rc))
5848 pData->pLedsConnector = (PDMILEDCONNECTORS *)pBase->pfnQueryInterface(pBase, PDMINTERFACE_LED_CONNECTORS);
5849 else if (rc != VERR_PDM_NO_ATTACHED_DRIVER)
5850 {
5851 AssertMsgFailed(("Failed to attach to status driver. rc=%Vrc\n", rc));
5852 return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot attach to status driver."));
5853 }
5854
5855 /*
5856 * Attach the units.
5857 */
5858 uint32_t cbTotalBuffer = 0;
5859 for (uint32_t i = 0; i < RT_ELEMENTS(pData->aCts); i++)
5860 {
5861 PATACONTROLLER pCtl = &pData->aCts[i];
5862
5863 /*
5864 * Start the worker thread.
5865 */
5866 pCtl->uAsyncIOState = ATA_AIO_NEW;
5867 rc = RTSemEventCreate(&pCtl->AsyncIOSem);
5868 AssertRC(rc);
5869 rc = RTSemEventCreate(&pCtl->SuspendIOSem);
5870 AssertRC(rc);
5871 rc = RTSemMutexCreate(&pCtl->AsyncIORequestMutex);
5872 AssertRC(rc);
5873 ataAsyncIOClearRequests(pCtl);
5874 rc = RTThreadCreate(&pCtl->AsyncIOThread, ataAsyncIOLoop, (void *)pCtl, 128*1024, RTTHREADTYPE_IO, 0, "ATA");
5875 AssertRC(rc);
5876 Assert(pCtl->AsyncIOThread != NIL_RTTHREAD && pCtl->AsyncIOSem != NIL_RTSEMEVENT && pCtl->SuspendIOSem != NIL_RTSEMEVENT && pCtl->AsyncIORequestMutex != NIL_RTSEMMUTEX);
5877 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));
5878
5879 for (uint32_t j = 0; j < RT_ELEMENTS(pCtl->aIfs); j++)
5880 {
5881 static const char *s_apszDescs[RT_ELEMENTS(pData->aCts)][RT_ELEMENTS(pCtl->aIfs)] =
5882 {
5883 { "Primary Master", "Primary Slave" },
5884 { "Secondary Master", "Secondary Slave" }
5885 };
5886
5887 /*
5888 * Try attach the block device and get the interfaces,
5889 * required as well as optional.
5890 */
5891 ATADevState *pIf = &pCtl->aIfs[j];
5892
5893 rc = PDMDevHlpDriverAttach(pDevIns, pIf->iLUN, &pIf->IBase, &pIf->pDrvBase, s_apszDescs[i][j]);
5894 if (VBOX_SUCCESS(rc))
5895 rc = ataConfigLun(pDevIns, pIf);
5896 else if (rc == VERR_PDM_NO_ATTACHED_DRIVER)
5897 {
5898 pIf->pDrvBase = NULL;
5899 pIf->pDrvBlock = NULL;
5900 pIf->cbIOBuffer = 0;
5901 pIf->pbIOBufferHC = NULL;
5902 pIf->pbIOBufferGC = NIL_RTGCPHYS;
5903 LogRel(("PIIX3 ATA: LUN#%d: no unit\n", pIf->iLUN));
5904 }
5905 else
5906 {
5907 AssertMsgFailed(("Failed to attach LUN#%d. rc=%Vrc\n", pIf->iLUN, rc));
5908 switch (rc)
5909 {
5910 case VERR_ACCESS_DENIED:
5911 /* Error already catched by DrvHostBase */
5912 return rc;
5913 default:
5914 return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS, N_(
5915 "PIIX3 cannot attach drive to the %s"), s_apszDescs[i][j]);
5916 }
5917 }
5918 cbTotalBuffer += pIf->cbIOBuffer;
5919 }
5920 }
5921
5922 rc = PDMDevHlpSSMRegister(pDevIns, pDevIns->pDevReg->szDeviceName, iInstance,
5923 ATA_SAVED_STATE_VERSION, sizeof(*pData) + cbTotalBuffer,
5924 ataSaveLoadPrep, ataSaveExec, NULL,
5925 ataSaveLoadPrep, ataLoadExec, NULL);
5926 if (VBOX_FAILURE(rc))
5927 return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot register save state handlers."));
5928
5929 /*
5930 * Initialize the device state.
5931 */
5932 ataReset(pDevIns);
5933
5934 return VINF_SUCCESS;
5935}
5936
5937
5938/**
5939 * The device registration structure.
5940 */
5941const PDMDEVREG g_DevicePIIX3IDE =
5942{
5943 /* u32Version */
5944 PDM_DEVREG_VERSION,
5945 /* szDeviceName */
5946 "piix3ide",
5947 /* szGCMod */
5948 "VBoxDDGC.gc",
5949 /* szR0Mod */
5950 "VBoxDDR0.r0",
5951 /* pszDescription */
5952 "Intel PIIX3 ATA controller.\n"
5953 " LUN #0 is primary master.\n"
5954 " LUN #1 is primary slave.\n"
5955 " LUN #2 is secondary master.\n"
5956 " LUN #3 is secondary slave.\n"
5957 " LUN #999 is the LED/Status connector.",
5958 /* fFlags */
5959 PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT | PDM_DEVREG_FLAGS_GUEST_BITS_DEFAULT | PDM_DEVREG_FLAGS_GC | PDM_DEVREG_FLAGS_R0,
5960 /* fClass */
5961 PDM_DEVREG_CLASS_STORAGE,
5962 /* cMaxInstances */
5963 1,
5964 /* cbInstance */
5965 sizeof(PCIATAState),
5966 /* pfnConstruct */
5967 ataConstruct,
5968 /* pfnDestruct */
5969 ataDestruct,
5970 /* pfnRelocate */
5971 ataRelocate,
5972 /* pfnIOCtl */
5973 NULL,
5974 /* pfnPowerOn */
5975 NULL,
5976 /* pfnReset */
5977 ataReset,
5978 /* pfnSuspend */
5979 ataSuspend,
5980 /* pfnResume */
5981 ataResume,
5982 /* pfnAttach */
5983 ataAttach,
5984 /* pfnDetach */
5985 ataDetach,
5986 /* pfnQueryInterface. */
5987 NULL,
5988 /* pfnInitComplete */
5989 NULL,
5990 /* pfnPowerOff */
5991 ataPowerOff
5992};
5993#endif /* IN_RING3 */
5994#endif /* !VBOX_DEVICE_STRUCT_TESTCASE */
5995
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