예제 #1
0
static void handle_setup(td243fc_rev2_softc_t *sc)
{
    jresult_t rc;

    /* HSU Addition */
    /* Fix for the case where SETUP EP interrupt received before previous 
       OUT EP interrupt was handled. In this case we need to first handle 
       the OUT transaction. */
    td243fc_rev2_ep_t *ep = &sc->ep[0]; 
    request_t *req = ep->req;

    if (req != NULL)
    {
      DBG_W(DSLAVE_DCD, ("DCD: handle_setup, ep0_out is pending\n"));
      handle_ep0_out_req(sc);
      /* Wait for Setup DMA initiated in handle_ep0_out_req by req_finish to 
         complete before processing the SETUP. */
      jdelay_us(TD243FC_DMA_SETTLE_TIME);
    }
    /* HSU End */

    DBG_V(DSLAVE_DCD, ("DCD: handle SETUP\n"));

    CLEAR4(TD243FC_EPN_CONFIG_CONTROL_REG(0, 0), TD243FC_SETUP_RECV);

    rc = core_handle_ep0(sc->core_ctx, sc->dma_buf.vaddr , SPEED_FULL);
    if (rc)
    {
        DBG_E(DSLAVE_DCD, ("DCD: Setup request was handled rc = %d\n", rc));
        dcd_stall_ep(sc->dev, NULL, 1);
        prepare_setup_transfer(sc);
    }
}
예제 #2
0
/**
 * Function name:  cbw_read_complete
 * Description:    Completion callback, which is called at the completion of a
 *                 command block wrapper (CBW) request (send_csw).
 * Description:    Command block wrapper (CBW) read completion callback.
 *                 Sets the command to status ''in progress''.
 * Parameters: 
 *     @fd: (IN) FD context
 *
 * Return value: Last command status
 * Scope:        Local
 **/
void cbw_read_complete(request_t *request)
{
    fd_storage_t *fd = (fd_storage_t *)request->context;
    request_status_t status = request->status;

    DBG_V(DSLAVE_MS_USB, ("CBW Complete ep %d size %d status %d\n",
        fd->out_pipe->address, request->transfer_size, status));

    /* Request is ready for next transfer */
    request->status = REQUEST_READY;
   
    if (status != REQUEST_COMPLETED)
    {
        /* HSU addition: Error handling */
        if (status != REQUEST_CANCELLED)
        {
            DBG_W(DSLAVE_MS_USB, ("MASS: Error %d on reading data from out pipe.\n", status));
        }
        else
            DBG_I(DSLAVE_MS_USB, ("MASS: %s - failed reading data from out pipe.\n",
                status == REQUEST_CANCELLED ? "Cancelled" : "Error", status));
        /******* End HSU addition **************************/
    }
    else
    {
        DBG_V(DSLAVE_MS_USB, ("MASS: Got packet (%d)\n", 
            request->bytes_transferred));       

        handle_cbw(fd, request->buffer.vaddr, request->bytes_transferred);
    }
}
예제 #3
0
파일: sdl_player.c 프로젝트: Andrewftv/lbmc
static ret_code_t schedule_sdl(video_player_h h, media_buffer_t *buf)
{
    player_ctx_t *ctx = (player_ctx_t *)h;

    if (ctx->common.first_pkt)
    {
        clock_gettime(CLOCK_MONOTONIC, &ctx->common.base_time);
        ctx->common.first_pkt = 0;
    }
    else if (buf->pts_ms != AV_NOPTS_VALUE)
    {
        struct timespec curr_time;
        int diff;

        clock_gettime(CLOCK_MONOTONIC, &curr_time);
        diff = util_time_diff(&curr_time, &ctx->common.base_time);
        DBG_V("Current PTS=%lld time diff=%d\n", buf->pts_ms, diff);
        if (diff > 0 && buf->pts_ms > diff)
        {
            diff = buf->pts_ms - diff;
            if (diff > 5000)
            {
                DBG_W("The frame requests %d msec wait. Drop it and continue\n", diff);
                decode_release_video_buffer(ctx->common.demux_ctx, buf);
                return L_FAILED;
            }
            DBG_V("Going to sleep for %d ms\n", diff);
            msleep_wait(ctx->common.sched, diff);
        }
    }
    return L_OK;
}
예제 #4
0
/**
 * Function name:  send_csw_callback
 * Description:    Completion callback, which is called at the completion of a
 *                 command status wrapper (CSW) request (send_csw).
 * Parameters: 
 *     @request: (IN) Core request
 *
 * Return value: None
 * Scope:        Global
 **/
