struct pvr2_context *pvr2_context_create(
	struct usb_interface *intf,
	const struct usb_device_id *devid,
	void (*setup_func)(struct pvr2_context *))
{
	struct pvr2_context *mp = NULL;
	mp = kzalloc(sizeof(*mp),GFP_KERNEL);
	if (!mp) goto done;
	pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr_main id=%p",mp);
	mp->setup_func = setup_func;
	mutex_init(&mp->mutex);
	mp->hdw = pvr2_hdw_create(intf,devid);
	if (!mp->hdw) {
		pvr2_context_destroy(mp);
		mp = NULL;
		goto done;
	}

	mp->workqueue = create_singlethread_workqueue("pvrusb2");
	INIT_WORK(&mp->workinit, pvr2_context_setup);
	INIT_WORK(&mp->workpoll, pvr2_context_poll);
	queue_work(mp->workqueue,&mp->workinit);
 done:
	return mp;
}
예제 #2
0
struct pvr2_context *pvr2_context_create(
    struct usb_interface *intf,
    const struct usb_device_id *devid,
    void (*setup_func)(struct pvr2_context *))
{
    struct pvr2_context *mp = NULL;
    mp = kzalloc(sizeof(*mp),GFP_KERNEL);
    if (!mp) goto done;
    pvr2_trace(PVR2_TRACE_CTXT,"pvr2_context %p (create)",mp);
    mp->setup_func = setup_func;
    mutex_init(&mp->mutex);
    mutex_lock(&pvr2_context_mutex);
    mp->exist_prev = pvr2_context_exist_last;
    mp->exist_next = NULL;
    pvr2_context_exist_last = mp;
    if (mp->exist_prev) {
        mp->exist_prev->exist_next = mp;
    } else {
        pvr2_context_exist_first = mp;
    }
    mutex_unlock(&pvr2_context_mutex);
    mp->hdw = pvr2_hdw_create(intf,devid);
    if (!mp->hdw) {
        pvr2_context_destroy(mp);
        mp = NULL;
        goto done;
    }
    pvr2_context_set_notify(mp, !0);
 done:
    return mp;
}
void pvr2_context_exit(struct pvr2_context *mp)
{
	int destroy_flag = 0;
	if (!(mp->mc_first || !mp->disconnect_flag)) {
		destroy_flag = !0;
	}
	pvr2_trace(PVR2_TRACE_CREG,"pvr2_context_exit(id=%p) outside",mp);
	mutex_unlock(&mp->mutex);
	if (destroy_flag) pvr2_context_destroy(mp);
}
예제 #4
0
static void pvr2_context_check(struct pvr2_context *mp)
{
    struct pvr2_channel *ch1, *ch2;
    pvr2_trace(PVR2_TRACE_CTXT,
           "pvr2_context %p (notify)", mp);
    if (!mp->initialized_flag && !mp->disconnect_flag) {
        mp->initialized_flag = !0;
        pvr2_trace(PVR2_TRACE_CTXT,
               "pvr2_context %p (initialize)", mp);
        /* Finish hardware initialization */
        if (pvr2_hdw_initialize(mp->hdw,
                    (void (*)(void *))pvr2_context_notify,
                    mp)) {
            mp->video_stream.stream =
                pvr2_hdw_get_video_stream(mp->hdw);
            /* Trigger interface initialization.  By doing this
               here initialization runs in our own safe and
               cozy thread context. */
            if (mp->setup_func) mp->setup_func(mp);
        } else {
            pvr2_trace(PVR2_TRACE_CTXT,
                   "pvr2_context %p (thread skipping setup)",
                   mp);
            /* Even though initialization did not succeed,
               we're still going to continue anyway.  We need
               to do this in order to await the expected
               disconnect (which we will detect in the normal
               course of operation). */
        }
    }

    for (ch1 = mp->mc_first; ch1; ch1 = ch2) {
        ch2 = ch1->mc_next;
        if (ch1->check_func) ch1->check_func(ch1);
    }

    if (mp->disconnect_flag && !mp->mc_first) {
        /* Go away... */
        pvr2_context_destroy(mp);
        return;
    }
}
static void pvr2_context_check(struct pvr2_context *mp)
{
	struct pvr2_channel *ch1, *ch2;
	pvr2_trace(PVR2_TRACE_CTXT,
		   "pvr2_context %p (notify)", mp);
	if (!mp->initialized_flag && !mp->disconnect_flag) {
		mp->initialized_flag = !0;
		pvr2_trace(PVR2_TRACE_CTXT,
			   "pvr2_context %p (initialize)", mp);
		/*                                */
		if (pvr2_hdw_initialize(mp->hdw,
					(void (*)(void *))pvr2_context_notify,
					mp)) {
			mp->video_stream.stream =
				pvr2_hdw_get_video_stream(mp->hdw);
			/*                                                 
                                                  
                           */
			if (mp->setup_func) mp->setup_func(mp);
		} else {
			pvr2_trace(PVR2_TRACE_CTXT,
				   "pvr2_context %p (thread skipping setup)",
				   mp);
			/*                                            
                                                    
                                               
                                                    
                            */
		}
	}

	for (ch1 = mp->mc_first; ch1; ch1 = ch2) {
		ch2 = ch1->mc_next;
		if (ch1->check_func) ch1->check_func(ch1);
	}

	if (mp->disconnect_flag && !mp->mc_first) {
		/*            */
		pvr2_context_destroy(mp);
		return;
	}
}