static void iforce_usb_irq(struct urb *urb) { struct iforce *iforce = urb->context; int status; switch (urb->status) { case 0: /* success */ break; case -ECONNRESET: case -ENOENT: case -ESHUTDOWN: /* this urb is terminated, clean up */ dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); return; default: dbg("%s - urb has status of: %d", __FUNCTION__, urb->status); goto exit; } iforce_process_packet(iforce, (iforce->data[0] << 8) | (urb->actual_length - 1), iforce->data + 1); exit: status = usb_submit_urb (urb, GFP_ATOMIC); if (status) err ("%s - usb_submit_urb failed with result %d", __FUNCTION__, status); }
static irqreturn_t iforce_serio_irq(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs) { struct iforce *iforce = serio_get_drvdata(serio); if (!iforce->pkt) { if (data == 0x2b) iforce->pkt = 1; goto out; } if (!iforce->id) { if (data > 3 && data != 0xff) iforce->pkt = 0; else iforce->id = data; goto out; } if (!iforce->len) { if (data > IFORCE_MAX_LENGTH) { iforce->pkt = 0; iforce->id = 0; } else { iforce->len = data; } goto out; } if (iforce->idx < iforce->len) { iforce->csum += iforce->data[iforce->idx++] = data; goto out; } if (iforce->idx == iforce->len) { iforce_process_packet(iforce, (iforce->id << 8) | iforce->idx, iforce->data, regs); iforce->pkt = 0; iforce->id = 0; iforce->len = 0; iforce->idx = 0; iforce->csum = 0; } out: return IRQ_HANDLED; }