static void iguanair_close(struct rc_dev *rdev) { struct iguanair *ir = rdev->priv; int rc; mutex_lock(&ir->lock); rc = iguanair_receiver(ir, false); ir->receiver_on = false; if (rc && rc != -ENODEV) dev_warn(ir->dev, "failed to disable receiver: %d\n", rc); mutex_unlock(&ir->lock); }
static int iguanair_open(struct rc_dev *rdev) { struct iguanair *ir = rdev->priv; int rc; mutex_lock(&ir->lock); rc = iguanair_receiver(ir, true); if (rc == 0) ir->receiver_on = true; mutex_unlock(&ir->lock); return rc; }
static int iguanair_resume(struct usb_interface *intf) { struct iguanair *ir = usb_get_intfdata(intf); int rc = 0; mutex_lock(&ir->lock); if (ir->receiver_on) { rc = iguanair_receiver(ir, true); if (rc) dev_warn(ir->dev, "failed to enable receiver after resume\n"); } mutex_unlock(&ir->lock); return rc; }
static int iguanair_suspend(struct usb_interface *intf, pm_message_t message) { struct iguanair *ir = usb_get_intfdata(intf); int rc = 0; mutex_lock(&ir->lock); if (ir->receiver_on) { rc = iguanair_receiver(ir, false); if (rc) dev_warn(ir->dev, "failed to disable receiver for suspend\n"); } mutex_unlock(&ir->lock); return rc; }
static int iguanair_open(struct rc_dev *rdev) { struct iguanair *ir = rdev->priv; int rc; mutex_lock(&ir->lock); usb_submit_urb(ir->urb_in, GFP_KERNEL); BUG_ON(ir->receiver_on); rc = iguanair_receiver(ir, true); if (rc == 0) ir->receiver_on = true; mutex_unlock(&ir->lock); return rc; }
static int iguanair_tx(struct rc_dev *dev, unsigned *txbuf, unsigned count) { struct iguanair *ir = dev->priv; uint8_t space, *payload; unsigned i, size, rc; struct send_packet *packet; mutex_lock(&ir->lock); /* convert from us to carrier periods */ for (i = size = 0; i < count; i++) { txbuf[i] = DIV_ROUND_CLOSEST(txbuf[i] * ir->carrier, 1000000); size += (txbuf[i] + 126) / 127; } packet = kmalloc(sizeof(*packet) + size, GFP_KERNEL); if (!packet) { rc = -ENOMEM; goto out; } if (size > ir->bufsize) { rc = -E2BIG; goto out; } packet->header.start = 0; packet->header.direction = DIR_OUT; packet->header.cmd = CMD_SEND; packet->length = size; packet->channels = ir->channels << 4; packet->busy7 = ir->busy7; packet->busy4 = ir->busy4; space = 0; payload = packet->payload; for (i = 0; i < count; i++) { unsigned periods = txbuf[i]; while (periods > 127) { *payload++ = 127 | space; periods -= 127; } *payload++ = periods | space; space ^= 0x80; } if (ir->receiver_on) { rc = iguanair_receiver(ir, false); if (rc) { dev_warn(ir->dev, "disable receiver before transmit failed\n"); goto out; } } ir->tx_overflow = false; INIT_COMPLETION(ir->completion); rc = iguanair_send(ir, packet, size + 8, NULL, NULL); if (rc == 0) { wait_for_completion_timeout(&ir->completion, TIMEOUT); if (ir->tx_overflow) rc = -EOVERFLOW; } ir->tx_overflow = false; if (ir->receiver_on) { if (iguanair_receiver(ir, true)) dev_warn(ir->dev, "re-enable receiver after transmit failed\n"); } out: mutex_unlock(&ir->lock); kfree(packet); return rc; }