Ejemplo n.º 1
0
/*!
 * mxc_gptcr_timer_int_hndlr() - timer interrupt
 * @param irq
 * @param dev_id
 * @param regs
 */
irqreturn_t mxc_gptcr_timer_int_hndlr (int irq, void *dev_id, struct pt_regs *regs)
{               
        u32 gptsr = *_reg_GPT_GPTSR;


	*_reg_GPT_GPTIR &= ~(0x04);

        if (gptsr & (0x01 << 2)){
        	TRACE_MSG7(OCD, "cnt: %08x match: %08x gptsr: %08x GPTCNT: %08x GPTCR: %08x GPTSR: %08x GPTOCR3: %08x\n",
		                       mxc_gptcr_ticks_set, mxc_gptcr_match_set, gptsr,
		                        *_reg_GPT_GPTCNT, *_reg_GPT_GPTCR, *_reg_GPT_GPTSR, *_reg_GPT_GPTOCR3);

		*_reg_GPT_GPTCR &= ~(0x7 << 26);
		*_reg_GPT_GPTOCR3 = 0;
                TRACE_MSG0(OCD, "OCM3");
                TRACE_MSG1(OCD, "active: %x", mxc_gptcr_active);
                if (mxc_gptcr_active) {
                        TRACE_MSG0(OCD, "calling otg_event"); 
                        mxc_gptcr_active = 0;
                        otg_event(ocd_instance->otg, TMOUT, OCD, "TMOUT");
                }
                else {
                        TRACE_MSG0(OCD, "skipping otg_event"); 
                }
		*_reg_GPT_GPTSR |= 0x4;
		return IRQ_HANDLED;
	}

	if (!mxc_shared_int)
		*_reg_GPT_GPTIR |= 0x4;
		
	return IRQ_NONE;
}
Ejemplo n.º 2
0
/*! net_fd_start_xmit_nocrc
 * @brief - start sending a buffer
 *
 * @param function_instance - pointer to this function instance
 * @param buffer buffer containing data to send
 * @param len  - length of data to send
 * @param data instance data
 * @return: 0 if all OK
 *         -EINVAL, -EUNATCH, -ENOMEM
 *         rc from usbd_start_in_urb() if that fails (is != 0, may be one of err values above)
 *         Note: -ECOMM is interpreted by calling routine as signal to leave IF stopped.
 */
int net_fd_start_xmit_nocrc (struct usbd_function_instance *function_instance, u8 *buffer, int len, void *data)
{
        struct usb_network_private *npd = function_instance->privdata;
        struct usbd_urb *urb = NULL;
        int rc;
        int in_pkt_sz;
        u8 *cp;
        u32 crc;
        #ifndef CONFIG_OTG_NETWORK_DOUBLE_IN
        int xmit_index = 0;
        int endpoint_index = BULK_IN_A;
        #else /* CONFIG_OTG_NETWORK_DOUBLE_IN */
        int xmit_index = (otg_atomic_read(&npd->xmit_urbs_started[0]) <= otg_atomic_read(&npd->xmit_urbs_started[1]))
                ? 0 : 1;
        int endpoint_index = (xmit_index) ? BULK_IN_B : BULK_IN_A;
        #endif /* CONFIG_OTG_NETWORK_DOUBLE_IN */

        TRACE_MSG7(NTT,"npd: %p function: %p flags: %04x len: %d endpoint_index: %d xmit_started: %d %d",
                        npd, function_instance, npd->flags, len, endpoint_index,
                        otg_atomic_read(&npd->xmit_urbs_started[0]), otg_atomic_read(&npd->xmit_urbs_started[1]));

        in_pkt_sz = usbd_endpoint_wMaxPacketSize(function_instance, endpoint_index, usbd_high_speed(function_instance));

        /* allocate urb 5 bytes larger than required */
        if (!(urb = usbd_alloc_urb (function_instance, endpoint_index, len + 5 + in_pkt_sz, net_fd_urb_sent_bulk ))) {
                u8 epa = usbd_endpoint_bEndpointAddress(function_instance, endpoint_index, usbd_high_speed(function_instance));
                TRACE_MSG2(NTT,"urb alloc failed len: %d endpoint: %02x", len, epa);
                printk(KERN_ERR"%s: urb alloc failed len: %d endpoint: %02x\n", __FUNCTION__, len, epa);
                return -ENOMEM;
        }

        urb->actual_length = len;

        memcpy (urb->buffer, buffer, len);
        urb->function_privdata = data;
        urb->actual_length = len;
        otg_atomic_add(urb->actual_length, &npd->queued_bytes);
        otg_atomic_inc(&npd->xmit_urbs_started[xmit_index]);
        if ((rc = usbd_start_in_urb (urb))) {
                TRACE_MSG1(NTT,"FAILED: %d", rc);
                printk(KERN_ERR"%s: FAILED: %d\n", __FUNCTION__, rc);
                urb->function_privdata = NULL;
                otg_atomic_sub(urb->actual_length, &npd->queued_bytes);
                otg_atomic_dec(&npd->xmit_urbs_started[xmit_index]);
                usbd_free_urb (urb);
                return rc;
        }
        return 0;
}
Ejemplo n.º 3
0
/*! net_fd_recv_urb_mdlm
 * @brief callback to process a received URB
 *
 * @param urb - pointer to received urb
 * @param rc - dummy parameter
 * @return non-zero for failure.
 */
