Changeset 42393 in vbox
- Timestamp:
- Jul 25, 2012 1:47:59 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/DevAHCI.cpp
r42325 r42393 185 185 #define AHCI_CMDFIS_C RT_BIT(7) /* Host to device. */ 186 186 #define AHCI_CMDFIS_I RT_BIT(6) /* Device to Host. */ 187 #define AHCI_CMDFIS_D RT_BIT(5) 187 188 188 189 #define AHCI_CMDFIS_CMD 2 … … 263 264 /** Task encountered a buffer overflow. */ 264 265 #define AHCI_REQ_OVERFLOW RT_BIT_32(0) 266 /** Request is a PIO data command, if this flag is not set it either is 267 * a command which does not transfer data or a DMA command based on the transfer size. */ 268 #define AHCI_REQ_PIO_DATA RT_BIT_32(1) 265 269 266 270 /** … … 4866 4870 4867 4871 /** 4872 * Create a PIO setup FIS and post it into the memory area of the guest. 4873 * 4874 * @returns nothing. 4875 * @param pAhciPort The port of the SATA controller. 4876 * @param pAhciReq The state of the task. 4877 * @param pCmdFis Pointer to the command FIS from the guest. 4878 * @param fInterrupt If an interrupt should be send to the guest. 4879 */ 4880 static void ahciSendPioSetupFis(PAHCIPort pAhciPort, PAHCIREQ pAhciReq, uint8_t *pCmdFis, 4881 bool fInterrupt) 4882 { 4883 uint8_t abPioSetupFis[20]; 4884 bool fAssertIntr = false; 4885 PAHCI pAhci = pAhciPort->CTX_SUFF(pAhci); 4886 4887 ahciLog(("%s: building PIO setup Fis\n", __FUNCTION__)); 4888 4889 AssertMsg( pAhciReq->cbTransfer > 0 4890 && pAhciReq->cbTransfer <= 65534, 4891 ("Can't send PIO setup FIS for requests with 0 bytes to transfer or greater than 65534\n")); 4892 4893 if (pAhciPort->regCMD & AHCI_PORT_CMD_FRE) 4894 { 4895 memset(&abPioSetupFis[0], 0, sizeof(abPioSetupFis)); 4896 abPioSetupFis[AHCI_CMDFIS_TYPE] = AHCI_CMDFIS_TYPE_PIOSETUP; 4897 abPioSetupFis[AHCI_CMDFIS_BITS] = (fInterrupt ? AHCI_CMDFIS_I : 0); 4898 if (pAhciReq->enmTxDir == AHCITXDIR_READ) 4899 abPioSetupFis[AHCI_CMDFIS_BITS] |= AHCI_CMDFIS_D; 4900 abPioSetupFis[AHCI_CMDFIS_STS] = pAhciReq->uATARegStatus; 4901 abPioSetupFis[AHCI_CMDFIS_ERR] = pAhciReq->uATARegError; 4902 abPioSetupFis[AHCI_CMDFIS_SECTN] = pCmdFis[AHCI_CMDFIS_SECTN]; 4903 abPioSetupFis[AHCI_CMDFIS_CYLL] = pCmdFis[AHCI_CMDFIS_CYLL]; 4904 abPioSetupFis[AHCI_CMDFIS_CYLH] = pCmdFis[AHCI_CMDFIS_CYLH]; 4905 abPioSetupFis[AHCI_CMDFIS_HEAD] = pCmdFis[AHCI_CMDFIS_HEAD]; 4906 abPioSetupFis[AHCI_CMDFIS_SECTNEXP] = pCmdFis[AHCI_CMDFIS_SECTNEXP]; 4907 abPioSetupFis[AHCI_CMDFIS_CYLLEXP] = pCmdFis[AHCI_CMDFIS_CYLLEXP]; 4908 abPioSetupFis[AHCI_CMDFIS_CYLHEXP] = pCmdFis[AHCI_CMDFIS_CYLHEXP]; 4909 abPioSetupFis[AHCI_CMDFIS_SECTC] = pCmdFis[AHCI_CMDFIS_SECTC]; 4910 abPioSetupFis[AHCI_CMDFIS_SECTCEXP] = pCmdFis[AHCI_CMDFIS_SECTCEXP]; 4911 4912 /* Set transfer count. */ 4913 abPioSetupFis[16] = (pAhciReq->cbTransfer >> 8) & 0xff; 4914 abPioSetupFis[17] = pAhciReq->cbTransfer & 0xff; 4915 4916 /* Update registers. */ 4917 pAhciPort->regTFD = (pAhciReq->uATARegError << 8) | pAhciReq->uATARegStatus; 4918 4919 ahciPostFisIntoMemory(pAhciPort, AHCI_CMDFIS_TYPE_PIOSETUP, abPioSetupFis); 4920 4921 if (fInterrupt) 4922 { 4923 ASMAtomicOrU32(&pAhciPort->regIS, AHCI_PORT_IS_PSS); 4924 /* Check if we should assert an interrupt */ 4925 if (pAhciPort->regIE & AHCI_PORT_IE_PSE) 4926 fAssertIntr = true; 4927 } 4928 4929 if (fAssertIntr) 4930 { 4931 int rc = ahciHbaSetInterrupt(pAhci, pAhciPort->iLUN, VERR_IGNORED); 4932 AssertRC(rc); 4933 } 4934 } 4935 } 4936 4937 /** 4868 4938 * Build a D2H FIS and post into the memory area of the guest. 4869 4939 * 4870 4940 * @returns Nothing 4871 4941 * @param pAhciPort The port of the SATA controller. 4872 * @param pAhciReq The state of the task.4942 * @param pAhciReq The state of the task. 4873 4943 * @param pCmdFis Pointer to the command FIS from the guest. 4874 4944 * @param fInterrupt If an interrupt should be send to the guest. … … 5643 5713 } 5644 5714 else 5715 { 5716 /* Post a PIO setup FIS first if this is a PIO command which transfers data. */ 5717 if (pAhciReq->fFlags & AHCI_REQ_PIO_DATA) 5718 ahciSendPioSetupFis(pAhciPort, pAhciReq, pAhciReq->cmdFis, false /* fInterrupt */); 5645 5719 ahciSendD2HFis(pAhciPort, pAhciReq, pAhciReq->cmdFis, true); 5720 } 5646 5721 } 5647 5722 } … … 5740 5815 &u16Temp[0], sizeof(u16Temp)); 5741 5816 5817 pAhciReq->fFlags |= AHCI_REQ_PIO_DATA; 5742 5818 pAhciReq->cbTransfer = cbCopied; 5743 5819 } … … 5952 6028 &aBuf[offLogRead], cbLogRead); 5953 6029 6030 pAhciReq->fFlags |= AHCI_REQ_PIO_DATA; 5954 6031 pAhciReq->cbTransfer = cbCopied; 5955 6032 }
Note:
See TracChangeset
for help on using the changeset viewer.