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); } }
/** * 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); } }
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; }
/** * 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)); } } }
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); } } }
/** * 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; }
/** * 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); }
/** * 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; }
/* 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); }
/** * 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; }
/* 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; }
/** * 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; }
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); } }
/** * 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; }