int net_fd_recv_urb_mdlm(struct usbd_urb *urb, int rc)
{
        struct usbd_function_instance *function_instance = urb->function_instance;
        struct usb_network_private *npd = function_instance->privdata;
        void *os_data = NULL;
        void *os_buffer = NULL;
        int crc_bad = 0;
        int trim = 0;
        int len;
        u32 crc;
        u32 temmp;
        len = urb->actual_length;
        trim = 0;

        //TRACE_MSG2(NTT, "status: %d actual_length: %d", urb->status, urb->actual_length);
        //RETURN_EINVAL_IF (urb->status == USBD_URB_OK);

        os_data = urb->function_privdata;

        //TRACE_MSG2(NTT, "os_data: %x os_buffer: %x", os_data, os_buffer);


        #if defined(CONFIG_OTG_NETWORK_BLAN_PADAFTER)
        {
                /* This version simply checks for a correct CRC along the
                 * entire packet. Some UDC's have trouble with some packet
                 * sizes, this allows us to add pad bytes after the CRC.
                 */

                u8 *src = urb->buffer;
                int copied;

                // XXX this should work, but the MIPS optimizer seems to get it wrong....
                //copied = (len < urb->wMaxPacketSize) ? 0 : ((len / urb->wMaxPacketSize) - 1) * urb->wMaxPacketSize;

                if (len < urb->wMaxPacketSize*2)
                        copied = 0;
                else {
                        int pkts = ((len - urb->wMaxPacketSize) / urb->wMaxPacketSize);
                        copied = (pkts - 1) * urb->wMaxPacketSize;
                }

                len -= copied;
                crc = CRC32_INIT;
                for (; copied-- > 0 ; crc = COMPUTE_FCS (crc, *os_buffer++ = *src++));

                for (; (len-- > 0) && (CRC32_GOOD != crc); crc = COMPUTE_FCS (crc, *os_buffer++ = *src++));

                trim = len + 4;

                if (CRC32_GOOD != crc) {
                        TRACE_MSG1(NTT,"AAA frame: %03x", urb->framenum);
                        THROW_IF(npd->seen_crc, crc_error);
                }
                else
                        npd->seen_crc = 1;
        }
        //#else /* defined(CONFIG_OTG_NETWORK_BLAN_PADAFTER) */
        #elif defined(CONFIG_OTG_NETWORK_BLAN_CRC) || defined(CONFIG_OTG_NETWORK_SAFE_CRC)
        /*
         * The CRC can be sent in two ways when the size of the transfer
         * ends up being a multiple of the packetsize:
         *
         *                                           |
         *                <data> <CRC><CRC><CRC><CRC>|<???>     case 1
         *                <data> <NUL><CRC><CRC><CRC>|<CRC>     case 2
         *           <data> <NUL><CRC><CRC><CRC><CRC>|          case 3
         *     <data> <NUL><CRC><CRC><CRC>|<CRC>     |          case 4
         *                                           |
         *
         * This complicates CRC checking, there are four scenarios:
         *
         *      1. length is 1 more than multiple of packetsize with a trailing byte
         *      2. length is 1 more than multiple of packetsize
         *      3. length is multiple of packetsize
         *      4. none of the above
         *
         * Finally, even though we always compute CRC, we do not actually throw
         * things away until and unless we have previously seen a good CRC.
         * This allows backwards compatibility with hosts that do not support
         * adding a CRC to the frame.
         *
         */

        // test if 1 more than packetsize multiple
        if (1 == (len % urb->wMaxPacketSize)) {
                u8 *cp = urb->buffer + len - 1 - 4;
                // copy and CRC up to the packetsize boundary
                crc = crc32_nocopy(urb->buffer, len - 1, CRC32_INIT);

                if (TRACE_VERBOSE)
                        TRACE_MSG7(NTT,"A CRC nocopy: %08x %08x len: %d CRC: %02x %02x %02x %02x",
                                        CRC32_GOOD, crc, len, cp[0], cp[1], cp[2], cp[3]);

                // if the CRC is good then this is case 1
                if (CRC32_GOOD != crc) {

                        crc = crc32_nocopy(urb->buffer + len - 1, 1, crc);

                        if (CRC32_GOOD != crc) {
                                //crc_errors[len%64]++;
                                TRACE_MSG3(NTT,"A CRC error %08x %08x %03x", CRC32_GOOD, crc, urb->framenum);
                                printk(KERN_INFO"%s: A CRC\n", __FUNCTION__);
                                npd->seen_crc_error = 1;
                                THROW_IF(npd->seen_crc, crc_error);
                        }
                        else
                                npd->seen_crc = 1;
                }
                else
                        npd->seen_crc = 1;

        }
        else {
                u8 *cp = urb->buffer + len - 4;
                crc = crc32_nocopy(urb->buffer, len, CRC32_INIT);
                if (TRACE_VERBOSE)
                        TRACE_MSG7(NTT,"B CRC nocopy: %08x %08x len: %d CRC: %02x %02x %02x %02x",
                                        CRC32_GOOD, crc, len, cp[0], cp[1], cp[2], cp[3]);

                if (CRC32_GOOD != crc) {
                        //crc_errors[len%64]++;
                        TRACE_MSG3(NTT,"B CRC error %08x %08x %03x", CRC32_GOOD, crc, urb->framenum);
                        if (TRACE_VERBOSE) {

                                TRACE_MSG2(NTT, "status: %d actual_length: %d", urb->status, urb->actual_length);

                                TRACE_NRECV(NTT, 32, urb->buffer);
                                TRACE_MSG0(NTT, "--");
                                TRACE_RECV(NTT, urb->actual_length, urb->buffer);
                        }
                        printk(KERN_INFO"%s: B CRC\n", __FUNCTION__);
                        npd->seen_crc_error = 1;
                        THROW_IF(npd->seen_crc, crc_error);
                }
                else
                        npd->seen_crc = 1;

                // XXX shorten by 4 bytes?

        }
        // trim IFF we are paying attention to crc
        if (npd->seen_crc)
                trim = 4;
        #endif /* defined(CONFIG_OTG_NETWORK_BLAN_CRC) ...*/

        if (net_fd_recv_buffer(function_instance, urb->buffer, len, os_data, crc_bad, trim)) {
                TRACE_MSG0(NTT, "FAILED");
                net_os_dealloc_buffer(function_instance, os_data, os_buffer);
        }

        // catch a simple error, just increment missed error and general error
        CATCH(error) {
                //TRACE_MSG4(NTT,"CATCH(error) urb: %p status: %d len: %d function: %p",
                //                urb, urb->status, urb->actual_length, function_instance);
                // catch a CRC error
                CATCH(crc_error) {
                        crc_bad = 1;
                        npd->seen_crc_error = 1;
                }
        }
        return 0;
}
Ejemplo n.º 4
0
/*! net_fd_start_xmit_ecm
 * @brief - start sending to host
 * @param function_instance
 * @param buffer data storage area
 * @param len - length of data to transmit
 * @param data - instance private data
 *
 * @return: 0 if all OK
 *         -EINVAL, -EUNATCH, -ENOMEM
 *         rc from usbd_start_in_urb() if that fails (is != 0, may be one of err values above)
 *         Note: -ECOMM is interpreted by calling routine as signal to leave IF stopped.
 */
