VirtualBox

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

Last change on this file since 469 was 433, checked in by vboxsync, 18 years ago

Fixed IDE for OpenSolaris 10.

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