⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bpp.c

📁 优龙2410linux2.6.8内核源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
          pins |= BPP_PP_nStrobe;          set_pins(pins, minor);      }      return cnt - remaining;}/* * Write data using ECP mode. Watch out that the port may be set up * for reading. If so, turn the port around. */static long write_ecp(unsigned minor, const char __user *c, unsigned long cnt){      unsigned short pins = get_pins(minor);      unsigned long remaining = cnt;      if (instances[minor].direction) {          int rc;            /* Event 47 Request bus be turned around */          pins |= BPP_PP_nInit;          set_pins(pins, minor);            /* Wait for Event 49: Peripheral relinquished bus */          rc = wait_for(BPP_GP_PError, 0, TIME_PResponse, minor);          pins |= BPP_PP_nAutoFd;          instances[minor].direction = 0;          set_pins(pins, minor);      }      while (remaining > 0) {          unsigned char byte;          int rc;          if (get_user(byte, c))		  return -EFAULT;          rc = wait_for(0, BPP_GP_Busy, TIME_PResponse, minor);          if (rc == -1) return -ETIMEDOUT;          c += 1;          bpp_outb_p(byte, base_addrs[minor]);          pins &= ~BPP_PP_nStrobe;          set_pins(pins, minor);          pins |= BPP_PP_nStrobe;          rc = wait_for(BPP_GP_Busy, 0, TIME_PResponse, minor);          if (rc == -1) return -EIO;          set_pins(pins, minor);      }      return cnt - remaining;}/* * Write to the peripheral. Be sensitive of the current mode. If I'm * in a mode that can be turned around (ECP) then just do * that. Otherwise, terminate and do my writing in compat mode. This * is the safest course as any device can handle it. */static ssize_t bpp_write(struct file *f, const char __user *c, size_t cnt, loff_t * ppos){      long errno = 0;      unsigned minor = iminor(f->f_dentry->d_inode);      if (minor >= BPP_NO) return -ENODEV;      if (!instances[minor].present) return -ENODEV;      switch (instances[minor].mode) {        case ECP:        case ECP_RLE:          errno = write_ecp(minor, c, cnt);          break;        case COMPATIBILITY:          errno = write_compat(minor, c, cnt);          break;        default:          terminate(minor);          errno = write_compat(minor, c, cnt);      }      return errno;}static int bpp_ioctl(struct inode *inode, struct file *f, unsigned int cmd,		 unsigned long arg){      int errno = 0;      unsigned minor = iminor(inode);      if (minor >= BPP_NO) return -ENODEV;      if (!instances[minor].present) return -ENODEV;      switch (cmd) {        case BPP_PUT_PINS:          set_pins(arg, minor);          break;        case BPP_GET_PINS:          errno = get_pins(minor);          break;        case BPP_PUT_DATA:          bpp_outb_p(arg, base_addrs[minor]);          break;        case BPP_GET_DATA:          errno = bpp_inb_p(base_addrs[minor]);          break;        case BPP_SET_INPUT:          if (arg)            if (instances[minor].enhanced) {                unsigned short bits = get_pins(minor);                instances[minor].direction = 0x20;                set_pins(bits, minor);            } else {                errno = -ENOTTY;            }          else {              unsigned short bits = get_pins(minor);              instances[minor].direction = 0x00;              set_pins(bits, minor);          }          break;        default:            errno = -EINVAL;      }      return errno;}static struct file_operations bpp_fops = {	.owner =	THIS_MODULE,	.read =		bpp_read,	.write =	bpp_write,	.ioctl =	bpp_ioctl,	.open =		bpp_open,	.release =	bpp_release,};#if defined(__i386__)#define collectLptPorts()  {}static void probeLptPort(unsigned idx){      unsigned int testvalue;      const unsigned short lpAddr = base_addrs[idx];      instances[idx].present = 0;      instances[idx].enhanced = 0;      instances[idx].direction = 0;      instances[idx].mode = COMPATIBILITY;      instances[idx].wait_queue = 0;      instances[idx].run_length = 0;      instances[idx].run_flag = 0;      init_timer(&instances[idx].timer_list);      instances[idx].timer_list.function = bpp_wake_up;      if (!request_region(lpAddr,3, dev_name)) return;      /*       * First, make sure the instance exists. Do this by writing to       * the data latch and reading the value back. If the port *is*       * present, test to see if it supports extended-mode       * operation. This will be required for IEEE1284 reverse       * transfers.       */      outb_p(BPP_PROBE_CODE, lpAddr);      for (testvalue=0; testvalue<BPP_DELAY; testvalue++)            ;      testvalue = inb_p(lpAddr);      if (testvalue == BPP_PROBE_CODE) {            unsigned save;            instances[idx].present = 1;            save = inb_p(lpAddr+2);            for (testvalue=0; testvalue<BPP_DELAY; testvalue++)                  ;            outb_p(save|0x20, lpAddr+2);            for (testvalue=0; testvalue<BPP_DELAY; testvalue++)                  ;            outb_p(~BPP_PROBE_CODE, lpAddr);            for (testvalue=0; testvalue<BPP_DELAY; testvalue++)                  ;            testvalue = inb_p(lpAddr);            if ((testvalue&0xff) == (0xff&~BPP_PROBE_CODE))                  instances[idx].enhanced = 0;            else                  instances[idx].enhanced = 1;            outb_p(save, lpAddr+2);      }      else {            release_region(lpAddr,3);      }      /*       * Leave the port in compat idle mode.       */      set_pins(BPP_PP_nAutoFd|BPP_PP_nStrobe|BPP_PP_nInit, idx);      printk("bpp%d: Port at 0x%03x: Enhanced mode %s\n", idx, base_addrs[idx],            instances[idx].enhanced? "SUPPORTED" : "UNAVAILABLE");}static inline void freeLptPort(int idx){      release_region(base_addrs[idx], 3);}#endif#if defined(__sparc__)static unsigned long map_bpp(struct sbus_dev *dev, int idx){      return sbus_ioremap(&dev->resource[0], 0, BPP_SIZE, "bpp");}static int collectLptPorts(void){	struct sbus_bus *bus;	struct sbus_dev *dev;	int count;	count = 0;	for_all_sbusdev(dev, bus) {		if (strcmp(dev->prom_name, "SUNW,bpp") == 0) {			if (count >= BPP_NO) {				printk(KERN_NOTICE				       "bpp: More than %d bpp ports,"				       " rest is ignored\n", BPP_NO);				return count;			}			base_addrs[count] = map_bpp(dev, count);			count++;		}	}	return count;}static void probeLptPort(unsigned idx){      unsigned long rp = base_addrs[idx];      __u32 csr;      char *brand;      instances[idx].present = 0;      instances[idx].enhanced = 0;      instances[idx].direction = 0;      instances[idx].mode = COMPATIBILITY;      init_waitqueue_head(&instances[idx].wait_queue);      instances[idx].run_length = 0;      instances[idx].run_flag = 0;      init_timer(&instances[idx].timer_list);      instances[idx].timer_list.function = bpp_wake_up;      if (rp == 0) return;      instances[idx].present = 1;      instances[idx].enhanced = 1;   /* Sure */      csr = sbus_readl(rp + BPP_CSR);      if ((csr & P_DRAINING) != 0 && (csr & P_ERR_PEND) == 0) {            udelay(20);            csr = sbus_readl(rp + BPP_CSR);            if ((csr & P_DRAINING) != 0 && (csr & P_ERR_PEND) == 0) {                  printk("bpp%d: DRAINING still active (0x%08x)\n", idx, csr);            }      }      printk("bpp%d: reset with 0x%08x ..", idx, csr);      sbus_writel((csr | P_RESET) & ~P_INT_EN, rp + BPP_CSR);      udelay(500);      sbus_writel(sbus_readl(rp + BPP_CSR) & ~P_RESET, rp + BPP_CSR);      csr = sbus_readl(rp + BPP_CSR);      printk(" done with csr=0x%08x ocr=0x%04x\n",         csr, sbus_readw(rp + BPP_OCR));      switch (csr & P_DEV_ID_MASK) {      case P_DEV_ID_ZEBRA:            brand = "Zebra";            break;      case P_DEV_ID_L64854:            brand = "DMA2";            break;      default:            brand = "Unknown";      }      printk("bpp%d: %s at 0x%lx\n", idx, brand, rp);      /*       * Leave the port in compat idle mode.       */      set_pins(BPP_PP_nAutoFd|BPP_PP_nStrobe|BPP_PP_nInit, idx);      return;}static inline void freeLptPort(int idx){      sbus_iounmap(base_addrs[idx], BPP_SIZE);}#endifstatic int __init bpp_init(void){	int rc;	unsigned idx;	rc = collectLptPorts();	if (rc == 0)		return -ENODEV;	rc = register_chrdev(BPP_MAJOR, dev_name, &bpp_fops);	if (rc < 0)		return rc;	for (idx = 0; idx < BPP_NO; idx++) {		instances[idx].opened = 0;		probeLptPort(idx);	}	devfs_mk_dir("bpp");	for (idx = 0; idx < BPP_NO; idx++) {		devfs_mk_cdev(MKDEV(BPP_MAJOR, idx),				S_IFCHR | S_IRUSR | S_IWUSR, "bpp/%d", idx);	}	return 0;}static void __exit bpp_cleanup(void){	unsigned idx;	for (idx = 0; idx < BPP_NO; idx++)		devfs_remove("bpp/%d", idx);	devfs_remove("bpp");	unregister_chrdev(BPP_MAJOR, dev_name);	for (idx = 0;  idx < BPP_NO; idx++) {		if (instances[idx].present)			freeLptPort(idx);	}}module_init(bpp_init);module_exit(bpp_cleanup);MODULE_LICENSE("GPL");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -