diff options
Diffstat (limited to 'src/VBox/HostDrivers/VBoxUSB/solaris/VBoxUSB-solaris.c')
-rw-r--r-- | src/VBox/HostDrivers/VBoxUSB/solaris/VBoxUSB-solaris.c | 72 |
1 files changed, 40 insertions, 32 deletions
diff --git a/src/VBox/HostDrivers/VBoxUSB/solaris/VBoxUSB-solaris.c b/src/VBox/HostDrivers/VBoxUSB/solaris/VBoxUSB-solaris.c index 54eab7a1..d417d28b 100644 --- a/src/VBox/HostDrivers/VBoxUSB/solaris/VBoxUSB-solaris.c +++ b/src/VBox/HostDrivers/VBoxUSB/solaris/VBoxUSB-solaris.c @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2008-2012 Oracle Corporation + * Copyright (C) 2008-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -95,7 +95,7 @@ /** -=-=-=-=-=-=- Tunable Parameters -=-=-=-=-=-=- */ /** Time to wait while draining inflight UBRs on suspend, in seconds. */ -#define VBOXUSB_DRAIN_TIME 30 +#define VBOXUSB_DRAIN_TIME 20 /** Ctrl Xfer timeout in seconds. */ #define VBOXUSB_CTRL_XFER_TIMEOUT 10 /** Bulk Xfer timeout in seconds. */ @@ -249,6 +249,7 @@ typedef struct vboxusb_urb_t VUSBXFERTYPE enmType; /* Xfer type */ VUSBDIRECTION enmDir; /* Xfer direction */ VUSBSTATUS enmStatus; /* URB status */ + bool fShortOk; /* Whether receiving less data than requested is acceptable. */ RTR3PTR pvDataR3; /* Userspace address of the original data buffer */ size_t cbDataR3; /* Size of the data buffer */ mblk_t *pMsg; /* Pointer to the data buffer */ @@ -1866,10 +1867,11 @@ LOCAL int vboxUSBSolarisReapURB(vboxusb_state_t *pState, PVBOXUSBREQ_URB pUrbReq /* * Paranoia: we should have a single message block almost always. */ - if (RT_LIKELY(!pUrb->pMsg->b_cont && cbData > 0)) + if (RT_LIKELY( !pUrb->pMsg->b_cont + && cbData)) { rc = ddi_copyout(pUrb->pMsg->b_rptr, (void *)pUrbReq->pvData, cbData, Mode); - if (RT_UNLIKELY(rc != 0)) + if (RT_UNLIKELY(rc)) { LogRel((DEVICE_NAME ":vboxUSBSolarisReapUrb ddi_copyout failed! rc=%d\n", rc)); pUrbReq->enmStatus = VUSBSTATUS_INVALID; @@ -1942,16 +1944,13 @@ LOCAL int vboxUSBSolarisReapURB(vboxusb_state_t *pState, PVBOXUSBREQ_URB pUrbReq { AssertCompile(sizeof(pUrbReq->aIsocPkts) == sizeof(pUrb->aIsocPkts)); pUrbReq->cIsocPkts = pUrb->cIsocPkts; -#if 0 + for (unsigned i = 0; i < pUrb->cIsocPkts; i++) { - pUrbReq->aIsocPkts[i].cbPkt = pUrb->aIsocPkts[i].cbPkt; - pUrbReq->aIsocPkts[i].cbActPkt = pUrb->aIsocPkts[i].cbActPkt; + pUrbReq->aIsocPkts[i].cbPkt = pUrb->aIsocPkts[i].cbPkt; + pUrbReq->aIsocPkts[i].cbActPkt = pUrb->aIsocPkts[i].cbActPkt; pUrbReq->aIsocPkts[i].enmStatus = pUrb->aIsocPkts[i].enmStatus; } -#else - bcopy(pUrb->aIsocPkts, pUrbReq->aIsocPkts, pUrb->cIsocPkts * sizeof(VUSBISOC_PKT_DESC)); -#endif if (pUrb->enmDir == VUSBDIRECTION_IN) { @@ -1979,7 +1978,6 @@ LOCAL int vboxUSBSolarisReapURB(vboxusb_state_t *pState, PVBOXUSBREQ_URB pUrbReq else mutex_exit(&pState->Mtx); - Log((DEVICE_NAME ":vboxUSBSolarisReapUrb returns %d\n", rc)); return rc; } @@ -2232,7 +2230,7 @@ LOCAL int vboxUSBSolarisCloseDevice(vboxusb_state_t *pState, VBOXUSB_RESET_LEVEL mutex_enter(&pState->Mtx); int rc = vboxUSBSolarisDeviceState(pState->DevState); - if (enmReset == VBOXUSB_RESET_LEVEL_NONE) + if (enmReset == VBOXUSB_RESET_LEVEL_CLOSE) { vboxUSBSolarisCloseAllPipes(pState, true /* ControlPipe */); pState->fClosed = true; @@ -2661,8 +2659,6 @@ LOCAL void vboxUSBSolarisCloseAllPipes(vboxusb_state_t *pState, bool fDefault) */ LOCAL int vboxUSBSolarisOpenPipe(vboxusb_state_t *pState, vboxusb_ep_t *pEp) { -// LogFunc((DEVICE_NAME ":vboxUSBSolarisOpenPipe pState=%p pEp=%p\n", pState, pEp)); - Assert(mutex_owned(&pState->Mtx)); /* @@ -2671,6 +2667,7 @@ LOCAL int vboxUSBSolarisOpenPipe(vboxusb_state_t *pState, vboxusb_ep_t *pEp) if (pEp->pPipe) return VINF_SUCCESS; + /* * Default Endpoint; already opened just copy the pipe handle. */ @@ -2690,6 +2687,7 @@ LOCAL int vboxUSBSolarisOpenPipe(vboxusb_state_t *pState, vboxusb_ep_t *pEp) mutex_enter(&pState->Mtx); if (rc == USB_SUCCESS) { + LogFunc((DEVICE_NAME ":vboxUSBSolarisOpenPipe: Opened pipe. pState=%p pEp=%p\n", pState, pEp)); usb_pipe_set_private(pEp->pPipe, (usb_opaque_t)pEp); /* @@ -2925,14 +2923,16 @@ LOCAL vboxusb_urb_t *vboxUSBSolarisQueueURB(vboxusb_state_t *pState, PVBOXUSBREQ if (RT_LIKELY(pUrbReq)) { - pUrb->pvUrbR3 = pUrbReq->pvUrbR3; + pUrb->pvUrbR3 = pUrbReq->pvUrbR3; pUrb->bEndpoint = pUrbReq->bEndpoint; - pUrb->enmType = pUrbReq->enmType; - pUrb->enmDir = pUrbReq->enmDir; + pUrb->enmType = pUrbReq->enmType; + pUrb->enmDir = pUrbReq->enmDir; pUrb->enmStatus = pUrbReq->enmStatus; - pUrb->cbDataR3 = pUrbReq->cbData; - pUrb->pvDataR3 = (RTR3PTR)pUrbReq->pvData; + pUrb->fShortOk = pUrbReq->fShortOk; + pUrb->pvDataR3 = (RTR3PTR)pUrbReq->pvData; + pUrb->cbDataR3 = pUrbReq->cbData; pUrb->cIsocPkts = pUrbReq->cIsocPkts; + if (pUrbReq->enmType == VUSBXFERTYPE_ISOC) { for (unsigned i = 0; i < pUrbReq->cIsocPkts; i++) @@ -3067,12 +3067,7 @@ LOCAL int vboxUSBSolarisCtrlXfer(vboxusb_state_t *pState, vboxusb_ep_t *pEp, vbo AssertPtrReturn(pUrb->pMsg, VERR_INVALID_PARAMETER); uchar_t *pSetupData = pUrb->pMsg->b_rptr; - size_t cbData = pUrb->cbDataR3 - VBOXUSB_CTRL_XFER_SIZE; - - /* - * Solaris USBA gives us garbage and incorrect message lengths making it impossible to use - * pre-allocated control messages. The allocation of "ctrl_data" is not documented well. - */ + size_t cbData = pUrb->cbDataR3 > VBOXUSB_CTRL_XFER_SIZE ? pUrb->cbDataR3 - VBOXUSB_CTRL_XFER_SIZE : 0; /* * Allocate a wrapper request. @@ -3091,7 +3086,7 @@ LOCAL int vboxUSBSolarisCtrlXfer(vboxusb_state_t *pState, vboxusb_ep_t *pEp, vbo pReq->ctrl_wLength = (pSetupData[7] << VBOXUSB_CTRL_XFER_SIZE) | pSetupData[6]; if ( pUrb->enmDir == VUSBDIRECTION_OUT - && cbData > 0) + && cbData) { pUrb->pMsg->b_rptr += VBOXUSB_CTRL_XFER_SIZE; bcopy(pUrb->pMsg->b_rptr, pReq->ctrl_data->b_wptr, cbData); @@ -3104,13 +3099,21 @@ LOCAL int vboxUSBSolarisCtrlXfer(vboxusb_state_t *pState, vboxusb_ep_t *pEp, vbo /* * Initialize callbacks and timeouts. */ + usb_req_attrs_t fAttributes = USB_ATTRS_AUTOCLEARING; + if ( pUrb->enmDir == VUSBDIRECTION_IN + && pUrb->fShortOk) + { + fAttributes |= USB_ATTRS_SHORT_XFER_OK; + } pReq->ctrl_cb = vboxUSBSolarisCtrlXferCompleted; pReq->ctrl_exc_cb = vboxUSBSolarisCtrlXferCompleted; pReq->ctrl_timeout = VBOXUSB_CTRL_XFER_TIMEOUT; - pReq->ctrl_attributes = USB_ATTRS_AUTOCLEARING | (pUrb->enmDir == VUSBDIRECTION_IN ? USB_ATTRS_SHORT_XFER_OK : 0); + pReq->ctrl_attributes = fAttributes; pReq->ctrl_client_private = (usb_opaque_t)pUrb; + LogFunc((DEVICE_NAME ":vboxUSBSolarisCtrlXfer ctrl_wLength=%#RX16 cbData=%#zx fShortOk=%RTbool\n", pReq->ctrl_wLength, + cbData, !!(fAttributes & USB_ATTRS_SHORT_XFER_OK))); Log((DEVICE_NAME ":vboxUSBSolarisCtrlXfer %.*Rhxd\n", VBOXUSB_CTRL_XFER_SIZE, pSetupData)); /* @@ -3177,7 +3180,7 @@ LOCAL void vboxUSBSolarisCtrlXferCompleted(usb_pipe_handle_t pPipe, usb_ctrl_req pReq->ctrl_data = NULL; vboxUSBSolarisConcatMsg(pUrb); -#if defined(DEBUG_ramshankar) +#ifdef DEBUG_ramshankar if ( pUrb->pMsg && pUrb->pMsg->b_cont == NULL) /* Concat succeeded */ { @@ -3191,8 +3194,6 @@ LOCAL void vboxUSBSolarisCtrlXferCompleted(usb_pipe_handle_t pPipe, usb_ctrl_req * Update the URB and move to landed list for reaping. */ vboxUSBSolarisDeQueueURB(pUrb, pReq->ctrl_completion_reason); - usb_free_ctrl_req(pReq); - return; } else { @@ -3233,14 +3234,20 @@ LOCAL int vboxUSBSolarisBulkXfer(vboxusb_state_t *pState, vboxusb_ep_t *pEp, vbo /* * Initialize Bulk Xfer, callbacks and timeouts. */ + usb_req_attrs_t fAttributes = USB_ATTRS_AUTOCLEARING; if (pUrb->enmDir == VUSBDIRECTION_OUT) pReq->bulk_data = pUrb->pMsg; + else if ( pUrb->enmDir == VUSBDIRECTION_IN + && pUrb->fShortOk) + { + fAttributes |= USB_ATTRS_SHORT_XFER_OK; + } pReq->bulk_len = pUrb->cbDataR3; pReq->bulk_cb = vboxUSBSolarisBulkXferCompleted; pReq->bulk_exc_cb = vboxUSBSolarisBulkXferCompleted; pReq->bulk_timeout = VBOXUSB_BULK_XFER_TIMEOUT; - pReq->bulk_attributes = USB_ATTRS_AUTOCLEARING | (pUrb->enmDir == VUSBDIRECTION_IN ? USB_ATTRS_SHORT_XFER_OK : 0); + pReq->bulk_attributes = fAttributes; pReq->bulk_client_private = (usb_opaque_t)pUrb; /* Don't obtain state lock here, we're just reading unchanging data... */ @@ -3357,8 +3364,9 @@ LOCAL int vboxUSBSolarisIntrXfer(vboxusb_state_t *pState, vboxusb_ep_t *pEp, vbo } else { + Assert(pUrb->enmDir == VUSBDIRECTION_IN); pReq->intr_data = NULL; - pReq->intr_attributes = USB_ATTRS_AUTOCLEARING | USB_ATTRS_ONE_XFER | USB_ATTRS_SHORT_XFER_OK; + pReq->intr_attributes = USB_ATTRS_AUTOCLEARING | USB_ATTRS_ONE_XFER | (pUrb->fShortOk ? USB_ATTRS_SHORT_XFER_OK : 0); } pReq->intr_len = pUrb->cbDataR3; /* Not pEp->EpDesc.wMaxPacketSize */ |