/* poll the device fifo status register. not to be confused with * the poll syscall. */ static void cm4040_do_poll(unsigned long dummy) { struct reader_dev *dev = (struct reader_dev *) dummy; unsigned int obs = xinb(dev->p_dev->resource[0]->start + REG_OFFSET_BUFFER_STATUS); if ((obs & BSR_BULK_IN_FULL)) { set_bit(BS_READABLE, &dev->buffer_status); DEBUGP(4, dev, "waking up read_wait\n"); wake_up_interruptible(&dev->read_wait); } else clear_bit(BS_READABLE, &dev->buffer_status); if (!(obs & BSR_BULK_OUT_FULL)) { set_bit(BS_WRITABLE, &dev->buffer_status); DEBUGP(4, dev, "waking up write_wait\n"); wake_up_interruptible(&dev->write_wait); } else clear_bit(BS_WRITABLE, &dev->buffer_status); if (dev->buffer_status) wake_up_interruptible(&dev->poll_wait); mod_timer(&dev->poll_timer, jiffies + POLL_PERIOD); }
static int wait_for_bulk_out_ready(struct reader_dev *dev) { int i, rc; int iobase = dev->p_dev->resource[0]->start; for (i = 0; i < POLL_LOOP_COUNT; i++) { if ((xinb(iobase + REG_OFFSET_BUFFER_STATUS) & BSR_BULK_OUT_FULL) == 0) { DEBUGP(4, dev, "BulkOut empty (i=%d)\n", i); return 1; } } DEBUGP(4, dev, "wait_event_interruptible_timeout(timeout=%ld\n", dev->timeout); rc = wait_event_interruptible_timeout(dev->write_wait, test_and_clear_bit(BS_WRITABLE, &dev->buffer_status), dev->timeout); if (rc > 0) DEBUGP(4, dev, "woke up: BulkOut empty\n"); else if (rc == 0) DEBUGP(4, dev, "woke up: BulkOut full, returning 0 :(\n"); else if (rc < 0) DEBUGP(4, dev, "woke up: signal arrived\n"); return rc; }
static int wait_for_bulk_in_ready(struct reader_dev *dev) { int i, rc; int iobase = dev->p_dev->io.BasePort1; for (i = 0; i < POLL_LOOP_COUNT; i++) { if ((xinb(iobase + REG_OFFSET_BUFFER_STATUS) & BSR_BULK_IN_FULL) == BSR_BULK_IN_FULL) { DEBUGP(3, dev, "BulkIn full (i=%d)\n", i); return 1; } } DEBUGP(4, dev, "wait_event_interruptible_timeout(timeout=%ld\n", dev->timeout); rc = wait_event_interruptible_timeout(dev->read_wait, test_and_clear_bit(BS_READABLE, &dev->buffer_status), dev->timeout); if (rc > 0) DEBUGP(4, dev, "woke up: BulkIn full\n"); else if (rc == 0) DEBUGP(4, dev, "woke up: BulkIn not full, returning 0 :(\n"); else if (rc < 0) DEBUGP(4, dev, "woke up: signal arrived\n"); return rc; }
static ssize_t cm4040_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos) { struct reader_dev *dev = filp->private_data; int iobase = dev->p_dev->io.BasePort1; size_t bytes_to_read; unsigned long i; size_t min_bytes_to_read; int rc; unsigned char uc; DEBUGP(2, dev, "-> cm4040_read(%s,%d)\n", current->comm, current->pid); if (count == 0) return 0; if (count < 10) return -EFAULT; if (filp->f_flags & O_NONBLOCK) { DEBUGP(4, dev, "filep->f_flags O_NONBLOCK set\n"); DEBUGP(2, dev, "<- cm4040_read (failure)\n"); return -EAGAIN; } if (!pcmcia_dev_present(dev->p_dev)) return -ENODEV; for (i = 0; i < 5; i++) { rc = wait_for_bulk_in_ready(dev); if (rc <= 0) { DEBUGP(5, dev, "wait_for_bulk_in_ready rc=%.2x\n", rc); DEBUGP(2, dev, "<- cm4040_read (failed)\n"); if (rc == -ERESTARTSYS) return rc; return -EIO; } dev->r_buf[i] = xinb(iobase + REG_OFFSET_BULK_IN); #ifdef PCMCIA_DEBUG if (pc_debug >= 6) printk(KERN_DEBUG "%lu:%2x ", i, dev->r_buf[i]); } printk("\n"); #else }