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