int net_fd_start_xmit_ecm (struct usbd_function_instance *function_instance, u8 *buffer, int len, void *data)
{
        struct usb_network_private *npd = function_instance->privdata;
        struct usbd_urb *urb = NULL;
        int rc;
        int in_pkt_sz;
        u32 crc;
        //#ifndef CONFIG_OTG_NETWORK_DOUBLE_IN
        int xmit_index = 0;
        int endpoint_index = BULK_IN_A;
        //#else /* CONFIG_OTG_NETWORK_DOUBLE_IN */
        //int xmit_index = (otg_atomic_read(&npd->xmit_urbs_started[0]) <= otg_atomic_read(&npd->xmit_urbs_started[1]))
        //        ? 0 : 1;
        //int endpoint_index = (xmit_index) ? BULK_IN_B : BULK_IN_A;
        //#endif /* CONFIG_OTG_NETWORK_DOUBLE_IN */

        TRACE_MSG7(NTT,"npd: %p function: %p flags: %04x len: %d endpoint_index: %d xmit_started: %d %d",
                        npd, function_instance, npd->flags, len, endpoint_index,
                        otg_atomic_read(&npd->xmit_urbs_started[0]), otg_atomic_read(&npd->xmit_urbs_started[1]));

        in_pkt_sz = usbd_endpoint_wMaxPacketSize(function_instance, endpoint_index, usbd_high_speed(function_instance));

        //TRACE_MSG0(NTT,"SIMPLE_CRC");
        // allocate urb 5 bytes larger than required
        if (!(urb = usbd_alloc_urb (function_instance, endpoint_index, len + 5 + 4 + in_pkt_sz, net_fd_urb_sent_bulk ))) {
                u8 epa = usbd_endpoint_bEndpointAddress(function_instance, endpoint_index, usbd_high_speed(function_instance));
                TRACE_MSG2(NTT,"urb alloc failed len: %d endpoint: %02x", len, epa);
                printk(KERN_ERR"%s: urb alloc failed len: %d endpoint: %02x\n", __FUNCTION__, len, epa);
                return -ENOMEM;
        }
        urb->actual_length = len;

        #if defined(CONFIG_OTG_NETWORK_BLAN_CRC) || defined(CONFIG_OTG_NETWORK_SAFE_CRC)

        // copy and crc len bytes
        crc = crc32_copy(urb->buffer, buffer, len, CRC32_INIT);

        if ((urb->actual_length % in_pkt_sz) == (in_pkt_sz - 4)) {

                #undef CONFIG_OTG_NETWORK_PADBYTE
                #ifdef CONFIG_OTG_NETWORK_PADBYTE
                // add a pad byte if required to ensure a short packet, usbdnet driver
                // will correctly handle pad byte before or after CRC, but the MCCI driver
                // wants it before the CRC.
                crc = crc32_pad(urb->buffer + urb->actual_length, 1, crc);
                urb->actual_length++;
                #else /* CONFIG_OTG_NETWORK_PADBYTE */
                urb->flags |= USBD_URB_SENDZLP;
                TRACE_MSG2(NTT,"setting ZLP: urb: %p flags: %x", urb, urb->flags);
                #endif /* CONFIG_OTG_NETWORK_PADBYTE */
        }
        crc = ~crc;
        urb->buffer[urb->actual_length++] = crc & 0xff;
        urb->buffer[urb->actual_length++] = (crc >> 8) & 0xff;
        urb->buffer[urb->actual_length++] = (crc >> 16) & 0xff;
        urb->buffer[urb->actual_length++] = (crc >> 24) & 0xff;
        #if defined(CONFIG_OTG_NETWORK_BLAN_FERMAT)
        if (npd->fermat) fermat_encode(urb->buffer, urb->actual_length);
        #endif

        #else /* defined(CONFIG_OTG_NETWORK_BLAN_CRC) ...*/

        memcpy (urb->buffer, buffer, len);
        if ((urb->actual_length % in_pkt_sz) == (in_pkt_sz)) {
                /* no longer in Kconfig - change undef to define to active padbyte */
                #undef CONFIG_OTG_NETWORK_PADBYTE
                #ifdef CONFIG_OTG_NETWORK_PADBYTE
                urb->actual_length++;
                #else /* CONFIG_OTG_NETWORK_PADBYTE */
                urb->flags |= USBD_URB_SENDZLP;
                TRACE_MSG2(NTT,"setting ZLP: urb: %p flags: %x", urb, urb->flags);
                #endif /* CONFIG_OTG_NETWORK_PADBYTE */
        }


        #endif /* defined(CONFIG_OTG_NETWORK_BLAN_CRC) ...*/

        //TRACE_MSG3(NTT,"urb: %p buf: %p priv: %p", urb, data, urb->function_privdata);
        urb->function_privdata = data;

        otg_atomic_add(urb->actual_length, &npd->queued_bytes);
        otg_atomic_inc(&npd->xmit_urbs_started[xmit_index]);
        if ((rc = usbd_start_in_urb (urb))) {

                TRACE_MSG1(NTT,"FAILED: %d", rc);
                printk(KERN_ERR"%s: FAILED: %d\n", __FUNCTION__, rc);
                urb->function_privdata = NULL;
                otg_atomic_sub(urb->actual_length, &npd->queued_bytes);
                otg_atomic_dec(&npd->xmit_urbs_started[xmit_index]);
                usbd_free_urb (urb);

                return rc;
        }
        return 0;
}