transfer_descriptor.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2011 Jan Vesely
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  *
00009  * - Redistributions of source code must retain the above copyright
00010  *   notice, this list of conditions and the following disclaimer.
00011  * - Redistributions in binary form must reproduce the above copyright
00012  *   notice, this list of conditions and the following disclaimer in the
00013  *   documentation and/or other materials provided with the distribution.
00014  * - The name of the author may not be used to endorse or promote products
00015  *   derived from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00018  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00019  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00020  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
00021  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00022  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00023  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00024  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00025  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00026  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027  */
00034 #include <errno.h>
00035 #include <usb/debug.h>
00036 
00037 #include "transfer_descriptor.h"
00038 #include "../utils/malloc32.h"
00039 
00062 void td_init(td_t *instance, int err_count, size_t size, bool toggle, bool iso,
00063     bool low_speed, usb_target_t target, usb_packet_id pid, void *buffer,
00064     td_t *next)
00065 {
00066         assert(instance);
00067         assert(size < 1024);
00068         assert((pid == USB_PID_SETUP) || (pid == USB_PID_IN)
00069             || (pid == USB_PID_OUT));
00070 
00071         const uint32_t next_pa = addr_to_phys(next);
00072         assert((next_pa & LINK_POINTER_ADDRESS_MASK) == next_pa);
00073 
00074         instance->next = 0
00075             | LINK_POINTER_VERTICAL_FLAG
00076             | (next_pa ? next_pa : LINK_POINTER_TERMINATE_FLAG);
00077 
00078         instance->status = 0
00079             | ((err_count & TD_STATUS_ERROR_COUNT_MASK)
00080                 << TD_STATUS_ERROR_COUNT_POS)
00081             | (low_speed ? TD_STATUS_LOW_SPEED_FLAG : 0)
00082             | (iso ? TD_STATUS_ISOCHRONOUS_FLAG : 0)
00083             | TD_STATUS_ERROR_ACTIVE;
00084 
00085         if (pid == USB_PID_IN && !iso) {
00086                 instance->status |= TD_STATUS_SPD_FLAG;
00087         }
00088 
00089         instance->device = 0
00090             | (((size - 1) & TD_DEVICE_MAXLEN_MASK) << TD_DEVICE_MAXLEN_POS)
00091             | (toggle ? TD_DEVICE_DATA_TOGGLE_ONE_FLAG : 0)
00092             | ((target.address & TD_DEVICE_ADDRESS_MASK)
00093                 << TD_DEVICE_ADDRESS_POS)
00094             | ((target.endpoint & TD_DEVICE_ENDPOINT_MASK)
00095                 << TD_DEVICE_ENDPOINT_POS)
00096             | ((pid & TD_DEVICE_PID_MASK) << TD_DEVICE_PID_POS);
00097 
00098         instance->buffer_ptr = addr_to_phys(buffer);
00099 
00100         usb_log_debug2("Created TD(%p): %X:%X:%X:%X(%p).\n",
00101             instance, instance->next, instance->status, instance->device,
00102             instance->buffer_ptr, buffer);
00103         td_print_status(instance);
00104         if (pid == USB_PID_SETUP) {
00105                 usb_log_debug("SETUP BUFFER: %s\n",
00106                     usb_debug_str_buffer(buffer, 8, 8));
00107         }
00108 }
00109 /*----------------------------------------------------------------------------*/
00115 int td_status(td_t *instance)
00116 {
00117         assert(instance);
00118 
00119         /* This is hc internal error it should never be reported. */
00120         if ((instance->status & TD_STATUS_ERROR_BIT_STUFF) != 0)
00121                 return EAGAIN;
00122 
00123         /* CRC or timeout error, like device not present or bad data,
00124          * it won't be reported unless err count reached zero */
00125         if ((instance->status & TD_STATUS_ERROR_CRC) != 0)
00126                 return EBADCHECKSUM;
00127 
00128         /* HC does not end transactions on these, it should never be reported */
00129         if ((instance->status & TD_STATUS_ERROR_NAK) != 0)
00130                 return EAGAIN;
00131 
00132         /* Buffer overrun or underrun */
00133         if ((instance->status & TD_STATUS_ERROR_BUFFER) != 0)
00134                 return ERANGE;
00135 
00136         /* Device babble is something serious */
00137         if ((instance->status & TD_STATUS_ERROR_BABBLE) != 0)
00138                 return EIO;
00139 
00140         /* Stall might represent err count reaching zero or stall response from
00141          * the device. If err count reached zero, one of the above is reported*/
00142         if ((instance->status & TD_STATUS_ERROR_STALLED) != 0)
00143                 return ESTALL;
00144 
00145         return EOK;
00146 }
00147 /*----------------------------------------------------------------------------*/
00152 void td_print_status(td_t *instance)
00153 {
00154         assert(instance);
00155         const uint32_t s = instance->status;
00156         usb_log_debug2("TD(%p) status(%#" PRIx32 "):%s %d,%s%s%s%s%s%s%s%s%s%s%s %zu.\n",
00157             instance, instance->status,
00158             (s & TD_STATUS_SPD_FLAG) ? " SPD," : "",
00159             (s >> TD_STATUS_ERROR_COUNT_POS) & TD_STATUS_ERROR_COUNT_MASK,
00160             (s & TD_STATUS_LOW_SPEED_FLAG) ? " LOW SPEED," : "",
00161             (s & TD_STATUS_ISOCHRONOUS_FLAG) ? " ISOCHRONOUS," : "",
00162             (s & TD_STATUS_IOC_FLAG) ? " IOC," : "",
00163             (s & TD_STATUS_ERROR_ACTIVE) ? " ACTIVE," : "",
00164             (s & TD_STATUS_ERROR_STALLED) ? " STALLED," : "",
00165             (s & TD_STATUS_ERROR_BUFFER) ? " BUFFER," : "",
00166             (s & TD_STATUS_ERROR_BABBLE) ? " BABBLE," : "",
00167             (s & TD_STATUS_ERROR_NAK) ? " NAK," : "",
00168             (s & TD_STATUS_ERROR_CRC) ? " CRC/TIMEOUT," : "",
00169             (s & TD_STATUS_ERROR_BIT_STUFF) ? " BIT_STUFF," : "",
00170             (s & TD_STATUS_ERROR_RESERVED) ? " RESERVED," : "",
00171             td_act_size(instance)
00172         );
00173 }

Generated on Thu Jun 2 07:45:44 2011 for HelenOS/USB by  doxygen 1.4.7