void send_csw_callback(request_t *request)
{
    fd_storage_t *fd = (fd_storage_t *)request->context;
    request_status_t status = request->status;

    DBG_V(DSLAVE_MS_USB, ("MASS: CSW sent %d out of %d.\n",
        request->bytes_transferred, request->transfer_size));

    /* Request is ready for next transfer */
    request->status = REQUEST_READY;

    if (status != REQUEST_COMPLETED ||
        request->bytes_transferred != request->transfer_size)
    {
        DBG_W(DSLAVE_MS_USB, ("MASS: Error sending CSW. Stalling IN.\n"));
        if (status != REQUEST_CANCELLED)
            core_abort_pipe(fd->core_ctx, fd->in_pipe);
        core_stall_pipe(fd->core_ctx, fd->in_pipe, 1);
    }
    else
    {
        jresult_t rc;

        /* Get next Command (CBW) */
        DBG_V(DSLAVE_MS_USB, ("MASS: Waiting for next CBW.\n"));
        clear_cmd_in_progress(fd);
        rc = post_read(fd, fd->cmd_request, USB_BULK_CB_WRAP_LEN, 
            cbw_read_complete, fd);
        if (rc)
        {
            DBG_E(DSLAVE_MS_USB, ("Failed to post next CBW (%d)\n", rc));
        }
    }
}
예제 #5
0
static void dps_init_storage(void)
{
    sicd_store_t *store;
    sicd_object_t *obj;
    jint_t i;
    jresult_t rc;

    store = sicd_store_get_first();
    if (!store)
    {
        DBG_W(DSLAVE_DPS_API, ("dps_init_storage: could not find store "
            "to place sample JPG in\n"));
        return;
    }

    app_ctx.store_id = store->id;

    /* Add our sample jpg objects for pictbridge sample tests */
    for (i=0; sample_image[i].image; i++)
    {
        obj = jmalloc(sizeof(sicd_object_t), M_ZERO);
        if (!obj)
        {
            DBG_E(DSLAVE_DPS_API, ("dps_init_storage: failed to allocate "
                " sicd_object_t for sample image %u\n", i+1));
            return;
        }

        sample_image[i].id = obj->id = sicd_get_new_obj_handle();
        obj->info.storage_id = store->id;
        obj->info.format = PTP_OBJ_FORMAT_IMG_JPEG;
        obj->info.compressed_size = sample_image[i].image_size;
        obj->info.thumb_format = PTP_OBJ_FORMAT_IMG_JPEG;
        obj->info.thumb_compressed_size = sample_image[i].thumb_size;
        obj->info.filename = ptp_string_atow(sample_image[i].name);
        obj->data = (juint8_t*)jmalloc(obj->info.compressed_size, 0);
        if (obj->data)
        {
            j_memcpy(obj->data, sample_image[i].image,
                obj->info.compressed_size);
        }
        
        obj->sample_data = (juint8_t*)jmalloc(obj->info.thumb_compressed_size,
            0);
        if (obj->sample_data)
        {
            j_memcpy(obj->sample_data, sample_image[i].thumb,
                obj->info.thumb_compressed_size);
        }
        
        rc = sicd_store_add_object(store->id, obj);
        if (rc)
        {
            DBG_E(DSLAVE_DPS_API, ("dps_init_storage: failed on "
                "sicd_store_add_object (%u)\n", rc));
            sicd_free_object(NULL, obj);
        }
    }
}
예제 #6
0
/**
 * Function name:  ep0_callback
 * Description:   Callback function called once transfer on ep0 is done 
 * Parameters:
 *     @request: (IN) Core request
 *
 * Return value:   None
 * Scope:          Local
 **/
