VirtualBox

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

最後變更 在這個檔案從11284是 11284,由 vboxsync 提交於 17 年 前

Devices: %Vrc -> %Rrc (just preferred, not mandatory (yet))

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

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette