- Timestamp:
- Dec 30, 2007 5:06:27 PM (17 years ago)
- svn:sync-xref-src-repo-rev:
- 27047
- Location:
- trunk
- Files:
-
- 1 deleted
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/pdmifs.h
r6156 r6222 145 145 PDMINTERFACE_VUSB_DEVICE, 146 146 147 /** PDMIHOST DEVICEPORT - The Host Device port interface. (Down) Coupled with PDMINTERFACE_HOST_DEVICE_CONNECTOR. */148 PDMINTERFACE_HOST_ DEVICE_PORT,149 /** PDMIHOST DEVICECONNECTOR - The Host device connector interface (Up) Coupled with PDMINTERFACE_HOST_DEVICE_PORT. */150 PDMINTERFACE_HOST_ DEVICE_CONNECTOR,147 /** PDMIHOSTPARALLELPORT - The Host Parallel port interface. (Down) Coupled with PDMINTERFACE_HOST_PARALLEL_CONNECTOR. */ 148 PDMINTERFACE_HOST_PARALLEL_PORT, 149 /** PDMIHOSTPARALLELCONNECTOR - The Host Parallel connector interface (Up) Coupled with PDMINTERFACE_HOST_PARALLEL_PORT. */ 150 PDMINTERFACE_HOST_PARALLEL_CONNECTOR, 151 151 152 152 /** Maximum interface number. */ … … 1660 1660 1661 1661 1662 /** Pointer to a host device port interface. */ 1663 typedef struct PDMIHOSTDEVICEPORT *PPDMIHOSTDEVICEPORT; 1664 /** 1665 * Char port interface. 1666 * Pair with PDMIHOSTDEVICECONNECTOR. 1667 */ 1668 typedef struct PDMIHOSTDEVICEPORT 1662 /** Mode of the parallel port */ 1663 typedef enum PDMPARALLELPORTMODE 1664 { 1665 PDM_PARALLEL_PORT_MODE_COMPAT, 1666 PDM_PARALLEL_PORT_MODE_EPP, 1667 PDM_PARALLEL_PORT_MODE_ECP 1668 } PDMPARALLELPORTMODE; 1669 1670 /** Pointer to a host parallel port interface. */ 1671 typedef struct PDMIHOSTPARALLELPORT *PPDMIHOSTPARALLELPORT; 1672 1673 /** 1674 * Host parallel port interface. 1675 * Pair with PDMIHOSTPARALLELCONNECTOR. 1676 */ 1677 typedef struct PDMIHOSTPARALLELPORT 1669 1678 { 1670 1679 /** … … 1677 1686 * @thread Any thread. 1678 1687 */ 1679 DECLR3CALLBACKMEMBER(int, pfnNotifyRead,(PPDMIHOSTDEVICEPORT pInterface, const void *pvBuf, size_t *pcbRead)); 1680 } PDMIHOSTDEVICEPORT; 1681 1682 1683 /** Pointer to a Host Device connector interface. */ 1684 typedef struct PDMIHOSTDEVICECONNECTOR *PPDMIHOSTDEVICECONNECTOR; 1685 /** 1686 * Host device connector interface 1687 * Pair with PDMIHOSTDEVICEPORT. 1688 */ 1689 typedef struct PDMIHOSTDEVICECONNECTOR 1688 DECLR3CALLBACKMEMBER(int, pfnNotifyRead,(PPDMIHOSTPARALLELPORT pInterface, const void *pvBuf, size_t *pcbRead)); 1689 1690 /** 1691 * Notify device/driver that an interrupt has occured. 1692 * 1693 * @returns VBox status code. 1694 * @param pInterface Pointer to the interface structure containing the called function pointer. 1695 * @thread Any thread. 1696 */ 1697 DECLR3CALLBACKMEMBER(int, pfnNotifyInterrupt, (PPDMIHOSTPARALLELPORT pInterface)); 1698 } PDMIHOSTPARALLELPORT; 1699 1700 1701 /** Pointer to a Host Parallel connector interface. */ 1702 typedef struct PDMIHOSTPARALLELCONNECTOR *PPDMIHOSTPARALLELCONNECTOR; 1703 1704 /** 1705 * Host parallel connector interface 1706 * Pair with PDMIHOSTPARALLELPORT. 1707 */ 1708 typedef struct PDMIHOSTPARALLELCONNECTOR 1690 1709 { 1691 1710 /** … … 1698 1717 * @thread Any thread. 1699 1718 */ 1700 DECLR3CALLBACKMEMBER(int, pfnWrite,(PPDMIHOST DEVICECONNECTOR pInterface, const void *pvBuf, size_t *pcbWrite));1719 DECLR3CALLBACKMEMBER(int, pfnWrite,(PPDMIHOSTPARALLELCONNECTOR pInterface, const void *pvBuf, size_t *pcbWrite)); 1701 1720 1702 1721 /** … … 1709 1728 * @thread Any thread. 1710 1729 */ 1711 DECLR3CALLBACKMEMBER(int, pfnRead,(PPDMIHOSTDEVICECONNECTOR pInterface, void *pvBuf, size_t *pcbRead)); 1712 1713 /** 1714 * Perform IO control on the host device. 1715 * 1716 * @returns VBox status code. 1717 * @param pInterface Pointer to the interface structure containing the called function pointer. 1718 * @param uCommand The number of the command to set or get data 1719 * @param pvData Where to store the command data. 1720 * @thread Any thread. 1721 */ 1722 DECLR3CALLBACKMEMBER(int, pfnIOCtl,(PPDMIHOSTDEVICECONNECTOR pInterface, RTUINT uCommand, void *pvData)); 1723 } PDMIHOSTDEVICECONNECTOR; 1730 DECLR3CALLBACKMEMBER(int, pfnRead,(PPDMIHOSTPARALLELCONNECTOR pInterface, void *pvBuf, size_t *pcbRead)); 1731 1732 /** 1733 * Write control register bits. 1734 * 1735 * @returns VBox status code. 1736 * @param pInterface Pointer to the interface structure containing the called function pointer. 1737 * @param val The new control register value. 1738 * @thread Any thread. 1739 */ 1740 DECLR3CALLBACKMEMBER(int, pfnWriteControl,(PPDMIHOSTPARALLELCONNECTOR pInterface, uint8_t val)); 1741 1742 /** 1743 * Read control register bits. 1744 * 1745 * @returns VBox status code. 1746 * @param pInterface Pointer to the interface structure containing the called function pointer. 1747 * @param pvBuf Where to store the control register bits. 1748 * @thread Any thread. 1749 */ 1750 DECLR3CALLBACKMEMBER(int, pfnReadControl,(PPDMIHOSTPARALLELCONNECTOR pInterface, uint8_t *pvBuf)); 1751 1752 /** 1753 * Read status register bits. 1754 * 1755 * @returns VBox status code. 1756 * @param pInterface Pointer to the interface structure containing the called function pointer. 1757 * @param pvBuf Where to store the status register bits. 1758 * @thread Any thread. 1759 */ 1760 DECLR3CALLBACKMEMBER(int, pfnReadStatus,(PPDMIHOSTPARALLELCONNECTOR pInterface, uint8_t *pvBuf)); 1761 1762 /** 1763 * Set mode of the host parallel port. 1764 * 1765 * @returns VBox status code. 1766 * @param pInterface Pointer to the interface structure containing the called function pointer. 1767 * @param mode The mode of the host parallel port. 1768 * @thread Any thread. 1769 */ 1770 DECLR3CALLBACKMEMBER(int, pfnSetMode,(PPDMIHOSTPARALLELCONNECTOR pInterface, PDMPARALLELPORTMODE mode)); 1771 } PDMIHOSTPARALLELCONNECTOR; 1724 1772 1725 1773 -
trunk/src/VBox/Devices/PC/vbox.dsl
r4774 r6222 414 414 }) 415 415 } 416 417 // Parallel port 418 Device (LPT) 419 { 420 Name (_HID, EisaId ("PNP0400")) 421 Method (_STA, 0, NotSerialized) 422 { 423 Return (0x0F) 424 } 425 Name (_CRS, ResourceTemplate () 426 { 427 IO (Decode16, 0x0378, 0x0378, 0x08, 0x08) 428 IO (Decode16, 0x0778, 0x0778, 0x08, 0x08) 429 IRQNoFlags () {7} 430 }) 431 } 416 432 } 417 433 -
trunk/src/VBox/Devices/Parallel/DevParallel.cpp
r5999 r6222 32 32 33 33 #include "Builtins.h" 34 #include "ParallelIOCtlCmd.h"35 34 36 35 #define PARALLEL_SAVED_STATE_VERSION 1 … … 44 43 #define LPT_STATUS_IRQ 0x04 45 44 #define LPT_STATUS_BIT1 0x02 /* reserved (only for completeness) */ 46 #define LPT_STATUS_ BIT0 0x01 /* reserved (only for completeness) */45 #define LPT_STATUS_EPP_TIMEOUT 0x01 47 46 48 47 #define LPT_CONTROL_BIT7 0x80 /* reserved (only for completeness) */ … … 55 54 #define LPT_CONTROL_STROBE 0x01 56 55 56 /** mode defines for the extended control register */ 57 #define LPT_ECP_ECR_CHIPMODE_MASK 0xe0 58 #define LPT_ECP_ECR_CHIPMODE_GET_BITS(reg) ((reg) >> 5) 59 #define LPT_ECP_ECR_CHIPMODE_SET_BITS(val) ((val) << 5) 60 #define LPT_ECP_ECR_CHIPMODE_CONFIGURATION 0x07 61 #define LPT_ECP_ECR_CHIPMODE_FIFO_TEST 0x06 62 #define LPT_ECP_ECR_CHIPMODE_RESERVED 0x05 63 #define LPT_ECP_ECR_CHIPMODE_EPP 0x04 64 #define LPT_ECP_ECR_CHIPMODE_ECP_FIFO 0x03 65 #define LPT_ECP_ECR_CHIPMODE_PP_FIFO 0x02 66 #define LPT_ECP_ECR_CHIPMODE_BYTE 0x01 67 #define LPT_ECP_ECR_CHIPMODE_COMPAT 0x00 68 69 /** FIFO status bits in extended control register */ 70 #define LPT_ECP_ECR_FIFO_MASK 0x03 71 #define LPT_ECP_ECR_FIFO_SOME_DATA 0x00 72 #define LPT_ECP_ECR_FIFO_FULL 0x02 73 #define LPT_ECP_ECR_FIFO_EMPTY 0x01 74 75 #define LPT_ECP_CONFIGA_FIFO_WITDH_MASK 0x70 76 #define LPT_ECP_CONFIGA_FIFO_WIDTH_GET_BITS(reg) ((reg) >> 4) 77 #define LPT_ECP_CONFIGA_FIFO_WIDTH_SET_BITS(val) ((val) << 4) 78 #define LPT_ECP_CONFIGA_FIFO_WIDTH_16 0x00 79 #define LPT_ECP_CONFIGA_FIFO_WIDTH_32 0x20 80 #define LPT_ECP_CONFIGA_FIFO_WIDTH_8 0x10 81 82 #define LPT_ECP_FIFO_DEPTH 2 83 84 57 85 typedef struct ParallelState 58 86 { … … 70 98 R3PTRTYPE(PDMIBASE) IBase; 71 99 /** The host device port interface. */ 72 R3PTRTYPE(PDMIHOST DEVICEPORT) IHostDevicePort;100 R3PTRTYPE(PDMIHOSTPARALLELPORT) IHostParallelPort; 73 101 /** Pointer to the attached base driver. */ 74 102 R3PTRTYPE(PPDMIBASE) pDrvBase; 75 103 /** Pointer to the attached host device. */ 76 R3PTRTYPE(PPDMIHOST DEVICECONNECTOR) pDrvHostDeviceConnector;104 R3PTRTYPE(PPDMIHOSTPARALLELCONNECTOR) pDrvHostParallelConnector; 77 105 78 106 uint8_t reg_data; 79 107 uint8_t reg_status; 80 108 uint8_t reg_control; 109 uint8_t reg_epp_addr; 110 uint8_t reg_epp_data; 111 uint8_t reg_ecp_ecr; 112 uint8_t reg_ecp_base_plus_400h; /* has different meanings */ 113 uint8_t reg_ecp_config_b; 114 115 /** The ECP FIFO implementation*/ 116 uint8_t ecp_fifo[LPT_ECP_FIFO_DEPTH]; 117 int act_fifo_pos_write; 118 int act_fifo_pos_read; 81 119 82 120 int irq; 121 uint8_t epp_timeout; 83 122 84 123 bool fGCEnabled; … … 94 133 #ifndef VBOX_DEVICE_STRUCT_TESTCASE 95 134 135 #define PDMIHOSTPARALLELPORT_2_PARALLELSTATE(pInstance) ( (ParallelState *)((uintptr_t)(pInterface) - RT_OFFSETOF(ParallelState, IHostParallelPort)) ) 136 #define PDMIHOSTDEVICEPORT_2_PARALLELSTATE(pInstance) ( (ParallelState *)((uintptr_t)(pInterface) - RT_OFFSETOF(ParallelState, IHostDevicePort)) ) 96 137 #define PDMIBASE_2_PARALLELSTATE(pInstance) ( (ParallelState *)((uintptr_t)(pInterface) - RT_OFFSETOF(ParallelState, IBase)) ) 97 #define PDMIHOSTDEVICEPORT_2_PARALLELSTATE(pInstance) ( (ParallelState *)((uintptr_t)(pInterface) - RT_OFFSETOF(ParallelState, IHostDevicePort)) )98 99 138 100 139 __BEGIN_DECLS 101 140 PDMBOTHCBDECL(int) parallelIOPortRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb); 102 141 PDMBOTHCBDECL(int) parallelIOPortWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb); 142 #if 0 143 PDMBOTHCBDECL(int) parallelIOPortReadECP(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb); 144 PDMBOTHCBDECL(int) parallelIOPortWriteECP(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb); 145 #endif 103 146 __END_DECLS 104 147 105 106 static void parallel_update_irq(ParallelState *s) 107 { 108 if (s->reg_control & LPT_CONTROL_ENABLE_IRQ_VIA_ACK){148 static void parallel_set_irq(ParallelState *s) 149 { 150 if (s->reg_control & LPT_CONTROL_ENABLE_IRQ_VIA_ACK) 151 { 109 152 Log(("parallel_update_irq %d 1\n", s->irq)); 110 153 PDMDevHlpISASetIrqNoWait(CTXSUFF(s->pDevIns), s->irq, 1); 111 } else { 112 Log(("parallel_update_irq %d 0\n", s->irq)); 113 PDMDevHlpISASetIrqNoWait(CTXSUFF(s->pDevIns), s->irq, 0); 114 } 154 } 155 } 156 157 static void parallel_clear_irq(ParallelState *s) 158 { 159 Log(("parallel_update_irq %d 0\n", s->irq)); 160 PDMDevHlpISASetIrqNoWait(CTXSUFF(s->pDevIns), s->irq, 0); 115 161 } 116 162 … … 122 168 addr &= 7; 123 169 LogFlow(("parallel: write addr=0x%02x val=0x%02x\n", addr, val)); 170 ch = val; 171 124 172 switch(addr) { 125 173 default: … … 129 177 return VINF_IOM_HC_IOPORT_WRITE; 130 178 #else 131 ch = val;132 179 s->reg_data = ch; 133 if (RT_LIKELY(s->pDrvHost DeviceConnector))180 if (RT_LIKELY(s->pDrvHostParallelConnector)) 134 181 { 135 182 Log(("parallel_io_port_write: write 0x%X\n", ch)); 136 183 size_t cbWrite = 1; 137 int rc = s->pDrvHost DeviceConnector->pfnWrite(s->pDrvHostDeviceConnector, &ch, &cbWrite);184 int rc = s->pDrvHostParallelConnector->pfnWrite(s->pDrvHostParallelConnector, &ch, &cbWrite); 138 185 AssertRC(rc); 139 186 } … … 143 190 break; 144 191 case 2: 145 s->reg_control = val; 146 parallel_update_irq(s); 192 /** Set the reserved bits to one */ 193 ch |= (LPT_CONTROL_BIT6 | LPT_CONTROL_BIT7); 194 if (ch != s->reg_control) { 195 #ifndef IN_RING3 196 NOREF(ch); 197 return VINF_IOM_HC_IOPORT_WRITE; 198 #else 199 int rc = s->pDrvHostParallelConnector->pfnWriteControl(s->pDrvHostParallelConnector, ch); 200 AssertRC(rc); 201 s->reg_control = val; 202 #endif 203 } 147 204 break; 148 205 case 3: 206 s->reg_epp_addr = val; 149 207 break; 150 208 case 4: 209 s->reg_epp_data = val; 151 210 break; 152 211 case 5: … … 171 230 default: 172 231 case 0: 232 if (!(s->reg_control & LPT_CONTROL_ENABLE_BIDIRECT)) 233 ret = s->reg_data; 234 else 235 { 173 236 #ifndef IN_RING3 174 237 *pRC = VINF_IOM_HC_IOPORT_READ; 175 238 #else 176 if (RT_LIKELY(s->pDrvHost DeviceConnector))239 if (RT_LIKELY(s->pDrvHostParallelConnector)) 177 240 { 178 241 size_t cbRead; 179 int rc = s->pDrvHost DeviceConnector->pfnRead(s->pDrvHostDeviceConnector, &s->reg_data, &cbRead);242 int rc = s->pDrvHostParallelConnector->pfnRead(s->pDrvHostParallelConnector, &s->reg_data, &cbRead); 180 243 Log(("parallel_io_port_read: read 0x%X\n", s->reg_data)); 181 244 AssertRC(rc); … … 183 246 ret = s->reg_data; 184 247 #endif 248 } 185 249 break; 186 250 case 1: 251 #ifndef IN_RING3 252 *pRC = VINF_IOM_HC_IOPORT_READ; 253 #else 254 if (RT_LIKELY(s->pDrvHostParallelConnector)) 255 { 256 int rc = s->pDrvHostParallelConnector->pfnReadStatus(s->pDrvHostParallelConnector, &s->reg_status); 257 AssertRC(rc); 258 } 187 259 ret = s->reg_status; 260 parallel_clear_irq(s); 261 #endif 188 262 break; 189 263 case 2: … … 191 265 break; 192 266 case 3: 267 ret = s->reg_epp_addr; 193 268 break; 194 269 case 4: 270 ret = s->reg_epp_data; 195 271 break; 196 272 case 5: … … 205 281 } 206 282 283 #if 0 284 static int parallel_ioport_write_ecp(void *opaque, uint32_t addr, uint32_t val) 285 { 286 ParallelState *s = (ParallelState *)opaque; 287 unsigned char ch; 288 289 addr &= 7; 290 LogFlow(("parallel: write ecp addr=0x%02x val=0x%02x\n", addr, val)); 291 ch = val; 292 switch(addr) { 293 default: 294 case 0: 295 if (LPT_ECP_ECR_CHIPMODE_GET_BITS(s->reg_ecp_ecr) == LPT_ECP_ECR_CHIPMODE_FIFO_TEST) { 296 s->ecp_fifo[s->act_fifo_pos_write] = ch; 297 s->act_fifo_pos_write++; 298 if (s->act_fifo_pos_write < LPT_ECP_FIFO_DEPTH) { 299 /** FIFO has some data (clear both FIFO bits) */ 300 s->reg_ecp_ecr &= ~(LPT_ECP_ECR_FIFO_EMPTY | LPT_ECP_ECR_FIFO_FULL); 301 } else { 302 /** FIFO is full */ 303 /** Clear FIFO empty bit */ 304 s->reg_ecp_ecr &= ~LPT_ECP_ECR_FIFO_EMPTY; 305 /** Set FIFO full bit */ 306 s->reg_ecp_ecr |= LPT_ECP_ECR_FIFO_FULL; 307 s->act_fifo_pos_write = 0; 308 } 309 } else { 310 s->reg_ecp_base_plus_400h = ch; 311 } 312 break; 313 case 1: 314 s->reg_ecp_config_b = ch; 315 break; 316 case 2: 317 /** If we change the mode clear FIFO */ 318 if ((ch & LPT_ECP_ECR_CHIPMODE_MASK) != (s->reg_ecp_ecr & LPT_ECP_ECR_CHIPMODE_MASK)) { 319 /** reset the fifo */ 320 s->act_fifo_pos_write = 0; 321 s->act_fifo_pos_read = 0; 322 /** Set FIFO empty bit */ 323 s->reg_ecp_ecr |= LPT_ECP_ECR_FIFO_EMPTY; 324 /** Clear FIFO full bit */ 325 s->reg_ecp_ecr &= ~LPT_ECP_ECR_FIFO_FULL; 326 } 327 /** Set new mode */ 328 s->reg_ecp_ecr |= LPT_ECP_ECR_CHIPMODE_SET_BITS(LPT_ECP_ECR_CHIPMODE_GET_BITS(ch)); 329 break; 330 case 3: 331 break; 332 case 4: 333 break; 334 case 5: 335 break; 336 case 6: 337 break; 338 case 7: 339 break; 340 } 341 return VINF_SUCCESS; 342 } 343 344 static uint32_t parallel_ioport_read_ecp(void *opaque, uint32_t addr, int *pRC) 345 { 346 ParallelState *s = (ParallelState *)opaque; 347 uint32_t ret = ~0U; 348 349 *pRC = VINF_SUCCESS; 350 351 addr &= 7; 352 switch(addr) { 353 default: 354 case 0: 355 if (LPT_ECP_ECR_CHIPMODE_GET_BITS(s->reg_ecp_ecr) == LPT_ECP_ECR_CHIPMODE_FIFO_TEST) { 356 ret = s->ecp_fifo[s->act_fifo_pos_read]; 357 s->act_fifo_pos_read++; 358 if (s->act_fifo_pos_read == LPT_ECP_FIFO_DEPTH) 359 s->act_fifo_pos_read = 0; /** end of FIFO, start at beginning */ 360 if (s->act_fifo_pos_read == s->act_fifo_pos_write) { 361 /** FIFO is empty */ 362 /** Set FIFO empty bit */ 363 s->reg_ecp_ecr |= LPT_ECP_ECR_FIFO_EMPTY; 364 /** Clear FIFO full bit */ 365 s->reg_ecp_ecr &= ~LPT_ECP_ECR_FIFO_FULL; 366 } else { 367 /** FIFO has some data (clear all FIFO bits) */ 368 s->reg_ecp_ecr &= ~(LPT_ECP_ECR_FIFO_EMPTY | LPT_ECP_ECR_FIFO_FULL); 369 } 370 } else { 371 ret = s->reg_ecp_base_plus_400h; 372 } 373 break; 374 case 1: 375 ret = s->reg_ecp_config_b; 376 break; 377 case 2: 378 ret = s->reg_ecp_ecr; 379 break; 380 case 3: 381 break; 382 case 4: 383 break; 384 case 5: 385 break; 386 case 6: 387 break; 388 case 7: 389 break; 390 } 391 LogFlow(("parallel: read ecp addr=0x%02x val=0x%02x\n", addr, ret)); 392 return ret; 393 } 394 #endif 395 207 396 #ifdef IN_RING3 208 static DECLCALLBACK(int) parallelNotifyRead(PPDMICHARPORT pInterface, const void *pvBuf, size_t *pcbRead) 209 { 210 ParallelState *pData = PDMIHOSTDEVICEPORT_2_PARALLELSTATE(pInterface); 211 int rc; 212 213 NOREF(pvBuf); NOREF(pcbRead); NOREF(pData); NOREF(rc); 397 static DECLCALLBACK(int) parallelNotifyInterrupt(PPDMIHOSTPARALLELPORT pInterface) 398 { 399 ParallelState *pData = PDMIHOSTPARALLELPORT_2_PARALLELSTATE(pInterface); 400 401 PDMCritSectEnter(&pData->CritSect, VINF_SUCCESS); 402 parallel_set_irq(pData); 403 PDMCritSectLeave(&pData->CritSect); 404 214 405 return VINF_SUCCESS; 215 #if 0216 Assert(*pcbRead != 0);217 218 PDMCritSectEnter(&pData->CritSect, VERR_PERMISSION_DENIED);219 if (pData->lsr & UART_LSR_DR)220 {221 /* If a character is still in the read queue, then wait for it to be emptied. */222 PDMCritSectLeave(&pData->CritSect);223 rc = RTSemEventWait(pData->ReceiveSem, 250);224 if (VBOX_FAILURE(rc))225 return rc;226 227 PDMCritSectEnter(&pData->CritSect, VERR_PERMISSION_DENIED);228 }229 230 if (!(pData->lsr & UART_LSR_DR))231 {232 pData->rbr = *(const char *)pvBuf;233 pData->lsr |= UART_LSR_DR;234 serial_update_irq(pData);235 *pcbRead = 1;236 rc = VINF_SUCCESS;237 }238 else239 rc = VERR_TIMEOUT;240 241 PDMCritSectLeave(&pData->CritSect);242 243 return rc;244 #endif245 406 } 246 407 #endif /* IN_RING3 */ … … 312 473 } 313 474 475 #if 0 476 /** 477 * Port I/O Handler for OUT operations on ECP registers. 478 * 479 * @returns VBox status code. 480 * 481 * @param pDevIns The device instance. 482 * @param pvUser User argument. 483 * @param Port Port number used for the IN operation. 484 * @param u32 The value to output. 485 * @param cb The value size in bytes. 486 */ 487 PDMBOTHCBDECL(int) parallelIOPortWriteECP(PPDMDEVINS pDevIns, void *pvUser, 488 RTIOPORT Port, uint32_t u32, unsigned cb) 489 { 490 ParallelState *pData = PDMINS2DATA(pDevIns, ParallelState *); 491 int rc = VINF_SUCCESS; 492 493 if (cb == 1) 494 { 495 rc = PDMCritSectEnter(&pData->CritSect, VINF_IOM_HC_IOPORT_WRITE); 496 if (rc == VINF_SUCCESS) 497 { 498 Log2(("%s: ecp port %#06x val %#04x\n", __FUNCTION__, Port, u32)); 499 rc = parallel_ioport_write_ecp (pData, Port, u32); 500 PDMCritSectLeave(&pData->CritSect); 501 } 502 } 503 else 504 AssertMsgFailed(("Port=%#x cb=%d u32=%#x\n", Port, cb, u32)); 505 506 return rc; 507 } 508 509 /** 510 * Port I/O Handler for IN operations on ECP registers. 511 * 512 * @returns VBox status code. 513 * 514 * @param pDevIns The device instance. 515 * @param pvUser User argument. 516 * @param Port Port number used for the IN operation. 517 * @param u32 The value to output. 518 * @param cb The value size in bytes. 519 */ 520 PDMBOTHCBDECL(int) parallelIOPortReadECP(PPDMDEVINS pDevIns, void *pvUser, 521 RTIOPORT Port, uint32_t *pu32, unsigned cb) 522 { 523 ParallelState *pData = PDMINS2DATA(pDevIns, ParallelState *); 524 int rc = VINF_SUCCESS; 525 526 if (cb == 1) 527 { 528 rc = PDMCritSectEnter(&pData->CritSect, VINF_IOM_HC_IOPORT_READ); 529 if (rc == VINF_SUCCESS) 530 { 531 *pu32 = parallel_ioport_read_ecp (pData, Port, &rc); 532 Log2(("%s: ecp port %#06x val %#04x\n", __FUNCTION__, Port, *pu32)); 533 PDMCritSectLeave(&pData->CritSect); 534 } 535 } 536 else 537 rc = VERR_IOM_IOPORT_UNUSED; 538 539 return rc; 540 } 541 #endif 542 314 543 #ifdef IN_RING3 315 544 /** … … 384 613 { 385 614 ParallelState *pData = PDMINS2DATA(pDevIns, ParallelState *); 386 pData->pDevInsGC = PDMDEVINS_2_GCPTR(pDevIns);615 pData->pDevInsGC += offDelta; 387 616 } 388 617 … … 395 624 case PDMINTERFACE_BASE: 396 625 return &pData->IBase; 397 case PDMINTERFACE_HOST_ DEVICE_PORT:398 return &pData->IHost DevicePort;626 case PDMINTERFACE_HOST_PARALLEL_PORT: 627 return &pData->IHostParallelPort; 399 628 default: 400 629 return NULL; … … 415 644 ParallelState *pData = PDMINS2DATA(pDevIns, ParallelState *); 416 645 417 RTSemEventDestroy(pData->ReceiveSem);418 pData->ReceiveSem = NIL_RTSEMEVENT;419 420 646 PDMR3CritSectDelete(&pData->CritSect); 647 421 648 return VINF_SUCCESS; 422 649 } … … 441 668 { 442 669 int rc; 443 ParallelState 670 ParallelState *pData = PDMINS2DATA(pDevIns, ParallelState*); 444 671 uint16_t io_base; 445 672 uint8_t irq_lvl; … … 454 681 */ 455 682 if (!CFGMR3AreValuesValid(pCfgHandle, "IRQ\0IOBase\0")) 456 return VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES; 683 return PDMDEV_SET_ERROR(pDevIns, VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES, 684 N_("Configuration error: Unknown config key")); 457 685 458 686 rc = CFGMR3QueryBool(pCfgHandle, "GCEnabled", &pData->fGCEnabled); … … 473 701 pData->IBase.pfnQueryInterface = parallelQueryInterface; 474 702 475 /* I CharPort */476 /* pData->ICharPort.pfnNotifyRead = parallelNotifyRead; */703 /* IHostParallelPort */ 704 pData->IHostParallelPort.pfnNotifyInterrupt = parallelNotifyInterrupt; 477 705 478 706 rc = RTSemEventCreate(&pData->ReceiveSem); … … 489 717 return rc; 490 718 491 /** @todo r=bird: Check for VERR_CFGM_VALUE_NOT_FOUND and provide sensible defaults.492 * Also do AssertMsgFailed(("Configuration error:....)) in the failure cases of CFGMR3Query*()493 * and CFGR3AreValuesValid() like we're doing in the other devices. */494 719 rc = CFGMR3QueryU8(pCfgHandle, "IRQ", &irq_lvl); 495 if (VBOX_FAILURE(rc)) 496 return rc; 720 if (rc == VERR_CFGM_VALUE_NOT_FOUND) 721 irq_lvl = 7; 722 else if (VBOX_FAILURE(rc)) 723 return PDMDEV_SET_ERROR(pDevIns, rc, 724 N_("Configuration error: Failed to get the \"IRQ\" value")); 497 725 498 726 rc = CFGMR3QueryU16(pCfgHandle, "IOBase", &io_base); 499 if (VBOX_FAILURE(rc)) 500 return rc; 727 if (rc == VERR_CFGM_VALUE_NOT_FOUND) 728 io_base = 0x378; 729 else if (VBOX_FAILURE(rc)) 730 return PDMDEV_SET_ERROR(pDevIns, rc, 731 N_("Configuration error: Failed to get the \"IOBase\" value")); 501 732 502 733 Log(("parallelConstruct instance %d iobase=%04x irq=%d\n", iInstance, io_base, irq_lvl)); 503 734 504 735 pData->irq = irq_lvl; 505 pData->reg_status = LPT_STATUS_BUSY | LPT_STATUS_IRQ;506 pData->reg_control = LPT_CONTROL_STROBE | LPT_CONTROL_AUTO_LINEFEED | LPT_CONTROL_SELECT_PRINTER;507 736 pData->base = io_base; 737 738 /* Init parallel state */ 739 pData->reg_data = 0; 740 pData->reg_ecp_ecr = LPT_ECP_ECR_CHIPMODE_COMPAT | LPT_ECP_ECR_FIFO_EMPTY; 741 pData->act_fifo_pos_read = 0; 742 pData->act_fifo_pos_write = 0; 743 508 744 rc = PDMDevHlpIOPortRegister(pDevIns, io_base, 8, 0, 509 745 parallelIOPortWrite, parallelIOPortRead, 510 746 NULL, NULL, "PARALLEL"); 511 if (VBOX_FAILURE 747 if (VBOX_FAILURE(rc)) 512 748 return rc; 513 749 750 #if 0 751 /* register ecp registers */ 752 rc = PDMDevHlpIOPortRegister(pDevIns, io_base+0x400, 8, 0, 753 parallelIOPortWriteECP, parallelIOPortReadECP, 754 NULL, NULL, "PARALLEL ECP"); 755 if (VBOX_FAILURE(rc)) 756 return rc; 757 #endif 758 514 759 if (pData->fGCEnabled) 760 { 515 761 rc = PDMDevHlpIOPortRegisterGC(pDevIns, io_base, 8, 0, "parallelIOPortWrite", 516 762 "parallelIOPortRead", NULL, NULL, "Parallel"); 763 if (VBOX_FAILURE(rc)) 764 return rc; 765 766 #if 0 767 rc = PDMDevHlpIOPortRegisterGC(pDevIns, io_base+0x400, 8, 0, "parallelIOPortWriteECP", 768 "parallelIOPortReadECP", NULL, NULL, "Parallel Ecp"); 769 if (VBOX_FAILURE(rc)) 770 return rc; 771 #endif 772 } 517 773 518 774 if (pData->fR0Enabled) 775 { 519 776 rc = PDMDevHlpIOPortRegisterR0(pDevIns, io_base, 8, 0, "parallelIOPortWrite", 520 777 "parallelIOPortRead", NULL, NULL, "Parallel"); 521 522 /* Attach the char driver and get the interfaces. For now no run-time 778 if (VBOX_FAILURE(rc)) 779 return rc; 780 781 #if 0 782 rc = PDMDevHlpIOPortRegisterR0(pDevIns, io_base+0x400, 8, 0, "parallelIOPortWriteECP", 783 "parallelIOPortReadECP", NULL, NULL, "Parallel Ecp"); 784 if (VBOX_FAILURE(rc)) 785 return rc; 786 #endif 787 } 788 789 /* Attach the parallel port driver and get the interfaces. For now no run-time 523 790 * changes are supported. */ 524 791 rc = PDMDevHlpDriverAttach(pDevIns, 0, &pData->IBase, &pData->pDrvBase, "Parallel Host"); 525 792 if (VBOX_SUCCESS(rc)) 526 793 { 527 pData->pDrvHostDeviceConnector = (PDMIHOSTDEVICECONNECTOR *)pData->pDrvBase->pfnQueryInterface(pData->pDrvBase, PDMINTERFACE_HOST_DEVICE_CONNECTOR); 528 if (!pData->pDrvHostDeviceConnector) 794 pData->pDrvHostParallelConnector = (PDMIHOSTPARALLELCONNECTOR *)pData->pDrvBase->pfnQueryInterface(pData->pDrvBase, 795 PDMINTERFACE_HOST_PARALLEL_CONNECTOR); 796 if (!pData->pDrvHostParallelConnector) 529 797 { 530 AssertMsgFailed(("Configuration error: instance %d has no charinterface!\n", iInstance));798 AssertMsgFailed(("Configuration error: instance %d has no host parallel interface!\n", iInstance)); 531 799 return VERR_PDM_MISSING_INTERFACE; 532 800 } … … 536 804 { 537 805 pData->pDrvBase = NULL; 538 pData->pDrvHost DeviceConnector = NULL;806 pData->pDrvHostParallelConnector = NULL; 539 807 LogRel(("Parallel%d: no unit\n", iInstance)); 540 808 } … … 545 813 N_("Parallel device %d cannot attach to host driver\n"), iInstance); 546 814 } 815 816 /** Set compatibility mode */ 817 pData->pDrvHostParallelConnector->pfnSetMode(pData->pDrvHostParallelConnector, PDM_PARALLEL_PORT_MODE_COMPAT); 818 /** Get status of control register */ 819 pData->pDrvHostParallelConnector->pfnReadControl(pData->pDrvHostParallelConnector, &pData->reg_control); 547 820 548 821 rc = PDMDevHlpSSMRegister( -
trunk/src/VBox/Devices/Parallel/DrvHostParallel.cpp
r5999 r6222 23 23 #define LOG_GROUP LOG_GROUP_DRV_HOST_PARALLEL 24 24 #include <VBox/pdmdrv.h> 25 #include <VBox/pdmthread.h> 25 26 #include <iprt/asm.h> 26 27 #include <iprt/assert.h> 27 28 #include <iprt/stream.h> 28 29 #include <iprt/semaphore.h> 30 #include <iprt/file.h> 29 31 30 32 #ifdef RT_OS_LINUX … … 36 38 # include <linux/ppdev.h> 37 39 # include <linux/parport.h> 40 # include <errno.h> 38 41 #endif 39 42 40 43 #include "Builtins.h" 41 #include "ParallelIOCtlCmd.h"42 43 44 44 45 /******************************************************************************* … … 51 52 { 52 53 /** Pointer to the driver instance structure. */ 53 PPDMDRVINS pDrvIns;54 PPDMDRVINS pDrvIns; 54 55 /** Pointer to the char port interface of the driver/device above us. */ 55 PPDMIHOST DEVICEPORT pDrvHostDevicePort;56 PPDMIHOSTPARALLELPORT pDrvHostParallelPort; 56 57 /** Our host device interface. */ 57 PDMIHOST DEVICECONNECTOR IHostDeviceConnector;58 PDMIHOSTPARALLELCONNECTOR IHostParallelConnector; 58 59 /** Our host device port interface. */ 59 PDMIHOST DEVICEPORT IHostDevicePort;60 PDMIHOSTPARALLELPORT IHostParallelPort; 60 61 /** Device Path */ 61 char *pszDevicePath;62 char *pszDevicePath; 62 63 /** Device Handle */ 63 RTFILE FileDevice; 64 /** Flag to notify the receive thread it should terminate. */ 65 volatile bool fShutdown; 66 /** Receive thread ID. */ 67 RTTHREAD ReceiveThread; 68 /** Send thread ID. */ 69 RTTHREAD SendThread; 70 /** Send event semephore */ 71 RTSEMEVENT SendSem; 72 64 RTFILE FileDevice; 65 /** Thread waiting for interrupts. */ 66 PPDMTHREAD pMonitorThread; 67 /** Wakeup pipe read end. */ 68 RTFILE WakeupPipeR; 69 /** Wakeup pipe write end. */ 70 RTFILE WakeupPipeW; 73 71 } DRVHOSTPARALLEL, *PDRVHOSTPARALLEL; 74 72 75 73 /** Converts a pointer to DRVHOSTPARALLEL::IHostDeviceConnector to a PDRHOSTPARALLEL. */ 76 #define PDMIHOST DEVICECONNECTOR_2_DRVHOSTPARALLEL(pInterface) ( (PDRVHOSTPARALLEL)((uintptr_t)pInterface - RT_OFFSETOF(DRVHOSTPARALLEL, IHostDeviceConnector)) )74 #define PDMIHOSTPARALLELCONNECTOR_2_DRVHOSTPARALLEL(pInterface) ( (PDRVHOSTPARALLEL)((uintptr_t)pInterface - RT_OFFSETOF(DRVHOSTPARALLEL, IHostParallelConnector)) ) 77 75 /** Converts a pointer to DRVHOSTPARALLEL::IHostDevicePort to a PDRHOSTPARALLEL. */ 78 #define PDMIHOST DEVICEPORT_2_DRVHOSTPARALLEL(pInterface) ( (PDRVHOSTPARALLEL)((uintptr_t)pInterface - RT_OFFSETOF(DRVHOSTPARALLEL, IHostDevicePort)) )76 #define PDMIHOSTPARALLELPORT_2_DRVHOSTPARALLEL(pInterface) ( (PDRVHOSTPARALLEL)((uintptr_t)pInterface - RT_OFFSETOF(DRVHOSTPARALLEL, IHostParallelPort)) ) 79 77 80 78 /* -=-=-=-=- IBase -=-=-=-=- */ … … 96 94 case PDMINTERFACE_BASE: 97 95 return &pDrvIns->IBase; 98 case PDMINTERFACE_HOST_ DEVICE_CONNECTOR:99 return &pData->IHost DeviceConnector;96 case PDMINTERFACE_HOST_PARALLEL_CONNECTOR: 97 return &pData->IHostParallelConnector; 100 98 default: 101 99 return NULL; … … 106 104 107 105 /** @copydoc PDMICHAR::pfnWrite */ 108 static DECLCALLBACK(int) drvHostParallelWrite(PPDMIHOST DEVICECONNECTOR pInterface, const void *pvBuf, size_t *cbWrite)109 { 110 PDRVHOSTPARALLEL pData = PDMIHOST DEVICECONNECTOR_2_DRVHOSTPARALLEL(pInterface);106 static DECLCALLBACK(int) drvHostParallelWrite(PPDMIHOSTPARALLELCONNECTOR pInterface, const void *pvBuf, size_t *cbWrite) 107 { 108 PDRVHOSTPARALLEL pData = PDMIHOSTPARALLELCONNECTOR_2_DRVHOSTPARALLEL(pInterface); 111 109 const unsigned char *pBuffer = (const unsigned char *)pvBuf; 112 110 … … 114 112 115 113 ioctl(pData->FileDevice, PPWDATA, pBuffer); 116 117 RTSemEventSignal(pData->SendSem); 118 return VINF_SUCCESS; 119 } 120 121 static DECLCALLBACK(int) drvHostParallelRead(PPDMIHOST DEVICECONNECTOR pInterface, void *pvBuf, size_t *cbRead)122 { 123 PDRVHOSTPARALLEL pData = PDMIHOST DEVICECONNECTOR_2_DRVHOSTPARALLEL(pInterface);114 *cbWrite = 1; 115 116 return VINF_SUCCESS; 117 } 118 119 static DECLCALLBACK(int) drvHostParallelRead(PPDMIHOSTPARALLELCONNECTOR pInterface, void *pvBuf, size_t *cbRead) 120 { 121 PDRVHOSTPARALLEL pData = PDMIHOSTPARALLELCONNECTOR_2_DRVHOSTPARALLEL(pInterface); 124 122 unsigned char *pBuffer = (unsigned char *)pvBuf; 125 123 … … 132 130 } 133 131 134 static DECLCALLBACK(int) drvHostParallelIOCtl(PPDMIHOSTDEVICECONNECTOR pInterface, RTUINT uCommand, 135 void *pvData) 136 { 137 PDRVHOSTPARALLEL pData = PDMIHOSTDEVICECONNECTOR_2_DRVHOSTPARALLEL(pInterface); 138 unsigned long ioctlCommand; 139 140 LogFlow(("%s: uCommand=%d pvData=%#p\n", __FUNCTION__, uCommand, pvData)); 141 142 switch (uCommand) { 143 case LPT_IOCTL_COMMAND_SET_CONTROL: 144 ioctlCommand = PPWCONTROL; 132 static DECLCALLBACK(int) drvHostParallelSetMode(PPDMIHOSTPARALLELCONNECTOR pInterface, PDMPARALLELPORTMODE mode) 133 { 134 PDRVHOSTPARALLEL pData = PDMIHOSTPARALLELCONNECTOR_2_DRVHOSTPARALLEL(pInterface); 135 int ppdev_mode; 136 137 LogFlow(("%s: mode=%d\n", __FUNCTION__, mode)); 138 139 switch (mode) { 140 case PDM_PARALLEL_PORT_MODE_COMPAT: 141 ppdev_mode = IEEE1284_MODE_COMPAT; 145 142 break; 146 case LPT_IOCTL_COMMAND_GET_CONTROL:147 ioctlCommand = PPRCONTROL;143 case PDM_PARALLEL_PORT_MODE_EPP: 144 ppdev_mode = IEEE1284_MODE_EPP; 148 145 break; 149 default: 150 AssertMsgFailed(("uCommand = %d?\n")); 151 return VERR_INVALID_PARAMETER; 152 } 153 154 ioctl(pData->FileDevice, ioctlCommand, pvData); 155 156 return VINF_SUCCESS; 146 case PDM_PARALLEL_PORT_MODE_ECP: 147 //ppdev_mode = IEEE1284_MODE_ECP; 148 break; 149 } 150 151 ioctl(pData->FileDevice, PPSETMODE, &ppdev_mode); 152 153 return VINF_SUCCESS; 154 } 155 156 static DECLCALLBACK(int) drvHostParallelWriteControl(PPDMIHOSTPARALLELCONNECTOR pInterface, uint8_t val) 157 { 158 PDRVHOSTPARALLEL pData = PDMIHOSTPARALLELCONNECTOR_2_DRVHOSTPARALLEL(pInterface); 159 160 LogFlow(("%s: val=%d\n", __FUNCTION__, val)); 161 162 ioctl(pData->FileDevice, PPWCONTROL, &val); 163 164 return VINF_SUCCESS; 165 } 166 167 static DECLCALLBACK(int) drvHostParallelReadControl(PPDMIHOSTPARALLELCONNECTOR pInterface, uint8_t *pvBuf) 168 { 169 PDRVHOSTPARALLEL pData = PDMIHOSTPARALLELCONNECTOR_2_DRVHOSTPARALLEL(pInterface); 170 uint8_t val; 171 172 ioctl(pData->FileDevice, PPRCONTROL, &val); 173 174 LogFlow(("%s: val=%d\n", __FUNCTION__, val)); 175 176 *pvBuf = val; 177 178 return VINF_SUCCESS; 179 } 180 181 static DECLCALLBACK(int) drvHostParallelReadStatus(PPDMIHOSTPARALLELCONNECTOR pInterface, uint8_t *pvBuf) 182 { 183 PDRVHOSTPARALLEL pData = PDMIHOSTPARALLELCONNECTOR_2_DRVHOSTPARALLEL(pInterface); 184 uint8_t val; 185 186 ioctl(pData->FileDevice, PPRSTATUS, &val); 187 188 LogFlow(("%s: val=%d\n", __FUNCTION__, val)); 189 190 *pvBuf = val; 191 192 return VINF_SUCCESS; 193 } 194 195 static DECLCALLBACK(int) drvHostParallelMonitorThread(PPDMDRVINS pDrvIns, PPDMTHREAD pThread) 196 { 197 PDRVHOSTPARALLEL pData = PDMINS2DATA(pDrvIns, PDRVHOSTPARALLEL); 198 fd_set readfds; 199 200 /* 201 * We can wait for interrupts using the select call on linux hosts. 202 */ 203 204 /* 205 * Setup the file descriptor set. 206 */ 207 FD_ZERO(&readfds); 208 FD_SET(pData->FileDevice, &readfds); 209 FD_SET(pData->WakeupPipeR, &readfds); 210 211 while (pThread->enmState == PDMTHREADSTATE_RUNNING) 212 { 213 int rc; 214 215 rc = select(FD_SETSIZE, &readfds, NULL, NULL, NULL); 216 if (rc < 0) 217 { 218 AssertMsgFailed(("select failed with rc=%d\n", RTErrConvertFromErrno(errno))); 219 return RTErrConvertFromErrno(errno); 220 } 221 222 if (FD_ISSET(pData->WakeupPipeR, &readfds)) 223 { 224 /* notification to terminate -- drain the pipe */ 225 char ch; 226 size_t cbRead; 227 RTFileRead(pData->WakeupPipeR, &ch, 1, &cbRead); 228 continue; 229 } 230 231 /* Interrupt occured. */ 232 rc = pData->pDrvHostParallelPort->pfnNotifyInterrupt(pData->pDrvHostParallelPort); 233 AssertRC(rc); 234 } 235 236 return VINF_SUCCESS; 237 } 238 239 /** 240 * Unblock the monitor thread so it can respond to a state change. 241 * 242 * @returns a VBox status code. 243 * @param pDrvIns The driver instance. 244 * @param pThread The send thread. 245 */ 246 static DECLCALLBACK(int) drvHostParallelWakeupMonitorThread(PPDMDRVINS pDrvIns, PPDMTHREAD pThread) 247 { 248 PDRVHOSTPARALLEL pData = PDMINS2DATA(pDrvIns, PDRVHOSTPARALLEL); 249 250 return RTFileWrite(pData->WakeupPipeW, "", 1, NULL); 157 251 } 158 252 … … 177 271 * Init basic data members and interfaces. 178 272 */ 179 pData->ReceiveThread = NIL_RTTHREAD; 180 pData->fShutdown = false; 273 181 274 /* IBase. */ 182 pDrvIns->IBase.pfnQueryInterface = drvHostParallelQueryInterface; 183 /* IChar. */ 184 pData->IHostDeviceConnector.pfnWrite = drvHostParallelWrite; 185 pData->IHostDeviceConnector.pfnIOCtl = drvHostParallelIOCtl; 186 pData->IHostDeviceConnector.pfnRead = drvHostParallelRead; 275 pDrvIns->IBase.pfnQueryInterface = drvHostParallelQueryInterface; 276 /* IHostParallelConnector. */ 277 pData->IHostParallelConnector.pfnWrite = drvHostParallelWrite; 278 pData->IHostParallelConnector.pfnRead = drvHostParallelRead; 279 pData->IHostParallelConnector.pfnSetMode = drvHostParallelSetMode; 280 pData->IHostParallelConnector.pfnWriteControl = drvHostParallelWriteControl; 281 pData->IHostParallelConnector.pfnReadControl = drvHostParallelReadControl; 282 pData->IHostParallelConnector.pfnReadStatus = drvHostParallelReadStatus; 187 283 188 284 /* … … 218 314 219 315 /* 220 * Get the IHostDevicePort interface of the above driver/device. 221 */ 222 pData->pDrvHostDevicePort = (PPDMIHOSTDEVICEPORT)pDrvIns->pUpBase->pfnQueryInterface(pDrvIns->pUpBase, PDMINTERFACE_HOST_DEVICE_PORT); 223 if (!pData->pDrvHostDevicePort) 224 return PDMDrvHlpVMSetError(pDrvIns, VERR_PDM_MISSING_INTERFACE_ABOVE, RT_SRC_POS, N_("Parallel#%d has no parallel port interface above"), pDrvIns->iInstance); 225 226 rc = RTSemEventCreate(&pData->SendSem); 227 AssertRC(rc); 316 * Get the IHostParallelPort interface of the above driver/device. 317 */ 318 pData->pDrvHostParallelPort = (PPDMIHOSTPARALLELPORT)pDrvIns->pUpBase->pfnQueryInterface(pDrvIns->pUpBase, PDMINTERFACE_HOST_PARALLEL_PORT); 319 if (!pData->pDrvHostParallelPort) 320 return PDMDrvHlpVMSetError(pDrvIns, VERR_PDM_MISSING_INTERFACE_ABOVE, RT_SRC_POS, N_("Parallel#%d has no parallel port interface above"), 321 pDrvIns->iInstance); 322 323 /* 324 * Create wakeup pipe. 325 */ 326 int aFDs[2]; 327 if (pipe(aFDs) != 0) 328 { 329 int rc = RTErrConvertFromErrno(errno); 330 AssertRC(rc); 331 return rc; 332 } 333 pData->WakeupPipeR = aFDs[0]; 334 pData->WakeupPipeW = aFDs[1]; 335 336 /* 337 * Start waiting for interrupts. 338 */ 339 rc = PDMDrvHlpPDMThreadCreate(pDrvIns, &pData->pMonitorThread, pData, drvHostParallelMonitorThread, drvHostParallelWakeupMonitorThread, 0, 340 RTTHREADTYPE_IO, "Interrupt Monitor"); 341 if (VBOX_FAILURE(rc)) 342 return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, N_("HostSerial#%d cannot create monitor thread"), pDrvIns->iInstance); 228 343 229 344 return VINF_SUCCESS; … … 244 359 245 360 LogFlow(("%s: iInstance=%d\n", __FUNCTION__, pDrvIns->iInstance)); 246 247 pData->fShutdown = true;248 if (pData->ReceiveThread)249 {250 RTThreadWait(pData->ReceiveThread, 1000, NULL);251 if (pData->ReceiveThread != NIL_RTTHREAD)252 LogRel(("Parallel%d: receive thread did not terminate\n", pDrvIns->iInstance));253 }254 255 RTSemEventSignal(pData->SendSem);256 RTSemEventDestroy(pData->SendSem);257 pData->SendSem = NIL_RTSEMEVENT;258 259 if (pData->SendThread)260 {261 RTThreadWait(pData->SendThread, 1000, NULL);262 if (pData->SendThread != NIL_RTTHREAD)263 LogRel(("Parallel%d: send thread did not terminate\n", pDrvIns->iInstance));264 }265 361 266 362 ioctl(pData->FileDevice, PPRELEASE);
Note:
See TracChangeset
for help on using the changeset viewer.