static void ep0_callback(request_t *request)
{
    if (request->status != REQUEST_COMPLETED)
    {
        DBG_W(DSLAVE_MS_USB, ("MASS: %s - failed sending data through ep0 "
            "%d.\n", request->status == REQUEST_CANCELLED ?
            "Cancelled" : "Error", request->status));
    }
    request->status = REQUEST_READY;
}
예제 #7
0
/**
 * Function name:  handle_cbw
 * Description:    Handles a command block wrapper (CBW) request.
 * Parameters: 
 *     @fd:     (IN) FD context
 *     @buffer: (IN) CBW buffer
 *     @size:   (IN) Buffer size, in bytes
 *
 * Return value: None
 * Scope:        Global
 **/
void handle_cbw(fd_storage_t *fd, void *buffer, juint32_t size)
{
    struct bulk_cb_wrap *cbw = (struct bulk_cb_wrap *)buffer;
    juint8_t command[MAX_COMMAND_SIZE];

    DBG_V(DSLAVE_MS_USB, ("MASS: Got CBW [%d] Tag: %x\n", size, 
        le32toh(cbw->tag)));

    if (size < USB_BULK_CB_WRAP_LEN)
    {
        DBG_W(DSLAVE_MS_USB, ("MASS: Received buffer size (%d) is smaller "
            "than the valid CBW buffer size (%d).\n",
            size, USB_BULK_CB_WRAP_LEN));
        goto error;
    }
    
    if (le32toh(cbw->signature) != USB_BULK_CB_SIG)
    {
        DBG_W(DSLAVE_MS_USB, ("MASS: Bad CBW signature.\n"));
        goto error;
    }

    if (test_and_set_cmd_in_progress(fd))
    {
        DBG_W(DSLAVE_MS_USB, ("MASS: Got CBW when one is already in "
            "progress."));
        goto error;
    }

    /* Make a copy of the command so do_scsi_command can use the buffer freely */
    j_memcpy(&command, cbw->CDB, sizeof(command));

    do_scsi_command(fd->scsi_device, command, cbw->length,
        le32toh(cbw->data_size), le32toh(cbw->tag), cbw->lun,
        cbw->flags & USB_BULK_IN_FLAG,
        (juint8_t *)fd->cmd_request->buffer.vaddr);

    return;

error:
    fatal_processing_error(fd);
}
예제 #8
0
/**
 * Function name:  enable
 * Description:    Enables the mass storage function driver.
 * Parameters: 
 *     @context: (IN) FD context
 *
 * Return value: 0 on success, otherwise an error code
 * Scope:        Local
 **/
