Changeset 38710 in vbox for trunk/src/VBox/Devices
- Timestamp:
- Sep 11, 2011 7:46:38 PM (14 years ago)
- svn:sync-xref-src-repo-rev:
- 73954
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/DevATA.cpp
r38664 r38710 4004 4004 #endif /* IN_RING3 */ 4005 4005 4006 /* 4007 * Note: There are four distinct cases of port I/O handling depending on 4008 * which devices (if any) are attached to an IDE channel: 4009 * 4010 * 1) No device attached. No response to writes or reads (i.e. reads return 4011 * all bits set). 4012 * 4013 * 2) Both devices attached. Reads and writes are processed normally. 4014 * 4015 * 3) Device 0 only. If device 0 is selected, normal behavior applies. But 4016 * if Device 1 is selected, writes are still directed to Device 0 (except 4017 * commands are not executed), reads from control/command registers are 4018 * directed to Device 0, but status/alt status reads return 0. If Device 1 4019 * is a PACKET device, all reads return 0. See ATAPI-6 clause 9.16.1 and 4020 * Table 18 in clause 7.1. 4021 * 4022 * 4) Device 1 only - non-standard(!). Device 1 can't tell if Device 0 is 4023 * present or not and behaves the same. That means if Device 0 is selected, 4024 * Device 1 responds to writes (except commands are not executed) but does 4025 * not respond to reads. If Device 1 selected, normal behavior applies. 4026 * See ATAPI-6 clause 9.16.2 and Table 15 in clause 7.1. 4027 */ 4028 4006 4029 static int ataIOPortWriteU8(PATACONTROLLER pCtl, uint32_t addr, uint32_t val) 4007 4030 { 4008 Log2(("%s: write addr=%#x val=%#04x\n", __FUNCTION__, addr, val));4031 Log2(("%s: LUN#%d write addr=%#x val=%#04x\n", __FUNCTION__, pCtl->aIfs[pCtl->iSelectedIf].iLUN, addr, val)); 4009 4032 addr &= 7; 4010 4033 switch (addr) … … 4095 4118 default: 4096 4119 case 7: /* command */ 4097 /* ignore commands to non existant slave */4120 /* ignore commands to non-existent device */ 4098 4121 if (pCtl->iSelectedIf && !pCtl->aIfs[pCtl->iSelectedIf].pDrvBlock) 4099 4122 break; … … 4112 4135 { 4113 4136 ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf]; 4114 uint32_t val; 4115 bool fHOB; 4116 4137 uint32_t val; 4138 bool fHOB; 4139 4140 /* Check if the guest is reading from a non-existent device. */ 4141 if (!s->pDrvBlock) 4142 { 4143 if (pCtl->iSelectedIf) /* Device 1 selected, Device 0 responding for it. */ 4144 { 4145 if (!pCtl->aIfs[0].pDrvBlock) /* @todo: this case should never get here! */ 4146 { 4147 Log2(("%s: addr=%#x: no device on channel\n", __FUNCTION__, addr)); 4148 return VERR_IOM_IOPORT_UNUSED; 4149 } 4150 if (((addr & 7) != 1) && pCtl->aIfs[0].fATAPI) { 4151 Log2(("%s: addr=%#x, val=0: LUN#%d not attached/LUN#%d ATAPI\n", __FUNCTION__, addr, 4152 s->iLUN, pCtl->aIfs[0].iLUN)); 4153 *pu32 = 0; 4154 return VINF_SUCCESS; 4155 } 4156 /* Else handle normally. */ 4157 } 4158 else /* Device 0 selected (but not present). */ 4159 { 4160 Log2(("%s: addr=%#x: LUN#%d not attached\n", __FUNCTION__, addr, s->iLUN)); 4161 return VERR_IOM_IOPORT_UNUSED; 4162 } 4163 } 4117 4164 fHOB = !!(s->uATARegDevCtl & (1 << 7)); 4118 4165 switch (addr & 7) … … 4133 4180 break; 4134 4181 case 2: /* sector count */ 4135 if (!s->pDrvBlock) 4136 val = 0; 4137 else if (fHOB) 4182 if (fHOB) 4138 4183 val = s->uATARegNSectorHOB; 4139 4184 else … … 4141 4186 break; 4142 4187 case 3: /* sector number */ 4143 if (!s->pDrvBlock) 4144 val = 0; 4145 else if (fHOB) 4188 if (fHOB) 4146 4189 val = s->uATARegSectorHOB; 4147 4190 else … … 4149 4192 break; 4150 4193 case 4: /* cylinder low */ 4151 if (!s->pDrvBlock) 4152 val = 0; 4153 else if (fHOB) 4194 if (fHOB) 4154 4195 val = s->uATARegLCylHOB; 4155 4196 else … … 4157 4198 break; 4158 4199 case 5: /* cylinder high */ 4159 if (!s->pDrvBlock) 4160 val = 0; 4161 else if (fHOB) 4200 if (fHOB) 4162 4201 val = s->uATARegHCylHOB; 4163 4202 else … … 4251 4290 } 4252 4291 } 4253 Log2(("%s: addr=%#x val=%#04x\n", __FUNCTION__, addr, val));4292 Log2(("%s: LUN#%d addr=%#x val=%#04x\n", __FUNCTION__, s->iLUN, addr, val)); 4254 4293 *pu32 = val; 4255 4294 return VINF_SUCCESS;
Note:
See TracChangeset
for help on using the changeset viewer.