コード例 #1
0
/**
 *	gigaset_read_int_callback
 *
 *	It is called if the data was received from the device.
 */
static void gigaset_read_int_callback(struct urb *urb, struct pt_regs *regs)
{
	struct inbuf_t *inbuf = urb->context;
	struct cardstate *cs = inbuf->cs;
	int resubmit = 0;
	int r;
	unsigned numbytes;
	unsigned char *src;
	unsigned long flags;

	if (!urb->status) {
		if (!cs->connected) {
			err("%s: disconnected", __func__); /* should never happen */
			return;
		}

		numbytes = urb->actual_length;

		if (numbytes) {
			src = inbuf->rcvbuf;
			if (unlikely(*src))
				dev_warn(cs->dev,
				    "%s: There was no leading 0, but 0x%02x!\n",
					 __func__, (unsigned) *src);
			++src; /* skip leading 0x00 */
			--numbytes;
			if (gigaset_fill_inbuf(inbuf, src, numbytes)) {
				gig_dbg(DEBUG_INTR, "%s-->BH", __func__);
				gigaset_schedule_event(inbuf->cs);
			}
		} else
			gig_dbg(DEBUG_INTR, "Received zero block length");
		resubmit = 1;
	} else {
		/* The urb might have been killed. */
		gig_dbg(DEBUG_ANY, "%s - nonzero read bulk status received: %d",
			__func__, urb->status);
		if (urb->status != -ENOENT) { /* not killed */
			if (!cs->connected) {
				err("%s: disconnected", __func__); /* should never happen */
				return;
			}
			resubmit = 1;
		}
	}

	if (resubmit) {
		spin_lock_irqsave(&cs->lock, flags);
		r = cs->connected ? usb_submit_urb(urb, SLAB_ATOMIC) : -ENODEV;
		spin_unlock_irqrestore(&cs->lock, flags);
		if (r)
			dev_err(cs->dev, "error %d when resubmitting urb.\n",
				-r);
	}
}
コード例 #2
0
/*
 * Interrupt Input URB completion routine
 */
static void gigaset_read_int_callback(struct urb *urb)
{
	struct cardstate *cs = urb->context;
	struct inbuf_t *inbuf = cs->inbuf;
	int status = urb->status;
	int r;
	unsigned numbytes;
	unsigned char *src;
	unsigned long flags;

	if (!status) {
		numbytes = urb->actual_length;

		if (numbytes) {
			src = cs->hw.usb->rcvbuf;
			if (unlikely(*src))
				dev_warn(cs->dev,
				    "%s: There was no leading 0, but 0x%02x!\n",
					 __func__, (unsigned) *src);
			++src; /* skip leading 0x00 */
			--numbytes;
			if (gigaset_fill_inbuf(inbuf, src, numbytes)) {
				gig_dbg(DEBUG_INTR, "%s-->BH", __func__);
				gigaset_schedule_event(inbuf->cs);
			}
		} else
			gig_dbg(DEBUG_INTR, "Received zero block length");
	} else {
		/* The urb might have been killed. */
		gig_dbg(DEBUG_ANY, "%s - nonzero status received: %d",
			__func__, status);
		if (status == -ENOENT || status == -ESHUTDOWN)
			/* killed or endpoint shutdown: don't resubmit */
			return;
	}

	/* resubmit URB */
	spin_lock_irqsave(&cs->lock, flags);
	if (!cs->connected) {
		spin_unlock_irqrestore(&cs->lock, flags);
		pr_err("%s: disconnected\n", __func__);
		return;
	}
	r = usb_submit_urb(urb, GFP_ATOMIC);
	spin_unlock_irqrestore(&cs->lock, flags);
	if (r)
		dev_err(cs->dev, "error %d resubmitting URB\n", -r);
}