VirtualBox

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

Last change on this file since 12740 was 12740, checked in by vboxsync, 16 years ago

Don't overwrite SCSI_INQUIRY if passthrough is active. Otherwise Windows will not detect burning capabilities anymore (see #1477)

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