VirtualBox

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

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

Fixed small problem with iSCSI translation detection (returns unknown
geometry). Also fixed small problem with LBA selection for disks between
512MB and 8GB (not triggered for VDIs).

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