static jresult_t enable(context_t context)
{
    jresult_t rc = 0;
    jint_t i;
    fd_storage_t *fd = (fd_storage_t *)context;

    if (fd->state == STATE_ENABLED)
    {
        DBG_W(DSLAVE_MS_USB, ("enable: Trying to enable already enabled FD\n"));
        goto Exit;
    }

    for (i = 0; i < SCSI_TRANSFER_BUFFERS; i++)
        ALLOC_MSFD_REQUEST(i);

    /* Get the pipe numbers that the Core assigned to our descriptors */
    DBG_I(DSLAVE_MS_USB, ("FD: Pipe %p is %d.\n",
        &fd->fd_desc->interfaces[0].alt_ifs[0].pipes[0],
        fd->fd_desc->interfaces[0].alt_ifs[0].pipes[0].address));

    fd->out_pipe = &fd->fd_desc->interfaces[0].alt_ifs[0].pipes[0];
    fd->in_pipe  = &fd->fd_desc->interfaces[0].alt_ifs[0].pipes[1];

    rc = scsi_enable(fd->scsi_device);
    if (rc)
        goto Exit;

    rc = post_read(fd, fd->cmd_request, USB_BULK_CB_WRAP_LEN,
        cbw_read_complete, fd);
    if (rc)
    /* HSU addition: CR 159898 */
    {
        DBG_E(DSLAVE_MS_USB, ("Failed to post CBW on enable (%d)\n", rc));
        goto Exit;
    }
    /******* End HSU addition **************************/

    fd->state = STATE_ENABLED;

Exit:
    if (rc)
    {
        for (i = 0; i < SCSI_TRANSFER_BUFFERS; i++)
            FREE_MSFD_REQUEST(i);
    }

    return rc;
}
예제 #9
0
/* Transfer completion callback - passed to the Core for async transfers */
static void cdc_data_xfer_complete(usbd_xfer_handle xfer, 
    usbd_private_handle priv, usbd_status rc)
{
    cdc_cmd_priv_t *xfer_priv = (cdc_cmd_priv_t *)priv;

    DECLARE_FNAME("cdc_data_xfer_complete");

    KASSERT(xfer, ("%s: Null xfer handle\n", fname));

    DBG_V(DHOST_CDC_GENERAL, ("%s: Data xfer %p complete, status %d\n", fname,
        xfer, rc));

    switch (rc)
    {
    case 0:
        break;
    case USBD_CANCELLED:
        /* xfer has been canceled (abort_pipe was called) */
        DBG_W(DHOST_CDC_GENERAL, ("%s: xfer %p was canceled\n", fname, xfer));
        break;

    default:
        DBG_E(DHOST_CDC_GENERAL, ("%s: xfer completed with %d\n", fname, rc));
    }
    
    /* Activate callback */
    if (xfer_priv->req_type == GET_DATA || xfer_priv->req_type == SEND_DATA)
    {
        xfer_priv->cdc_callback.data_cb(xfer_priv->app_ctx, 
            xfer_priv->app_priv, xfer->buffer, xfer->actlen, 
            status_to_result(rc));
    }
#ifdef JDEBUG
    else
    {
        DBG_E(DHOST_CDC_GENERAL, ("%s: Unknown request type %d\n", fname, 
            xfer_priv->req_type));
    }
#endif

    usbd_free_xfer(xfer);
    cdc_uninit_request_priv(xfer_priv);
}
예제 #10
0
/**
 * Function name:  post_write
 * Description:    Sends data to the host.
 * Parameters: 
 *     @fd:       (IN) FD context 
 *     @req:      (IN) Request to use for the transfer
 *     @size:     (IN) Transfer size, in bytes
 *     @callback: (IN) Completion callback
 *     @context:  (IN) Context for the completion callback
 *
 * Return value: 0 on success, otherwise an error code
 * Scope:        Global
 **/
jresult_t post_write(fd_storage_t *fd, request_t *req, juint32_t size, 
    callback_t callback, context_t context)
{
    jresult_t rc = 0;

    req->transfer_size = size;
    req->complete = callback;
    req->context = context;

    rc = core_send_data(fd->core_ctx, fd->in_pipe, req);
    if (rc)
    {
        DBG_W(DSLAVE_MS_USB, ("MASS: Error writing data. Stalling IN pipe.\n"));
        core_abort_pipe(fd->core_ctx, fd->in_pipe);
        core_stall_pipe(fd->core_ctx, fd->in_pipe, 1);
    }

    return rc;
}
예제 #11
0
/* General CDC asynchronous transfer function */
static jresult_t cdc_async_transfer(cdc_cmd_priv_t *priv, 
    usbd_pipe_handle pipe, void *membuf, juint32_t size, 
    usbd_xfer_handle xfer)
{
    jresult_t rc;
    usbd_status status;
    juint16_t flags = USBD_SHORT_XFER_OK | USBD_FORCE_SHORT_XFER;
    DECLARE_FNAME("cdc_async_transfer");
    
    DBG_X(DHOST_CDC_GENERAL, ("%s: Entered\n", fname));

    /* Allocate a transfer request object and set up a xfer */
    xfer = usbd_alloc_xfer(priv->sc->device);
    if (!xfer)
    {
        DBG_E(DHOST_CDC_GENERAL, ("%s: Failed to allocate xfer\n", fname));
        rc = JENOMEM;
        goto Error;
    }
    usbd_setup_xfer(xfer, pipe, (void *)priv, membuf, size, flags, 
        CDC_DATA_XFER_TIMEOUT, cdc_data_xfer_complete);

    /* Execute xfer */
    status = usbd_transfer(xfer);
    if (status && status != USBD_IN_PROGRESS) 
    {
        DBG_W(DHOST_CDC_GENERAL, ("%s: failed to setup transfer, %s\n", fname, 
            usbd_errstr(status)));
        rc = status_to_result(status);
        goto Error;
    }
    return 0;

Error:
    if (xfer)
        usbd_free_xfer(xfer);

    return rc;
}
예제 #12
0
/**
 * Function name:  post_read
 * Description:    Sends a read request to the host.
 * Parameters: 
 *     @fd:       (IN) FD context
 *     @req:      (IN) Request to use for the transfer
 *     @size:     (IN) Trasfer size, in bytes
 *     @callback: (IN) Completion callback
 *     @context:  (IN) Context for the completion callback
 *
 * Return value: 0 on success, otherwise an error code
 * Scope:        Global
 **/
