VirtualBox

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

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

DevATA: Added rainy day todo for MMR3HyperAllocOnceNoRel

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 223.6 KB
Line 
1/* $Id: DevATA.cpp 12586 2008-09-18 17:21:13Z 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 {
1572 /* Make sure that the real drive cannot be identified.
1573 * Motivation: changing the VM configuration should be as
1574 * invisible as possible to the guest. */
1575 Log3(("ATAPI PT inquiry data before (%d): %.*Vhxs\n", cbTransfer, cbTransfer, s->CTX_SUFF(pbIOBuffer)));
1576 ataSCSIPadStr(s->CTX_SUFF(pbIOBuffer) + 8, "VBOX", 8);
1577 ataSCSIPadStr(s->CTX_SUFF(pbIOBuffer) + 16, "CD-ROM", 16);
1578 ataSCSIPadStr(s->CTX_SUFF(pbIOBuffer) + 32, "1.0", 4);
1579 }
1580 if (cbTransfer)
1581 Log3(("ATAPI PT data read (%d): %.*Vhxs\n", cbTransfer, cbTransfer, s->CTX_SUFF(pbIOBuffer)));
1582 }
1583 s->iSourceSink = ATAFN_SS_NULL;
1584 atapiCmdOK(s);
1585 }
1586 else
1587 {
1588 if (s->cErrors < MAX_LOG_REL_ERRORS)
1589 {
1590 uint8_t u8Cmd = s->aATAPICmd[0];
1591 do
1592 {
1593 /* don't log superflous errors */
1594 if ( rc == VERR_DEV_IO_ERROR
1595 && ( u8Cmd == SCSI_TEST_UNIT_READY
1596 || u8Cmd == SCSI_READ_CAPACITY
1597 || u8Cmd == SCSI_READ_TOC_PMA_ATIP))
1598 break;
1599 s->cErrors++;
1600 LogRel(("PIIX3 ATA: LUN#%d: CD-ROM passthrough cmd=%#04x sense=%d ASC=%#02x ASCQ=%#02x %Rrc\n",
1601 s->iLUN, u8Cmd, abATAPISense[2] & 0x0f, abATAPISense[12], abATAPISense[13], rc));
1602 } while (0);
1603 }
1604 atapiCmdError(s, abATAPISense, sizeof(abATAPISense));
1605 }
1606 return false;
1607}
1608
1609
1610static bool atapiReadSectors(ATADevState *s, uint32_t iATAPILBA, uint32_t cSectors, uint32_t cbSector)
1611{
1612 Assert(cSectors > 0);
1613 s->iATAPILBA = iATAPILBA;
1614 s->cbATAPISector = cbSector;
1615 ataStartTransfer(s, cSectors * cbSector, PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_READ, true);
1616 return false;
1617}
1618
1619
1620static bool atapiReadCapacitySS(ATADevState *s)
1621{
1622 uint8_t *pbBuf = s->CTX_SUFF(pbIOBuffer);
1623
1624 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
1625 Assert(s->cbElementaryTransfer <= 8);
1626 ataH2BE_U32(pbBuf, s->cTotalSectors - 1);
1627 ataH2BE_U32(pbBuf + 4, 2048);
1628 s->iSourceSink = ATAFN_SS_NULL;
1629 atapiCmdOK(s);
1630 return false;
1631}
1632
1633
1634static bool atapiReadDiscInformationSS(ATADevState *s)
1635{
1636 uint8_t *pbBuf = s->CTX_SUFF(pbIOBuffer);
1637
1638 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
1639 Assert(s->cbElementaryTransfer <= 34);
1640 memset(pbBuf, '\0', 34);
1641 ataH2BE_U16(pbBuf, 32);
1642 pbBuf[2] = (0 << 4) | (3 << 2) | (2 << 0); /* not erasable, complete session, complete disc */
1643 pbBuf[3] = 1; /* number of first track */
1644 pbBuf[4] = 1; /* number of sessions (LSB) */
1645 pbBuf[5] = 1; /* first track number in last session (LSB) */
1646 pbBuf[6] = 1; /* last track number in last session (LSB) */
1647 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 */
1648 pbBuf[8] = 0; /* disc type = CD-ROM */
1649 pbBuf[9] = 0; /* number of sessions (MSB) */
1650 pbBuf[10] = 0; /* number of sessions (MSB) */
1651 pbBuf[11] = 0; /* number of sessions (MSB) */
1652 ataH2BE_U32(pbBuf + 16, 0x00ffffff); /* last session lead-in start time is not available */
1653 ataH2BE_U32(pbBuf + 20, 0x00ffffff); /* last possible start time for lead-out is not available */
1654 s->iSourceSink = ATAFN_SS_NULL;
1655 atapiCmdOK(s);
1656 return false;
1657}
1658
1659
1660static bool atapiReadTrackInformationSS(ATADevState *s)
1661{
1662 uint8_t *pbBuf = s->CTX_SUFF(pbIOBuffer);
1663
1664 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
1665 Assert(s->cbElementaryTransfer <= 36);
1666 /* Accept address/number type of 1 only, and only track 1 exists. */
1667 if ((s->aATAPICmd[1] & 0x03) != 1 || ataBE2H_U32(&s->aATAPICmd[2]) != 1)
1668 {
1669 atapiCmdErrorSimple(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INV_FIELD_IN_CMD_PACKET);
1670 return false;
1671 }
1672 memset(pbBuf, '\0', 36);
1673 ataH2BE_U16(pbBuf, 34);
1674 pbBuf[2] = 1; /* track number (LSB) */
1675 pbBuf[3] = 1; /* session number (LSB) */
1676 pbBuf[5] = (0 << 5) | (0 << 4) | (4 << 0); /* not damaged, primary copy, data track */
1677 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 */
1678 pbBuf[7] = (0 << 1) | (0 << 0); /* last recorded address not valid, next recordable address not valid */
1679 ataH2BE_U32(pbBuf + 8, 0); /* track start address is 0 */
1680 ataH2BE_U32(pbBuf + 24, s->cTotalSectors); /* track size */
1681 pbBuf[32] = 0; /* track number (MSB) */
1682 pbBuf[33] = 0; /* session number (MSB) */
1683 s->iSourceSink = ATAFN_SS_NULL;
1684 atapiCmdOK(s);
1685 return false;
1686}
1687
1688
1689static bool atapiGetConfigurationSS(ATADevState *s)
1690{
1691 uint8_t *pbBuf = s->CTX_SUFF(pbIOBuffer);
1692
1693 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
1694 Assert(s->cbElementaryTransfer <= 32);
1695 /* Accept valid request types only, and only starting feature 0. */
1696 if ((s->aATAPICmd[1] & 0x03) == 3 || ataBE2H_U16(&s->aATAPICmd[2]) != 0)
1697 {
1698 atapiCmdErrorSimple(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INV_FIELD_IN_CMD_PACKET);
1699 return false;
1700 }
1701 memset(pbBuf, '\0', 32);
1702 ataH2BE_U32(pbBuf, 16);
1703 /** @todo implement switching between CD-ROM and DVD-ROM profile (the only
1704 * way to differentiate them right now is based on the image size). Also
1705 * implement signalling "no current profile" if no medium is loaded. */
1706 ataH2BE_U16(pbBuf + 6, 0x08); /* current profile: read-only CD */
1707
1708 ataH2BE_U16(pbBuf + 8, 0); /* feature 0: list of profiles supported */
1709 pbBuf[10] = (0 << 2) | (1 << 1) | (1 || 0); /* version 0, persistent, current */
1710 pbBuf[11] = 8; /* additional bytes for profiles */
1711 /* The MMC-3 spec says that DVD-ROM read capability should be reported
1712 * before CD-ROM read capability. */
1713 ataH2BE_U16(pbBuf + 12, 0x10); /* profile: read-only DVD */
1714 pbBuf[14] = (0 << 0); /* NOT current profile */
1715 ataH2BE_U16(pbBuf + 16, 0x08); /* profile: read only CD */
1716 pbBuf[18] = (1 << 0); /* current profile */
1717 /* Other profiles we might want to add in the future: 0x40 (BD-ROM) and 0x50 (HDDVD-ROM) */
1718 s->iSourceSink = ATAFN_SS_NULL;
1719 atapiCmdOK(s);
1720 return false;
1721}
1722
1723
1724static bool atapiInquirySS(ATADevState *s)
1725{
1726 uint8_t *pbBuf = s->CTX_SUFF(pbIOBuffer);
1727
1728 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
1729 Assert(s->cbElementaryTransfer <= 36);
1730 pbBuf[0] = 0x05; /* CD-ROM */
1731 pbBuf[1] = 0x80; /* removable */
1732#if 1/*ndef VBOX*/ /** @todo implement MESN + AENC. (async notification on removal and stuff.) */
1733 pbBuf[2] = 0x00; /* ISO */
1734 pbBuf[3] = 0x21; /* ATAPI-2 (XXX: put ATAPI-4 ?) */
1735#else
1736 pbBuf[2] = 0x00; /* ISO */
1737 pbBuf[3] = 0x91; /* format 1, MESN=1, AENC=9 ??? */
1738#endif
1739 pbBuf[4] = 31; /* additional length */
1740 pbBuf[5] = 0; /* reserved */
1741 pbBuf[6] = 0; /* reserved */
1742 pbBuf[7] = 0; /* reserved */
1743 ataSCSIPadStr(pbBuf + 8, "VBOX", 8);
1744 ataSCSIPadStr(pbBuf + 16, "CD-ROM", 16);
1745 ataSCSIPadStr(pbBuf + 32, "1.0", 4);
1746 s->iSourceSink = ATAFN_SS_NULL;
1747 atapiCmdOK(s);
1748 return false;
1749}
1750
1751
1752static bool atapiModeSenseErrorRecoverySS(ATADevState *s)
1753{
1754 uint8_t *pbBuf = s->CTX_SUFF(pbIOBuffer);
1755
1756 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
1757 Assert(s->cbElementaryTransfer <= 16);
1758 ataH2BE_U16(&pbBuf[0], 16 + 6);
1759 pbBuf[2] = 0x70;
1760 pbBuf[3] = 0;
1761 pbBuf[4] = 0;
1762 pbBuf[5] = 0;
1763 pbBuf[6] = 0;
1764 pbBuf[7] = 0;
1765
1766 pbBuf[8] = 0x01;
1767 pbBuf[9] = 0x06;
1768 pbBuf[10] = 0x00;
1769 pbBuf[11] = 0x05;
1770 pbBuf[12] = 0x00;
1771 pbBuf[13] = 0x00;
1772 pbBuf[14] = 0x00;
1773 pbBuf[15] = 0x00;
1774 s->iSourceSink = ATAFN_SS_NULL;
1775 atapiCmdOK(s);
1776 return false;
1777}
1778
1779
1780static bool atapiModeSenseCDStatusSS(ATADevState *s)
1781{
1782 uint8_t *pbBuf = s->CTX_SUFF(pbIOBuffer);
1783
1784 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
1785 Assert(s->cbElementaryTransfer <= 40);
1786 ataH2BE_U16(&pbBuf[0], 38);
1787 pbBuf[2] = 0x70;
1788 pbBuf[3] = 0;
1789 pbBuf[4] = 0;
1790 pbBuf[5] = 0;
1791 pbBuf[6] = 0;
1792 pbBuf[7] = 0;
1793
1794 pbBuf[8] = 0x2a;
1795 pbBuf[9] = 30; /* page length */
1796 pbBuf[10] = 0x08; /* DVD-ROM read support */
1797 pbBuf[11] = 0x00; /* no write support */
1798 /* The following claims we support audio play. This is obviously false,
1799 * but the Linux generic CDROM support makes many features depend on this
1800 * capability. If it's not set, this causes many things to be disabled. */
1801 pbBuf[12] = 0x71; /* multisession support, mode 2 form 1/2 support, audio play */
1802 pbBuf[13] = 0x00; /* no subchannel reads supported */
1803 pbBuf[14] = (1 << 0) | (1 << 3) | (1 << 5); /* lock supported, eject supported, tray type loading mechanism */
1804 if (s->pDrvMount->pfnIsLocked(s->pDrvMount))
1805 pbBuf[14] |= 1 << 1; /* report lock state */
1806 pbBuf[15] = 0; /* no subchannel reads supported, no separate audio volume control, no changer etc. */
1807 ataH2BE_U16(&pbBuf[16], 5632); /* (obsolete) claim 32x speed support */
1808 ataH2BE_U16(&pbBuf[18], 2); /* number of audio volume levels */
1809 ataH2BE_U16(&pbBuf[20], s->cbIOBuffer / _1K); /* buffer size supported in Kbyte */
1810 ataH2BE_U16(&pbBuf[22], 5632); /* (obsolete) current read speed 32x */
1811 pbBuf[24] = 0; /* reserved */
1812 pbBuf[25] = 0; /* reserved for digital audio (see idx 15) */
1813 ataH2BE_U16(&pbBuf[26], 0); /* (obsolete) maximum write speed */
1814 ataH2BE_U16(&pbBuf[28], 0); /* (obsolete) current write speed */
1815 ataH2BE_U16(&pbBuf[30], 0); /* copy management revision supported 0=no CSS */
1816 pbBuf[32] = 0; /* reserved */
1817 pbBuf[33] = 0; /* reserved */
1818 pbBuf[34] = 0; /* reserved */
1819 pbBuf[35] = 1; /* rotation control CAV */
1820 ataH2BE_U16(&pbBuf[36], 0); /* current write speed */
1821 ataH2BE_U16(&pbBuf[38], 0); /* number of write speed performance descriptors */
1822 s->iSourceSink = ATAFN_SS_NULL;
1823 atapiCmdOK(s);
1824 return false;
1825}
1826
1827
1828static bool atapiRequestSenseSS(ATADevState *s)
1829{
1830 uint8_t *pbBuf = s->CTX_SUFF(pbIOBuffer);
1831
1832 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
1833 memset(pbBuf, '\0', s->cbElementaryTransfer);
1834 memcpy(pbBuf, s->abATAPISense, RT_MIN(s->cbElementaryTransfer, sizeof(s->abATAPISense)));
1835 s->iSourceSink = ATAFN_SS_NULL;
1836 atapiCmdOK(s);
1837 return false;
1838}
1839
1840
1841static bool atapiMechanismStatusSS(ATADevState *s)
1842{
1843 uint8_t *pbBuf = s->CTX_SUFF(pbIOBuffer);
1844
1845 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
1846 Assert(s->cbElementaryTransfer <= 8);
1847 ataH2BE_U16(pbBuf, 0);
1848 /* no current LBA */
1849 pbBuf[2] = 0;
1850 pbBuf[3] = 0;
1851 pbBuf[4] = 0;
1852 pbBuf[5] = 1;
1853 ataH2BE_U16(pbBuf + 6, 0);
1854 s->iSourceSink = ATAFN_SS_NULL;
1855 atapiCmdOK(s);
1856 return false;
1857}
1858
1859
1860static bool atapiReadTOCNormalSS(ATADevState *s)
1861{
1862 uint8_t *pbBuf = s->CTX_SUFF(pbIOBuffer), *q, iStartTrack;
1863 bool fMSF;
1864 uint32_t cbSize;
1865
1866 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
1867 fMSF = (s->aATAPICmd[1] >> 1) & 1;
1868 iStartTrack = s->aATAPICmd[6];
1869 if (iStartTrack > 1 && iStartTrack != 0xaa)
1870 {
1871 atapiCmdErrorSimple(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INV_FIELD_IN_CMD_PACKET);
1872 return false;
1873 }
1874 q = pbBuf + 2;
1875 *q++ = 1; /* first session */
1876 *q++ = 1; /* last session */
1877 if (iStartTrack <= 1)
1878 {
1879 *q++ = 0; /* reserved */
1880 *q++ = 0x14; /* ADR, control */
1881 *q++ = 1; /* track number */
1882 *q++ = 0; /* reserved */
1883 if (fMSF)
1884 {
1885 *q++ = 0; /* reserved */
1886 ataLBA2MSF(q, 0);
1887 q += 3;
1888 }
1889 else
1890 {
1891 /* sector 0 */
1892 ataH2BE_U32(q, 0);
1893 q += 4;
1894 }
1895 }
1896 /* lead out track */
1897 *q++ = 0; /* reserved */
1898 *q++ = 0x14; /* ADR, control */
1899 *q++ = 0xaa; /* track number */
1900 *q++ = 0; /* reserved */
1901 if (fMSF)
1902 {
1903 *q++ = 0; /* reserved */
1904 ataLBA2MSF(q, s->cTotalSectors);
1905 q += 3;
1906 }
1907 else
1908 {
1909 ataH2BE_U32(q, s->cTotalSectors);
1910 q += 4;
1911 }
1912 cbSize = q - pbBuf;
1913 ataH2BE_U16(pbBuf, cbSize - 2);
1914 if (cbSize < s->cbTotalTransfer)
1915 s->cbTotalTransfer = cbSize;
1916 s->iSourceSink = ATAFN_SS_NULL;
1917 atapiCmdOK(s);
1918 return false;
1919}
1920
1921
1922static bool atapiReadTOCMultiSS(ATADevState *s)
1923{
1924 uint8_t *pbBuf = s->CTX_SUFF(pbIOBuffer);
1925 bool fMSF;
1926
1927 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
1928 Assert(s->cbElementaryTransfer <= 12);
1929 fMSF = (s->aATAPICmd[1] >> 1) & 1;
1930 /* multi session: only a single session defined */
1931/** @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. */
1932 memset(pbBuf, 0, 12);
1933 pbBuf[1] = 0x0a;
1934 pbBuf[2] = 0x01;
1935 pbBuf[3] = 0x01;
1936 pbBuf[5] = 0x14; /* ADR, control */
1937 pbBuf[6] = 1; /* first track in last complete session */
1938 if (fMSF)
1939 {
1940 pbBuf[8] = 0; /* reserved */
1941 ataLBA2MSF(&pbBuf[9], 0);
1942 }
1943 else
1944 {
1945 /* sector 0 */
1946 ataH2BE_U32(pbBuf + 8, 0);
1947 }
1948 s->iSourceSink = ATAFN_SS_NULL;
1949 atapiCmdOK(s);
1950 return false;
1951}
1952
1953
1954static bool atapiReadTOCRawSS(ATADevState *s)
1955{
1956 uint8_t *pbBuf = s->CTX_SUFF(pbIOBuffer), *q, iStartTrack;
1957 bool fMSF;
1958 uint32_t cbSize;
1959
1960 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
1961 fMSF = (s->aATAPICmd[1] >> 1) & 1;
1962 iStartTrack = s->aATAPICmd[6];
1963
1964 q = pbBuf + 2;
1965 *q++ = 1; /* first session */
1966 *q++ = 1; /* last session */
1967
1968 *q++ = 1; /* session number */
1969 *q++ = 0x14; /* data track */
1970 *q++ = 0; /* track number */
1971 *q++ = 0xa0; /* first track in program area */
1972 *q++ = 0; /* min */
1973 *q++ = 0; /* sec */
1974 *q++ = 0; /* frame */
1975 *q++ = 0;
1976 *q++ = 1; /* first track */
1977 *q++ = 0x00; /* disk type CD-DA or CD data */
1978 *q++ = 0;
1979
1980 *q++ = 1; /* session number */
1981 *q++ = 0x14; /* data track */
1982 *q++ = 0; /* track number */
1983 *q++ = 0xa1; /* last track in program area */
1984 *q++ = 0; /* min */
1985 *q++ = 0; /* sec */
1986 *q++ = 0; /* frame */
1987 *q++ = 0;
1988 *q++ = 1; /* last track */
1989 *q++ = 0;
1990 *q++ = 0;
1991
1992 *q++ = 1; /* session number */
1993 *q++ = 0x14; /* data track */
1994 *q++ = 0; /* track number */
1995 *q++ = 0xa2; /* lead-out */
1996 *q++ = 0; /* min */
1997 *q++ = 0; /* sec */
1998 *q++ = 0; /* frame */
1999 if (fMSF)
2000 {
2001 *q++ = 0; /* reserved */
2002 ataLBA2MSF(q, s->cTotalSectors);
2003 q += 3;
2004 }
2005 else
2006 {
2007 ataH2BE_U32(q, s->cTotalSectors);
2008 q += 4;
2009 }
2010
2011 *q++ = 1; /* session number */
2012 *q++ = 0x14; /* ADR, control */
2013 *q++ = 0; /* track number */
2014 *q++ = 1; /* point */
2015 *q++ = 0; /* min */
2016 *q++ = 0; /* sec */
2017 *q++ = 0; /* frame */
2018 if (fMSF)
2019 {
2020 *q++ = 0; /* reserved */
2021 ataLBA2MSF(q, 0);
2022 q += 3;
2023 }
2024 else
2025 {
2026 /* sector 0 */
2027 ataH2BE_U32(q, 0);
2028 q += 4;
2029 }
2030
2031 cbSize = q - pbBuf;
2032 ataH2BE_U16(pbBuf, cbSize - 2);
2033 if (cbSize < s->cbTotalTransfer)
2034 s->cbTotalTransfer = cbSize;
2035 s->iSourceSink = ATAFN_SS_NULL;
2036 atapiCmdOK(s);
2037 return false;
2038}
2039
2040
2041static void atapiParseCmdVirtualATAPI(ATADevState *s)
2042{
2043 const uint8_t *pbPacket;
2044 uint8_t *pbBuf;
2045 uint32_t cbMax;
2046
2047 pbPacket = s->aATAPICmd;
2048 pbBuf = s->CTX_SUFF(pbIOBuffer);
2049 switch (pbPacket[0])
2050 {
2051 case SCSI_TEST_UNIT_READY:
2052 if (s->cNotifiedMediaChange > 0)
2053 {
2054 if (s->cNotifiedMediaChange-- > 2)
2055 atapiCmdErrorSimple(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
2056 else
2057 atapiCmdErrorSimple(s, SCSI_SENSE_UNIT_ATTENTION, SCSI_ASC_MEDIUM_MAY_HAVE_CHANGED); /* media changed */
2058 }
2059 else if (s->pDrvMount->pfnIsMounted(s->pDrvMount))
2060 atapiCmdOK(s);
2061 else
2062 atapiCmdErrorSimple(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
2063 break;
2064 case SCSI_MODE_SENSE_10:
2065 {
2066 uint8_t uPageControl, uPageCode;
2067 cbMax = ataBE2H_U16(pbPacket + 7);
2068 uPageControl = pbPacket[2] >> 6;
2069 uPageCode = pbPacket[2] & 0x3f;
2070 switch (uPageControl)
2071 {
2072 case SCSI_PAGECONTROL_CURRENT:
2073 switch (uPageCode)
2074 {
2075 case SCSI_MODEPAGE_ERROR_RECOVERY:
2076 ataStartTransfer(s, RT_MIN(cbMax, 16), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_MODE_SENSE_ERROR_RECOVERY, true);
2077 break;
2078 case SCSI_MODEPAGE_CD_STATUS:
2079 ataStartTransfer(s, RT_MIN(cbMax, 40), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_MODE_SENSE_CD_STATUS, true);
2080 break;
2081 default:
2082 goto error_cmd;
2083 }
2084 break;
2085 case SCSI_PAGECONTROL_CHANGEABLE:
2086 goto error_cmd;
2087 case SCSI_PAGECONTROL_DEFAULT:
2088 goto error_cmd;
2089 default:
2090 case SCSI_PAGECONTROL_SAVED:
2091 atapiCmdErrorSimple(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_SAVING_PARAMETERS_NOT_SUPPORTED);
2092 break;
2093 }
2094 }
2095 break;
2096 case SCSI_REQUEST_SENSE:
2097 cbMax = pbPacket[4];
2098 ataStartTransfer(s, RT_MIN(cbMax, 18), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_REQUEST_SENSE, true);
2099 break;
2100 case SCSI_PREVENT_ALLOW_MEDIUM_REMOVAL:
2101 if (s->pDrvMount->pfnIsMounted(s->pDrvMount))
2102 {
2103 if (pbPacket[4] & 1)
2104 s->pDrvMount->pfnLock(s->pDrvMount);
2105 else
2106 s->pDrvMount->pfnUnlock(s->pDrvMount);
2107 atapiCmdOK(s);
2108 }
2109 else
2110 atapiCmdErrorSimple(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
2111 break;
2112 case SCSI_READ_10:
2113 case SCSI_READ_12:
2114 {
2115 uint32_t cSectors, iATAPILBA;
2116
2117 if (s->cNotifiedMediaChange > 0)
2118 {
2119 s->cNotifiedMediaChange-- ;
2120 atapiCmdErrorSimple(s, SCSI_SENSE_UNIT_ATTENTION, SCSI_ASC_MEDIUM_MAY_HAVE_CHANGED); /* media changed */
2121 break;
2122 }
2123 else if (!s->pDrvMount->pfnIsMounted(s->pDrvMount))
2124 {
2125 atapiCmdErrorSimple(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
2126 break;
2127 }
2128 if (pbPacket[0] == SCSI_READ_10)
2129 cSectors = ataBE2H_U16(pbPacket + 7);
2130 else
2131 cSectors = ataBE2H_U32(pbPacket + 6);
2132 iATAPILBA = ataBE2H_U32(pbPacket + 2);
2133 if (cSectors == 0)
2134 {
2135 atapiCmdOK(s);
2136 break;
2137 }
2138 if ((uint64_t)iATAPILBA + cSectors > s->cTotalSectors)
2139 {
2140 /* Rate limited logging, one log line per second. For
2141 * guests that insist on reading from places outside the
2142 * valid area this often generates too many release log
2143 * entries otherwise. */
2144 static uint64_t uLastLogTS = 0;
2145 if (RTTimeMilliTS() >= uLastLogTS + 1000)
2146 {
2147 LogRel(("PIIX3 ATA: LUN#%d: CD-ROM block number %Ld invalid (READ)\n", s->iLUN, (uint64_t)iATAPILBA + cSectors));
2148 uLastLogTS = RTTimeMilliTS();
2149 }
2150 atapiCmdErrorSimple(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_LOGICAL_BLOCK_OOR);
2151 break;
2152 }
2153 atapiReadSectors(s, iATAPILBA, cSectors, 2048);
2154 }
2155 break;
2156 case SCSI_READ_CD:
2157 {
2158 uint32_t cSectors, iATAPILBA;
2159
2160 if (s->cNotifiedMediaChange > 0)
2161 {
2162 s->cNotifiedMediaChange-- ;
2163 atapiCmdErrorSimple(s, SCSI_SENSE_UNIT_ATTENTION, SCSI_ASC_MEDIUM_MAY_HAVE_CHANGED); /* media changed */
2164 break;
2165 }
2166 else if (!s->pDrvMount->pfnIsMounted(s->pDrvMount))
2167 {
2168 atapiCmdErrorSimple(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
2169 break;
2170 }
2171 cSectors = (pbPacket[6] << 16) | (pbPacket[7] << 8) | pbPacket[8];
2172 iATAPILBA = ataBE2H_U32(pbPacket + 2);
2173 if (cSectors == 0)
2174 {
2175 atapiCmdOK(s);
2176 break;
2177 }
2178 if ((uint64_t)iATAPILBA + cSectors > s->cTotalSectors)
2179 {
2180 /* Rate limited logging, one log line per second. For
2181 * guests that insist on reading from places outside the
2182 * valid area this often generates too many release log
2183 * entries otherwise. */
2184 static uint64_t uLastLogTS = 0;
2185 if (RTTimeMilliTS() >= uLastLogTS + 1000)
2186 {
2187 LogRel(("PIIX3 ATA: LUN#%d: CD-ROM block number %Ld invalid (READ CD)\n", s->iLUN, (uint64_t)iATAPILBA + cSectors));
2188 uLastLogTS = RTTimeMilliTS();
2189 }
2190 atapiCmdErrorSimple(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_LOGICAL_BLOCK_OOR);
2191 break;
2192 }
2193 switch (pbPacket[9] & 0xf8)
2194 {
2195 case 0x00:
2196 /* nothing */
2197 atapiCmdOK(s);
2198 break;
2199 case 0x10:
2200 /* normal read */
2201 atapiReadSectors(s, iATAPILBA, cSectors, 2048);
2202 break;
2203 case 0xf8:
2204 /* read all data */
2205 atapiReadSectors(s, iATAPILBA, cSectors, 2352);
2206 break;
2207 default:
2208 LogRel(("PIIX3 ATA: LUN#%d: CD-ROM sector format not supported\n", s->iLUN));
2209 atapiCmdErrorSimple(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INV_FIELD_IN_CMD_PACKET);
2210 break;
2211 }
2212 }
2213 break;
2214 case SCSI_SEEK_10:
2215 {
2216 uint32_t iATAPILBA;
2217 if (s->cNotifiedMediaChange > 0)
2218 {
2219 s->cNotifiedMediaChange-- ;
2220 atapiCmdErrorSimple(s, SCSI_SENSE_UNIT_ATTENTION, SCSI_ASC_MEDIUM_MAY_HAVE_CHANGED); /* media changed */
2221 break;
2222 }
2223 else if (!s->pDrvMount->pfnIsMounted(s->pDrvMount))
2224 {
2225 atapiCmdErrorSimple(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
2226 break;
2227 }
2228 iATAPILBA = ataBE2H_U32(pbPacket + 2);
2229 if (iATAPILBA > s->cTotalSectors)
2230 {
2231 /* Rate limited logging, one log line per second. For
2232 * guests that insist on seeking to places outside the
2233 * valid area this often generates too many release log
2234 * entries otherwise. */
2235 static uint64_t uLastLogTS = 0;
2236 if (RTTimeMilliTS() >= uLastLogTS + 1000)
2237 {
2238 LogRel(("PIIX3 ATA: LUN#%d: CD-ROM block number %Ld invalid (SEEK)\n", s->iLUN, (uint64_t)iATAPILBA));
2239 uLastLogTS = RTTimeMilliTS();
2240 }
2241 atapiCmdErrorSimple(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_LOGICAL_BLOCK_OOR);
2242 break;
2243 }
2244 atapiCmdOK(s);
2245 ataSetStatus(s, ATA_STAT_SEEK); /* Linux expects this. */
2246 }
2247 break;
2248 case SCSI_START_STOP_UNIT:
2249 {
2250 int rc = VINF_SUCCESS;
2251 switch (pbPacket[4] & 3)
2252 {
2253 case 0: /* 00 - Stop motor */
2254 case 1: /* 01 - Start motor */
2255 break;
2256 case 2: /* 10 - Eject media */
2257 /* This must be done from EMT. */
2258 {
2259 PATACONTROLLER pCtl = ATADEVSTATE_2_CONTROLLER(s);
2260 PPDMDEVINS pDevIns = ATADEVSTATE_2_DEVINS(s);
2261 PVMREQ pReq;
2262
2263 PDMCritSectLeave(&pCtl->lock);
2264 rc = VMR3ReqCall(PDMDevHlpGetVM(pDevIns), &pReq, RT_INDEFINITE_WAIT,
2265 (PFNRT)s->pDrvMount->pfnUnmount, 2, s->pDrvMount, false);
2266 AssertReleaseRC(rc);
2267 VMR3ReqFree(pReq);
2268 {
2269 STAM_PROFILE_START(&pCtl->StatLockWait, a);
2270 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
2271 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
2272 }
2273 }
2274 break;
2275 case 3: /* 11 - Load media */
2276 /** @todo rc = s->pDrvMount->pfnLoadMedia(s->pDrvMount) */
2277 break;
2278 }
2279 if (RT_SUCCESS(rc))
2280 atapiCmdOK(s);
2281 else
2282 atapiCmdErrorSimple(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIA_LOAD_OR_EJECT_FAILED);
2283 }
2284 break;
2285 case SCSI_MECHANISM_STATUS:
2286 {
2287 cbMax = ataBE2H_U16(pbPacket + 8);
2288 ataStartTransfer(s, RT_MIN(cbMax, 8), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_MECHANISM_STATUS, true);
2289 }
2290 break;
2291 case SCSI_READ_TOC_PMA_ATIP:
2292 {
2293 uint8_t format;
2294
2295 if (s->cNotifiedMediaChange > 0)
2296 {
2297 s->cNotifiedMediaChange-- ;
2298 atapiCmdErrorSimple(s, SCSI_SENSE_UNIT_ATTENTION, SCSI_ASC_MEDIUM_MAY_HAVE_CHANGED); /* media changed */
2299 break;
2300 }
2301 else if (!s->pDrvMount->pfnIsMounted(s->pDrvMount))
2302 {
2303 atapiCmdErrorSimple(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
2304 break;
2305 }
2306 cbMax = ataBE2H_U16(pbPacket + 7);
2307 /* SCSI MMC-3 spec says format is at offset 2 (lower 4 bits),
2308 * but Linux kernel uses offset 9 (topmost 2 bits). Hope that
2309 * the other field is clear... */
2310 format = (pbPacket[2] & 0xf) | (pbPacket[9] >> 6);
2311 switch (format)
2312 {
2313 case 0:
2314 ataStartTransfer(s, cbMax, PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_READ_TOC_NORMAL, true);
2315 break;
2316 case 1:
2317 ataStartTransfer(s, RT_MIN(cbMax, 12), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_READ_TOC_MULTI, true);
2318 break;
2319 case 2:
2320 ataStartTransfer(s, cbMax, PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_READ_TOC_RAW, true);
2321 break;
2322 default:
2323 error_cmd:
2324 atapiCmdErrorSimple(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INV_FIELD_IN_CMD_PACKET);
2325 break;
2326 }
2327 }
2328 break;
2329 case SCSI_READ_CAPACITY:
2330 if (s->cNotifiedMediaChange > 0)
2331 {
2332 s->cNotifiedMediaChange-- ;
2333 atapiCmdErrorSimple(s, SCSI_SENSE_UNIT_ATTENTION, SCSI_ASC_MEDIUM_MAY_HAVE_CHANGED); /* media changed */
2334 break;
2335 }
2336 else if (!s->pDrvMount->pfnIsMounted(s->pDrvMount))
2337 {
2338 atapiCmdErrorSimple(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
2339 break;
2340 }
2341 ataStartTransfer(s, 8, PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_READ_CAPACITY, true);
2342 break;
2343 case SCSI_READ_DISC_INFORMATION:
2344 if (s->cNotifiedMediaChange > 0)
2345 {
2346 s->cNotifiedMediaChange-- ;
2347 atapiCmdErrorSimple(s, SCSI_SENSE_UNIT_ATTENTION, SCSI_ASC_MEDIUM_MAY_HAVE_CHANGED); /* media changed */
2348 break;
2349 }
2350 else if (!s->pDrvMount->pfnIsMounted(s->pDrvMount))
2351 {
2352 atapiCmdErrorSimple(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
2353 break;
2354 }
2355 cbMax = ataBE2H_U16(pbPacket + 7);
2356 ataStartTransfer(s, RT_MIN(cbMax, 34), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_READ_DISC_INFORMATION, true);
2357 break;
2358 case SCSI_READ_TRACK_INFORMATION:
2359 if (s->cNotifiedMediaChange > 0)
2360 {
2361 s->cNotifiedMediaChange-- ;
2362 atapiCmdErrorSimple(s, SCSI_SENSE_UNIT_ATTENTION, SCSI_ASC_MEDIUM_MAY_HAVE_CHANGED); /* media changed */
2363 break;
2364 }
2365 else if (!s->pDrvMount->pfnIsMounted(s->pDrvMount))
2366 {
2367 atapiCmdErrorSimple(s, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT);
2368 break;
2369 }
2370 cbMax = ataBE2H_U16(pbPacket + 7);
2371 ataStartTransfer(s, RT_MIN(cbMax, 36), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_READ_TRACK_INFORMATION, true);
2372 break;
2373 case SCSI_GET_CONFIGURATION:
2374 /* No media change stuff here, it can confuse Linux guests. */
2375 cbMax = ataBE2H_U16(pbPacket + 7);
2376 ataStartTransfer(s, RT_MIN(cbMax, 32), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_GET_CONFIGURATION, true);
2377 break;
2378 case SCSI_INQUIRY:
2379 cbMax = pbPacket[4];
2380 ataStartTransfer(s, RT_MIN(cbMax, 36), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_INQUIRY, true);
2381 break;
2382 default:
2383 atapiCmdErrorSimple(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_ILLEGAL_OPCODE);
2384 break;
2385 }
2386}
2387
2388
2389/*
2390 * Parse ATAPI commands, passing them directly to the CD/DVD drive.
2391 */
2392static void atapiParseCmdPassthrough(ATADevState *s)
2393{
2394 const uint8_t *pbPacket;
2395 uint8_t *pbBuf;
2396 uint32_t cSectors, iATAPILBA;
2397 uint32_t cbTransfer = 0;
2398 PDMBLOCKTXDIR uTxDir = PDMBLOCKTXDIR_NONE;
2399
2400 pbPacket = s->aATAPICmd;
2401 pbBuf = s->CTX_SUFF(pbIOBuffer);
2402 switch (pbPacket[0])
2403 {
2404 case SCSI_BLANK:
2405 goto sendcmd;
2406 case SCSI_CLOSE_TRACK_SESSION:
2407 goto sendcmd;
2408 case SCSI_ERASE_10:
2409 iATAPILBA = ataBE2H_U32(pbPacket + 2);
2410 cbTransfer = ataBE2H_U16(pbPacket + 7);
2411 Log2(("ATAPI PT: lba %d\n", iATAPILBA));
2412 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
2413 goto sendcmd;
2414 case SCSI_FORMAT_UNIT:
2415 cbTransfer = s->uATARegLCyl | (s->uATARegHCyl << 8); /* use ATAPI transfer length */
2416 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
2417 goto sendcmd;
2418 case SCSI_GET_CONFIGURATION:
2419 cbTransfer = ataBE2H_U16(pbPacket + 7);
2420 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2421 goto sendcmd;
2422 case SCSI_GET_EVENT_STATUS_NOTIFICATION:
2423 cbTransfer = ataBE2H_U16(pbPacket + 7);
2424 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2425 goto sendcmd;
2426 case SCSI_GET_PERFORMANCE:
2427 cbTransfer = s->uATARegLCyl | (s->uATARegHCyl << 8); /* use ATAPI transfer length */
2428 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2429 goto sendcmd;
2430 case SCSI_INQUIRY:
2431 cbTransfer = pbPacket[4];
2432 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2433 goto sendcmd;
2434 case SCSI_LOAD_UNLOAD_MEDIUM:
2435 goto sendcmd;
2436 case SCSI_MECHANISM_STATUS:
2437 cbTransfer = ataBE2H_U16(pbPacket + 8);
2438 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2439 goto sendcmd;
2440 case SCSI_MODE_SELECT_10:
2441 cbTransfer = ataBE2H_U16(pbPacket + 7);
2442 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
2443 goto sendcmd;
2444 case SCSI_MODE_SENSE_10:
2445 cbTransfer = ataBE2H_U16(pbPacket + 7);
2446 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2447 goto sendcmd;
2448 case SCSI_PAUSE_RESUME:
2449 goto sendcmd;
2450 case SCSI_PLAY_AUDIO_10:
2451 goto sendcmd;
2452 case SCSI_PLAY_AUDIO_12:
2453 goto sendcmd;
2454 case SCSI_PLAY_AUDIO_MSF:
2455 goto sendcmd;
2456 case SCSI_PREVENT_ALLOW_MEDIUM_REMOVAL:
2457 /** @todo do not forget to unlock when a VM is shut down */
2458 goto sendcmd;
2459 case SCSI_READ_10:
2460 iATAPILBA = ataBE2H_U32(pbPacket + 2);
2461 cSectors = ataBE2H_U16(pbPacket + 7);
2462 Log2(("ATAPI PT: lba %d sectors %d\n", iATAPILBA, cSectors));
2463 s->cbATAPISector = 2048; /**< @todo this size is not always correct */
2464 cbTransfer = cSectors * s->cbATAPISector;
2465 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2466 goto sendcmd;
2467 case SCSI_READ_12:
2468 iATAPILBA = ataBE2H_U32(pbPacket + 2);
2469 cSectors = ataBE2H_U32(pbPacket + 6);
2470 Log2(("ATAPI PT: lba %d sectors %d\n", iATAPILBA, cSectors));
2471 s->cbATAPISector = 2048; /**< @todo this size is not always correct */
2472 cbTransfer = cSectors * s->cbATAPISector;
2473 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2474 goto sendcmd;
2475 case SCSI_READ_BUFFER:
2476 cbTransfer = ataBE2H_U24(pbPacket + 6);
2477 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2478 goto sendcmd;
2479 case SCSI_READ_BUFFER_CAPACITY:
2480 cbTransfer = ataBE2H_U16(pbPacket + 7);
2481 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2482 goto sendcmd;
2483 case SCSI_READ_CAPACITY:
2484 cbTransfer = 8;
2485 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2486 goto sendcmd;
2487 case SCSI_READ_CD:
2488 s->cbATAPISector = 2048; /**< @todo this size is not always correct */
2489 cbTransfer = ataBE2H_U24(pbPacket + 6) / s->cbATAPISector * s->cbATAPISector;
2490 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2491 goto sendcmd;
2492 case SCSI_READ_CD_MSF:
2493 cSectors = ataMSF2LBA(pbPacket + 6) - ataMSF2LBA(pbPacket + 3);
2494 if (cSectors > 32)
2495 cSectors = 32; /* Limit transfer size to 64~74K. Safety first. In any case this can only harm software doing CDDA extraction. */
2496 s->cbATAPISector = 2048; /**< @todo this size is not always correct */
2497 cbTransfer = cSectors * s->cbATAPISector;
2498 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2499 goto sendcmd;
2500 case SCSI_READ_DISC_INFORMATION:
2501 cbTransfer = ataBE2H_U16(pbPacket + 7);
2502 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2503 goto sendcmd;
2504 case SCSI_READ_DVD_STRUCTURE:
2505 cbTransfer = ataBE2H_U16(pbPacket + 8);
2506 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2507 goto sendcmd;
2508 case SCSI_READ_FORMAT_CAPACITIES:
2509 cbTransfer = ataBE2H_U16(pbPacket + 7);
2510 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2511 goto sendcmd;
2512 case SCSI_READ_SUBCHANNEL:
2513 cbTransfer = ataBE2H_U16(pbPacket + 7);
2514 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2515 goto sendcmd;
2516 case SCSI_READ_TOC_PMA_ATIP:
2517 cbTransfer = ataBE2H_U16(pbPacket + 7);
2518 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2519 goto sendcmd;
2520 case SCSI_READ_TRACK_INFORMATION:
2521 cbTransfer = ataBE2H_U16(pbPacket + 7);
2522 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2523 goto sendcmd;
2524 case SCSI_REPAIR_TRACK:
2525 goto sendcmd;
2526 case SCSI_REPORT_KEY:
2527 cbTransfer = ataBE2H_U16(pbPacket + 8);
2528 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2529 goto sendcmd;
2530 case SCSI_REQUEST_SENSE:
2531 cbTransfer = pbPacket[4];
2532 if ((s->abATAPISense[2] & 0x0f) != SCSI_SENSE_NONE)
2533 {
2534 ataStartTransfer(s, RT_MIN(cbTransfer, 18), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_REQUEST_SENSE, true);
2535 break;
2536 }
2537 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2538 goto sendcmd;
2539 case SCSI_RESERVE_TRACK:
2540 goto sendcmd;
2541 case SCSI_SCAN:
2542 goto sendcmd;
2543 case SCSI_SEEK_10:
2544 goto sendcmd;
2545 case SCSI_SEND_CUE_SHEET:
2546 cbTransfer = ataBE2H_U24(pbPacket + 6);
2547 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
2548 goto sendcmd;
2549 case SCSI_SEND_DVD_STRUCTURE:
2550 cbTransfer = ataBE2H_U16(pbPacket + 8);
2551 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
2552 goto sendcmd;
2553 case SCSI_SEND_EVENT:
2554 cbTransfer = ataBE2H_U16(pbPacket + 8);
2555 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
2556 goto sendcmd;
2557 case SCSI_SEND_KEY:
2558 cbTransfer = ataBE2H_U16(pbPacket + 8);
2559 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
2560 goto sendcmd;
2561 case SCSI_SEND_OPC_INFORMATION:
2562 cbTransfer = ataBE2H_U16(pbPacket + 7);
2563 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
2564 goto sendcmd;
2565 case SCSI_SET_CD_SPEED:
2566 goto sendcmd;
2567 case SCSI_SET_READ_AHEAD:
2568 goto sendcmd;
2569 case SCSI_SET_STREAMING:
2570 cbTransfer = ataBE2H_U16(pbPacket + 9);
2571 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
2572 goto sendcmd;
2573 case SCSI_START_STOP_UNIT:
2574 goto sendcmd;
2575 case SCSI_STOP_PLAY_SCAN:
2576 goto sendcmd;
2577 case SCSI_SYNCHRONIZE_CACHE:
2578 goto sendcmd;
2579 case SCSI_TEST_UNIT_READY:
2580 goto sendcmd;
2581 case SCSI_VERIFY_10:
2582 goto sendcmd;
2583 case SCSI_WRITE_10:
2584 iATAPILBA = ataBE2H_U32(pbPacket + 2);
2585 cSectors = ataBE2H_U16(pbPacket + 7);
2586 Log2(("ATAPI PT: lba %d sectors %d\n", iATAPILBA, cSectors));
2587#if 0
2588 /* The sector size is determined by the async I/O thread. */
2589 s->cbATAPISector = 0;
2590 /* Preliminary, will be corrected once the sector size is known. */
2591 cbTransfer = cSectors;
2592#else
2593 s->cbATAPISector = 2048; /**< @todo this size is not always correct */
2594 cbTransfer = cSectors * s->cbATAPISector;
2595#endif
2596 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
2597 goto sendcmd;
2598 case SCSI_WRITE_12:
2599 iATAPILBA = ataBE2H_U32(pbPacket + 2);
2600 cSectors = ataBE2H_U32(pbPacket + 6);
2601 Log2(("ATAPI PT: lba %d sectors %d\n", iATAPILBA, cSectors));
2602#if 0
2603 /* The sector size is determined by the async I/O thread. */
2604 s->cbATAPISector = 0;
2605 /* Preliminary, will be corrected once the sector size is known. */
2606 cbTransfer = cSectors;
2607#else
2608 s->cbATAPISector = 2048; /**< @todo this size is not always correct */
2609 cbTransfer = cSectors * s->cbATAPISector;
2610#endif
2611 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
2612 goto sendcmd;
2613 case SCSI_WRITE_AND_VERIFY_10:
2614 iATAPILBA = ataBE2H_U32(pbPacket + 2);
2615 cSectors = ataBE2H_U16(pbPacket + 7);
2616 Log2(("ATAPI PT: lba %d sectors %d\n", iATAPILBA, cSectors));
2617 /* The sector size is determined by the async I/O thread. */
2618 s->cbATAPISector = 0;
2619 /* Preliminary, will be corrected once the sector size is known. */
2620 cbTransfer = cSectors;
2621 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
2622 goto sendcmd;
2623 case SCSI_WRITE_BUFFER:
2624 switch (pbPacket[1] & 0x1f)
2625 {
2626 case 0x04: /* download microcode */
2627 case 0x05: /* download microcode and save */
2628 case 0x06: /* download microcode with offsets */
2629 case 0x07: /* download microcode with offsets and save */
2630 case 0x0e: /* download microcode with offsets and defer activation */
2631 case 0x0f: /* activate deferred microcode */
2632 LogRel(("PIIX3 ATA: LUN#%d: CD-ROM passthrough command attempted to update firmware, blocked\n", s->iLUN));
2633 atapiCmdErrorSimple(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INV_FIELD_IN_CMD_PACKET);
2634 break;
2635 default:
2636 cbTransfer = ataBE2H_U16(pbPacket + 6);
2637 uTxDir = PDMBLOCKTXDIR_TO_DEVICE;
2638 goto sendcmd;
2639 }
2640 break;
2641 case SCSI_REPORT_LUNS: /* Not part of MMC-3, but used by Windows. */
2642 cbTransfer = ataBE2H_U32(pbPacket + 6);
2643 uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
2644 goto sendcmd;
2645 case SCSI_REZERO_UNIT:
2646 /* Obsolete command used by cdrecord. What else would one expect?
2647 * This command is not sent to the drive, it is handled internally,
2648 * as the Linux kernel doesn't like it (message "scsi: unknown
2649 * opcode 0x01" in syslog) and replies with a sense code of 0,
2650 * which sends cdrecord to an endless loop. */
2651 atapiCmdErrorSimple(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_ILLEGAL_OPCODE);
2652 break;
2653 default:
2654 LogRel(("PIIX3 ATA: LUN#%d: passthrough unimplemented for command %#x\n", s->iLUN, pbPacket[0]));
2655 atapiCmdErrorSimple(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_ILLEGAL_OPCODE);
2656 break;
2657 sendcmd:
2658 /* Send a command to the drive, passing data in/out as required. */
2659 Log2(("ATAPI PT: max size %d\n", cbTransfer));
2660 Assert(cbTransfer <= s->cbIOBuffer);
2661 if (cbTransfer == 0)
2662 uTxDir = PDMBLOCKTXDIR_NONE;
2663 ataStartTransfer(s, cbTransfer, uTxDir, ATAFN_BT_ATAPI_PASSTHROUGH_CMD, ATAFN_SS_ATAPI_PASSTHROUGH, true);
2664 }
2665}
2666
2667
2668static void atapiParseCmd(ATADevState *s)
2669{
2670 const uint8_t *pbPacket;
2671
2672 pbPacket = s->aATAPICmd;
2673#ifdef DEBUG
2674 Log(("%s: LUN#%d DMA=%d CMD=%#04x \"%s\"\n", __FUNCTION__, s->iLUN, s->fDMA, pbPacket[0], SCSICmdText(pbPacket[0])));
2675#else /* !DEBUG */
2676 Log(("%s: LUN#%d DMA=%d CMD=%#04x\n", __FUNCTION__, s->iLUN, s->fDMA, pbPacket[0]));
2677#endif /* !DEBUG */
2678 Log2(("%s: limit=%#x packet: %.*Vhxs\n", __FUNCTION__, s->uATARegLCyl | (s->uATARegHCyl << 8), ATAPI_PACKET_SIZE, pbPacket));
2679
2680 if (s->fATAPIPassthrough)
2681 atapiParseCmdPassthrough(s);
2682 else
2683 atapiParseCmdVirtualATAPI(s);
2684}
2685
2686
2687static bool ataPacketSS(ATADevState *s)
2688{
2689 s->fDMA = !!(s->uATARegFeature & 1);
2690 memcpy(s->aATAPICmd, s->CTX_SUFF(pbIOBuffer), ATAPI_PACKET_SIZE);
2691 s->uTxDir = PDMBLOCKTXDIR_NONE;
2692 s->cbTotalTransfer = 0;
2693 s->cbElementaryTransfer = 0;
2694 atapiParseCmd(s);
2695 return false;
2696}
2697
2698
2699/**
2700 * Called when a media is mounted.
2701 *
2702 * @param pInterface Pointer to the interface structure containing the called function pointer.
2703 */
2704static DECLCALLBACK(void) ataMountNotify(PPDMIMOUNTNOTIFY pInterface)
2705{
2706 ATADevState *pIf = PDMIMOUNTNOTIFY_2_ATASTATE(pInterface);
2707 Log(("%s: changing LUN#%d\n", __FUNCTION__, pIf->iLUN));
2708
2709 /* Ignore the call if we're called while being attached. */
2710 if (!pIf->pDrvBlock)
2711 return;
2712
2713 if (pIf->fATAPI)
2714 pIf->cTotalSectors = pIf->pDrvBlock->pfnGetSize(pIf->pDrvBlock) / 2048;
2715 else
2716 pIf->cTotalSectors = pIf->pDrvBlock->pfnGetSize(pIf->pDrvBlock) / 512;
2717
2718 /* Report media changed in TEST UNIT and other (probably incorrect) places. */
2719 if (pIf->cNotifiedMediaChange < 2)
2720 pIf->cNotifiedMediaChange = 2;
2721}
2722
2723/**
2724 * Called when a media is unmounted
2725 * @param pInterface Pointer to the interface structure containing the called function pointer.
2726 */
2727static DECLCALLBACK(void) ataUnmountNotify(PPDMIMOUNTNOTIFY pInterface)
2728{
2729 ATADevState *pIf = PDMIMOUNTNOTIFY_2_ATASTATE(pInterface);
2730 Log(("%s:\n", __FUNCTION__));
2731 pIf->cTotalSectors = 0;
2732
2733 /*
2734 * Whatever I do, XP will not use the GET MEDIA STATUS nor the EVENT stuff.
2735 * However, it will respond to TEST UNIT with a 0x6 0x28 (media changed) sense code.
2736 * So, we'll give it 4 TEST UNIT command to catch up, two which the media is not
2737 * present and 2 in which it is changed.
2738 */
2739 pIf->cNotifiedMediaChange = 4;
2740}
2741
2742static void ataPacketBT(ATADevState *s)
2743{
2744 s->cbElementaryTransfer = s->cbTotalTransfer;
2745 s->uATARegNSector = (s->uATARegNSector & ~7) | ATAPI_INT_REASON_CD;
2746 Log2(("%s: interrupt reason %#04x\n", __FUNCTION__, s->uATARegNSector));
2747 ataSetStatusValue(s, ATA_STAT_READY);
2748}
2749
2750
2751static void ataResetDevice(ATADevState *s)
2752{
2753 s->cMultSectors = ATA_MAX_MULT_SECTORS;
2754 s->cNotifiedMediaChange = 0;
2755 ataUnsetIRQ(s);
2756
2757 s->uATARegSelect = 0x20;
2758 ataSetStatusValue(s, ATA_STAT_READY);
2759 ataSetSignature(s);
2760 s->cbTotalTransfer = 0;
2761 s->cbElementaryTransfer = 0;
2762 s->iIOBufferPIODataStart = 0;
2763 s->iIOBufferPIODataEnd = 0;
2764 s->iBeginTransfer = ATAFN_BT_NULL;
2765 s->iSourceSink = ATAFN_SS_NULL;
2766 s->fATAPITransfer = false;
2767 s->uATATransferMode = ATA_MODE_UDMA | 2; /* PIIX3 supports only up to UDMA2 */
2768
2769 s->uATARegFeature = 0;
2770}
2771
2772
2773static bool ataExecuteDeviceDiagnosticSS(ATADevState *s)
2774{
2775 ataSetSignature(s);
2776 if (s->fATAPI)
2777 ataSetStatusValue(s, 0); /* NOTE: READY is _not_ set */
2778 else
2779 ataSetStatusValue(s, ATA_STAT_READY);
2780 s->uATARegError = 0x01;
2781 return false;
2782}
2783
2784
2785static void ataParseCmd(ATADevState *s, uint8_t cmd)
2786{
2787#ifdef DEBUG
2788 Log(("%s: LUN#%d CMD=%#04x \"%s\"\n", __FUNCTION__, s->iLUN, cmd, ATACmdText(cmd)));
2789#else /* !DEBUG */
2790 Log(("%s: LUN#%d CMD=%#04x\n", __FUNCTION__, s->iLUN, cmd));
2791#endif /* !DEBUG */
2792 s->fLBA48 = false;
2793 s->fDMA = false;
2794 if (cmd == ATA_IDLE_IMMEDIATE)
2795 {
2796 /* Detect Linux timeout recovery, first tries IDLE IMMEDIATE (which
2797 * would overwrite the failing command unfortunately), then RESET. */
2798 int32_t uCmdWait = -1;
2799 uint64_t uNow = RTTimeNanoTS();
2800 if (s->u64CmdTS)
2801 uCmdWait = (uNow - s->u64CmdTS) / 1000;
2802 LogRel(("PIIX3 ATA: LUN#%d: IDLE IMMEDIATE, CmdIf=%#04x (%d usec ago)\n",
2803 s->iLUN, s->uATARegCommand, uCmdWait));
2804 }
2805 s->uATARegCommand = cmd;
2806 switch (cmd)
2807 {
2808 case ATA_IDENTIFY_DEVICE:
2809 if (s->pDrvBlock && !s->fATAPI)
2810 ataStartTransfer(s, 512, PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_NULL, ATAFN_SS_IDENTIFY, false);
2811 else
2812 {
2813 if (s->fATAPI)
2814 ataSetSignature(s);
2815 ataCmdError(s, ABRT_ERR);
2816 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
2817 }
2818 break;
2819 case ATA_INITIALIZE_DEVICE_PARAMETERS:
2820 case ATA_RECALIBRATE:
2821 ataCmdOK(s, ATA_STAT_SEEK);
2822 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
2823 break;
2824 case ATA_SET_MULTIPLE_MODE:
2825 if ( s->uATARegNSector != 0
2826 && ( s->uATARegNSector > ATA_MAX_MULT_SECTORS
2827 || (s->uATARegNSector & (s->uATARegNSector - 1)) != 0))
2828 {
2829 ataCmdError(s, ABRT_ERR);
2830 }
2831 else
2832 {
2833 Log2(("%s: set multi sector count to %d\n", __FUNCTION__, s->uATARegNSector));
2834 s->cMultSectors = s->uATARegNSector;
2835 ataCmdOK(s, 0);
2836 }
2837 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
2838 break;
2839 case ATA_READ_VERIFY_SECTORS_EXT:
2840 s->fLBA48 = true;
2841 case ATA_READ_VERIFY_SECTORS:
2842 case ATA_READ_VERIFY_SECTORS_WITHOUT_RETRIES:
2843 /* do sector number check ? */
2844 ataCmdOK(s, 0);
2845 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
2846 break;
2847 case ATA_READ_SECTORS_EXT:
2848 s->fLBA48 = true;
2849 case ATA_READ_SECTORS:
2850 case ATA_READ_SECTORS_WITHOUT_RETRIES:
2851 if (!s->pDrvBlock)
2852 goto abort_cmd;
2853 s->cSectorsPerIRQ = 1;
2854 ataStartTransfer(s, ataGetNSectors(s) * 512, PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_READ_WRITE_SECTORS, ATAFN_SS_READ_SECTORS, false);
2855 break;
2856 case ATA_WRITE_SECTORS_EXT:
2857 s->fLBA48 = true;
2858 case ATA_WRITE_SECTORS:
2859 case ATA_WRITE_SECTORS_WITHOUT_RETRIES:
2860 s->cSectorsPerIRQ = 1;
2861 ataStartTransfer(s, ataGetNSectors(s) * 512, PDMBLOCKTXDIR_TO_DEVICE, ATAFN_BT_READ_WRITE_SECTORS, ATAFN_SS_WRITE_SECTORS, false);
2862 break;
2863 case ATA_READ_MULTIPLE_EXT:
2864 s->fLBA48 = true;
2865 case ATA_READ_MULTIPLE:
2866 if (!s->cMultSectors)
2867 goto abort_cmd;
2868 s->cSectorsPerIRQ = s->cMultSectors;
2869 ataStartTransfer(s, ataGetNSectors(s) * 512, PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_READ_WRITE_SECTORS, ATAFN_SS_READ_SECTORS, false);
2870 break;
2871 case ATA_WRITE_MULTIPLE_EXT:
2872 s->fLBA48 = true;
2873 case ATA_WRITE_MULTIPLE:
2874 if (!s->cMultSectors)
2875 goto abort_cmd;
2876 s->cSectorsPerIRQ = s->cMultSectors;
2877 ataStartTransfer(s, ataGetNSectors(s) * 512, PDMBLOCKTXDIR_TO_DEVICE, ATAFN_BT_READ_WRITE_SECTORS, ATAFN_SS_WRITE_SECTORS, false);
2878 break;
2879 case ATA_READ_DMA_EXT:
2880 s->fLBA48 = true;
2881 case ATA_READ_DMA:
2882 case ATA_READ_DMA_WITHOUT_RETRIES:
2883 if (!s->pDrvBlock)
2884 goto abort_cmd;
2885 s->cSectorsPerIRQ = ATA_MAX_MULT_SECTORS;
2886 s->fDMA = true;
2887 ataStartTransfer(s, ataGetNSectors(s) * 512, PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_READ_WRITE_SECTORS, ATAFN_SS_READ_SECTORS, false);
2888 break;
2889 case ATA_WRITE_DMA_EXT:
2890 s->fLBA48 = true;
2891 case ATA_WRITE_DMA:
2892 case ATA_WRITE_DMA_WITHOUT_RETRIES:
2893 if (!s->pDrvBlock)
2894 goto abort_cmd;
2895 s->cSectorsPerIRQ = ATA_MAX_MULT_SECTORS;
2896 s->fDMA = true;
2897 ataStartTransfer(s, ataGetNSectors(s) * 512, PDMBLOCKTXDIR_TO_DEVICE, ATAFN_BT_READ_WRITE_SECTORS, ATAFN_SS_WRITE_SECTORS, false);
2898 break;
2899 case ATA_READ_NATIVE_MAX_ADDRESS_EXT:
2900 s->fLBA48 = true;
2901 ataSetSector(s, s->cTotalSectors - 1);
2902 ataCmdOK(s, 0);
2903 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
2904 break;
2905 case ATA_SEEK: /* Used by the SCO OpenServer. Command is marked as obsolete */
2906 ataCmdOK(s, 0);
2907 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
2908 break;
2909 case ATA_READ_NATIVE_MAX_ADDRESS:
2910 ataSetSector(s, RT_MIN(s->cTotalSectors, 1 << 28) - 1);
2911 ataCmdOK(s, 0);
2912 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
2913 break;
2914 case ATA_CHECK_POWER_MODE:
2915 s->uATARegNSector = 0xff; /* drive active or idle */
2916 ataCmdOK(s, 0);
2917 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
2918 break;
2919 case ATA_SET_FEATURES:
2920 Log2(("%s: feature=%#x\n", __FUNCTION__, s->uATARegFeature));
2921 if (!s->pDrvBlock)
2922 goto abort_cmd;
2923 switch (s->uATARegFeature)
2924 {
2925 case 0x02: /* write cache enable */
2926 Log2(("%s: write cache enable\n", __FUNCTION__));
2927 ataCmdOK(s, ATA_STAT_SEEK);
2928 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
2929 break;
2930 case 0xaa: /* read look-ahead enable */
2931 Log2(("%s: read look-ahead enable\n", __FUNCTION__));
2932 ataCmdOK(s, ATA_STAT_SEEK);
2933 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
2934 break;
2935 case 0x55: /* read look-ahead disable */
2936 Log2(("%s: read look-ahead disable\n", __FUNCTION__));
2937 ataCmdOK(s, ATA_STAT_SEEK);
2938 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
2939 break;
2940 case 0xcc: /* reverting to power-on defaults enable */
2941 Log2(("%s: revert to power-on defaults enable\n", __FUNCTION__));
2942 ataCmdOK(s, ATA_STAT_SEEK);
2943 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
2944 break;
2945 case 0x66: /* reverting to power-on defaults disable */
2946 Log2(("%s: revert to power-on defaults disable\n", __FUNCTION__));
2947 ataCmdOK(s, ATA_STAT_SEEK);
2948 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
2949 break;
2950 case 0x82: /* write cache disable */
2951 Log2(("%s: write cache disable\n", __FUNCTION__));
2952 /* As per the ATA/ATAPI-6 specs, a write cache disable
2953 * command MUST flush the write buffers to disc. */
2954 ataStartTransfer(s, 0, PDMBLOCKTXDIR_NONE, ATAFN_BT_NULL, ATAFN_SS_FLUSH, false);
2955 break;
2956 case 0x03: { /* set transfer mode */
2957 Log2(("%s: transfer mode %#04x\n", __FUNCTION__, s->uATARegNSector));
2958 switch (s->uATARegNSector & 0xf8)
2959 {
2960 case 0x00: /* PIO default */
2961 case 0x08: /* PIO mode */
2962 break;
2963 case ATA_MODE_MDMA: /* MDMA mode */
2964 s->uATATransferMode = (s->uATARegNSector & 0xf8) | RT_MIN(s->uATARegNSector & 0x07, ATA_MDMA_MODE_MAX);
2965 break;
2966 case ATA_MODE_UDMA: /* UDMA mode */
2967 s->uATATransferMode = (s->uATARegNSector & 0xf8) | RT_MIN(s->uATARegNSector & 0x07, ATA_UDMA_MODE_MAX);
2968 break;
2969 default:
2970 goto abort_cmd;
2971 }
2972 ataCmdOK(s, ATA_STAT_SEEK);
2973 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
2974 break;
2975 }
2976 default:
2977 goto abort_cmd;
2978 }
2979 /*
2980 * OS/2 workarond:
2981 * The OS/2 IDE driver from MCP2 appears to rely on the feature register being
2982 * reset here. According to the specification, this is a driver bug as the register
2983 * contents are undefined after the call. This means we can just as well reset it.
2984 */
2985 s->uATARegFeature = 0;
2986 break;
2987 case ATA_FLUSH_CACHE_EXT:
2988 case ATA_FLUSH_CACHE:
2989 if (!s->pDrvBlock || s->fATAPI)
2990 goto abort_cmd;
2991 ataStartTransfer(s, 0, PDMBLOCKTXDIR_NONE, ATAFN_BT_NULL, ATAFN_SS_FLUSH, false);
2992 break;
2993 case ATA_STANDBY_IMMEDIATE:
2994 ataCmdOK(s, 0);
2995 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
2996 break;
2997 case ATA_IDLE_IMMEDIATE:
2998 LogRel(("PIIX3 ATA: LUN#%d: aborting current command\n", s->iLUN));
2999 ataAbortCurrentCommand(s, false);
3000 break;
3001 /* ATAPI commands */
3002 case ATA_IDENTIFY_PACKET_DEVICE:
3003 if (s->fATAPI)
3004 ataStartTransfer(s, 512, PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_NULL, ATAFN_SS_ATAPI_IDENTIFY, false);
3005 else
3006 {
3007 ataCmdError(s, ABRT_ERR);
3008 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
3009 }
3010 break;
3011 case ATA_EXECUTE_DEVICE_DIAGNOSTIC:
3012 ataStartTransfer(s, 0, PDMBLOCKTXDIR_NONE, ATAFN_BT_NULL, ATAFN_SS_EXECUTE_DEVICE_DIAGNOSTIC, false);
3013 break;
3014 case ATA_DEVICE_RESET:
3015 if (!s->fATAPI)
3016 goto abort_cmd;
3017 LogRel(("PIIX3 ATA: LUN#%d: performing device RESET\n", s->iLUN));
3018 ataAbortCurrentCommand(s, true);
3019 break;
3020 case ATA_PACKET:
3021 if (!s->fATAPI)
3022 goto abort_cmd;
3023 /* overlapping commands not supported */
3024 if (s->uATARegFeature & 0x02)
3025 goto abort_cmd;
3026 ataStartTransfer(s, ATAPI_PACKET_SIZE, PDMBLOCKTXDIR_TO_DEVICE, ATAFN_BT_PACKET, ATAFN_SS_PACKET, false);
3027 break;
3028 default:
3029 abort_cmd:
3030 ataCmdError(s, ABRT_ERR);
3031 ataSetIRQ(s); /* Shortcut, do not use AIO thread. */
3032 break;
3033 }
3034}
3035
3036
3037/**
3038 * Waits for a particular async I/O thread to complete whatever it
3039 * is doing at the moment.
3040 *
3041 * @returns true on success.
3042 * @returns false when the thread is still processing.
3043 * @param pThis Pointer to the controller data.
3044 * @param cMillies How long to wait (total).
3045 */
3046static bool ataWaitForAsyncIOIsIdle(PATACONTROLLER pCtl, unsigned cMillies)
3047{
3048 uint64_t u64Start;
3049
3050 /*
3051 * Wait for any pending async operation to finish
3052 */
3053 u64Start = RTTimeMilliTS();
3054 for (;;)
3055 {
3056 if (ataAsyncIOIsIdle(pCtl, false))
3057 return true;
3058 if (RTTimeMilliTS() - u64Start >= cMillies)
3059 break;
3060
3061 /* Sleep for a bit. */
3062 RTThreadSleep(100);
3063 }
3064
3065 return false;
3066}
3067
3068#endif /* IN_RING3 */
3069
3070static int ataIOPortWriteU8(PATACONTROLLER pCtl, uint32_t addr, uint32_t val)
3071{
3072 Log2(("%s: write addr=%#x val=%#04x\n", __FUNCTION__, addr, val));
3073 addr &= 7;
3074 switch (addr)
3075 {
3076 case 0:
3077 break;
3078 case 1: /* feature register */
3079 /* NOTE: data is written to the two drives */
3080 pCtl->aIfs[0].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
3081 pCtl->aIfs[1].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
3082 pCtl->aIfs[0].uATARegFeatureHOB = pCtl->aIfs[0].uATARegFeature;
3083 pCtl->aIfs[1].uATARegFeatureHOB = pCtl->aIfs[1].uATARegFeature;
3084 pCtl->aIfs[0].uATARegFeature = val;
3085 pCtl->aIfs[1].uATARegFeature = val;
3086 break;
3087 case 2: /* sector count */
3088 pCtl->aIfs[0].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
3089 pCtl->aIfs[1].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
3090 pCtl->aIfs[0].uATARegNSectorHOB = pCtl->aIfs[0].uATARegNSector;
3091 pCtl->aIfs[1].uATARegNSectorHOB = pCtl->aIfs[1].uATARegNSector;
3092 pCtl->aIfs[0].uATARegNSector = val;
3093 pCtl->aIfs[1].uATARegNSector = val;
3094 break;
3095 case 3: /* sector number */
3096 pCtl->aIfs[0].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
3097 pCtl->aIfs[1].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
3098 pCtl->aIfs[0].uATARegSectorHOB = pCtl->aIfs[0].uATARegSector;
3099 pCtl->aIfs[1].uATARegSectorHOB = pCtl->aIfs[1].uATARegSector;
3100 pCtl->aIfs[0].uATARegSector = val;
3101 pCtl->aIfs[1].uATARegSector = val;
3102 break;
3103 case 4: /* cylinder low */
3104 pCtl->aIfs[0].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
3105 pCtl->aIfs[1].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
3106 pCtl->aIfs[0].uATARegLCylHOB = pCtl->aIfs[0].uATARegLCyl;
3107 pCtl->aIfs[1].uATARegLCylHOB = pCtl->aIfs[1].uATARegLCyl;
3108 pCtl->aIfs[0].uATARegLCyl = val;
3109 pCtl->aIfs[1].uATARegLCyl = val;
3110 break;
3111 case 5: /* cylinder high */
3112 pCtl->aIfs[0].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
3113 pCtl->aIfs[1].uATARegDevCtl &= ~ATA_DEVCTL_HOB;
3114 pCtl->aIfs[0].uATARegHCylHOB = pCtl->aIfs[0].uATARegHCyl;
3115 pCtl->aIfs[1].uATARegHCylHOB = pCtl->aIfs[1].uATARegHCyl;
3116 pCtl->aIfs[0].uATARegHCyl = val;
3117 pCtl->aIfs[1].uATARegHCyl = val;
3118 break;
3119 case 6: /* drive/head */
3120 pCtl->aIfs[0].uATARegSelect = (val & ~0x10) | 0xa0;
3121 pCtl->aIfs[1].uATARegSelect = (val | 0x10) | 0xa0;
3122 if (((val >> 4) & 1) != pCtl->iSelectedIf)
3123 {
3124 PPDMDEVINS pDevIns = CONTROLLER_2_DEVINS(pCtl);
3125
3126 /* select another drive */
3127 pCtl->iSelectedIf = (val >> 4) & 1;
3128 /* The IRQ line is multiplexed between the two drives, so
3129 * update the state when switching to another drive. Only need
3130 * to update interrupt line if it is enabled and there is a
3131 * state change. */
3132 if ( !(pCtl->aIfs[pCtl->iSelectedIf].uATARegDevCtl & ATA_DEVCTL_DISABLE_IRQ)
3133 && ( pCtl->aIfs[pCtl->iSelectedIf].fIrqPending
3134 != pCtl->aIfs[pCtl->iSelectedIf ^ 1].fIrqPending))
3135 {
3136 if (pCtl->aIfs[pCtl->iSelectedIf].fIrqPending)
3137 {
3138 Log2(("%s: LUN#%d asserting IRQ (drive select change)\n", __FUNCTION__, pCtl->aIfs[pCtl->iSelectedIf].iLUN));
3139 /* The BMDMA unit unconditionally sets BM_STATUS_INT if
3140 * the interrupt line is asserted. It monitors the line
3141 * for a rising edge. */
3142 pCtl->BmDma.u8Status |= BM_STATUS_INT;
3143 if (pCtl->irq == 16)
3144 PDMDevHlpPCISetIrqNoWait(pDevIns, 0, 1);
3145 else
3146 PDMDevHlpISASetIrqNoWait(pDevIns, pCtl->irq, 1);
3147 }
3148 else
3149 {
3150 Log2(("%s: LUN#%d deasserting IRQ (drive select change)\n", __FUNCTION__, pCtl->aIfs[pCtl->iSelectedIf].iLUN));
3151 if (pCtl->irq == 16)
3152 PDMDevHlpPCISetIrqNoWait(pDevIns, 0, 0);
3153 else
3154 PDMDevHlpISASetIrqNoWait(pDevIns, pCtl->irq, 0);
3155 }
3156 }
3157 }
3158 break;
3159 default:
3160 case 7: /* command */
3161 /* ignore commands to non existant slave */
3162 if (pCtl->iSelectedIf && !pCtl->aIfs[pCtl->iSelectedIf].pDrvBlock)
3163 break;
3164#ifndef IN_RING3
3165 /* Don't do anything complicated in GC */
3166 return VINF_IOM_HC_IOPORT_WRITE;
3167#else /* IN_RING3 */
3168 ataParseCmd(&pCtl->aIfs[pCtl->iSelectedIf], val);
3169#endif /* !IN_RING3 */
3170 }
3171 return VINF_SUCCESS;
3172}
3173
3174
3175static int ataIOPortReadU8(PATACONTROLLER pCtl, uint32_t addr, uint32_t *pu32)
3176{
3177 ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf];
3178 uint32_t val;
3179 bool fHOB;
3180
3181 fHOB = !!(s->uATARegDevCtl & (1 << 7));
3182 switch (addr & 7)
3183 {
3184 case 0: /* data register */
3185 val = 0xff;
3186 break;
3187 case 1: /* error register */
3188 /* The ATA specification is very terse when it comes to specifying
3189 * the precise effects of reading back the error/feature register.
3190 * The error register (read-only) shares the register number with
3191 * the feature register (write-only), so it seems that it's not
3192 * necessary to support the usual HOB readback here. */
3193 if (!s->pDrvBlock)
3194 val = 0;
3195 else
3196 val = s->uATARegError;
3197 break;
3198 case 2: /* sector count */
3199 if (!s->pDrvBlock)
3200 val = 0;
3201 else if (fHOB)
3202 val = s->uATARegNSectorHOB;
3203 else
3204 val = s->uATARegNSector;
3205 break;
3206 case 3: /* sector number */
3207 if (!s->pDrvBlock)
3208 val = 0;
3209 else if (fHOB)
3210 val = s->uATARegSectorHOB;
3211 else
3212 val = s->uATARegSector;
3213 break;
3214 case 4: /* cylinder low */
3215 if (!s->pDrvBlock)
3216 val = 0;
3217 else if (fHOB)
3218 val = s->uATARegLCylHOB;
3219 else
3220 val = s->uATARegLCyl;
3221 break;
3222 case 5: /* cylinder high */
3223 if (!s->pDrvBlock)
3224 val = 0;
3225 else if (fHOB)
3226 val = s->uATARegHCylHOB;
3227 else
3228 val = s->uATARegHCyl;
3229 break;
3230 case 6: /* drive/head */
3231 /* This register must always work as long as there is at least
3232 * one drive attached to the controller. It is common between
3233 * both drives anyway (completely identical content). */
3234 if (!pCtl->aIfs[0].pDrvBlock && !pCtl->aIfs[1].pDrvBlock)
3235 val = 0;
3236 else
3237 val = s->uATARegSelect;
3238 break;
3239 default:
3240 case 7: /* primary status */
3241 {
3242 /* Counter for number of busy status seen in GC in a row. */
3243 static unsigned cBusy = 0;
3244
3245 if (!s->pDrvBlock)
3246 val = 0;
3247 else
3248 val = s->uATARegStatus;
3249
3250 /* Give the async I/O thread an opportunity to make progress,
3251 * don't let it starve by guests polling frequently. EMT has a
3252 * lower priority than the async I/O thread, but sometimes the
3253 * host OS doesn't care. With some guests we are only allowed to
3254 * be busy for about 5 milliseconds in some situations. Note that
3255 * this is no guarantee for any other VBox thread getting
3256 * scheduled, so this just lowers the CPU load a bit when drives
3257 * are busy. It cannot help with timing problems. */
3258 if (val & ATA_STAT_BUSY)
3259 {
3260#ifdef IN_RING3
3261 cBusy = 0;
3262 PDMCritSectLeave(&pCtl->lock);
3263
3264 RTThreadYield();
3265
3266 {
3267 STAM_PROFILE_START(&pCtl->StatLockWait, a);
3268 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
3269 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
3270 }
3271
3272 val = s->uATARegStatus;
3273#else /* !IN_RING3 */
3274 /* Cannot yield CPU in guest context. And switching to host
3275 * context for each and every busy status is too costly,
3276 * especially on SMP systems where we don't gain much by
3277 * yielding the CPU to someone else. */
3278 if (++cBusy >= 20)
3279 {
3280 cBusy = 0;
3281 return VINF_IOM_HC_IOPORT_READ;
3282 }
3283#endif /* !IN_RING3 */
3284 }
3285 else
3286 cBusy = 0;
3287 ataUnsetIRQ(s);
3288 break;
3289 }
3290 }
3291 Log2(("%s: addr=%#x val=%#04x\n", __FUNCTION__, addr, val));
3292 *pu32 = val;
3293 return VINF_SUCCESS;
3294}
3295
3296
3297static uint32_t ataStatusRead(PATACONTROLLER pCtl, uint32_t addr)
3298{
3299 ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf];
3300 uint32_t val;
3301
3302 if ((!pCtl->aIfs[0].pDrvBlock && !pCtl->aIfs[1].pDrvBlock) ||
3303 (pCtl->iSelectedIf == 1 && !s->pDrvBlock))
3304 val = 0;
3305 else
3306 val = s->uATARegStatus;
3307 Log2(("%s: addr=%#x val=%#04x\n", __FUNCTION__, addr, val));
3308 return val;
3309}
3310
3311static int ataControlWrite(PATACONTROLLER pCtl, uint32_t addr, uint32_t val)
3312{
3313#ifndef IN_RING3
3314 if ((val ^ pCtl->aIfs[0].uATARegDevCtl) & ATA_DEVCTL_RESET)
3315 return VINF_IOM_HC_IOPORT_WRITE; /* The RESET stuff is too complicated for GC. */
3316#endif /* !IN_RING3 */
3317
3318 Log2(("%s: addr=%#x val=%#04x\n", __FUNCTION__, addr, val));
3319 /* RESET is common for both drives attached to a controller. */
3320 if (!(pCtl->aIfs[0].uATARegDevCtl & ATA_DEVCTL_RESET) &&
3321 (val & ATA_DEVCTL_RESET))
3322 {
3323#ifdef IN_RING3
3324 /* Software RESET low to high */
3325 int32_t uCmdWait0 = -1, uCmdWait1 = -1;
3326 uint64_t uNow = RTTimeNanoTS();
3327 if (pCtl->aIfs[0].u64CmdTS)
3328 uCmdWait0 = (uNow - pCtl->aIfs[0].u64CmdTS) / 1000;
3329 if (pCtl->aIfs[1].u64CmdTS)
3330 uCmdWait1 = (uNow - pCtl->aIfs[1].u64CmdTS) / 1000;
3331 LogRel(("PIIX3 ATA: Ctl#%d: RESET, DevSel=%d AIOIf=%d CmdIf0=%#04x (%d usec ago) CmdIf1=%#04x (%d usec ago)\n",
3332 ATACONTROLLER_IDX(pCtl), pCtl->iSelectedIf, pCtl->iAIOIf,
3333 pCtl->aIfs[0].uATARegCommand, uCmdWait0,
3334 pCtl->aIfs[1].uATARegCommand, uCmdWait1));
3335 pCtl->fReset = true;
3336 /* Everything must be done after the reset flag is set, otherwise
3337 * there are unavoidable races with the currently executing request
3338 * (which might just finish in the mean time). */
3339 pCtl->fChainedTransfer = false;
3340 for (uint32_t i = 0; i < RT_ELEMENTS(pCtl->aIfs); i++)
3341 {
3342 ataResetDevice(&pCtl->aIfs[i]);
3343 /* The following cannot be done using ataSetStatusValue() since the
3344 * reset flag is already set, which suppresses all status changes. */
3345 pCtl->aIfs[i].uATARegStatus = ATA_STAT_BUSY | ATA_STAT_SEEK;
3346 Log2(("%s: LUN#%d status %#04x\n", __FUNCTION__, pCtl->aIfs[i].iLUN, pCtl->aIfs[i].uATARegStatus));
3347 pCtl->aIfs[i].uATARegError = 0x01;
3348 }
3349 ataAsyncIOClearRequests(pCtl);
3350 Log2(("%s: Ctl#%d: message to async I/O thread, resetA\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
3351 if (val & ATA_DEVCTL_HOB)
3352 {
3353 val &= ~ATA_DEVCTL_HOB;
3354 Log2(("%s: ignored setting HOB\n", __FUNCTION__));
3355 }
3356 ataAsyncIOPutRequest(pCtl, &ataResetARequest);
3357#else /* !IN_RING3 */
3358 AssertMsgFailed(("RESET handling is too complicated for GC\n"));
3359#endif /* IN_RING3 */
3360 }
3361 else if ((pCtl->aIfs[0].uATARegDevCtl & ATA_DEVCTL_RESET) &&
3362 !(val & ATA_DEVCTL_RESET))
3363 {
3364#ifdef IN_RING3
3365 /* Software RESET high to low */
3366 Log(("%s: deasserting RESET\n", __FUNCTION__));
3367 Log2(("%s: Ctl#%d: message to async I/O thread, resetC\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
3368 if (val & ATA_DEVCTL_HOB)
3369 {
3370 val &= ~ATA_DEVCTL_HOB;
3371 Log2(("%s: ignored setting HOB\n", __FUNCTION__));
3372 }
3373 ataAsyncIOPutRequest(pCtl, &ataResetCRequest);
3374#else /* !IN_RING3 */
3375 AssertMsgFailed(("RESET handling is too complicated for GC\n"));
3376#endif /* IN_RING3 */
3377 }
3378
3379 /* Change of interrupt disable flag. Update interrupt line if interrupt
3380 * is pending on the current interface. */
3381 if ((val ^ pCtl->aIfs[0].uATARegDevCtl) & ATA_DEVCTL_DISABLE_IRQ
3382 && pCtl->aIfs[pCtl->iSelectedIf].fIrqPending)
3383 {
3384 if (!(val & ATA_DEVCTL_DISABLE_IRQ))
3385 {
3386 Log2(("%s: LUN#%d asserting IRQ (interrupt disable change)\n", __FUNCTION__, pCtl->aIfs[pCtl->iSelectedIf].iLUN));
3387 /* The BMDMA unit unconditionally sets BM_STATUS_INT if the
3388 * interrupt line is asserted. It monitors the line for a rising
3389 * edge. */
3390 pCtl->BmDma.u8Status |= BM_STATUS_INT;
3391 if (pCtl->irq == 16)
3392 PDMDevHlpPCISetIrqNoWait(CONTROLLER_2_DEVINS(pCtl), 0, 1);
3393 else
3394 PDMDevHlpISASetIrqNoWait(CONTROLLER_2_DEVINS(pCtl), pCtl->irq, 1);
3395 }
3396 else
3397 {
3398 Log2(("%s: LUN#%d deasserting IRQ (interrupt disable change)\n", __FUNCTION__, pCtl->aIfs[pCtl->iSelectedIf].iLUN));
3399 if (pCtl->irq == 16)
3400 PDMDevHlpPCISetIrqNoWait(CONTROLLER_2_DEVINS(pCtl), 0, 0);
3401 else
3402 PDMDevHlpISASetIrqNoWait(CONTROLLER_2_DEVINS(pCtl), pCtl->irq, 0);
3403 }
3404 }
3405
3406 if (val & ATA_DEVCTL_HOB)
3407 Log2(("%s: set HOB\n", __FUNCTION__));
3408
3409 pCtl->aIfs[0].uATARegDevCtl = val;
3410 pCtl->aIfs[1].uATARegDevCtl = val;
3411
3412 return VINF_SUCCESS;
3413}
3414
3415#ifdef IN_RING3
3416
3417static void ataPIOTransfer(PATACONTROLLER pCtl)
3418{
3419 ATADevState *s;
3420
3421 s = &pCtl->aIfs[pCtl->iAIOIf];
3422 Log3(("%s: if=%p\n", __FUNCTION__, s));
3423
3424 if (s->cbTotalTransfer && s->iIOBufferCur > s->iIOBufferEnd)
3425 {
3426 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"));
3427 /* Any guest OS that triggers this case has a pathetic ATA driver.
3428 * In a real system it would block the CPU via IORDY, here we do it
3429 * very similarly by not continuing with the current instruction
3430 * until the transfer to/from the storage medium is completed. */
3431 if (s->iSourceSink != ATAFN_SS_NULL)
3432 {
3433 bool fRedo;
3434 uint8_t status = s->uATARegStatus;
3435 ataSetStatusValue(s, ATA_STAT_BUSY);
3436 Log2(("%s: calling source/sink function\n", __FUNCTION__));
3437 fRedo = g_apfnSourceSinkFuncs[s->iSourceSink](s);
3438 pCtl->fRedo = fRedo;
3439 if (RT_UNLIKELY(fRedo))
3440 return;
3441 ataSetStatusValue(s, status);
3442 s->iIOBufferCur = 0;
3443 s->iIOBufferEnd = s->cbElementaryTransfer;
3444 }
3445 }
3446 if (s->cbTotalTransfer)
3447 {
3448 if (s->fATAPITransfer)
3449 ataPIOTransferLimitATAPI(s);
3450
3451 if (s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE && s->cbElementaryTransfer > s->cbTotalTransfer)
3452 s->cbElementaryTransfer = s->cbTotalTransfer;
3453
3454 Log2(("%s: %s tx_size=%d elem_tx_size=%d index=%d end=%d\n",
3455 __FUNCTION__, s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE ? "T2I" : "I2T",
3456 s->cbTotalTransfer, s->cbElementaryTransfer,
3457 s->iIOBufferCur, s->iIOBufferEnd));
3458 ataPIOTransferStart(s, s->iIOBufferCur, s->cbElementaryTransfer);
3459 s->cbTotalTransfer -= s->cbElementaryTransfer;
3460 s->iIOBufferCur += s->cbElementaryTransfer;
3461
3462 if (s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE && s->cbElementaryTransfer > s->cbTotalTransfer)
3463 s->cbElementaryTransfer = s->cbTotalTransfer;
3464 }
3465 else
3466 ataPIOTransferStop(s);
3467}
3468
3469
3470DECLINLINE(void) ataPIOTransferFinish(PATACONTROLLER pCtl, ATADevState *s)
3471{
3472 /* Do not interfere with RESET processing if the PIO transfer finishes
3473 * while the RESET line is asserted. */
3474 if (pCtl->fReset)
3475 {
3476 Log2(("%s: Ctl#%d: suppressed continuing PIO transfer as RESET is active\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
3477 return;
3478 }
3479
3480 if ( s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE
3481 || ( s->iSourceSink != ATAFN_SS_NULL
3482 && s->iIOBufferCur >= s->iIOBufferEnd))
3483 {
3484 /* Need to continue the transfer in the async I/O thread. This is
3485 * the case for write operations or generally for not yet finished
3486 * transfers (some data might need to be read). */
3487 ataUnsetStatus(s, ATA_STAT_READY | ATA_STAT_DRQ);
3488 ataSetStatus(s, ATA_STAT_BUSY);
3489
3490 Log2(("%s: Ctl#%d: message to async I/O thread, continuing PIO transfer\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
3491 ataAsyncIOPutRequest(pCtl, &ataPIORequest);
3492 }
3493 else
3494 {
3495 /* Either everything finished (though some data might still be pending)
3496 * or some data is pending before the next read is due. */
3497
3498 /* Continue a previously started transfer. */
3499 ataUnsetStatus(s, ATA_STAT_DRQ);
3500 ataSetStatus(s, ATA_STAT_READY);
3501
3502 if (s->cbTotalTransfer)
3503 {
3504 /* There is more to transfer, happens usually for large ATAPI
3505 * reads - the protocol limits the chunk size to 65534 bytes. */
3506 ataPIOTransfer(pCtl);
3507 ataSetIRQ(s);
3508 }
3509 else
3510 {
3511 Log2(("%s: Ctl#%d: skipping message to async I/O thread, ending PIO transfer\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
3512 /* Finish PIO transfer. */
3513 ataPIOTransfer(pCtl);
3514 Assert(!pCtl->fRedo);
3515 }
3516 }
3517}
3518
3519#endif /* IN_RING3 */
3520
3521static int ataDataWrite(PATACONTROLLER pCtl, uint32_t addr, uint32_t cbSize, const uint8_t *pbBuf)
3522{
3523 ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf];
3524 uint8_t *p;
3525
3526 if (s->iIOBufferPIODataStart < s->iIOBufferPIODataEnd)
3527 {
3528 Assert(s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE);
3529 p = s->CTX_SUFF(pbIOBuffer) + s->iIOBufferPIODataStart;
3530#ifndef IN_RING3
3531 /* All but the last transfer unit is simple enough for GC, but
3532 * sending a request to the async IO thread is too complicated. */
3533 if (s->iIOBufferPIODataStart + cbSize < s->iIOBufferPIODataEnd)
3534 {
3535 memcpy(p, pbBuf, cbSize);
3536 s->iIOBufferPIODataStart += cbSize;
3537 }
3538 else
3539 return VINF_IOM_HC_IOPORT_WRITE;
3540#else /* IN_RING3 */
3541 memcpy(p, pbBuf, cbSize);
3542 s->iIOBufferPIODataStart += cbSize;
3543 if (s->iIOBufferPIODataStart >= s->iIOBufferPIODataEnd)
3544 ataPIOTransferFinish(pCtl, s);
3545#endif /* !IN_RING3 */
3546 }
3547 else
3548 Log2(("%s: DUMMY data\n", __FUNCTION__));
3549 Log3(("%s: addr=%#x val=%.*Vhxs\n", __FUNCTION__, addr, cbSize, pbBuf));
3550 return VINF_SUCCESS;
3551}
3552
3553static int ataDataRead(PATACONTROLLER pCtl, uint32_t addr, uint32_t cbSize, uint8_t *pbBuf)
3554{
3555 ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf];
3556 uint8_t *p;
3557
3558 if (s->iIOBufferPIODataStart < s->iIOBufferPIODataEnd)
3559 {
3560 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE);
3561 p = s->CTX_SUFF(pbIOBuffer) + s->iIOBufferPIODataStart;
3562#ifndef IN_RING3
3563 /* All but the last transfer unit is simple enough for GC, but
3564 * sending a request to the async IO thread is too complicated. */
3565 if (s->iIOBufferPIODataStart + cbSize < s->iIOBufferPIODataEnd)
3566 {
3567 memcpy(pbBuf, p, cbSize);
3568 s->iIOBufferPIODataStart += cbSize;
3569 }
3570 else
3571 return VINF_IOM_HC_IOPORT_READ;
3572#else /* IN_RING3 */
3573 memcpy(pbBuf, p, cbSize);
3574 s->iIOBufferPIODataStart += cbSize;
3575 if (s->iIOBufferPIODataStart >= s->iIOBufferPIODataEnd)
3576 ataPIOTransferFinish(pCtl, s);
3577#endif /* !IN_RING3 */
3578 }
3579 else
3580 {
3581 Log2(("%s: DUMMY data\n", __FUNCTION__));
3582 memset(pbBuf, '\xff', cbSize);
3583 }
3584 Log3(("%s: addr=%#x val=%.*Vhxs\n", __FUNCTION__, addr, cbSize, pbBuf));
3585 return VINF_SUCCESS;
3586}
3587
3588#ifdef IN_RING3
3589
3590static void ataDMATransferStop(ATADevState *s)
3591{
3592 s->cbTotalTransfer = 0;
3593 s->cbElementaryTransfer = 0;
3594 s->iBeginTransfer = ATAFN_BT_NULL;
3595 s->iSourceSink = ATAFN_SS_NULL;
3596}
3597
3598
3599/**
3600 * Perform the entire DMA transfer in one go (unless a source/sink operation
3601 * has to be redone or a RESET comes in between). Unlike the PIO counterpart
3602 * this function cannot handle empty transfers.
3603 *
3604 * @param pCtl Controller for which to perform the transfer.
3605 */
3606static void ataDMATransfer(PATACONTROLLER pCtl)
3607{
3608 PPDMDEVINS pDevIns = CONTROLLER_2_DEVINS(pCtl);
3609 ATADevState *s = &pCtl->aIfs[pCtl->iAIOIf];
3610 bool fRedo;
3611 RTGCPHYS32 pDesc;
3612 uint32_t cbTotalTransfer, cbElementaryTransfer;
3613 uint32_t iIOBufferCur, iIOBufferEnd;
3614 uint32_t dmalen;
3615 PDMBLOCKTXDIR uTxDir;
3616 bool fLastDesc = false;
3617
3618 Assert(sizeof(BMDMADesc) == 8);
3619
3620 fRedo = pCtl->fRedo;
3621 if (RT_LIKELY(!fRedo))
3622 Assert(s->cbTotalTransfer);
3623 uTxDir = (PDMBLOCKTXDIR)s->uTxDir;
3624 cbTotalTransfer = s->cbTotalTransfer;
3625 cbElementaryTransfer = s->cbElementaryTransfer;
3626 iIOBufferCur = s->iIOBufferCur;
3627 iIOBufferEnd = s->iIOBufferEnd;
3628
3629 /* The DMA loop is designed to hold the lock only when absolutely
3630 * necessary. This avoids long freezes should the guest access the
3631 * ATA registers etc. for some reason. */
3632 PDMCritSectLeave(&pCtl->lock);
3633
3634 Log2(("%s: %s tx_size=%d elem_tx_size=%d index=%d end=%d\n",
3635 __FUNCTION__, uTxDir == PDMBLOCKTXDIR_FROM_DEVICE ? "T2I" : "I2T",
3636 cbTotalTransfer, cbElementaryTransfer,
3637 iIOBufferCur, iIOBufferEnd));
3638 for (pDesc = pCtl->pFirstDMADesc; pDesc <= pCtl->pLastDMADesc; pDesc += sizeof(BMDMADesc))
3639 {
3640 BMDMADesc DMADesc;
3641 RTGCPHYS32 pBuffer;
3642 uint32_t cbBuffer;
3643
3644 if (RT_UNLIKELY(fRedo))
3645 {
3646 pBuffer = pCtl->pRedoDMABuffer;
3647 cbBuffer = pCtl->cbRedoDMABuffer;
3648 fLastDesc = pCtl->fRedoDMALastDesc;
3649 }
3650 else
3651 {
3652 PDMDevHlpPhysRead(pDevIns, pDesc, &DMADesc, sizeof(BMDMADesc));
3653 pBuffer = RT_LE2H_U32(DMADesc.pBuffer);
3654 cbBuffer = RT_LE2H_U32(DMADesc.cbBuffer);
3655 fLastDesc = !!(cbBuffer & 0x80000000);
3656 cbBuffer &= 0xfffe;
3657 if (cbBuffer == 0)
3658 cbBuffer = 0x10000;
3659 if (cbBuffer > cbTotalTransfer)
3660 cbBuffer = cbTotalTransfer;
3661 }
3662
3663 while (RT_UNLIKELY(fRedo) || (cbBuffer && cbTotalTransfer))
3664 {
3665 if (RT_LIKELY(!fRedo))
3666 {
3667 dmalen = RT_MIN(cbBuffer, iIOBufferEnd - iIOBufferCur);
3668 Log2(("%s: DMA desc %#010x: addr=%#010x size=%#010x\n", __FUNCTION__,
3669 (int)pDesc, pBuffer, cbBuffer));
3670 if (uTxDir == PDMBLOCKTXDIR_FROM_DEVICE)
3671 PDMDevHlpPhysWrite(pDevIns, pBuffer, s->CTX_SUFF(pbIOBuffer) + iIOBufferCur, dmalen);
3672 else
3673 PDMDevHlpPhysRead(pDevIns, pBuffer, s->CTX_SUFF(pbIOBuffer) + iIOBufferCur, dmalen);
3674 iIOBufferCur += dmalen;
3675 cbTotalTransfer -= dmalen;
3676 cbBuffer -= dmalen;
3677 pBuffer += dmalen;
3678 }
3679 if ( iIOBufferCur == iIOBufferEnd
3680 && (uTxDir == PDMBLOCKTXDIR_TO_DEVICE || cbTotalTransfer))
3681 {
3682 if (uTxDir == PDMBLOCKTXDIR_FROM_DEVICE && cbElementaryTransfer > cbTotalTransfer)
3683 cbElementaryTransfer = cbTotalTransfer;
3684
3685 {
3686 STAM_PROFILE_START(&pCtl->StatLockWait, a);
3687 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
3688 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
3689 }
3690
3691 /* The RESET handler could have cleared the DMA transfer
3692 * state (since we didn't hold the lock until just now
3693 * the guest can continue in parallel). If so, the state
3694 * is already set up so the loop is exited immediately. */
3695 if (s->iSourceSink != ATAFN_SS_NULL)
3696 {
3697 s->iIOBufferCur = iIOBufferCur;
3698 s->iIOBufferEnd = iIOBufferEnd;
3699 s->cbElementaryTransfer = cbElementaryTransfer;
3700 s->cbTotalTransfer = cbTotalTransfer;
3701 Log2(("%s: calling source/sink function\n", __FUNCTION__));
3702 fRedo = g_apfnSourceSinkFuncs[s->iSourceSink](s);
3703 if (RT_UNLIKELY(fRedo))
3704 {
3705 pCtl->pFirstDMADesc = pDesc;
3706 pCtl->pRedoDMABuffer = pBuffer;
3707 pCtl->cbRedoDMABuffer = cbBuffer;
3708 pCtl->fRedoDMALastDesc = fLastDesc;
3709 }
3710 else
3711 {
3712 cbTotalTransfer = s->cbTotalTransfer;
3713 cbElementaryTransfer = s->cbElementaryTransfer;
3714
3715 if (uTxDir == PDMBLOCKTXDIR_TO_DEVICE && cbElementaryTransfer > cbTotalTransfer)
3716 cbElementaryTransfer = cbTotalTransfer;
3717 iIOBufferCur = 0;
3718 iIOBufferEnd = cbElementaryTransfer;
3719 }
3720 pCtl->fRedo = fRedo;
3721 }
3722 else
3723 {
3724 /* This forces the loop to exit immediately. */
3725 pDesc = pCtl->pLastDMADesc + 1;
3726 }
3727
3728 PDMCritSectLeave(&pCtl->lock);
3729 if (RT_UNLIKELY(fRedo))
3730 break;
3731 }
3732 }
3733
3734 if (RT_UNLIKELY(fRedo))
3735 break;
3736
3737 /* end of transfer */
3738 if (!cbTotalTransfer || fLastDesc)
3739 break;
3740
3741 {
3742 STAM_PROFILE_START(&pCtl->StatLockWait, a);
3743 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
3744 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
3745 }
3746
3747 if (!(pCtl->BmDma.u8Cmd & BM_CMD_START) || pCtl->fReset)
3748 {
3749 LogRel(("PIIX3 ATA: Ctl#%d: ABORT DMA%s\n", ATACONTROLLER_IDX(pCtl), pCtl->fReset ? " due to RESET" : ""));
3750 if (!pCtl->fReset)
3751 ataDMATransferStop(s);
3752 /* This forces the loop to exit immediately. */
3753 pDesc = pCtl->pLastDMADesc + 1;
3754 }
3755
3756 PDMCritSectLeave(&pCtl->lock);
3757 }
3758
3759 {
3760 STAM_PROFILE_START(&pCtl->StatLockWait, a);
3761 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
3762 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
3763 }
3764
3765 if (RT_UNLIKELY(fRedo))
3766 return;
3767
3768 if (fLastDesc)
3769 pCtl->BmDma.u8Status &= ~BM_STATUS_DMAING;
3770 s->cbTotalTransfer = cbTotalTransfer;
3771 s->cbElementaryTransfer = cbElementaryTransfer;
3772 s->iIOBufferCur = iIOBufferCur;
3773 s->iIOBufferEnd = iIOBufferEnd;
3774}
3775
3776
3777/**
3778 * Suspend I/O operations on a controller. Also suspends EMT, because it's
3779 * waiting for I/O to make progress. The next attempt to perform an I/O
3780 * operation will be made when EMT is resumed up again (as the resume
3781 * callback below restarts I/O).
3782 *
3783 * @param pCtl Controller for which to suspend I/O.
3784 */
3785static void ataSuspendRedo(PATACONTROLLER pCtl)
3786{
3787 PPDMDEVINS pDevIns = CONTROLLER_2_DEVINS(pCtl);
3788 PVMREQ pReq;
3789 int rc;
3790
3791 pCtl->fRedoIdle = true;
3792 rc = VMR3ReqCall(PDMDevHlpGetVM(pDevIns), &pReq, RT_INDEFINITE_WAIT,
3793 (PFNRT)PDMDevHlpVMSuspend, 1, pDevIns);
3794 AssertReleaseRC(rc);
3795 VMR3ReqFree(pReq);
3796}
3797
3798/** Asynch I/O thread for an interface. Once upon a time this was readable
3799 * code with several loops and a different semaphore for each purpose. But
3800 * then came the "how can one save the state in the middle of a PIO transfer"
3801 * question. The solution was to use an ASM, which is what's there now. */
3802static DECLCALLBACK(int) ataAsyncIOLoop(RTTHREAD ThreadSelf, void *pvUser)
3803{
3804 const ATARequest *pReq;
3805 uint64_t u64TS = 0; /* shut up gcc */
3806 uint64_t uWait;
3807 int rc = VINF_SUCCESS;
3808 PATACONTROLLER pCtl = (PATACONTROLLER)pvUser;
3809 ATADevState *s;
3810
3811 pReq = NULL;
3812 pCtl->fChainedTransfer = false;
3813 while (!pCtl->fShutdown)
3814 {
3815 /* Keep this thread from doing anything as long as EMT is suspended. */
3816 while (pCtl->fRedoIdle)
3817 {
3818 rc = RTSemEventWait(pCtl->SuspendIOSem, RT_INDEFINITE_WAIT);
3819 if (RT_FAILURE(rc) || pCtl->fShutdown)
3820 break;
3821
3822 pCtl->fRedoIdle = false;
3823 }
3824
3825 /* Wait for work. */
3826 if (pReq == NULL)
3827 {
3828 LogBird(("ata: %x: going to sleep...\n", pCtl->IOPortBase1));
3829 rc = RTSemEventWait(pCtl->AsyncIOSem, RT_INDEFINITE_WAIT);
3830 LogBird(("ata: %x: waking up\n", pCtl->IOPortBase1));
3831 if (RT_FAILURE(rc) || pCtl->fShutdown)
3832 break;
3833
3834 pReq = ataAsyncIOGetCurrentRequest(pCtl);
3835 }
3836
3837 if (pReq == NULL)
3838 continue;
3839
3840 ATAAIO ReqType = pReq->ReqType;
3841
3842 Log2(("%s: Ctl#%d: state=%d, req=%d\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl), pCtl->uAsyncIOState, ReqType));
3843 if (pCtl->uAsyncIOState != ReqType)
3844 {
3845 /* The new state is not the state that was expected by the normal
3846 * state changes. This is either a RESET/ABORT or there's something
3847 * really strange going on. */
3848 if ( (pCtl->uAsyncIOState == ATA_AIO_PIO || pCtl->uAsyncIOState == ATA_AIO_DMA)
3849 && (ReqType == ATA_AIO_PIO || ReqType == ATA_AIO_DMA))
3850 {
3851 /* Incorrect sequence of PIO/DMA states. Dump request queue. */
3852 ataAsyncIODumpRequests(pCtl);
3853 }
3854 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));
3855 }
3856
3857 /* Do our work. */
3858 {
3859 STAM_PROFILE_START(&pCtl->StatLockWait, a);
3860 LogBird(("ata: %x: entering critsect\n", pCtl->IOPortBase1));
3861 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
3862 LogBird(("ata: %x: entered\n", pCtl->IOPortBase1));
3863 STAM_PROFILE_STOP(&pCtl->StatLockWait, a);
3864 }
3865
3866 if (pCtl->uAsyncIOState == ATA_AIO_NEW && !pCtl->fChainedTransfer)
3867 {
3868 u64TS = RTTimeNanoTS();
3869#if defined(DEBUG) || defined(VBOX_WITH_STATISTICS)
3870 STAM_PROFILE_ADV_START(&pCtl->StatAsyncTime, a);
3871#endif /* DEBUG || VBOX_WITH_STATISTICS */
3872 }
3873
3874 switch (ReqType)
3875 {
3876 case ATA_AIO_NEW:
3877
3878 pCtl->iAIOIf = pReq->u.t.iIf;
3879 s = &pCtl->aIfs[pCtl->iAIOIf];
3880 s->cbTotalTransfer = pReq->u.t.cbTotalTransfer;
3881 s->uTxDir = pReq->u.t.uTxDir;
3882 s->iBeginTransfer = pReq->u.t.iBeginTransfer;
3883 s->iSourceSink = pReq->u.t.iSourceSink;
3884 s->iIOBufferEnd = 0;
3885 s->u64CmdTS = u64TS;
3886
3887 if (s->fATAPI)
3888 {
3889 if (pCtl->fChainedTransfer)
3890 {
3891 /* Only count the actual transfers, not the PIO
3892 * transfer of the ATAPI command bytes. */
3893 if (s->fDMA)
3894 STAM_REL_COUNTER_INC(&s->StatATAPIDMA);
3895 else
3896 STAM_REL_COUNTER_INC(&s->StatATAPIPIO);
3897 }
3898 }
3899 else
3900 {
3901 if (s->fDMA)
3902 STAM_REL_COUNTER_INC(&s->StatATADMA);
3903 else
3904 STAM_REL_COUNTER_INC(&s->StatATAPIO);
3905 }
3906
3907 pCtl->fChainedTransfer = false;
3908
3909 if (s->iBeginTransfer != ATAFN_BT_NULL)
3910 {
3911 Log2(("%s: Ctl#%d: calling begin transfer function\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
3912 g_apfnBeginTransFuncs[s->iBeginTransfer](s);
3913 s->iBeginTransfer = ATAFN_BT_NULL;
3914 if (s->uTxDir != PDMBLOCKTXDIR_FROM_DEVICE)
3915 s->iIOBufferEnd = s->cbElementaryTransfer;
3916 }
3917 else
3918 {
3919 s->cbElementaryTransfer = s->cbTotalTransfer;
3920 s->iIOBufferEnd = s->cbTotalTransfer;
3921 }
3922 s->iIOBufferCur = 0;
3923
3924 if (s->uTxDir != PDMBLOCKTXDIR_TO_DEVICE)
3925 {
3926 if (s->iSourceSink != ATAFN_SS_NULL)
3927 {
3928 bool fRedo;
3929 Log2(("%s: Ctl#%d: calling source/sink function\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
3930 fRedo = g_apfnSourceSinkFuncs[s->iSourceSink](s);
3931 pCtl->fRedo = fRedo;
3932 if (RT_UNLIKELY(fRedo))
3933 {
3934 /* Operation failed at the initial transfer, restart
3935 * everything from scratch by resending the current
3936 * request. Occurs very rarely, not worth optimizing. */
3937 LogRel(("%s: Ctl#%d: redo entire operation\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
3938 ataAsyncIOPutRequest(pCtl, pReq);
3939 ataSuspendRedo(pCtl);
3940 break;
3941 }
3942 }
3943 else
3944 ataCmdOK(s, 0);
3945 s->iIOBufferEnd = s->cbElementaryTransfer;
3946
3947 }
3948
3949 /* Do not go into the transfer phase if RESET is asserted.
3950 * The CritSect is released while waiting for the host OS
3951 * to finish the I/O, thus RESET is possible here. Most
3952 * important: do not change uAsyncIOState. */
3953 if (pCtl->fReset)
3954 break;
3955
3956 if (s->fDMA)
3957 {
3958 if (s->cbTotalTransfer)
3959 {
3960 ataSetStatus(s, ATA_STAT_DRQ);
3961
3962 pCtl->uAsyncIOState = ATA_AIO_DMA;
3963 /* If BMDMA is already started, do the transfer now. */
3964 if (pCtl->BmDma.u8Cmd & BM_CMD_START)
3965 {
3966 Log2(("%s: Ctl#%d: message to async I/O thread, continuing DMA transfer immediately\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
3967 ataAsyncIOPutRequest(pCtl, &ataDMARequest);
3968 }
3969 }
3970 else
3971 {
3972 Assert(s->uTxDir == PDMBLOCKTXDIR_NONE); /* Any transfer which has an initial transfer size of 0 must be marked as such. */
3973 /* Finish DMA transfer. */
3974 ataDMATransferStop(s);
3975 ataSetIRQ(s);
3976 pCtl->uAsyncIOState = ATA_AIO_NEW;
3977 }
3978 }
3979 else
3980 {
3981 if (s->cbTotalTransfer)
3982 {
3983 ataPIOTransfer(pCtl);
3984 Assert(!pCtl->fRedo);
3985 if (s->fATAPITransfer || s->uTxDir != PDMBLOCKTXDIR_TO_DEVICE)
3986 ataSetIRQ(s);
3987
3988 if (s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE || s->iSourceSink != ATAFN_SS_NULL)
3989 {
3990 /* Write operations and not yet finished transfers
3991 * must be completed in the async I/O thread. */
3992 pCtl->uAsyncIOState = ATA_AIO_PIO;
3993 }
3994 else
3995 {
3996 /* Finished read operation can be handled inline
3997 * in the end of PIO transfer handling code. Linux
3998 * depends on this, as it waits only briefly for
3999 * devices to become ready after incoming data
4000 * transfer. Cannot find anything in the ATA spec
4001 * that backs this assumption, but as all kernels
4002 * are affected (though most of the time it does
4003 * not cause any harm) this must work. */
4004 pCtl->uAsyncIOState = ATA_AIO_NEW;
4005 }
4006 }
4007 else
4008 {
4009 Assert(s->uTxDir == PDMBLOCKTXDIR_NONE); /* Any transfer which has an initial transfer size of 0 must be marked as such. */
4010 /* Finish PIO transfer. */
4011 ataPIOTransfer(pCtl);
4012 Assert(!pCtl->fRedo);
4013 if (!s->fATAPITransfer)
4014 ataSetIRQ(s);
4015 pCtl->uAsyncIOState = ATA_AIO_NEW;
4016 }
4017 }
4018 break;
4019
4020 case ATA_AIO_DMA:
4021 {
4022 BMDMAState *bm = &pCtl->BmDma;
4023 s = &pCtl->aIfs[pCtl->iAIOIf]; /* Do not remove or there's an instant crash after loading the saved state */
4024 ATAFNSS iOriginalSourceSink = (ATAFNSS)s->iSourceSink; /* Used by the hack below, but gets reset by then. */
4025
4026 if (s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE)
4027 AssertRelease(bm->u8Cmd & BM_CMD_WRITE);
4028 else
4029 AssertRelease(!(bm->u8Cmd & BM_CMD_WRITE));
4030
4031 if (RT_LIKELY(!pCtl->fRedo))
4032 {
4033 /* The specs say that the descriptor table must not cross a
4034 * 4K boundary. */
4035 pCtl->pFirstDMADesc = bm->pvAddr;
4036 pCtl->pLastDMADesc = RT_ALIGN_32(bm->pvAddr + 1, _4K) - sizeof(BMDMADesc);
4037 }
4038 ataDMATransfer(pCtl);
4039
4040 if (RT_UNLIKELY(pCtl->fRedo))
4041 {
4042 LogRel(("PIIX3 ATA: Ctl#%d: redo DMA operation\n", ATACONTROLLER_IDX(pCtl)));
4043 ataAsyncIOPutRequest(pCtl, &ataDMARequest);
4044 ataSuspendRedo(pCtl);
4045 break;
4046 }
4047
4048 /* The infamous delay IRQ hack. */
4049 if ( iOriginalSourceSink == ATAFN_SS_WRITE_SECTORS
4050 && s->cbTotalTransfer == 0
4051 && pCtl->DelayIRQMillies)
4052 {
4053 /* Delay IRQ for writing. Required to get the Win2K
4054 * installation work reliably (otherwise it crashes,
4055 * usually during component install). So far no better
4056 * solution has been found. */
4057 Log(("%s: delay IRQ hack\n", __FUNCTION__));
4058 PDMCritSectLeave(&pCtl->lock);
4059 RTThreadSleep(pCtl->DelayIRQMillies);
4060 PDMCritSectEnter(&pCtl->lock, VINF_SUCCESS);
4061 }
4062
4063 ataUnsetStatus(s, ATA_STAT_DRQ);
4064 Assert(!pCtl->fChainedTransfer);
4065 Assert(s->iSourceSink == ATAFN_SS_NULL);
4066 if (s->fATAPITransfer)
4067 {
4068 s->uATARegNSector = (s->uATARegNSector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
4069 Log2(("%s: Ctl#%d: interrupt reason %#04x\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl), s->uATARegNSector));
4070 s->fATAPITransfer = false;
4071 }
4072 ataSetIRQ(s);
4073 pCtl->uAsyncIOState = ATA_AIO_NEW;
4074 break;
4075 }
4076
4077 case ATA_AIO_PIO:
4078 s = &pCtl->aIfs[pCtl->iAIOIf]; /* Do not remove or there's an instant crash after loading the saved state */
4079
4080 if (s->iSourceSink != ATAFN_SS_NULL)
4081 {
4082 bool fRedo;
4083 Log2(("%s: Ctl#%d: calling source/sink function\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
4084 fRedo = g_apfnSourceSinkFuncs[s->iSourceSink](s);
4085 pCtl->fRedo = fRedo;
4086 if (RT_UNLIKELY(fRedo))
4087 {
4088 LogRel(("PIIX3 ATA: Ctl#%d: redo PIO operation\n", ATACONTROLLER_IDX(pCtl)));
4089 ataAsyncIOPutRequest(pCtl, &ataPIORequest);
4090 ataSuspendRedo(pCtl);
4091 break;
4092 }
4093 s->iIOBufferCur = 0;
4094 s->iIOBufferEnd = s->cbElementaryTransfer;
4095 }
4096 else
4097 {
4098 /* Continue a previously started transfer. */
4099 ataUnsetStatus(s, ATA_STAT_BUSY);
4100 ataSetStatus(s, ATA_STAT_READY);
4101 }
4102
4103 /* It is possible that the drives on this controller get RESET
4104 * during the above call to the source/sink function. If that's
4105 * the case, don't restart the transfer and don't finish it the
4106 * usual way. RESET handling took care of all that already.
4107 * Most important: do not change uAsyncIOState. */
4108 if (pCtl->fReset)
4109 break;
4110
4111 if (s->cbTotalTransfer)
4112 {
4113 ataPIOTransfer(pCtl);
4114 ataSetIRQ(s);
4115
4116 if (s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE || s->iSourceSink != ATAFN_SS_NULL)
4117 {
4118 /* Write operations and not yet finished transfers
4119 * must be completed in the async I/O thread. */
4120 pCtl->uAsyncIOState = ATA_AIO_PIO;
4121 }
4122 else
4123 {
4124 /* Finished read operation can be handled inline
4125 * in the end of PIO transfer handling code. Linux
4126 * depends on this, as it waits only briefly for
4127 * devices to become ready after incoming data
4128 * transfer. Cannot find anything in the ATA spec
4129 * that backs this assumption, but as all kernels
4130 * are affected (though most of the time it does
4131 * not cause any harm) this must work. */
4132 pCtl->uAsyncIOState = ATA_AIO_NEW;
4133 }
4134 }
4135 else
4136 {
4137 /* Finish PIO transfer. */
4138 ataPIOTransfer(pCtl);
4139 if ( !pCtl->fChainedTransfer
4140 && !s->fATAPITransfer
4141 && s->uTxDir != PDMBLOCKTXDIR_FROM_DEVICE)
4142 {
4143 ataSetIRQ(s);
4144 }
4145 pCtl->uAsyncIOState = ATA_AIO_NEW;
4146 }
4147 break;
4148
4149 case ATA_AIO_RESET_ASSERTED:
4150 pCtl->uAsyncIOState = ATA_AIO_RESET_CLEARED;
4151 ataPIOTransferStop(&pCtl->aIfs[0]);
4152 ataPIOTransferStop(&pCtl->aIfs[1]);
4153 /* Do not change the DMA registers, they are not affected by the
4154 * ATA controller reset logic. It should be sufficient to issue a
4155 * new command, which is now possible as the state is cleared. */
4156 break;
4157
4158 case ATA_AIO_RESET_CLEARED:
4159 pCtl->uAsyncIOState = ATA_AIO_NEW;
4160 pCtl->fReset = false;
4161 LogRel(("PIIX3 ATA: Ctl#%d: finished processing RESET\n",
4162 ATACONTROLLER_IDX(pCtl)));
4163 for (uint32_t i = 0; i < RT_ELEMENTS(pCtl->aIfs); i++)
4164 {
4165 if (pCtl->aIfs[i].fATAPI)
4166 ataSetStatusValue(&pCtl->aIfs[i], 0); /* NOTE: READY is _not_ set */
4167 else
4168 ataSetStatusValue(&pCtl->aIfs[i], ATA_STAT_READY | ATA_STAT_SEEK);
4169 ataSetSignature(&pCtl->aIfs[i]);
4170 }
4171 break;
4172
4173 case ATA_AIO_ABORT:
4174 /* Abort the current command only if it operates on the same interface. */
4175 if (pCtl->iAIOIf == pReq->u.a.iIf)
4176 {
4177 s = &pCtl->aIfs[pCtl->iAIOIf];
4178
4179 pCtl->uAsyncIOState = ATA_AIO_NEW;
4180 /* Do not change the DMA registers, they are not affected by the
4181 * ATA controller reset logic. It should be sufficient to issue a
4182 * new command, which is now possible as the state is cleared. */
4183 if (pReq->u.a.fResetDrive)
4184 {
4185 ataResetDevice(s);
4186 ataExecuteDeviceDiagnosticSS(s);
4187 }
4188 else
4189 {
4190 ataPIOTransferStop(s);
4191 ataUnsetStatus(s, ATA_STAT_BUSY | ATA_STAT_DRQ | ATA_STAT_SEEK | ATA_STAT_ERR);
4192 ataSetStatus(s, ATA_STAT_READY);
4193 ataSetIRQ(s);
4194 }
4195 }
4196 break;
4197
4198 default:
4199 AssertMsgFailed(("Undefined async I/O state %d\n", pCtl->uAsyncIOState));
4200 }
4201
4202 ataAsyncIORemoveCurrentRequest(pCtl, ReqType);
4203 pReq = ataAsyncIOGetCurrentRequest(pCtl);
4204
4205 if (pCtl->uAsyncIOState == ATA_AIO_NEW && !pCtl->fChainedTransfer)
4206 {
4207#if defined(DEBUG) || defined(VBOX_WITH_STATISTICS)
4208 STAM_PROFILE_ADV_STOP(&pCtl->StatAsyncTime, a);
4209#endif /* DEBUG || VBOX_WITH_STATISTICS */
4210
4211 u64TS = RTTimeNanoTS() - u64TS;
4212 uWait = u64TS / 1000;
4213 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)));
4214 /* Mark command as finished. */
4215 pCtl->aIfs[pCtl->iAIOIf].u64CmdTS = 0;
4216
4217 /*
4218 * Release logging of command execution times depends on the
4219 * command type. ATAPI commands often take longer (due to CD/DVD
4220 * spin up time etc.) so the threshold is different.
4221 */
4222 if (pCtl->aIfs[pCtl->iAIOIf].uATARegCommand != ATA_PACKET)
4223 {
4224 if (uWait > 8 * 1000 * 1000)
4225 {
4226 /*
4227 * Command took longer than 8 seconds. This is close
4228 * enough or over the guest's command timeout, so place
4229 * an entry in the release log to allow tracking such
4230 * timing errors (which are often caused by the host).
4231 */
4232 LogRel(("PIIX3 ATA: execution time for ATA command %#04x was %d seconds\n", pCtl->aIfs[pCtl->iAIOIf].uATARegCommand, uWait / (1000 * 1000)));
4233 }
4234 }
4235 else
4236 {
4237 if (uWait > 20 * 1000 * 1000)
4238 {
4239 /*
4240 * Command took longer than 20 seconds. This is close
4241 * enough or over the guest's command timeout, so place
4242 * an entry in the release log to allow tracking such
4243 * timing errors (which are often caused by the host).
4244 */
4245 LogRel(("PIIX3 ATA: execution time for ATAPI command %#04x was %d seconds\n", pCtl->aIfs[pCtl->iAIOIf].aATAPICmd[0], uWait / (1000 * 1000)));
4246 }
4247 }
4248
4249#if defined(DEBUG) || defined(VBOX_WITH_STATISTICS)
4250 if (uWait < pCtl->StatAsyncMinWait || !pCtl->StatAsyncMinWait)
4251 pCtl->StatAsyncMinWait = uWait;
4252 if (uWait > pCtl->StatAsyncMaxWait)
4253 pCtl->StatAsyncMaxWait = uWait;
4254
4255 STAM_COUNTER_ADD(&pCtl->StatAsyncTimeUS, uWait);
4256 STAM_COUNTER_INC(&pCtl->StatAsyncOps);
4257#endif /* DEBUG || VBOX_WITH_STATISTICS */
4258 }
4259
4260 LogBird(("ata: %x: leaving critsect\n", pCtl->IOPortBase1));
4261 PDMCritSectLeave(&pCtl->lock);
4262 }
4263
4264 /* Cleanup the state. */
4265 if (pCtl->AsyncIOSem)
4266 {
4267 RTSemEventDestroy(pCtl->AsyncIOSem);
4268 pCtl->AsyncIOSem = NIL_RTSEMEVENT;
4269 }
4270 if (pCtl->SuspendIOSem)
4271 {
4272 RTSemEventDestroy(pCtl->SuspendIOSem);
4273 pCtl->SuspendIOSem = NIL_RTSEMEVENT;
4274 }
4275 /* Do not destroy request mutex yet, still needed for proper shutdown. */
4276 pCtl->fShutdown = false;
4277 /* This must be last, as it also signals thread exit to EMT. */
4278 pCtl->AsyncIOThread = NIL_RTTHREAD;
4279
4280 Log2(("%s: Ctl#%d: return %Rrc\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl), rc));
4281 return rc;
4282}
4283
4284#endif /* IN_RING3 */
4285
4286static uint32_t ataBMDMACmdReadB(PATACONTROLLER pCtl, uint32_t addr)
4287{
4288 uint32_t val = pCtl->BmDma.u8Cmd;
4289 Log2(("%s: addr=%#06x val=%#04x\n", __FUNCTION__, addr, val));
4290 return val;
4291}
4292
4293
4294static void ataBMDMACmdWriteB(PATACONTROLLER pCtl, uint32_t addr, uint32_t val)
4295{
4296 Log2(("%s: addr=%#06x val=%#04x\n", __FUNCTION__, addr, val));
4297 if (!(val & BM_CMD_START))
4298 {
4299 pCtl->BmDma.u8Status &= ~BM_STATUS_DMAING;
4300 pCtl->BmDma.u8Cmd = val & (BM_CMD_START | BM_CMD_WRITE);
4301 }
4302 else
4303 {
4304#ifdef IN_RING3
4305 /* Check whether the guest OS wants to change DMA direction in
4306 * mid-flight. Not allowed, according to the PIIX3 specs. */
4307 Assert(!(pCtl->BmDma.u8Status & BM_STATUS_DMAING) || !((val ^ pCtl->BmDma.u8Cmd) & 0x04));
4308 pCtl->BmDma.u8Status |= BM_STATUS_DMAING;
4309 pCtl->BmDma.u8Cmd = val & (BM_CMD_START | BM_CMD_WRITE);
4310
4311 /* Do not continue DMA transfers while the RESET line is asserted. */
4312 if (pCtl->fReset)
4313 {
4314 Log2(("%s: Ctl#%d: suppressed continuing DMA transfer as RESET is active\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
4315 return;
4316 }
4317
4318 /* Do not start DMA transfers if there's a PIO transfer going on. */
4319 if (!pCtl->aIfs[pCtl->iSelectedIf].fDMA)
4320 return;
4321
4322 if (pCtl->aIfs[pCtl->iAIOIf].uATARegStatus & ATA_STAT_DRQ)
4323 {
4324 Log2(("%s: Ctl#%d: message to async I/O thread, continuing DMA transfer\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
4325 ataAsyncIOPutRequest(pCtl, &ataDMARequest);
4326 }
4327#else /* !IN_RING3 */
4328 AssertMsgFailed(("DMA START handling is too complicated for GC\n"));
4329#endif /* IN_RING3 */
4330 }
4331}
4332
4333static uint32_t ataBMDMAStatusReadB(PATACONTROLLER pCtl, uint32_t addr)
4334{
4335 uint32_t val = pCtl->BmDma.u8Status;
4336 Log2(("%s: addr=%#06x val=%#04x\n", __FUNCTION__, addr, val));
4337 return val;
4338}
4339
4340static void ataBMDMAStatusWriteB(PATACONTROLLER pCtl, uint32_t addr, uint32_t val)
4341{
4342 Log2(("%s: addr=%#06x val=%#04x\n", __FUNCTION__, addr, val));
4343 pCtl->BmDma.u8Status = (val & (BM_STATUS_D0DMA | BM_STATUS_D1DMA))
4344 | (pCtl->BmDma.u8Status & BM_STATUS_DMAING)
4345 | (pCtl->BmDma.u8Status & ~val & (BM_STATUS_ERROR | BM_STATUS_INT));
4346}
4347
4348static uint32_t ataBMDMAAddrReadL(PATACONTROLLER pCtl, uint32_t addr)
4349{
4350 uint32_t val = (uint32_t)pCtl->BmDma.pvAddr;
4351 Log2(("%s: addr=%#06x val=%#010x\n", __FUNCTION__, addr, val));
4352 return val;
4353}
4354
4355static void ataBMDMAAddrWriteL(PATACONTROLLER pCtl, uint32_t addr, uint32_t val)
4356{
4357 Log2(("%s: addr=%#06x val=%#010x\n", __FUNCTION__, addr, val));
4358 pCtl->BmDma.pvAddr = val & ~3;
4359}
4360
4361static void ataBMDMAAddrWriteLowWord(PATACONTROLLER pCtl, uint32_t addr, uint32_t val)
4362{
4363 Log2(("%s: addr=%#06x val=%#010x\n", __FUNCTION__, addr, val));
4364 pCtl->BmDma.pvAddr = (pCtl->BmDma.pvAddr & 0xFFFF0000) | RT_LOWORD(val & ~3);
4365
4366}
4367
4368static void ataBMDMAAddrWriteHighWord(PATACONTROLLER pCtl, uint32_t addr, uint32_t val)
4369{
4370 Log2(("%s: addr=%#06x val=%#010x\n", __FUNCTION__, addr, val));
4371 pCtl->BmDma.pvAddr = (RT_LOWORD(val) << 16) | RT_LOWORD(pCtl->BmDma.pvAddr);
4372}
4373
4374#define VAL(port, size) ( ((port) & 7) | ((size) << 3) )
4375
4376/**
4377 * Port I/O Handler for bus master DMA IN operations.
4378 * @see FNIOMIOPORTIN for details.
4379 */
4380PDMBOTHCBDECL(int) ataBMDMAIOPortRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
4381{
4382 uint32_t i = (uint32_t)(uintptr_t)pvUser;
4383 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
4384 PATACONTROLLER pCtl = &pThis->aCts[i];
4385 int rc;
4386
4387 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_HC_IOPORT_READ);
4388 if (rc != VINF_SUCCESS)
4389 return rc;
4390 switch (VAL(Port, cb))
4391 {
4392 case VAL(0, 1): *pu32 = ataBMDMACmdReadB(pCtl, Port); break;
4393 case VAL(0, 2): *pu32 = ataBMDMACmdReadB(pCtl, Port); break;
4394 case VAL(2, 1): *pu32 = ataBMDMAStatusReadB(pCtl, Port); break;
4395 case VAL(2, 2): *pu32 = ataBMDMAStatusReadB(pCtl, Port); break;
4396 case VAL(4, 4): *pu32 = ataBMDMAAddrReadL(pCtl, Port); break;
4397 case VAL(0, 4):
4398 /* The SCO OpenServer tries to read 4 bytes starting from offset 0. */
4399 *pu32 = ataBMDMACmdReadB(pCtl, Port) | (ataBMDMAStatusReadB(pCtl, Port) << 16);
4400 break;
4401 default:
4402 AssertMsgFailed(("%s: Unsupported read from port %x size=%d\n", __FUNCTION__, Port, cb));
4403 PDMCritSectLeave(&pCtl->lock);
4404 return VERR_IOM_IOPORT_UNUSED;
4405 }
4406 PDMCritSectLeave(&pCtl->lock);
4407 return rc;
4408}
4409
4410/**
4411 * Port I/O Handler for bus master DMA OUT operations.
4412 * @see FNIOMIOPORTOUT for details.
4413 */
4414PDMBOTHCBDECL(int) ataBMDMAIOPortWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
4415{
4416 uint32_t i = (uint32_t)(uintptr_t)pvUser;
4417 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
4418 PATACONTROLLER pCtl = &pThis->aCts[i];
4419 int rc;
4420
4421 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_HC_IOPORT_WRITE);
4422 if (rc != VINF_SUCCESS)
4423 return rc;
4424 switch (VAL(Port, cb))
4425 {
4426 case VAL(0, 1):
4427#ifndef IN_RING3
4428 if (u32 & BM_CMD_START)
4429 {
4430 rc = VINF_IOM_HC_IOPORT_WRITE;
4431 break;
4432 }
4433#endif /* !IN_RING3 */
4434 ataBMDMACmdWriteB(pCtl, Port, u32);
4435 break;
4436 case VAL(2, 1): ataBMDMAStatusWriteB(pCtl, Port, u32); break;
4437 case VAL(4, 4): ataBMDMAAddrWriteL(pCtl, Port, u32); break;
4438 case VAL(4, 2): ataBMDMAAddrWriteLowWord(pCtl, Port, u32); break;
4439 case VAL(6, 2): ataBMDMAAddrWriteHighWord(pCtl, Port, u32); break;
4440 default: AssertMsgFailed(("%s: Unsupported write to port %x size=%d val=%x\n", __FUNCTION__, Port, cb, u32)); break;
4441 }
4442 PDMCritSectLeave(&pCtl->lock);
4443 return rc;
4444}
4445
4446#undef VAL
4447
4448#ifdef IN_RING3
4449
4450/**
4451 * Callback function for mapping an PCI I/O region.
4452 *
4453 * @return VBox status code.
4454 * @param pPciDev Pointer to PCI device. Use pPciDev->pDevIns to get the device instance.
4455 * @param iRegion The region number.
4456 * @param GCPhysAddress Physical address of the region. If iType is PCI_ADDRESS_SPACE_IO, this is an
4457 * I/O port, else it's a physical address.
4458 * This address is *NOT* relative to pci_mem_base like earlier!
4459 * @param enmType One of the PCI_ADDRESS_SPACE_* values.
4460 */
4461static DECLCALLBACK(int) ataBMDMAIORangeMap(PPCIDEVICE pPciDev, /*unsigned*/ int iRegion, RTGCPHYS GCPhysAddress, uint32_t cb, PCIADDRESSSPACE enmType)
4462{
4463 PCIATAState *pThis = PCIDEV_2_PCIATASTATE(pPciDev);
4464 int rc = VINF_SUCCESS;
4465 Assert(enmType == PCI_ADDRESS_SPACE_IO);
4466 Assert(iRegion == 4);
4467 AssertMsg(RT_ALIGN(GCPhysAddress, 8) == GCPhysAddress, ("Expected 8 byte alignment. GCPhysAddress=%#x\n", GCPhysAddress));
4468
4469 /* Register the port range. */
4470 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
4471 {
4472 int rc2 = PDMDevHlpIOPortRegister(pPciDev->pDevIns, (RTIOPORT)GCPhysAddress + i * 8, 8,
4473 (RTHCPTR)i, ataBMDMAIOPortWrite, ataBMDMAIOPortRead, NULL, NULL, "ATA Bus Master DMA");
4474 AssertRC(rc2);
4475 if (rc2 < rc)
4476 rc = rc2;
4477
4478 if (pThis->fGCEnabled)
4479 {
4480 rc2 = PDMDevHlpIOPortRegisterGC(pPciDev->pDevIns, (RTIOPORT)GCPhysAddress + i * 8, 8,
4481 (RTGCPTR)i, "ataBMDMAIOPortWrite", "ataBMDMAIOPortRead", NULL, NULL, "ATA Bus Master DMA");
4482 AssertRC(rc2);
4483 if (rc2 < rc)
4484 rc = rc2;
4485 }
4486 if (pThis->fR0Enabled)
4487 {
4488 rc2 = PDMDevHlpIOPortRegisterR0(pPciDev->pDevIns, (RTIOPORT)GCPhysAddress + i * 8, 8,
4489 (RTR0PTR)i, "ataBMDMAIOPortWrite", "ataBMDMAIOPortRead", NULL, NULL, "ATA Bus Master DMA");
4490 AssertRC(rc2);
4491 if (rc2 < rc)
4492 rc = rc2;
4493 }
4494 }
4495 return rc;
4496}
4497
4498
4499/**
4500 * Reset notification.
4501 *
4502 * @returns VBox status.
4503 * @param pDevIns The device instance data.
4504 */
4505static DECLCALLBACK(void) ataReset(PPDMDEVINS pDevIns)
4506{
4507 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
4508
4509 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
4510 {
4511 pThis->aCts[i].iSelectedIf = 0;
4512 pThis->aCts[i].iAIOIf = 0;
4513 pThis->aCts[i].BmDma.u8Cmd = 0;
4514 /* Report that both drives present on the bus are in DMA mode. This
4515 * pretends that there is a BIOS that has set it up. Normal reset
4516 * default is 0x00. */
4517 pThis->aCts[i].BmDma.u8Status = (pThis->aCts[i].aIfs[0].pDrvBase != NULL ? BM_STATUS_D0DMA : 0)
4518 | (pThis->aCts[i].aIfs[1].pDrvBase != NULL ? BM_STATUS_D1DMA : 0);
4519 pThis->aCts[i].BmDma.pvAddr = 0;
4520
4521 pThis->aCts[i].fReset = true;
4522 pThis->aCts[i].fRedo = false;
4523 pThis->aCts[i].fRedoIdle = false;
4524 ataAsyncIOClearRequests(&pThis->aCts[i]);
4525 Log2(("%s: Ctl#%d: message to async I/O thread, reset controller\n", __FUNCTION__, i));
4526 ataAsyncIOPutRequest(&pThis->aCts[i], &ataResetARequest);
4527 ataAsyncIOPutRequest(&pThis->aCts[i], &ataResetCRequest);
4528 if (!ataWaitForAsyncIOIsIdle(&pThis->aCts[i], 30000))
4529 AssertReleaseMsgFailed(("Async I/O thread busy after reset\n"));
4530
4531 for (uint32_t j = 0; j < RT_ELEMENTS(pThis->aCts[i].aIfs); j++)
4532 ataResetDevice(&pThis->aCts[i].aIfs[j]);
4533 }
4534}
4535
4536
4537/* -=-=-=-=-=- PCIATAState::IBase -=-=-=-=-=- */
4538
4539/**
4540 * Queries an interface to the driver.
4541 *
4542 * @returns Pointer to interface.
4543 * @returns NULL if the interface was not supported by the device.
4544 * @param pInterface Pointer to ATADevState::IBase.
4545 * @param enmInterface The requested interface identification.
4546 */
4547static DECLCALLBACK(void *) ataStatus_QueryInterface(PPDMIBASE pInterface, PDMINTERFACE enmInterface)
4548{
4549 PCIATAState *pThis = PDMIBASE_2_PCIATASTATE(pInterface);
4550 switch (enmInterface)
4551 {
4552 case PDMINTERFACE_BASE:
4553 return &pThis->IBase;
4554 case PDMINTERFACE_LED_PORTS:
4555 return &pThis->ILeds;
4556 default:
4557 return NULL;
4558 }
4559}
4560
4561
4562/* -=-=-=-=-=- PCIATAState::ILeds -=-=-=-=-=- */
4563
4564/**
4565 * Gets the pointer to the status LED of a unit.
4566 *
4567 * @returns VBox status code.
4568 * @param pInterface Pointer to the interface structure containing the called function pointer.
4569 * @param iLUN The unit which status LED we desire.
4570 * @param ppLed Where to store the LED pointer.
4571 */
4572static DECLCALLBACK(int) ataStatus_QueryStatusLed(PPDMILEDPORTS pInterface, unsigned iLUN, PPDMLED *ppLed)
4573{
4574 PCIATAState *pThis = PDMILEDPORTS_2_PCIATASTATE(pInterface);
4575 if (iLUN >= 0 && iLUN <= 4)
4576 {
4577 switch (iLUN)
4578 {
4579 case 0: *ppLed = &pThis->aCts[0].aIfs[0].Led; break;
4580 case 1: *ppLed = &pThis->aCts[0].aIfs[1].Led; break;
4581 case 2: *ppLed = &pThis->aCts[1].aIfs[0].Led; break;
4582 case 3: *ppLed = &pThis->aCts[1].aIfs[1].Led; break;
4583 }
4584 Assert((*ppLed)->u32Magic == PDMLED_MAGIC);
4585 return VINF_SUCCESS;
4586 }
4587 return VERR_PDM_LUN_NOT_FOUND;
4588}
4589
4590
4591/* -=-=-=-=-=- ATADevState::IBase -=-=-=-=-=- */
4592
4593/**
4594 * Queries an interface to the driver.
4595 *
4596 * @returns Pointer to interface.
4597 * @returns NULL if the interface was not supported by the device.
4598 * @param pInterface Pointer to ATADevState::IBase.
4599 * @param enmInterface The requested interface identification.
4600 */
4601static DECLCALLBACK(void *) ataQueryInterface(PPDMIBASE pInterface, PDMINTERFACE enmInterface)
4602{
4603 ATADevState *pIf = PDMIBASE_2_ATASTATE(pInterface);
4604 switch (enmInterface)
4605 {
4606 case PDMINTERFACE_BASE:
4607 return &pIf->IBase;
4608 case PDMINTERFACE_BLOCK_PORT:
4609 return &pIf->IPort;
4610 case PDMINTERFACE_MOUNT_NOTIFY:
4611 return &pIf->IMountNotify;
4612 default:
4613 return NULL;
4614 }
4615}
4616
4617#endif /* IN_RING3 */
4618
4619
4620/* -=-=-=-=-=- Wrappers -=-=-=-=-=- */
4621
4622/**
4623 * Port I/O Handler for primary port range OUT operations.
4624 * @see FNIOMIOPORTOUT for details.
4625 */
4626PDMBOTHCBDECL(int) ataIOPortWrite1(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
4627{
4628 uint32_t i = (uint32_t)(uintptr_t)pvUser;
4629 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
4630 PATACONTROLLER pCtl = &pThis->aCts[i];
4631 int rc = VINF_SUCCESS;
4632
4633 Assert(i < 2);
4634
4635 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_HC_IOPORT_WRITE);
4636 if (rc != VINF_SUCCESS)
4637 return rc;
4638 if (cb == 1)
4639 rc = ataIOPortWriteU8(pCtl, Port, u32);
4640 else if (Port == pCtl->IOPortBase1)
4641 {
4642 Assert(cb == 2 || cb == 4);
4643 rc = ataDataWrite(pCtl, Port, cb, (const uint8_t *)&u32);
4644 }
4645 else
4646 AssertMsgFailed(("ataIOPortWrite1: unsupported write to port %x val=%x size=%d\n", Port, u32, cb));
4647 LogBird(("ata: leaving critsect\n"));
4648 PDMCritSectLeave(&pCtl->lock);
4649 LogBird(("ata: left critsect\n"));
4650 return rc;
4651}
4652
4653
4654/**
4655 * Port I/O Handler for primary port range IN operations.
4656 * @see FNIOMIOPORTIN for details.
4657 */
4658PDMBOTHCBDECL(int) ataIOPortRead1(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
4659{
4660 uint32_t i = (uint32_t)(uintptr_t)pvUser;
4661 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
4662 PATACONTROLLER pCtl = &pThis->aCts[i];
4663 int rc = VINF_SUCCESS;
4664
4665 Assert(i < 2);
4666
4667 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_HC_IOPORT_READ);
4668 if (rc != VINF_SUCCESS)
4669 return rc;
4670 if (cb == 1)
4671 {
4672 rc = ataIOPortReadU8(pCtl, Port, pu32);
4673 }
4674 else if (Port == pCtl->IOPortBase1)
4675 {
4676 Assert(cb == 2 || cb == 4);
4677 rc = ataDataRead(pCtl, Port, cb, (uint8_t *)pu32);
4678 if (cb == 2)
4679 *pu32 &= 0xffff;
4680 }
4681 else
4682 {
4683 AssertMsgFailed(("ataIOPortRead1: unsupported read from port %x size=%d\n", Port, cb));
4684 rc = VERR_IOM_IOPORT_UNUSED;
4685 }
4686 PDMCritSectLeave(&pCtl->lock);
4687 return rc;
4688}
4689
4690#ifndef IN_RING0
4691/**
4692 * Port I/O Handler for primary port range IN string operations.
4693 * @see FNIOMIOPORTINSTRING for details.
4694 */
4695PDMBOTHCBDECL(int) ataIOPortReadStr1(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, RTGCPTR *pGCPtrDst, PRTGCUINTREG pcTransfer, unsigned cb)
4696{
4697 uint32_t i = (uint32_t)(uintptr_t)pvUser;
4698 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
4699 PATACONTROLLER pCtl = &pThis->aCts[i];
4700 int rc = VINF_SUCCESS;
4701
4702 Assert(i < 2);
4703
4704 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_HC_IOPORT_READ);
4705 if (rc != VINF_SUCCESS)
4706 return rc;
4707 if (Port == pCtl->IOPortBase1)
4708 {
4709 uint32_t cTransAvailable, cTransfer = *pcTransfer, cbTransfer;
4710 RTGCPTR GCDst = *pGCPtrDst;
4711 ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf];
4712 Assert(cb == 2 || cb == 4);
4713
4714 cTransAvailable = (s->iIOBufferPIODataEnd - s->iIOBufferPIODataStart) / cb;
4715#ifndef IN_RING3
4716 /* The last transfer unit cannot be handled in GC, as it involves thread communication. */
4717 cTransAvailable--;
4718#endif /* !IN_RING3 */
4719 /* Do not handle the dummy transfer stuff here, leave it to the single-word transfers.
4720 * They are not performance-critical and generally shouldn't occur at all. */
4721 if (cTransAvailable > cTransfer)
4722 cTransAvailable = cTransfer;
4723 cbTransfer = cTransAvailable * cb;
4724
4725#ifdef IN_GC
4726 for (uint32_t i = 0; i < cbTransfer; i += cb)
4727 MMGCRamWriteNoTrapHandler((char *)GCDst + i, s->CTX_SUFF(pbIOBuffer) + s->iIOBufferPIODataStart + i, cb);
4728#else /* !IN_GC */
4729 rc = PGMPhysWriteGCPtrDirty(PDMDevHlpGetVM(pDevIns), GCDst, s->CTX_SUFF(pbIOBuffer) + s->iIOBufferPIODataStart, cbTransfer);
4730 Assert(rc == VINF_SUCCESS);
4731#endif /* IN_GC */
4732
4733 if (cbTransfer)
4734 Log3(("%s: addr=%#x val=%.*Vhxs\n", __FUNCTION__, Port, cbTransfer, s->CTX_SUFF(pbIOBuffer) + s->iIOBufferPIODataStart));
4735 s->iIOBufferPIODataStart += cbTransfer;
4736 *pGCPtrDst = (RTGCPTR)((RTGCUINTPTR)GCDst + cbTransfer);
4737 *pcTransfer = cTransfer - cTransAvailable;
4738#ifdef IN_RING3
4739 if (s->iIOBufferPIODataStart >= s->iIOBufferPIODataEnd)
4740 ataPIOTransferFinish(pCtl, s);
4741#endif /* IN_RING3 */
4742 }
4743 PDMCritSectLeave(&pCtl->lock);
4744 return rc;
4745}
4746
4747
4748/**
4749 * Port I/O Handler for primary port range OUT string operations.
4750 * @see FNIOMIOPORTOUTSTRING for details.
4751 */
4752PDMBOTHCBDECL(int) ataIOPortWriteStr1(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, RTGCPTR *pGCPtrSrc, PRTGCUINTREG pcTransfer, unsigned cb)
4753{
4754 uint32_t i = (uint32_t)(uintptr_t)pvUser;
4755 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
4756 PATACONTROLLER pCtl = &pThis->aCts[i];
4757 int rc;
4758
4759 Assert(i < 2);
4760
4761 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_HC_IOPORT_WRITE);
4762 if (rc != VINF_SUCCESS)
4763 return rc;
4764 if (Port == pCtl->IOPortBase1)
4765 {
4766 uint32_t cTransAvailable, cTransfer = *pcTransfer, cbTransfer;
4767 RTGCPTR GCSrc = *pGCPtrSrc;
4768 ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf];
4769 Assert(cb == 2 || cb == 4);
4770
4771 cTransAvailable = (s->iIOBufferPIODataEnd - s->iIOBufferPIODataStart) / cb;
4772#ifndef IN_RING3
4773 /* The last transfer unit cannot be handled in GC, as it involves thread communication. */
4774 cTransAvailable--;
4775#endif /* !IN_RING3 */
4776 /* Do not handle the dummy transfer stuff here, leave it to the single-word transfers.
4777 * They are not performance-critical and generally shouldn't occur at all. */
4778 if (cTransAvailable > cTransfer)
4779 cTransAvailable = cTransfer;
4780 cbTransfer = cTransAvailable * cb;
4781
4782#ifdef IN_GC
4783 for (uint32_t i = 0; i < cbTransfer; i += cb)
4784 MMGCRamReadNoTrapHandler(s->CTX_SUFF(pbIOBuffer) + s->iIOBufferPIODataStart + i, (char *)GCSrc + i, cb);
4785#else /* !IN_GC */
4786 rc = PGMPhysReadGCPtr(PDMDevHlpGetVM(pDevIns), s->CTX_SUFF(pbIOBuffer) + s->iIOBufferPIODataStart, GCSrc, cbTransfer);
4787 Assert(rc == VINF_SUCCESS);
4788#endif /* IN_GC */
4789
4790 if (cbTransfer)
4791 Log3(("%s: addr=%#x val=%.*Vhxs\n", __FUNCTION__, Port, cbTransfer, s->CTX_SUFF(pbIOBuffer) + s->iIOBufferPIODataStart));
4792 s->iIOBufferPIODataStart += cbTransfer;
4793 *pGCPtrSrc = (RTGCPTR)((RTGCUINTPTR)GCSrc + cbTransfer);
4794 *pcTransfer = cTransfer - cTransAvailable;
4795#ifdef IN_RING3
4796 if (s->iIOBufferPIODataStart >= s->iIOBufferPIODataEnd)
4797 ataPIOTransferFinish(pCtl, s);
4798#endif /* IN_RING3 */
4799 }
4800 PDMCritSectLeave(&pCtl->lock);
4801 return rc;
4802}
4803#endif /* !IN_RING0 */
4804
4805/**
4806 * Port I/O Handler for secondary port range OUT operations.
4807 * @see FNIOMIOPORTOUT for details.
4808 */
4809PDMBOTHCBDECL(int) ataIOPortWrite2(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
4810{
4811 uint32_t i = (uint32_t)(uintptr_t)pvUser;
4812 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
4813 PATACONTROLLER pCtl = &pThis->aCts[i];
4814 int rc;
4815
4816 Assert(i < 2);
4817
4818 if (cb != 1)
4819 return VINF_SUCCESS;
4820 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_HC_IOPORT_WRITE);
4821 if (rc != VINF_SUCCESS)
4822 return rc;
4823 rc = ataControlWrite(pCtl, Port, u32);
4824 PDMCritSectLeave(&pCtl->lock);
4825 return rc;
4826}
4827
4828
4829/**
4830 * Port I/O Handler for secondary port range IN operations.
4831 * @see FNIOMIOPORTIN for details.
4832 */
4833PDMBOTHCBDECL(int) ataIOPortRead2(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
4834{
4835 uint32_t i = (uint32_t)(uintptr_t)pvUser;
4836 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
4837 PATACONTROLLER pCtl = &pThis->aCts[i];
4838 int rc;
4839
4840 Assert(i < 2);
4841
4842 if (cb != 1)
4843 return VERR_IOM_IOPORT_UNUSED;
4844
4845 rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_HC_IOPORT_READ);
4846 if (rc != VINF_SUCCESS)
4847 return rc;
4848 *pu32 = ataStatusRead(pCtl, Port);
4849 PDMCritSectLeave(&pCtl->lock);
4850 return VINF_SUCCESS;
4851}
4852
4853#ifdef IN_RING3
4854
4855/**
4856 * Waits for all async I/O threads to complete whatever they
4857 * are doing at the moment.
4858 *
4859 * @returns true on success.
4860 * @returns false when one or more threads is still processing.
4861 * @param pThis Pointer to the instance data.
4862 * @param cMillies How long to wait (total).
4863 */
4864static bool ataWaitForAllAsyncIOIsIdle(PPDMDEVINS pDevIns, unsigned cMillies)
4865{
4866 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
4867 bool fVMLocked;
4868 uint64_t u64Start;
4869 PATACONTROLLER pCtl;
4870 bool fAllIdle = false;
4871
4872 /* The only way to deal cleanly with the VM lock is to check whether
4873 * it is owned now (it always is owned by EMT, which is the current
4874 * thread). Since this function is called several times during VM
4875 * shutdown, and the VM lock is only held for the first call (which
4876 * can be either from ataPowerOff or ataSuspend), there is no other
4877 * reasonable solution. */
4878 fVMLocked = VMMR3LockIsOwner(PDMDevHlpGetVM(pDevIns));
4879
4880 if (fVMLocked)
4881 pDevIns->pDevHlp->pfnUnlockVM(pDevIns);
4882 /*
4883 * Wait for any pending async operation to finish
4884 */
4885 u64Start = RTTimeMilliTS();
4886 for (;;)
4887 {
4888 /* Check all async I/O threads. */
4889 fAllIdle = true;
4890 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
4891 {
4892 pCtl = &pThis->aCts[i];
4893 fAllIdle &= ataAsyncIOIsIdle(pCtl, false);
4894 if (!fAllIdle)
4895 break;
4896 }
4897 if ( fAllIdle
4898 || RTTimeMilliTS() - u64Start >= cMillies)
4899 break;
4900
4901 /* Sleep for a bit. */
4902 RTThreadSleep(100);
4903 }
4904
4905 if (fVMLocked)
4906 pDevIns->pDevHlp->pfnLockVM(pDevIns);
4907
4908 if (!fAllIdle)
4909 LogRel(("PIIX3 ATA: Ctl#%d is still executing, DevSel=%d AIOIf=%d CmdIf0=%#04x CmdIf1=%#04x\n",
4910 ATACONTROLLER_IDX(pCtl), pCtl->iSelectedIf, pCtl->iAIOIf,
4911 pCtl->aIfs[0].uATARegCommand, pCtl->aIfs[1].uATARegCommand));
4912
4913 return fAllIdle;
4914}
4915
4916
4917DECLINLINE(void) ataRelocBuffer(PPDMDEVINS pDevIns, ATADevState *s)
4918{
4919 if (s->pbIOBufferR3)
4920 s->pbIOBufferRC = MMHyperR3ToRC(PDMDevHlpGetVM(pDevIns), s->pbIOBufferR3);
4921}
4922
4923
4924/**
4925 * @copydoc FNPDMDEVRELOCATE
4926 */
4927static DECLCALLBACK(void) ataRelocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta)
4928{
4929 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
4930
4931 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
4932 {
4933 pThis->aCts[i].pDevInsRC += offDelta;
4934 pThis->aCts[i].aIfs[0].pDevInsRC += offDelta;
4935 pThis->aCts[i].aIfs[0].pControllerRC += offDelta;
4936 ataRelocBuffer(pDevIns, &pThis->aCts[i].aIfs[0]);
4937 pThis->aCts[i].aIfs[1].pDevInsRC += offDelta;
4938 pThis->aCts[i].aIfs[1].pControllerRC += offDelta;
4939 ataRelocBuffer(pDevIns, &pThis->aCts[i].aIfs[1]);
4940 }
4941}
4942
4943
4944/**
4945 * Destroy a driver instance.
4946 *
4947 * Most VM resources are freed by the VM. This callback is provided so that any non-VM
4948 * resources can be freed correctly.
4949 *
4950 * @param pDevIns The device instance data.
4951 */
4952static DECLCALLBACK(int) ataDestruct(PPDMDEVINS pDevIns)
4953{
4954 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
4955 int rc;
4956
4957 Log(("%s:\n", __FUNCTION__));
4958
4959 /*
4960 * Terminate all async helper threads
4961 */
4962 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
4963 {
4964 if (pThis->aCts[i].AsyncIOThread != NIL_RTTHREAD)
4965 {
4966 ASMAtomicXchgU32(&pThis->aCts[i].fShutdown, true);
4967 rc = RTSemEventSignal(pThis->aCts[i].AsyncIOSem);
4968 AssertRC(rc);
4969 }
4970 }
4971
4972 /*
4973 * Wait for them to complete whatever they are doing and then
4974 * for them to terminate.
4975 */
4976 if (ataWaitForAllAsyncIOIsIdle(pDevIns, 20000))
4977 {
4978 for (unsigned i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
4979 {
4980 rc = RTThreadWait(pThis->aCts[i].AsyncIOThread, 30000 /* 30 s*/, NULL);
4981 AssertMsg(RT_SUCCESS(rc) || rc == VERR_INVALID_HANDLE, ("rc=%Rrc i=%d\n", rc, i));
4982 }
4983 }
4984 else
4985 AssertMsgFailed(("Async I/O is still busy!\n"));
4986
4987 /*
4988 * Now the request mutexes are no longer needed. Free resources.
4989 */
4990 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
4991 {
4992 if (pThis->aCts[i].AsyncIORequestMutex != NIL_RTSEMEVENT)
4993 {
4994 RTSemMutexDestroy(pThis->aCts[i].AsyncIORequestMutex);
4995 pThis->aCts[i].AsyncIORequestMutex = NIL_RTSEMEVENT;
4996 }
4997 }
4998 return VINF_SUCCESS;
4999}
5000
5001
5002/**
5003 * Detach notification.
5004 *
5005 * The DVD drive has been unplugged.
5006 *
5007 * @param pDevIns The device instance.
5008 * @param iLUN The logical unit which is being detached.
5009 */
5010static DECLCALLBACK(void) ataDetach(PPDMDEVINS pDevIns, unsigned iLUN)
5011{
5012 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
5013 PATACONTROLLER pCtl;
5014 ATADevState *pIf;
5015 unsigned iController;
5016 unsigned iInterface;
5017
5018 /*
5019 * Locate the controller and stuff.
5020 */
5021 iController = iLUN / RT_ELEMENTS(pThis->aCts[0].aIfs);
5022 AssertReleaseMsg(iController < RT_ELEMENTS(pThis->aCts), ("iController=%d iLUN=%d\n", iController, iLUN));
5023 pCtl = &pThis->aCts[iController];
5024
5025 iInterface = iLUN % RT_ELEMENTS(pThis->aCts[0].aIfs);
5026 pIf = &pCtl->aIfs[iInterface];
5027
5028 /*
5029 * Zero some important members.
5030 */
5031 pIf->pDrvBase = NULL;
5032 pIf->pDrvBlock = NULL;
5033 pIf->pDrvBlockBios = NULL;
5034 pIf->pDrvMount = NULL;
5035}
5036
5037
5038/**
5039 * Configure a LUN.
5040 *
5041 * @returns VBox status code.
5042 * @param pDevIns The device instance.
5043 * @param pIf The ATA unit state.
5044 */
5045static int ataConfigLun(PPDMDEVINS pDevIns, ATADevState *pIf)
5046{
5047 int rc;
5048 PDMBLOCKTYPE enmType;
5049
5050 /*
5051 * Query Block, Bios and Mount interfaces.
5052 */
5053 pIf->pDrvBlock = (PDMIBLOCK *)pIf->pDrvBase->pfnQueryInterface(pIf->pDrvBase, PDMINTERFACE_BLOCK);
5054 if (!pIf->pDrvBlock)
5055 {
5056 AssertMsgFailed(("Configuration error: LUN#%d hasn't a block interface!\n", pIf->iLUN));
5057 return VERR_PDM_MISSING_INTERFACE;
5058 }
5059
5060 /** @todo implement the BIOS invisible code path. */
5061 pIf->pDrvBlockBios = (PDMIBLOCKBIOS *)pIf->pDrvBase->pfnQueryInterface(pIf->pDrvBase, PDMINTERFACE_BLOCK_BIOS);
5062 if (!pIf->pDrvBlockBios)
5063 {
5064 AssertMsgFailed(("Configuration error: LUN#%d hasn't a block BIOS interface!\n", pIf->iLUN));
5065 return VERR_PDM_MISSING_INTERFACE;
5066 }
5067 pIf->pDrvMount = (PDMIMOUNT *)pIf->pDrvBase->pfnQueryInterface(pIf->pDrvBase, PDMINTERFACE_MOUNT);
5068
5069 /*
5070 * Validate type.
5071 */
5072 enmType = pIf->pDrvBlock->pfnGetType(pIf->pDrvBlock);
5073 if ( enmType != PDMBLOCKTYPE_CDROM
5074 && enmType != PDMBLOCKTYPE_DVD
5075 && enmType != PDMBLOCKTYPE_HARD_DISK)
5076 {
5077 AssertMsgFailed(("Configuration error: LUN#%d isn't a disk or cd/dvd-rom. enmType=%d\n", pIf->iLUN, enmType));
5078 return VERR_PDM_UNSUPPORTED_BLOCK_TYPE;
5079 }
5080 if ( ( enmType == PDMBLOCKTYPE_DVD
5081 || enmType == PDMBLOCKTYPE_CDROM)
5082 && !pIf->pDrvMount)
5083 {
5084 AssertMsgFailed(("Internal error: cdrom without a mountable interface, WTF???!\n"));
5085 return VERR_INTERNAL_ERROR;
5086 }
5087 pIf->fATAPI = enmType == PDMBLOCKTYPE_DVD || enmType == PDMBLOCKTYPE_CDROM;
5088 pIf->fATAPIPassthrough = pIf->fATAPI ? (pIf->pDrvBlock->pfnSendCmd != NULL) : false;
5089
5090 /*
5091 * Allocate I/O buffer.
5092 */
5093 PVM pVM = PDMDevHlpGetVM(pDevIns);
5094 if (pIf->cbIOBuffer)
5095 {
5096 /* Buffer is (probably) already allocated. Validate the fields,
5097 * because memory corruption can also overwrite pIf->cbIOBuffer. */
5098 if (pIf->fATAPI)
5099 AssertRelease(pIf->cbIOBuffer == _128K);
5100 else
5101 AssertRelease(pIf->cbIOBuffer == ATA_MAX_MULT_SECTORS * 512);
5102 Assert(pIf->pbIOBufferR3);
5103 Assert(pIf->pbIOBufferR0 == MMHyperR3ToR0(pVM, pIf->pbIOBufferR3));
5104 Assert(pIf->pbIOBufferRC == MMHyperR3ToRC(pVM, pIf->pbIOBufferR3));
5105 }
5106 else
5107 {
5108 if (pIf->fATAPI)
5109 pIf->cbIOBuffer = _128K;
5110 else
5111 pIf->cbIOBuffer = ATA_MAX_MULT_SECTORS * 512;
5112 Assert(!pIf->pbIOBufferR3);
5113 rc = MMHyperAlloc(pVM, pIf->cbIOBuffer, 1, MM_TAG_PDM_DEVICE_USER, (void **)&pIf->pbIOBufferR3); /** @todo rainy day: change to MMR3HyperAllocOnceNoRel */
5114 if (RT_FAILURE(rc))
5115 return VERR_NO_MEMORY;
5116 pIf->pbIOBufferR0 = MMHyperR3ToR0(pVM, pIf->pbIOBufferR3);
5117 pIf->pbIOBufferRC = MMHyperR3ToRC(pVM, pIf->pbIOBufferR3);
5118 }
5119
5120 /*
5121 * Init geometry (only for non-CD/DVD media).
5122 */
5123 if (pIf->fATAPI)
5124 {
5125 pIf->cTotalSectors = pIf->pDrvBlock->pfnGetSize(pIf->pDrvBlock) / 2048;
5126 pIf->PCHSGeometry.cCylinders = 0; /* dummy */
5127 pIf->PCHSGeometry.cHeads = 0; /* dummy */
5128 pIf->PCHSGeometry.cSectors = 0; /* dummy */
5129 LogRel(("PIIX3 ATA: LUN#%d: CD/DVD, total number of sectors %Ld, passthrough %s\n", pIf->iLUN, pIf->cTotalSectors, (pIf->fATAPIPassthrough ? "enabled" : "disabled")));
5130 }
5131 else
5132 {
5133 pIf->cTotalSectors = pIf->pDrvBlock->pfnGetSize(pIf->pDrvBlock) / 512;
5134 rc = pIf->pDrvBlockBios->pfnGetPCHSGeometry(pIf->pDrvBlockBios,
5135 &pIf->PCHSGeometry);
5136 if (rc == VERR_PDM_MEDIA_NOT_MOUNTED)
5137 {
5138 pIf->PCHSGeometry.cCylinders = 0;
5139 pIf->PCHSGeometry.cHeads = 16; /*??*/
5140 pIf->PCHSGeometry.cSectors = 63; /*??*/
5141 }
5142 else if (rc == VERR_PDM_GEOMETRY_NOT_SET)
5143 {
5144 pIf->PCHSGeometry.cCylinders = 0; /* autodetect marker */
5145 rc = VINF_SUCCESS;
5146 }
5147 AssertRC(rc);
5148
5149 if ( pIf->PCHSGeometry.cCylinders == 0
5150 || pIf->PCHSGeometry.cHeads == 0
5151 || pIf->PCHSGeometry.cSectors == 0
5152 )
5153 {
5154 uint64_t cCylinders = pIf->cTotalSectors / (16 * 63);
5155 pIf->PCHSGeometry.cCylinders = RT_MAX(RT_MIN(cCylinders, 16383), 1);
5156 pIf->PCHSGeometry.cHeads = 16;
5157 pIf->PCHSGeometry.cSectors = 63;
5158 /* Set the disk geometry information. */
5159 rc = pIf->pDrvBlockBios->pfnSetPCHSGeometry(pIf->pDrvBlockBios,
5160 &pIf->PCHSGeometry);
5161 }
5162 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));
5163 }
5164 return VINF_SUCCESS;
5165}
5166
5167
5168/**
5169 * Attach command.
5170 *
5171 * This is called when we change block driver for the DVD drive.
5172 *
5173 * @returns VBox status code.
5174 * @param pDevIns The device instance.
5175 * @param iLUN The logical unit which is being detached.
5176 */
5177static DECLCALLBACK(int) ataAttach(PPDMDEVINS pDevIns, unsigned iLUN)
5178{
5179 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
5180 PATACONTROLLER pCtl;
5181 ATADevState *pIf;
5182 int rc;
5183 unsigned iController;
5184 unsigned iInterface;
5185
5186 /*
5187 * Locate the controller and stuff.
5188 */
5189 iController = iLUN / RT_ELEMENTS(pThis->aCts[0].aIfs);
5190 AssertReleaseMsg(iController < RT_ELEMENTS(pThis->aCts), ("iController=%d iLUN=%d\n", iController, iLUN));
5191 pCtl = &pThis->aCts[iController];
5192
5193 iInterface = iLUN % RT_ELEMENTS(pThis->aCts[0].aIfs);
5194 pIf = &pCtl->aIfs[iInterface];
5195
5196 /* the usual paranoia */
5197 AssertRelease(!pIf->pDrvBase);
5198 AssertRelease(!pIf->pDrvBlock);
5199 Assert(ATADEVSTATE_2_CONTROLLER(pIf) == pCtl);
5200 Assert(pIf->iLUN == iLUN);
5201
5202 /*
5203 * Try attach the block device and get the interfaces,
5204 * required as well as optional.
5205 */
5206 rc = PDMDevHlpDriverAttach(pDevIns, pIf->iLUN, &pIf->IBase, &pIf->pDrvBase, NULL);
5207 if (RT_SUCCESS(rc))
5208 rc = ataConfigLun(pDevIns, pIf);
5209 else
5210 AssertMsgFailed(("Failed to attach LUN#%d. rc=%Rrc\n", pIf->iLUN, rc));
5211
5212 if (RT_FAILURE(rc))
5213 {
5214 pIf->pDrvBase = NULL;
5215 pIf->pDrvBlock = NULL;
5216 }
5217 return rc;
5218}
5219
5220
5221/**
5222 * Suspend notification.
5223 *
5224 * @returns VBox status.
5225 * @param pDevIns The device instance data.
5226 */
5227static DECLCALLBACK(void) ataSuspend(PPDMDEVINS pDevIns)
5228{
5229 Log(("%s:\n", __FUNCTION__));
5230 if (!ataWaitForAllAsyncIOIsIdle(pDevIns, 20000))
5231 AssertMsgFailed(("Async I/O didn't stop in 20 seconds!\n"));
5232 return;
5233}
5234
5235
5236/**
5237 * Resume notification.
5238 *
5239 * @returns VBox status.
5240 * @param pDevIns The device instance data.
5241 */
5242static DECLCALLBACK(void) ataResume(PPDMDEVINS pDevIns)
5243{
5244 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
5245 int rc;
5246
5247 Log(("%s:\n", __FUNCTION__));
5248 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
5249 {
5250 if (pThis->aCts[i].fRedo && pThis->aCts[i].fRedoIdle)
5251 {
5252 rc = RTSemEventSignal(pThis->aCts[i].SuspendIOSem);
5253 AssertRC(rc);
5254 }
5255 }
5256 return;
5257}
5258
5259
5260/**
5261 * Power Off notification.
5262 *
5263 * @returns VBox status.
5264 * @param pDevIns The device instance data.
5265 */
5266static DECLCALLBACK(void) ataPowerOff(PPDMDEVINS pDevIns)
5267{
5268 Log(("%s:\n", __FUNCTION__));
5269 if (!ataWaitForAllAsyncIOIsIdle(pDevIns, 20000))
5270 AssertMsgFailed(("Async I/O didn't stop in 20 seconds!\n"));
5271 return;
5272}
5273
5274
5275/**
5276 * Prepare state save and load operation.
5277 *
5278 * @returns VBox status code.
5279 * @param pDevIns Device instance of the device which registered the data unit.
5280 * @param pSSM SSM operation handle.
5281 */
5282static DECLCALLBACK(int) ataSaveLoadPrep(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
5283{
5284 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
5285
5286 /* sanity - the suspend notification will wait on the async stuff. */
5287 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
5288 {
5289 Assert(ataAsyncIOIsIdle(&pThis->aCts[i], false));
5290 if (!ataAsyncIOIsIdle(&pThis->aCts[i], false))
5291 return VERR_SSM_IDE_ASYNC_TIMEOUT;
5292 }
5293 return VINF_SUCCESS;
5294}
5295
5296
5297/**
5298 * Saves a state of the ATA device.
5299 *
5300 * @returns VBox status code.
5301 * @param pDevIns The device instance.
5302 * @param pSSMHandle The handle to save the state to.
5303 */
5304static DECLCALLBACK(int) ataSaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSMHandle)
5305{
5306 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
5307
5308 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
5309 {
5310 SSMR3PutU8(pSSMHandle, pThis->aCts[i].iSelectedIf);
5311 SSMR3PutU8(pSSMHandle, pThis->aCts[i].iAIOIf);
5312 SSMR3PutU8(pSSMHandle, pThis->aCts[i].uAsyncIOState);
5313 SSMR3PutBool(pSSMHandle, pThis->aCts[i].fChainedTransfer);
5314 SSMR3PutBool(pSSMHandle, pThis->aCts[i].fReset);
5315 SSMR3PutBool(pSSMHandle, pThis->aCts[i].fRedo);
5316 SSMR3PutBool(pSSMHandle, pThis->aCts[i].fRedoIdle);
5317 SSMR3PutBool(pSSMHandle, pThis->aCts[i].fRedoDMALastDesc);
5318 SSMR3PutMem(pSSMHandle, &pThis->aCts[i].BmDma, sizeof(pThis->aCts[i].BmDma));
5319 SSMR3PutGCPhys32(pSSMHandle, pThis->aCts[i].pFirstDMADesc);
5320 SSMR3PutGCPhys32(pSSMHandle, pThis->aCts[i].pLastDMADesc);
5321 SSMR3PutGCPhys32(pSSMHandle, pThis->aCts[i].pRedoDMABuffer);
5322 SSMR3PutU32(pSSMHandle, pThis->aCts[i].cbRedoDMABuffer);
5323
5324 for (uint32_t j = 0; j < RT_ELEMENTS(pThis->aCts[i].aIfs); j++)
5325 {
5326 SSMR3PutBool(pSSMHandle, pThis->aCts[i].aIfs[j].fLBA48);
5327 SSMR3PutBool(pSSMHandle, pThis->aCts[i].aIfs[j].fATAPI);
5328 SSMR3PutBool(pSSMHandle, pThis->aCts[i].aIfs[j].fIrqPending);
5329 SSMR3PutU8(pSSMHandle, pThis->aCts[i].aIfs[j].cMultSectors);
5330 SSMR3PutU32(pSSMHandle, pThis->aCts[i].aIfs[j].PCHSGeometry.cCylinders);
5331 SSMR3PutU32(pSSMHandle, pThis->aCts[i].aIfs[j].PCHSGeometry.cHeads);
5332 SSMR3PutU32(pSSMHandle, pThis->aCts[i].aIfs[j].PCHSGeometry.cSectors);
5333 SSMR3PutU32(pSSMHandle, pThis->aCts[i].aIfs[j].cSectorsPerIRQ);
5334 SSMR3PutU64(pSSMHandle, pThis->aCts[i].aIfs[j].cTotalSectors);
5335 SSMR3PutU8(pSSMHandle, pThis->aCts[i].aIfs[j].uATARegFeature);
5336 SSMR3PutU8(pSSMHandle, pThis->aCts[i].aIfs[j].uATARegFeatureHOB);
5337 SSMR3PutU8(pSSMHandle, pThis->aCts[i].aIfs[j].uATARegError);
5338 SSMR3PutU8(pSSMHandle, pThis->aCts[i].aIfs[j].uATARegNSector);
5339 SSMR3PutU8(pSSMHandle, pThis->aCts[i].aIfs[j].uATARegNSectorHOB);
5340 SSMR3PutU8(pSSMHandle, pThis->aCts[i].aIfs[j].uATARegSector);
5341 SSMR3PutU8(pSSMHandle, pThis->aCts[i].aIfs[j].uATARegSectorHOB);
5342 SSMR3PutU8(pSSMHandle, pThis->aCts[i].aIfs[j].uATARegLCyl);
5343 SSMR3PutU8(pSSMHandle, pThis->aCts[i].aIfs[j].uATARegLCylHOB);
5344 SSMR3PutU8(pSSMHandle, pThis->aCts[i].aIfs[j].uATARegHCyl);
5345 SSMR3PutU8(pSSMHandle, pThis->aCts[i].aIfs[j].uATARegHCylHOB);
5346 SSMR3PutU8(pSSMHandle, pThis->aCts[i].aIfs[j].uATARegSelect);
5347 SSMR3PutU8(pSSMHandle, pThis->aCts[i].aIfs[j].uATARegStatus);
5348 SSMR3PutU8(pSSMHandle, pThis->aCts[i].aIfs[j].uATARegCommand);
5349 SSMR3PutU8(pSSMHandle, pThis->aCts[i].aIfs[j].uATARegDevCtl);
5350 SSMR3PutU8(pSSMHandle, pThis->aCts[i].aIfs[j].uATATransferMode);
5351 SSMR3PutU8(pSSMHandle, pThis->aCts[i].aIfs[j].uTxDir);
5352 SSMR3PutU8(pSSMHandle, pThis->aCts[i].aIfs[j].iBeginTransfer);
5353 SSMR3PutU8(pSSMHandle, pThis->aCts[i].aIfs[j].iSourceSink);
5354 SSMR3PutBool(pSSMHandle, pThis->aCts[i].aIfs[j].fDMA);
5355 SSMR3PutBool(pSSMHandle, pThis->aCts[i].aIfs[j].fATAPITransfer);
5356 SSMR3PutU32(pSSMHandle, pThis->aCts[i].aIfs[j].cbTotalTransfer);
5357 SSMR3PutU32(pSSMHandle, pThis->aCts[i].aIfs[j].cbElementaryTransfer);
5358 SSMR3PutU32(pSSMHandle, pThis->aCts[i].aIfs[j].iIOBufferCur);
5359 SSMR3PutU32(pSSMHandle, pThis->aCts[i].aIfs[j].iIOBufferEnd);
5360 SSMR3PutU32(pSSMHandle, pThis->aCts[i].aIfs[j].iIOBufferPIODataStart);
5361 SSMR3PutU32(pSSMHandle, pThis->aCts[i].aIfs[j].iIOBufferPIODataEnd);
5362 SSMR3PutU32(pSSMHandle, pThis->aCts[i].aIfs[j].iATAPILBA);
5363 SSMR3PutU32(pSSMHandle, pThis->aCts[i].aIfs[j].cbATAPISector);
5364 SSMR3PutMem(pSSMHandle, &pThis->aCts[i].aIfs[j].aATAPICmd, sizeof(pThis->aCts[i].aIfs[j].aATAPICmd));
5365 SSMR3PutMem(pSSMHandle, &pThis->aCts[i].aIfs[j].abATAPISense, sizeof(pThis->aCts[i].aIfs[j].abATAPISense));
5366 SSMR3PutU8(pSSMHandle, pThis->aCts[i].aIfs[j].cNotifiedMediaChange);
5367 SSMR3PutMem(pSSMHandle, &pThis->aCts[i].aIfs[j].Led, sizeof(pThis->aCts[i].aIfs[j].Led));
5368 SSMR3PutU32(pSSMHandle, pThis->aCts[i].aIfs[j].cbIOBuffer);
5369 if (pThis->aCts[i].aIfs[j].cbIOBuffer)
5370 SSMR3PutMem(pSSMHandle, pThis->aCts[i].aIfs[j].CTX_SUFF(pbIOBuffer), pThis->aCts[i].aIfs[j].cbIOBuffer);
5371 else
5372 Assert(pThis->aCts[i].aIfs[j].CTX_SUFF(pbIOBuffer) == NULL);
5373 }
5374 }
5375 SSMR3PutBool(pSSMHandle, pThis->fPIIX4);
5376
5377 return SSMR3PutU32(pSSMHandle, ~0); /* sanity/terminator */
5378}
5379
5380
5381/**
5382 * Loads a saved ATA device state.
5383 *
5384 * @returns VBox status code.
5385 * @param pDevIns The device instance.
5386 * @param pSSMHandle The handle to the saved state.
5387 * @param u32Version The data unit version number.
5388 */
5389static DECLCALLBACK(int) ataLoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSMHandle, uint32_t u32Version)
5390{
5391 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
5392 int rc;
5393 uint32_t u32;
5394
5395 if ( u32Version != ATA_SAVED_STATE_VERSION
5396 && u32Version != ATA_SAVED_STATE_VERSION_WITHOUT_FULL_SENSE)
5397 {
5398 AssertMsgFailed(("u32Version=%d\n", u32Version));
5399 return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
5400 }
5401
5402 /*
5403 * Restore valid parts of the PCIATAState structure
5404 */
5405 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
5406 {
5407 /* integrity check */
5408 if (!ataAsyncIOIsIdle(&pThis->aCts[i], false))
5409 {
5410 AssertMsgFailed(("Async I/O for controller %d is active\n", i));
5411 rc = VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
5412 return rc;
5413 }
5414
5415 SSMR3GetU8(pSSMHandle, &pThis->aCts[i].iSelectedIf);
5416 SSMR3GetU8(pSSMHandle, &pThis->aCts[i].iAIOIf);
5417 SSMR3GetU8(pSSMHandle, &pThis->aCts[i].uAsyncIOState);
5418 SSMR3GetBool(pSSMHandle, &pThis->aCts[i].fChainedTransfer);
5419 SSMR3GetBool(pSSMHandle, (bool *)&pThis->aCts[i].fReset);
5420 SSMR3GetBool(pSSMHandle, (bool *)&pThis->aCts[i].fRedo);
5421 SSMR3GetBool(pSSMHandle, (bool *)&pThis->aCts[i].fRedoIdle);
5422 SSMR3GetBool(pSSMHandle, (bool *)&pThis->aCts[i].fRedoDMALastDesc);
5423 SSMR3GetMem(pSSMHandle, &pThis->aCts[i].BmDma, sizeof(pThis->aCts[i].BmDma));
5424 SSMR3GetGCPhys32(pSSMHandle, &pThis->aCts[i].pFirstDMADesc);
5425 SSMR3GetGCPhys32(pSSMHandle, &pThis->aCts[i].pLastDMADesc);
5426 SSMR3GetGCPhys32(pSSMHandle, &pThis->aCts[i].pRedoDMABuffer);
5427 SSMR3GetU32(pSSMHandle, &pThis->aCts[i].cbRedoDMABuffer);
5428
5429 for (uint32_t j = 0; j < RT_ELEMENTS(pThis->aCts[i].aIfs); j++)
5430 {
5431 SSMR3GetBool(pSSMHandle, &pThis->aCts[i].aIfs[j].fLBA48);
5432 SSMR3GetBool(pSSMHandle, &pThis->aCts[i].aIfs[j].fATAPI);
5433 SSMR3GetBool(pSSMHandle, &pThis->aCts[i].aIfs[j].fIrqPending);
5434 SSMR3GetU8(pSSMHandle, &pThis->aCts[i].aIfs[j].cMultSectors);
5435 SSMR3GetU32(pSSMHandle, &pThis->aCts[i].aIfs[j].PCHSGeometry.cCylinders);
5436 SSMR3GetU32(pSSMHandle, &pThis->aCts[i].aIfs[j].PCHSGeometry.cHeads);
5437 SSMR3GetU32(pSSMHandle, &pThis->aCts[i].aIfs[j].PCHSGeometry.cSectors);
5438 SSMR3GetU32(pSSMHandle, &pThis->aCts[i].aIfs[j].cSectorsPerIRQ);
5439 SSMR3GetU64(pSSMHandle, &pThis->aCts[i].aIfs[j].cTotalSectors);
5440 SSMR3GetU8(pSSMHandle, &pThis->aCts[i].aIfs[j].uATARegFeature);
5441 SSMR3GetU8(pSSMHandle, &pThis->aCts[i].aIfs[j].uATARegFeatureHOB);
5442 SSMR3GetU8(pSSMHandle, &pThis->aCts[i].aIfs[j].uATARegError);
5443 SSMR3GetU8(pSSMHandle, &pThis->aCts[i].aIfs[j].uATARegNSector);
5444 SSMR3GetU8(pSSMHandle, &pThis->aCts[i].aIfs[j].uATARegNSectorHOB);
5445 SSMR3GetU8(pSSMHandle, &pThis->aCts[i].aIfs[j].uATARegSector);
5446 SSMR3GetU8(pSSMHandle, &pThis->aCts[i].aIfs[j].uATARegSectorHOB);
5447 SSMR3GetU8(pSSMHandle, &pThis->aCts[i].aIfs[j].uATARegLCyl);
5448 SSMR3GetU8(pSSMHandle, &pThis->aCts[i].aIfs[j].uATARegLCylHOB);
5449 SSMR3GetU8(pSSMHandle, &pThis->aCts[i].aIfs[j].uATARegHCyl);
5450 SSMR3GetU8(pSSMHandle, &pThis->aCts[i].aIfs[j].uATARegHCylHOB);
5451 SSMR3GetU8(pSSMHandle, &pThis->aCts[i].aIfs[j].uATARegSelect);
5452 SSMR3GetU8(pSSMHandle, &pThis->aCts[i].aIfs[j].uATARegStatus);
5453 SSMR3GetU8(pSSMHandle, &pThis->aCts[i].aIfs[j].uATARegCommand);
5454 SSMR3GetU8(pSSMHandle, &pThis->aCts[i].aIfs[j].uATARegDevCtl);
5455 SSMR3GetU8(pSSMHandle, &pThis->aCts[i].aIfs[j].uATATransferMode);
5456 SSMR3GetU8(pSSMHandle, &pThis->aCts[i].aIfs[j].uTxDir);
5457 SSMR3GetU8(pSSMHandle, &pThis->aCts[i].aIfs[j].iBeginTransfer);
5458 SSMR3GetU8(pSSMHandle, &pThis->aCts[i].aIfs[j].iSourceSink);
5459 SSMR3GetBool(pSSMHandle, &pThis->aCts[i].aIfs[j].fDMA);
5460 SSMR3GetBool(pSSMHandle, &pThis->aCts[i].aIfs[j].fATAPITransfer);
5461 SSMR3GetU32(pSSMHandle, &pThis->aCts[i].aIfs[j].cbTotalTransfer);
5462 SSMR3GetU32(pSSMHandle, &pThis->aCts[i].aIfs[j].cbElementaryTransfer);
5463 SSMR3GetU32(pSSMHandle, &pThis->aCts[i].aIfs[j].iIOBufferCur);
5464 SSMR3GetU32(pSSMHandle, &pThis->aCts[i].aIfs[j].iIOBufferEnd);
5465 SSMR3GetU32(pSSMHandle, &pThis->aCts[i].aIfs[j].iIOBufferPIODataStart);
5466 SSMR3GetU32(pSSMHandle, &pThis->aCts[i].aIfs[j].iIOBufferPIODataEnd);
5467 SSMR3GetU32(pSSMHandle, &pThis->aCts[i].aIfs[j].iATAPILBA);
5468 SSMR3GetU32(pSSMHandle, &pThis->aCts[i].aIfs[j].cbATAPISector);
5469 SSMR3GetMem(pSSMHandle, &pThis->aCts[i].aIfs[j].aATAPICmd, sizeof(pThis->aCts[i].aIfs[j].aATAPICmd));
5470 if (u32Version != ATA_SAVED_STATE_VERSION_WITHOUT_FULL_SENSE)
5471 {
5472 SSMR3GetMem(pSSMHandle, pThis->aCts[i].aIfs[j].abATAPISense, sizeof(pThis->aCts[i].aIfs[j].abATAPISense));
5473 }
5474 else
5475 {
5476 uint8_t uATAPISenseKey, uATAPIASC;
5477 memset(pThis->aCts[i].aIfs[j].abATAPISense, '\0', sizeof(pThis->aCts[i].aIfs[j].abATAPISense));
5478 pThis->aCts[i].aIfs[j].abATAPISense[0] = 0x70 | (1 << 7);
5479 pThis->aCts[i].aIfs[j].abATAPISense[7] = 10;
5480 SSMR3GetU8(pSSMHandle, &uATAPISenseKey);
5481 SSMR3GetU8(pSSMHandle, &uATAPIASC);
5482 pThis->aCts[i].aIfs[j].abATAPISense[2] = uATAPISenseKey & 0x0f;
5483 pThis->aCts[i].aIfs[j].abATAPISense[12] = uATAPIASC;
5484 }
5485 /** @todo triple-check this hack after passthrough is working */
5486 SSMR3GetU8(pSSMHandle, &pThis->aCts[i].aIfs[j].cNotifiedMediaChange);
5487 SSMR3GetMem(pSSMHandle, &pThis->aCts[i].aIfs[j].Led, sizeof(pThis->aCts[i].aIfs[j].Led));
5488 SSMR3GetU32(pSSMHandle, &pThis->aCts[i].aIfs[j].cbIOBuffer);
5489 if (pThis->aCts[i].aIfs[j].cbIOBuffer)
5490 {
5491 if (pThis->aCts[i].aIfs[j].CTX_SUFF(pbIOBuffer))
5492 SSMR3GetMem(pSSMHandle, pThis->aCts[i].aIfs[j].CTX_SUFF(pbIOBuffer), pThis->aCts[i].aIfs[j].cbIOBuffer);
5493 else
5494 {
5495 LogRel(("ATA: No buffer for %d/%d\n", i, j));
5496 if (SSMR3HandleGetAfter(pSSMHandle) != SSMAFTER_DEBUG_IT)
5497 return VERR_SSM_LOAD_CONFIG_MISMATCH;
5498
5499 /* skip the buffer if we're loading for the debugger / animator. */
5500 uint8_t u8Ignored;
5501 size_t cbLeft = pThis->aCts[i].aIfs[j].cbIOBuffer;
5502 while (cbLeft-- > 0)
5503 SSMR3GetU8(pSSMHandle, &u8Ignored);
5504 }
5505 }
5506 else
5507 Assert(pThis->aCts[i].aIfs[j].CTX_SUFF(pbIOBuffer) == NULL);
5508 }
5509 }
5510 SSMR3GetBool(pSSMHandle, &pThis->fPIIX4);
5511
5512 rc = SSMR3GetU32(pSSMHandle, &u32);
5513 if (RT_FAILURE(rc))
5514 return rc;
5515 if (u32 != ~0U)
5516 {
5517 AssertMsgFailed(("u32=%#x expected ~0\n", u32));
5518 rc = VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
5519 return rc;
5520 }
5521
5522 return VINF_SUCCESS;
5523}
5524
5525
5526/**
5527 * Construct a device instance for a VM.
5528 *
5529 * @returns VBox status.
5530 * @param pDevIns The device instance data.
5531 * If the registration structure is needed, pDevIns->pDevReg points to it.
5532 * @param iInstance Instance number. Use this to figure out which registers and such to use.
5533 * The device number is also found in pDevIns->iInstance, but since it's
5534 * likely to be freqently used PDM passes it as parameter.
5535 * @param pCfgHandle Configuration node handle for the device. Use this to obtain the configuration
5536 * of the device instance. It's also found in pDevIns->pCfgHandle, but like
5537 * iInstance it's expected to be used a bit in this function.
5538 */
5539static DECLCALLBACK(int) ataConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfgHandle)
5540{
5541 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
5542 PPDMIBASE pBase;
5543 int rc;
5544 bool fGCEnabled;
5545 bool fR0Enabled;
5546 uint32_t DelayIRQMillies;
5547
5548 Assert(iInstance == 0);
5549
5550 /*
5551 * Initialize NIL handle values (for the destructor).
5552 */
5553 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
5554 {
5555 pThis->aCts[i].AsyncIOSem = NIL_RTSEMEVENT;
5556 pThis->aCts[i].SuspendIOSem = NIL_RTSEMEVENT;
5557 pThis->aCts[i].AsyncIORequestMutex = NIL_RTSEMEVENT;
5558 }
5559
5560 /*
5561 * Validate and read configuration.
5562 */
5563 if (!CFGMR3AreValuesValid(pCfgHandle, "GCEnabled\0IRQDelay\0R0Enabled\0PIIX4\0"))
5564 return PDMDEV_SET_ERROR(pDevIns, VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES,
5565 N_("PIIX3 configuration error: unknown option specified"));
5566
5567 rc = CFGMR3QueryBoolDef(pCfgHandle, "GCEnabled", &fGCEnabled, true);
5568 if (RT_FAILURE(rc))
5569 return PDMDEV_SET_ERROR(pDevIns, rc,
5570 N_("PIIX3 configuration error: failed to read GCEnabled as boolean"));
5571 Log(("%s: fGCEnabled=%d\n", __FUNCTION__, fGCEnabled));
5572
5573 rc = CFGMR3QueryBoolDef(pCfgHandle, "R0Enabled", &fR0Enabled, true);
5574 if (RT_FAILURE(rc))
5575 return PDMDEV_SET_ERROR(pDevIns, rc,
5576 N_("PIIX3 configuration error: failed to read R0Enabled as boolean"));
5577 Log(("%s: fR0Enabled=%d\n", __FUNCTION__, fR0Enabled));
5578
5579 rc = CFGMR3QueryU32Def(pCfgHandle, "IRQDelay", &DelayIRQMillies, 0);
5580 if (RT_FAILURE(rc))
5581 return PDMDEV_SET_ERROR(pDevIns, rc,
5582 N_("PIIX3 configuration error: failed to read IRQDelay as integer"));
5583 Log(("%s: DelayIRQMillies=%d\n", __FUNCTION__, DelayIRQMillies));
5584 Assert(DelayIRQMillies < 50);
5585
5586 rc = CFGMR3QueryBoolDef(pCfgHandle, "PIIX4", &pThis->fPIIX4, false);
5587 if (RT_FAILURE(rc))
5588 return PDMDEV_SET_ERROR(pDevIns, rc,
5589 N_("PIIX3 configuration error: failed to read PIIX4 as boolean"));
5590 Log(("%s: fPIIX4=%d\n", __FUNCTION__, pThis->fPIIX4));
5591
5592 /*
5593 * Initialize data (most of it anyway).
5594 */
5595 /* Status LUN. */
5596 pThis->IBase.pfnQueryInterface = ataStatus_QueryInterface;
5597 pThis->ILeds.pfnQueryStatusLed = ataStatus_QueryStatusLed;
5598
5599 /* PCI configuration space. */
5600 PCIDevSetVendorId(&pThis->dev, 0x8086); /* Intel */
5601 if (pThis->fPIIX4)
5602 {
5603 PCIDevSetDeviceId(&pThis->dev, 0x7111); /* PIIX4 IDE */
5604 PCIDevSetRevisionId(&pThis->dev, 0x01); /* PIIX4E */
5605 pThis->dev.config[0x48] = 0x00; /* UDMACTL */
5606 pThis->dev.config[0x4A] = 0x00; /* UDMATIM */
5607 pThis->dev.config[0x4B] = 0x00;
5608 }
5609 else
5610 PCIDevSetDeviceId(&pThis->dev, 0x7010); /* PIIX3 IDE */
5611 PCIDevSetCommand( &pThis->dev, PCI_COMMAND_IOACCESS | PCI_COMMAND_MEMACCESS | PCI_COMMAND_BUSMASTER);
5612 PCIDevSetClassProg( &pThis->dev, 0x8a); /* programming interface = PCI_IDE bus master is supported */
5613 PCIDevSetClassSub( &pThis->dev, 0x01); /* class_sub = PCI_IDE */
5614 PCIDevSetClassBase( &pThis->dev, 0x01); /* class_base = PCI_mass_storage */
5615 PCIDevSetHeaderType(&pThis->dev, 0x00);
5616
5617 pThis->pDevIns = pDevIns;
5618 pThis->fGCEnabled = fGCEnabled;
5619 pThis->fR0Enabled = fR0Enabled;
5620 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
5621 {
5622 pThis->aCts[i].pDevInsR3 = pDevIns;
5623 pThis->aCts[i].pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
5624 pThis->aCts[i].pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
5625 pThis->aCts[i].DelayIRQMillies = (uint32_t)DelayIRQMillies;
5626 for (uint32_t j = 0; j < RT_ELEMENTS(pThis->aCts[i].aIfs); j++)
5627 {
5628 pThis->aCts[i].aIfs[j].iLUN = i * RT_ELEMENTS(pThis->aCts) + j;
5629 pThis->aCts[i].aIfs[j].pDevInsR3 = pDevIns;
5630 pThis->aCts[i].aIfs[j].pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
5631 pThis->aCts[i].aIfs[j].pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
5632 pThis->aCts[i].aIfs[j].pControllerR3 = &pThis->aCts[i];
5633 pThis->aCts[i].aIfs[j].pControllerR0 = MMHyperR3ToR0(PDMDevHlpGetVM(pDevIns), &pThis->aCts[i]);
5634 pThis->aCts[i].aIfs[j].pControllerRC = MMHyperR3ToRC(PDMDevHlpGetVM(pDevIns), &pThis->aCts[i]);
5635 pThis->aCts[i].aIfs[j].IBase.pfnQueryInterface = ataQueryInterface;
5636 pThis->aCts[i].aIfs[j].IMountNotify.pfnMountNotify = ataMountNotify;
5637 pThis->aCts[i].aIfs[j].IMountNotify.pfnUnmountNotify = ataUnmountNotify;
5638 pThis->aCts[i].aIfs[j].Led.u32Magic = PDMLED_MAGIC;
5639 }
5640 }
5641
5642 Assert(RT_ELEMENTS(pThis->aCts) == 2);
5643 pThis->aCts[0].irq = 14;
5644 pThis->aCts[0].IOPortBase1 = 0x1f0;
5645 pThis->aCts[0].IOPortBase2 = 0x3f6;
5646 pThis->aCts[1].irq = 15;
5647 pThis->aCts[1].IOPortBase1 = 0x170;
5648 pThis->aCts[1].IOPortBase2 = 0x376;
5649
5650 /*
5651 * Register the PCI device.
5652 * N.B. There's a hack in the PIIX3 PCI bridge device to assign this
5653 * device the slot next to itself.
5654 */
5655 rc = PDMDevHlpPCIRegister(pDevIns, &pThis->dev);
5656 if (RT_FAILURE(rc))
5657 return PDMDEV_SET_ERROR(pDevIns, rc,
5658 N_("PIIX3 cannot register PCI device"));
5659 AssertMsg(pThis->dev.devfn == 9 || iInstance != 0, ("pThis->dev.devfn=%d\n", pThis->dev.devfn));
5660 rc = PDMDevHlpPCIIORegionRegister(pDevIns, 4, 0x10, PCI_ADDRESS_SPACE_IO, ataBMDMAIORangeMap);
5661 if (RT_FAILURE(rc))
5662 return PDMDEV_SET_ERROR(pDevIns, rc,
5663 N_("PIIX3 cannot register PCI I/O region for BMDMA"));
5664
5665 /*
5666 * Register the I/O ports.
5667 * The ports are all hardcoded and enforced by the PIIX3 host bridge controller.
5668 */
5669 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
5670 {
5671 rc = PDMDevHlpIOPortRegister(pDevIns, pThis->aCts[i].IOPortBase1, 8, (RTHCPTR)i,
5672 ataIOPortWrite1, ataIOPortRead1, ataIOPortWriteStr1, ataIOPortReadStr1, "ATA I/O Base 1");
5673 if (RT_FAILURE(rc))
5674 return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot register I/O handlers"));
5675
5676 if (fGCEnabled)
5677 {
5678 rc = PDMDevHlpIOPortRegisterGC(pDevIns, pThis->aCts[i].IOPortBase1, 8, (RTGCPTR)i,
5679 "ataIOPortWrite1", "ataIOPortRead1", "ataIOPortWriteStr1", "ataIOPortReadStr1", "ATA I/O Base 1");
5680 if (RT_FAILURE(rc))
5681 return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot register I/O handlers (GC)"));
5682 }
5683
5684 if (fR0Enabled)
5685 {
5686#if 1
5687 rc = PDMDevHlpIOPortRegisterR0(pDevIns, pThis->aCts[i].IOPortBase1, 8, (RTR0PTR)i,
5688 "ataIOPortWrite1", "ataIOPortRead1", NULL, NULL, "ATA I/O Base 1");
5689#else
5690 rc = PDMDevHlpIOPortRegisterR0(pDevIns, pThis->aCts[i].IOPortBase1, 8, (RTR0PTR)i,
5691 "ataIOPortWrite1", "ataIOPortRead1", "ataIOPortWriteStr1", "ataIOPortReadStr1", "ATA I/O Base 1");
5692#endif
5693 if (RT_FAILURE(rc))
5694 return PDMDEV_SET_ERROR(pDevIns, rc, "PIIX3 cannot register I/O handlers (R0).");
5695 }
5696
5697 rc = PDMDevHlpIOPortRegister(pDevIns, pThis->aCts[i].IOPortBase2, 1, (RTHCPTR)i,
5698 ataIOPortWrite2, ataIOPortRead2, NULL, NULL, "ATA I/O Base 2");
5699 if (RT_FAILURE(rc))
5700 return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot register base2 I/O handlers"));
5701
5702 if (fGCEnabled)
5703 {
5704 rc = PDMDevHlpIOPortRegisterGC(pDevIns, pThis->aCts[i].IOPortBase2, 1, (RTGCPTR)i,
5705 "ataIOPortWrite2", "ataIOPortRead2", NULL, NULL, "ATA I/O Base 2");
5706 if (RT_FAILURE(rc))
5707 return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot register base2 I/O handlers (GC)"));
5708 }
5709 if (fR0Enabled)
5710 {
5711 rc = PDMDevHlpIOPortRegisterR0(pDevIns, pThis->aCts[i].IOPortBase2, 1, (RTR0PTR)i,
5712 "ataIOPortWrite2", "ataIOPortRead2", NULL, NULL, "ATA I/O Base 2");
5713 if (RT_FAILURE(rc))
5714 return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot register base2 I/O handlers (R0)"));
5715 }
5716
5717 for (uint32_t j = 0; j < RT_ELEMENTS(pThis->aCts[i].aIfs); j++)
5718 {
5719 ATADevState *pIf = &pThis->aCts[i].aIfs[j];
5720 PDMDevHlpSTAMRegisterF(pDevIns, &pIf->StatATADMA, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of ATA DMA transfers.", "/Devices/ATA%d/Unit%d/DMA", i, j);
5721 PDMDevHlpSTAMRegisterF(pDevIns, &pIf->StatATAPIO, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of ATA PIO transfers.", "/Devices/ATA%d/Unit%d/PIO", i, j);
5722 PDMDevHlpSTAMRegisterF(pDevIns, &pIf->StatATAPIDMA, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of ATAPI DMA transfers.", "/Devices/ATA%d/Unit%d/AtapiDMA", i, j);
5723 PDMDevHlpSTAMRegisterF(pDevIns, &pIf->StatATAPIPIO, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of ATAPI PIO transfers.", "/Devices/ATA%d/Unit%d/AtapiPIO", i, j);
5724#ifdef VBOX_WITH_STATISTICS /** @todo release too. */
5725 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);
5726#endif
5727 PDMDevHlpSTAMRegisterF(pDevIns, &pIf->StatBytesRead, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES, "Amount of data read.", "/Devices/ATA%d/Unit%d/ReadBytes", i, j);
5728#ifdef VBOX_INSTRUMENT_DMA_WRITES
5729 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);
5730#endif
5731#ifdef VBOX_WITH_STATISTICS
5732 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);
5733#endif
5734 PDMDevHlpSTAMRegisterF(pDevIns, &pIf->StatBytesWritten, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES, "Amount of data written.", "/Devices/ATA%d/Unit%d/WrittenBytes", i, j);
5735#ifdef VBOX_WITH_STATISTICS
5736 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);
5737#endif
5738 }
5739#ifdef VBOX_WITH_STATISTICS /** @todo release too. */
5740 PDMDevHlpSTAMRegisterF(pDevIns, &pThis->aCts[i].StatAsyncOps, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "The number of async operations.", "/Devices/ATA%d/Async/Operations", i);
5741 /** @todo STAMUNIT_MICROSECS */
5742 PDMDevHlpSTAMRegisterF(pDevIns, &pThis->aCts[i].StatAsyncMinWait, STAMTYPE_U64_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_NONE, "Minimum wait in microseconds.", "/Devices/ATA%d/Async/MinWait", i);
5743 PDMDevHlpSTAMRegisterF(pDevIns, &pThis->aCts[i].StatAsyncMaxWait, STAMTYPE_U64_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_NONE, "Maximum wait in microseconds.", "/Devices/ATA%d/Async/MaxWait", i);
5744 PDMDevHlpSTAMRegisterF(pDevIns, &pThis->aCts[i].StatAsyncTimeUS, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_NONE, "Total time spent in microseconds.","/Devices/ATA%d/Async/TotalTimeUS", i);
5745 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);
5746 PDMDevHlpSTAMRegisterF(pDevIns, &pThis->aCts[i].StatLockWait, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling of locks.", "/Devices/ATA%d/Async/LockWait", i);
5747#endif /* VBOX_WITH_STATISTICS */
5748
5749 /* Initialize per-controller critical section */
5750 char szName[24];
5751 RTStrPrintf(szName, sizeof(szName), "ATA%d", i);
5752 rc = PDMDevHlpCritSectInit(pDevIns, &pThis->aCts[i].lock, szName);
5753 if (RT_FAILURE(rc))
5754 return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot initialize critical section"));
5755 }
5756
5757 /*
5758 * Attach status driver (optional).
5759 */
5760 rc = PDMDevHlpDriverAttach(pDevIns, PDM_STATUS_LUN, &pThis->IBase, &pBase, "Status Port");
5761 if (RT_SUCCESS(rc))
5762 pThis->pLedsConnector = (PDMILEDCONNECTORS *)pBase->pfnQueryInterface(pBase, PDMINTERFACE_LED_CONNECTORS);
5763 else if (rc != VERR_PDM_NO_ATTACHED_DRIVER)
5764 {
5765 AssertMsgFailed(("Failed to attach to status driver. rc=%Rrc\n", rc));
5766 return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot attach to status driver"));
5767 }
5768
5769 /*
5770 * Attach the units.
5771 */
5772 uint32_t cbTotalBuffer = 0;
5773 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++)
5774 {
5775 PATACONTROLLER pCtl = &pThis->aCts[i];
5776
5777 /*
5778 * Start the worker thread.
5779 */
5780 pCtl->uAsyncIOState = ATA_AIO_NEW;
5781 rc = RTSemEventCreate(&pCtl->AsyncIOSem);
5782 AssertRC(rc);
5783 rc = RTSemEventCreate(&pCtl->SuspendIOSem);
5784 AssertRC(rc);
5785 rc = RTSemMutexCreate(&pCtl->AsyncIORequestMutex);
5786 AssertRC(rc);
5787 ataAsyncIOClearRequests(pCtl);
5788 rc = RTThreadCreate(&pCtl->AsyncIOThread, ataAsyncIOLoop, (void *)pCtl, 128*1024, RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, "ATA");
5789 AssertRC(rc);
5790 Assert(pCtl->AsyncIOThread != NIL_RTTHREAD && pCtl->AsyncIOSem != NIL_RTSEMEVENT && pCtl->SuspendIOSem != NIL_RTSEMEVENT && pCtl->AsyncIORequestMutex != NIL_RTSEMMUTEX);
5791 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));
5792
5793 for (uint32_t j = 0; j < RT_ELEMENTS(pCtl->aIfs); j++)
5794 {
5795 static const char *s_apszDescs[RT_ELEMENTS(pThis->aCts)][RT_ELEMENTS(pCtl->aIfs)] =
5796 {
5797 { "Primary Master", "Primary Slave" },
5798 { "Secondary Master", "Secondary Slave" }
5799 };
5800
5801 /*
5802 * Try attach the block device and get the interfaces,
5803 * required as well as optional.
5804 */
5805 ATADevState *pIf = &pCtl->aIfs[j];
5806
5807 rc = PDMDevHlpDriverAttach(pDevIns, pIf->iLUN, &pIf->IBase, &pIf->pDrvBase, s_apszDescs[i][j]);
5808 if (RT_SUCCESS(rc))
5809 rc = ataConfigLun(pDevIns, pIf);
5810 else if (rc == VERR_PDM_NO_ATTACHED_DRIVER)
5811 {
5812 pIf->pDrvBase = NULL;
5813 pIf->pDrvBlock = NULL;
5814 pIf->cbIOBuffer = 0;
5815 pIf->pbIOBufferR3 = NULL;
5816 pIf->pbIOBufferR0 = NIL_RTR0PTR;
5817 pIf->pbIOBufferRC = NIL_RTGCPTR;
5818 LogRel(("PIIX3 ATA: LUN#%d: no unit\n", pIf->iLUN));
5819 }
5820 else
5821 {
5822 AssertMsgFailed(("Failed to attach LUN#%d. rc=%Rrc\n", pIf->iLUN, rc));
5823 switch (rc)
5824 {
5825 case VERR_ACCESS_DENIED:
5826 /* Error already catched by DrvHostBase */
5827 return rc;
5828 default:
5829 return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS,
5830 N_("PIIX3 cannot attach drive to the %s"),
5831 s_apszDescs[i][j]);
5832 }
5833 }
5834 cbTotalBuffer += pIf->cbIOBuffer;
5835 }
5836 }
5837
5838 rc = PDMDevHlpSSMRegister(pDevIns, pDevIns->pDevReg->szDeviceName, iInstance,
5839 ATA_SAVED_STATE_VERSION, sizeof(*pThis) + cbTotalBuffer,
5840 ataSaveLoadPrep, ataSaveExec, NULL,
5841 ataSaveLoadPrep, ataLoadExec, NULL);
5842 if (RT_FAILURE(rc))
5843 return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot register save state handlers"));
5844
5845 /*
5846 * Initialize the device state.
5847 */
5848 ataReset(pDevIns);
5849
5850 return VINF_SUCCESS;
5851}
5852
5853
5854/**
5855 * The device registration structure.
5856 */
5857const PDMDEVREG g_DevicePIIX3IDE =
5858{
5859 /* u32Version */
5860 PDM_DEVREG_VERSION,
5861 /* szDeviceName */
5862 "piix3ide",
5863 /* szGCMod */
5864 "VBoxDDGC.gc",
5865 /* szR0Mod */
5866 "VBoxDDR0.r0",
5867 /* pszDescription */
5868 "Intel PIIX3 ATA controller.\n"
5869 " LUN #0 is primary master.\n"
5870 " LUN #1 is primary slave.\n"
5871 " LUN #2 is secondary master.\n"
5872 " LUN #3 is secondary slave.\n"
5873 " LUN #999 is the LED/Status connector.",
5874 /* fFlags */
5875 PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT | PDM_DEVREG_FLAGS_GUEST_BITS_DEFAULT | PDM_DEVREG_FLAGS_GC | PDM_DEVREG_FLAGS_R0,
5876 /* fClass */
5877 PDM_DEVREG_CLASS_STORAGE,
5878 /* cMaxInstances */
5879 1,
5880 /* cbInstance */
5881 sizeof(PCIATAState),
5882 /* pfnConstruct */
5883 ataConstruct,
5884 /* pfnDestruct */
5885 ataDestruct,
5886 /* pfnRelocate */
5887 ataRelocate,
5888 /* pfnIOCtl */
5889 NULL,
5890 /* pfnPowerOn */
5891 NULL,
5892 /* pfnReset */
5893 ataReset,
5894 /* pfnSuspend */
5895 ataSuspend,
5896 /* pfnResume */
5897 ataResume,
5898 /* pfnAttach */
5899 ataAttach,
5900 /* pfnDetach */
5901 ataDetach,
5902 /* pfnQueryInterface. */
5903 NULL,
5904 /* pfnInitComplete */
5905 NULL,
5906 /* pfnPowerOff */
5907 ataPowerOff
5908};
5909#endif /* IN_RING3 */
5910#endif /* !VBOX_DEVICE_STRUCT_TESTCASE */
5911
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