VirtualBox

source: vbox/trunk/src/VBox/Devices/Storage/ATAController.cpp@ 37043

Last change on this file since 37043 was 36383, checked in by vboxsync, 14 years ago

AHCI+ATAController: Port r70670 + r70674 (Signal no current profile if no medium is loaded and add mandatory features to the GET CONFIGURATION reply)

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

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