jresult_t post_read(fd_storage_t *fd, request_t *req, juint32_t size, 
    callback_t callback, context_t context)
{
    jresult_t rc = 0;

    req->transfer_size = size;
    req->complete = callback;
    req->context = context;

    DBG_V(DSLAVE_MS_USB, ("Posting read on pipe %d, size %d, to FD %p.\n",
        fd->out_pipe->address, size, fd));

    rc = core_read_data(fd->core_ctx, fd->out_pipe, req);
    if (rc)
    {
        DBG_W(DSLAVE_MS_USB, ("MASS: Error posting a read request - 0x%x. "
            "Stalling OUT pipe.\n", rc));
        core_stall_pipe(fd->core_ctx, fd->out_pipe, 1);
    }

    return rc;
}
예제 #13
0
void get_cap_complete(dps_appctx_t appctx, dps_param_t result,
    dps_cap_array_t *cap_list)
{
    static char dbg_buf[1000];
    jint_t i, j;
    dps_param_t conf_setting = 0;
    static struct
    {
        char *cap_str;
        dps_param_t *conf_param;
        dps_param_t test_value;
        dps_param_t default_value;
    } cap_map[] = {
        { "print qualities", &app_ctx.jconfig.quality,
            TEST_DPS_QUALITY, DPS_QUALITY_DEFAULT },
        { "paper sizes", &app_ctx.jconfig.paper_size,
            TEST_DPS_PAPER_SIZE, DPS_PAPER_SIZE_DEFAULT },
        { "paper types", &app_ctx.jconfig.paper_type,
            TEST_DPS_PAPER_TYPE, DPS_PAPER_TYPE_DEFAULT },
        { "file types", &app_ctx.jconfig.file_type,
            TEST_DPS_FILE_TYPE, DPS_FILE_TYPE_DEFAULT },
        { "date prints", &app_ctx.jconfig.date_print,
            TEST_DPS_DATE_PRINT, DPS_DATE_PRINT_DEFAULT },
        { "filename prints",
            &app_ctx.jconfig.filename_print, TEST_DPS_FILENAME_PRINT,
            DPS_FILENAME_PRINT_DEFAULT },
        { "image optimizations",
            &app_ctx.jconfig.image_optimize, TEST_DPS_IMAGE_OPTIMIZE,
            DPS_IMAGE_OPTIMIZE_DEFAULT },
        { "layouts", &app_ctx.jconfig.layout,
            TEST_DPS_LAYOUT, DPS_LAYOUT_DEFAULT },
        { "fixed paper sizes",
            &app_ctx.jconfig.fixed_size, TEST_DPS_FIXED_SIZE,
            DPS_FIXED_SIZE_DEFAULT },
        { "croppings", &app_ctx.jconfig.cropping,
            TEST_DPS_CROPPING, DPS_CROPPING_DEFAULT },
    };
    
    DECLARE_FNAME("get_cap_complete");
    
    DBG_X(DSLAVE_DPS_API, ("%s: entered\n", fname));

    if (result!=DPS_RESULT_OK || !cap_list || !cap_list->count ||
        app_ctx.current_cap > DPS_CAP_CROPPINGS)
    {
        goto NextCapability;
    }

    /* Print out supported parameters */
    *dbg_buf = 0;
    i = app_ctx.current_cap;
    for (j=0; j<cap_list->count; j++)
    {
        j_snprintf(dbg_buf, sizeof(dbg_buf)-1, "%s 0x%X", dbg_buf,
            cap_list->capability[j]);

        if (cap_map[i].test_value == cap_list->capability[j])
            conf_setting = cap_map[i].test_value;
    }

    DBG_I(DSLAVE_DPS_API, ("%s: Supported %s: %s\n", fname,
        cap_map[app_ctx.current_cap].cap_str, dbg_buf));

    /* Set print config parameter */
    if (conf_setting)
    {
        *(cap_map[i].conf_param) = conf_setting;
        DBG_I(DSLAVE_DPS_API, ("%s:\t0x%X selected\n", fname, conf_setting));
    }
    else
    {
        *(cap_map[i].conf_param) = cap_map[i].default_value;
        DBG_W(DSLAVE_DPS_API, ("%s:\t0x%X is not supported by the printer."
            " using default (0x%X)\n", fname,
            cap_map[i].test_value, cap_map[i].default_value));
    }

NextCapability:

    if (app_ctx.current_cap >= DPS_CAP_CROPPINGS)
    {
        /* Done with capabilities - send a print job */
        execute_job();
    }
    else
    {
        /* Get more capabilities from printer */
        app_ctx.current_cap++;
        dps_get_capability(app_ctx.dpsh, app_ctx.current_cap,
            app_ctx.jconfig.paper_size);
    }
}
예제 #14
0
/** 
 * Function name:  control_msg
 * Description:    Handles a mass storage class-specific endpoint 0 request.
 * Parameters: 
 *     @context: (IN) FD context
 *     @buffer:  (IN) Buffer containing the control request
 *
 * Return value: 0 on success, otherwise an error code
 * Scope:        Local
 **/
