⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usbs_upd985xx.c

📁 NEC的USB接口驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
            return;        }    }        // We have a valid receive, with the data held in uncached->ep0_rx_buffer.    // Are we expecting the remaining data of a control transfer?    if (ep0.rx_expecting_data) {        // Was this data interrupted by a new setup packet?        if (0 != (ep0.rx_indicator.status & RXMBOX_STATUS_SETUP_SETUP)) {            // NOTE: it is not clear from the documentation exactly what            // happens here, e.g. is it guaranteed that the new control            // packet appears at the start of the buffer rather than            // after any data previously received? Given typical            // USB host-side implementations this scenario is considered            // sufficiently unlikely that no further investigation has            // been carried out.                        // Inform higher-level code that the receive has been aborted.            if ((usbs_control_return (*)(usbs_control_endpoint*, int)) 0 != ep0.common.complete_fn) {                (*ep0.common.complete_fn)(&ep0.common, -EIO);            }            ep0.rx_expecting_data       = false;            ep0.common.buffer           = (unsigned char*) 0;            ep0.common.buffer_size      = 0;            ep0.common.fill_buffer_fn   = 0;            ep0.common.complete_fn      = (usbs_control_return (*)(usbs_control_endpoint*, int)) 0;            // Fall through the main control message handling code below.        } else {            // Data was expected and received. Transfer the data to the            // user's buffer, and perform completion.            usbs_control_return result;            cyg_uint32          size     = ep0.rx_indicator.status & RXMBOX_STATUS_SIZE_MASK;                        CYG_ASSERT( (usbs_control_return (*)(usbs_control_endpoint*, int))0 != ep0.common.complete_fn, \                        "A completion function should be provided for OUT control messages");            CYG_ASSERT(size == ep0.common.buffer_size, "Inconsistency between buffer and transfer sizes");            memcpy(ep0.common.buffer, uncached->ep0_rx_buffer, size);            result = (*ep0.common.complete_fn)(&ep0.common, 0);            ep0.common.buffer           = (unsigned char*) 0;            ep0.common.buffer_size      = 0;            ep0.common.complete_fn      = (usbs_control_return (*)(usbs_control_endpoint*, int)) 0;            ep0.rx_expecting_data       = false;            // Start another receive for the next control message.            // Note that there has been a window where there was no receive            // in progress for endpoint 0, even though according to the            // USB spec a device must always be able to accept new            // control messages.            ep0_start_rx(8);            return;        }    }    // When we get here we should have an eight-byte control message    // in uncached->ep0_rx_buffer. This should get moved into    // the ep0.common.control_buffer so that higher-level code sees    // it in the appropriate location.    CYG_ASSERT((ep0.rx_indicator.address == &(uncached->ep0_rx_bufdescs[0])) || \               (ep0.rx_indicator.address == &(uncached->ep0_rx_bufdescs[2])),   \               "Received ep0 data should involve the ep0 rx buffer descriptor");        CYG_ASSERT(8 == (ep0.rx_indicator.status & RXMBOX_STATUS_SIZE_MASK), "Control messages should be 8 bytes");    memcpy(ep0.common.control_buffer, uncached->ep0_rx_buffer, 8);    // If we have received a control packet then any reset signals really    // will have come from the host and must be processed normally.    // Make sure that reset interrupts are no longer masked off.    if (0 == (*USBS_IMR2 & IBUS_SWAP32(USBS_GSR2_URST))) {        *USBS_IMR2              |= IBUS_SWAP32(USBS_GSR2_URST); FLUSH_IBUS();        usbs_upd985xx_gsr2_mask |= USBS_GSR2_URST;    }        {        usbs_control_return result  = USBS_CONTROL_RETURN_UNKNOWN;        usb_devreq*         req     = (usb_devreq*) ep0.common.control_buffer;        int length, direction, protocol, recipient;                    // Now we need to do some decoding of the data. A non-zero        // length field indicates that there will be a subsequent        // IN or OUT phase. The direction is controlled by the        // top bit of the first byte. The protocol is determined        // by other bits of the top byte.        length      = (req->length_hi << 8) | req->length_lo;        direction   = req->type & USB_DEVREQ_DIRECTION_MASK;        protocol    = req->type & USB_DEVREQ_TYPE_MASK;        recipient   = req->type & USB_DEVREQ_RECIPIENT_MASK;        DBG(("ep0, new control request: type %x, code %x\n", req->type, req->request));        DBG(("     %s, length %d, value hi %x lo %x, index hi %x lo %x\n",             (USB_DEVREQ_DIRECTION_OUT == direction) ? "out" : "in",             length, req->value_hi, req->value_lo, req->index_hi, req->index_lo));        if (USB_DEVREQ_TYPE_STANDARD == protocol) {                            // First see if the request can be handled entirely in            // this module.            if (USB_DEVREQ_SET_ADDRESS == req->request) {                // The USB device address should be in value_lo.                // No more data is expected.                int old_state = ep0.common.state;                int address = req->value_lo;                if ((0 != length) || (address > 127)) {                    result = USBS_CONTROL_RETURN_STALL;                } else {                    *USBS_GMR = (*USBS_GMR & ~(USBS_GMR_FA_MASK | USBS_GMR_VT)) | (address << USBS_GMR_FA_SHIFT); FLUSH_IBUS();                    result = USBS_CONTROL_RETURN_HANDLED;                }                // Switch to addressed state, informing higher-level                // code of this.                if (USBS_STATE_ADDRESSED != (old_state & USBS_STATE_MASK)) {                    ep0.common.state        = USBS_STATE_ADDRESSED;                    if ((void (*)(usbs_control_endpoint*, void*, usbs_state_change, int))0 != ep0.common.state_change_fn) {                        (*ep0.common.state_change_fn)(&ep0.common, ep0.common.state_change_data,                                                      USBS_STATE_CHANGE_ADDRESSED, old_state);                    }                }                // End of SET_ADDRESS handling            } else if (USB_DEVREQ_GET_STATUS == req->request) {                // GET_STATUS on the device as a whole is used to                // check the remote-wakeup and self-powered bits.                // GET_STATUS on an endpoint is used to determine                // the halted condition.                // GET_STATUS on anything else has to be left to                // other code.                if (USB_DEVREQ_RECIPIENT_DEVICE == recipient) {                    // The host should expect two bytes back.                    if ((2 == length) && (USB_DEVREQ_DIRECTION_IN == direction)) {                        ep0.common.control_buffer[0] = 0;   // Not self-powered, no remote wakeup                        ep0.common.control_buffer[1] = 0;                        ep0.common.buffer            = ep0.common.control_buffer;                        ep0.common.buffer_size       = 2;                        result                       = USBS_CONTROL_RETURN_HANDLED;                    } else {                        result = USBS_CONTROL_RETURN_STALL;                    }                                        } else if (USB_DEVREQ_RECIPIENT_ENDPOINT == recipient) {                    if ((2 == length) && (USB_DEVREQ_DIRECTION_IN == direction)) {                        int endpoint = req->index_lo;                        if (0 == endpoint) {                            // get-status on endpoint 0 is either undefined or always valid.                            // endpoint 0 is always up.                            ep0.common.control_buffer[0] = 0;                            result = USBS_CONTROL_RETURN_HANDLED;                        }#ifdef CYGPKG_DEVS_USB_UPD985XX_EP3                        else if (((USB_DEVREQ_INDEX_DIRECTION_IN | 3) == endpoint) &&                                 (USBS_STATE_CONFIGURED == (ep0.common.state & USBS_STATE_MASK))) {                            ep0.common.control_buffer[0] = ep3.common.halted;                            result = USBS_CONTROL_RETURN_HANDLED;                        }#endif                            #ifdef CYGPKG_DEVS_USB_UPD985XX_EP4                        else if (((USB_DEVREQ_INDEX_DIRECTION_OUT | 4) == endpoint) &&                                 (USBS_STATE_CONFIGURED == (ep0.common.state & USBS_STATE_MASK))) {                            ep0.common.control_buffer[0] = ep4.common.halted;                            result = USBS_CONTROL_RETURN_HANDLED;                                                        }#endif                            #ifdef CYGPKG_DEVS_USB_UPD985XX_EP5                        else if (((USB_DEVREQ_INDEX_DIRECTION_IN | 5) == endpoint) &&                                 (USBS_STATE_CONFIGURED == (ep0.common.state & USBS_STATE_MASK))) {                            ep0.common.control_buffer[0] = ep5.common.halted;                            result = USBS_CONTROL_RETURN_HANDLED;                        }#endif                                                    else {                            // An invalid endpoint has been specified or the                            // endpoint can only be examined in configured state.                            result = USBS_CONTROL_RETURN_STALL;                        }                        if (USBS_CONTROL_RETURN_HANDLED == result) {                            ep0.common.control_buffer[1] = 0;                            ep0.common.buffer            = ep0.common.control_buffer;                            ep0.common.buffer_size       = 2;                        }                    } else {                        result = USBS_CONTROL_RETURN_STALL;                    }                } // Endpoint or device get-status                                } else if (USB_DEVREQ_CLEAR_FEATURE == req->request) {                // CLEAR_FEATURE operates in much the same way as                // GET_STATUS                if (USB_DEVREQ_RECIPIENT_DEVICE == recipient) {                                            // No data should be transferred, and only remote-wakeup can be cleared.                    if ((0 != length) || (USB_DEVREQ_FEATURE_DEVICE_REMOTE_WAKEUP != req->value_lo)) {                        result = USBS_CONTROL_RETURN_STALL;                    } else {                        // Clearing remote-wakeup is a no-op.                        result = USBS_CONTROL_RETURN_HANDLED;                    }                } else if (USB_DEVREQ_RECIPIENT_ENDPOINT == recipient) {                    // The only feature that can be cleared is endpoint-halt, no data should be transferred.                    if ((0 != length) || (USB_DEVREQ_FEATURE_ENDPOINT_HALT != req->value_lo)) {                        result = USBS_CONTROL_RETURN_STALL;                    } else {                        int endpoint = req->index_lo;                        if (0 == endpoint) {                            // Clearing halt on endpoint 0 is always a no-op since that endpoint cannot be halted                        }#ifdef CYGPKG_DEVS_USB_UPD985XX_EP3                        else if (((USB_DEVREQ_INDEX_DIRECTION_IN | 3) == endpoint) &&                                 (USBS_STATE_CONFIGURED == (ep0.common.state & USBS_STATE_MASK))) {                            ep3_set_halted(&ep3.common, false);                            result = USBS_CONTROL_RETURN_HANDLED;                        }#endif#ifdef CYGPKG_DEVS_USB_UPD985XX_EP4                        else if (((USB_DEVREQ_INDEX_DIRECTION_OUT | 4) == endpoint) &&                                 (USBS_STATE_CONFIGURED == (ep0.common.state & USBS_STATE_MASK))) {                            ep4_set_halted(&ep4.common, false);                            result = USBS_CONTROL_RETURN_HANDLED;                        }#endif#ifdef CYGPKG_DEVS_USB_UPD985XX_EP5                        else if (((USB_DEVREQ_INDEX_DIRECTION_IN | 5) == endpoint) &&                                 (USBS_STATE_CONFIGURED == (ep0.common.state & USBS_STATE_MASK))) {                            ep5_set_halted(&ep5.common, false);                            result = USBS_CONTROL_RETURN_HANDLED;                        }#endif                        else {                            // Invalid endpoint or not in configured state.                            result = USBS_CONTROL_RETURN_STALL;                        }                    }                }   // Endpoing or device clear-feature                                } else if (USB_DEVREQ_SET_FEATURE == req->request) {                // SET_FEATURE also operates in much the same way as                // GET_STATUS                if (USB_DEVREQ_RECIPIENT_DEVICE == recipient) {                    // The only valid feature that can be set is remote-wakeup,                    // which is not supported by this driver.                    result = USBS_CONTROL_RETURN_STALL;                                        } else if (USB_DEVREQ_RECIPIENT_ENDPOINT == recipient) {                    // Only the halt condition can be set, and no data should be transferred.                    // Halting endpoint 0 should probably be disallowed although the                    // standard does not explicitly say so.                    if ((0 != length) ||                        (USB_DEVREQ_FEATURE_ENDPOINT_HALT != req->value_lo) ||                        (USBS_STATE_CONFIGURED != (ep0.common.state & USBS_STATE_MASK))) {                                                    result = USBS_CONTROL_RETURN_STALL;                                                } else {                        int endpoint = req->index_lo;                        if (0) {                        }#ifdef CYGPKG_DEVS_USB_UPD985XX_EP3                        else if ((USB_DEVREQ_INDEX_DIRECTION_IN | 3) == endpoint) {                            ep3_set_halted(&ep3.common, true);                            result = USBS_CONTROL_RETURN_HANDLED;                        }#endif                            #ifdef CYGPKG_DEVS_USB_UPD985XX_EP4                        else if ((USB_DEVREQ_INDEX_DIRECTION_OUT | 4) == endpoint) {                            ep4_set_halted(&ep4.common, true);                            result = USBS_CONTROL_RETURN_HANDLED;                        }#endif                            #ifdef CYGPKG_DEVS_USB_UPD985XX_EP5                        else if ((USB_DEVREQ_INDEX_DIRECTION_IN | 5) == endpoint) {                            ep5_set_halted(&ep5.common, true);                            result = USBS_CONTROL_RETURN_HANDLED;                        }#endif                                                    else {                            result = USBS_CONTROL_RETURN_STALL;                        }                    }                } // Endpoint or device set-feature            }            // If the result has not been handled yet, pass it to            // the installed callback function (if any).            if (USBS_CONTROL_RETURN_UNKNOWN == result) {                if ((usbs_control_return (*)(usbs_control_endpoint*, void*))0 != ep0.common.standard_control_fn) {                    result = (*ep0.common.standard_control_fn)(&ep0.common, ep0.common.standard_control_data);                }            }            // If the result has still not been handled, leave it to            // the default implementation in the USB slave common place.            if (USBS_CONTROL_RETURN_UNKNOWN == result) {            

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -