void lp_setup(char *str, int *ints) { LP_B(0) = ((ints[0] > 0) ? ints[1] : 0 ); LP_IRQ(0) = ((ints[0] > 1) ? ints[2] : 0 ); LP_B(1) = ((ints[0] > 2) ? ints[3] : 0 ); LP_IRQ(1) = ((ints[0] > 3) ? ints[4] : 0 ); LP_B(2) = ((ints[0] > 4) ? ints[5] : 0 ); LP_IRQ(2) = ((ints[0] > 5) ? ints[6] : 0 ); }
void cleanup_module(void) { int offset; unregister_chrdev(LP_MAJOR,"lp"); for (offset = 0; offset < LP_NO; offset++) { int base, size; base = LP_B(offset); size = (base == 0x3bc)? 3 : 8; if (LP_F(offset) & LP_EXIST) release_region(LP_B(offset),size); } }
int lp_init(void) { int offset = 0; int count = 0; #ifdef MODULE int failed = 0; #endif if (register_chrdev(LP_MAJOR,"lp",&lp_fops)) { printk("lp: unable to get major %d\n", LP_MAJOR); return -EIO; } #ifdef MODULE /* When user feeds parameters, use them */ for (offset=0; offset < LP_NO; offset++) { int specified=0; if (io[offset] != 0) { LP_B(offset) = io[offset]; specified++; } if (irq[offset] != 0) { LP_IRQ(offset) = irq[offset]; specified++; } if (specified) { if (lp_probe(offset) <= 0) { printk(KERN_INFO "lp%d: Not found\n", offset); failed++; } else count++; } } /* Successful specified devices increase count * Unsuccessful specified devices increase failed */ if (count) return 0; if (failed) { printk(KERN_INFO "lp: No override devices found.\n"); unregister_chrdev(LP_MAJOR,"lp"); return -EIO; } /* Only get here if there were no specified devices. To continue * would be silly since the above code has scribbled all over the * probe list. */ #endif /* take on all known port values */ for (offset = 0; offset < LP_NO; offset++) { int ret = lp_probe(offset); if (ret < 0) continue; count += ret; } if (count == 0) printk("lp: Driver configured but no interfaces found.\n"); return 0; }
static int lp_probe(int offset) { int base, size; unsigned int testvalue; base = LP_B(offset); if (base == 0) return -1; /* de-configured by command line */ if (LP_IRQ(offset) > 15) return -1; /* bogus interrupt value */ size = (base == 0x3bc)? 3 : 8; if (check_region(base, size) < 0) return -1; /* write to port & read back to check */ outb_p(LP_DUMMY, base); udelay(LP_DELAY); testvalue = inb_p(base); if (testvalue == LP_DUMMY) { LP_F(offset) |= LP_EXIST; lp_reset(offset); printk(KERN_INFO "lp%d at 0x%04x, ", offset, base); request_region(base, size, "lp"); if (LP_IRQ(offset)) printk("(irq = %d)\n", LP_IRQ(offset)); else printk("(polling)\n"); return 1; } else return 0; }
static inline int lp_char_polled(char lpchar, int minor) { int status, wait = 0; unsigned long count = 0; struct lp_stats *stats; do { status = LP_S(minor); count ++; if(need_resched) schedule(); } while(!LP_READY(minor,status) && count < LP_CHAR(minor)); if (count == LP_CHAR(minor)) { return 0; /* we timed out, and the character was /not/ printed */ } outb_p(lpchar, LP_B(minor)); stats = &LP_STAT(minor); stats->chars++; /* must wait before taking strobe high, and after taking strobe low, according spec. Some printers need it, others don't. */ while(wait != LP_WAIT(minor)) wait++; /* control port takes strobe high */ outb_p(( LP_PSELECP | LP_PINITP | LP_PSTROBE ), ( LP_C( minor ))); while(wait) wait--; /* take strobe low */ outb_p(( LP_PSELECP | LP_PINITP ), ( LP_C( minor ))); /* update waittime statistics */ if (count > stats->maxwait) { #ifdef LP_DEBUG printk(KERN_DEBUG "lp%d success after %d counts.\n",minor,count); #endif stats->maxwait = count; } count *= 256; wait = (count > stats->meanwait)? count - stats->meanwait : stats->meanwait - count; stats->meanwait = (255*stats->meanwait + count + 128) / 256; stats->mdev = ((127 * stats->mdev) + wait + 64) / 128; return 1; }
static inline int lp_char_interrupt(char lpchar, int minor) { int wait; unsigned long count = 0; unsigned char status; struct lp_stats *stats; do { if(need_resched) schedule(); if ((status = LP_S(minor)) & LP_PBUSY) { if (!LP_CAREFUL_READY(minor, status)) return 0; outb_p(lpchar, LP_B(minor)); stats = &LP_STAT(minor); stats->chars++; /* must wait before taking strobe high, and after taking strobe low, according spec. Some printers need it, others don't. */ wait = 0; while(wait != LP_WAIT(minor)) wait++; /* control port takes strobe high */ outb_p(( LP_PSELECP | LP_PINITP | LP_PSTROBE ), ( LP_C( minor ))); while(wait) wait--; /* take strobe low */ outb_p(( LP_PSELECP | LP_PINITP ), ( LP_C( minor ))); /* update waittime statistics */ if (count) { if (count > stats->maxwait) stats->maxwait = count; count *= 256; wait = (count > stats->meanwait)? count - stats->meanwait : stats->meanwait - count; stats->meanwait = (255*stats->meanwait + count + 128) / 256; stats->mdev = ((127 * stats->mdev) + wait + 64) / 128; } return 1; } } while (count++ < LP_CHAR(minor)); return 0; }