static jresult_t control_msg(void *context, void *buffer)
{
    jresult_t rc = JENOTSUP;
    fd_storage_t *fd = (fd_storage_t *)context;
    struct usb_ctrlrequest *req = (struct usb_ctrlrequest *)buffer;

    switch (req->bRequest)
    {
    case USB_BULK_RESET_REQUEST:
        DBG_I(DSLAVE_MS_USB, ("MASS: Bulk Reset Request.\n"));

        if (req->wValue || req->wLength != 0) /* HSU fix */
        {
            DBG_E(DSLAVE_MS_USB, ("MASS: Invalid MS_RESET request.\n"));
            break;
        }

        clear_cmd_in_progress(fd);
        core_abort_pipe(fd->core_ctx, fd->in_pipe);
        core_abort_pipe(fd->core_ctx, fd->out_pipe);

        /* Clear Stalls from pipes */
        core_stall_pipe(fd->core_ctx, fd->in_pipe, 0);
        core_stall_pipe(fd->core_ctx, fd->out_pipe, 0);

        /* Even if it fails, we still Reset since the host wants it */
        rc = send_ep0_reply(fd, 0);

        rc = post_read(fd, fd->cmd_request, USB_BULK_CB_WRAP_LEN, 
            cbw_read_complete, fd);
        /* HSU addition: CR 159898 */
        if (rc)
        {
            DBG_E(DSLAVE_MS_USB, ("Failed to post CBW on RESET_REQUEST (%d)\n", rc));
        }
        /******* End HSU addition **************************/
        break;

    case USB_BULK_GET_MAX_LUN_REQUEST:
        DBG_I(DSLAVE_MS_USB, ("MASS: Get max LUNs request.\n"));

        if (req->wValue || req->wLength != 1) /* HSU fix */
        {
            DBG_E(DSLAVE_MS_USB, ("MASS: Invalid MS_GET_MAX_LUN request.\n"));
            break;
        }
        /* HSU addition: CR 159898 */
        /* Clear Stalls from pipes */
        core_abort_pipe(fd->core_ctx, fd->in_pipe);
        core_stall_pipe(fd->core_ctx, fd->in_pipe, 0);

        core_abort_pipe(fd->core_ctx, fd->out_pipe);
        core_stall_pipe(fd->core_ctx, fd->out_pipe, 0);

        rc = post_read(fd, fd->cmd_request, USB_BULK_CB_WRAP_LEN, 
            cbw_read_complete, fd);
        if (rc)
        {
            DBG_E(DSLAVE_MS_USB, ("Failed to post CBW on GET_MAX_LUN_REQUEST (%d)\n", rc));
        }
        /******* End HSU addition **************************/

        ((juint8_t *)(fd->ep0_request->buffer.vaddr))[0] = fd->total_luns - 1;
        rc = send_ep0_reply(fd, 1);
        break;
        
    default:
        DBG_W(DSLAVE_MS_USB, ("MASS: Unknown EP0 request.\n"));
    }

    return rc;
}