📄 parport_ip32.c
字号:
parport_ip32_write_econtrol(p, ecr); } parport_ip32_write_econtrol(p, mode | ECR_nERRINTR | ECR_SERVINTR);}/*--- Basic functions needed for parport -------------------------------*//** * parport_ip32_read_data - return current contents of the DATA register * @p: pointer to &struct parport */static inline unsigned char parport_ip32_read_data(struct parport *p){ struct parport_ip32_private * const priv = p->physport->private_data; return readb(priv->regs.data);}/** * parport_ip32_write_data - set new contents for the DATA register * @p: pointer to &struct parport * @d: new value to write */static inline void parport_ip32_write_data(struct parport *p, unsigned char d){ struct parport_ip32_private * const priv = p->physport->private_data; writeb(d, priv->regs.data);}/** * parport_ip32_read_status - return current contents of the DSR register * @p: pointer to &struct parport */static inline unsigned char parport_ip32_read_status(struct parport *p){ struct parport_ip32_private * const priv = p->physport->private_data; return readb(priv->regs.dsr);}/** * __parport_ip32_read_control - return cached contents of the DCR register * @p: pointer to &struct parport */static inline unsigned int __parport_ip32_read_control(struct parport *p){ struct parport_ip32_private * const priv = p->physport->private_data; return priv->dcr_cache; /* use soft copy */}/** * __parport_ip32_write_control - set new contents for the DCR register * @p: pointer to &struct parport * @c: new value to write */static inline void __parport_ip32_write_control(struct parport *p, unsigned int c){ struct parport_ip32_private * const priv = p->physport->private_data; CHECK_EXTRA_BITS(p, c, priv->dcr_writable); c &= priv->dcr_writable; /* only writable bits */ writeb(c, priv->regs.dcr); priv->dcr_cache = c; /* update soft copy */}/** * __parport_ip32_frob_control - change bits from the DCR register * @p: pointer to &struct parport * @mask: bit mask of bits to change * @val: new value for changed bits * * This is equivalent to read from the DCR, mask out the bits in @mask, * exclusive-or with the bits in @val, and write the result to the DCR. * Actually, the cached contents of the DCR is used. */static inline void __parport_ip32_frob_control(struct parport *p, unsigned int mask, unsigned int val){ unsigned int c; c = (__parport_ip32_read_control(p) & ~mask) ^ val; __parport_ip32_write_control(p, c);}/** * parport_ip32_read_control - return cached contents of the DCR register * @p: pointer to &struct parport * * The return value is masked so as to only return the value of %DCR_STROBE, * %DCR_AUTOFD, %DCR_nINIT, and %DCR_SELECT. */static inline unsigned char parport_ip32_read_control(struct parport *p){ const unsigned int rm = DCR_STROBE | DCR_AUTOFD | DCR_nINIT | DCR_SELECT; return __parport_ip32_read_control(p) & rm;}/** * parport_ip32_write_control - set new contents for the DCR register * @p: pointer to &struct parport * @c: new value to write * * The value is masked so as to only change the value of %DCR_STROBE, * %DCR_AUTOFD, %DCR_nINIT, and %DCR_SELECT. */static inline void parport_ip32_write_control(struct parport *p, unsigned char c){ const unsigned int wm = DCR_STROBE | DCR_AUTOFD | DCR_nINIT | DCR_SELECT; CHECK_EXTRA_BITS(p, c, wm); __parport_ip32_frob_control(p, wm, c & wm);}/** * parport_ip32_frob_control - change bits from the DCR register * @p: pointer to &struct parport * @mask: bit mask of bits to change * @val: new value for changed bits * * This differs from __parport_ip32_frob_control() in that it only allows to * change the value of %DCR_STROBE, %DCR_AUTOFD, %DCR_nINIT, and %DCR_SELECT. */static inline unsigned char parport_ip32_frob_control(struct parport *p, unsigned char mask, unsigned char val){ const unsigned int wm = DCR_STROBE | DCR_AUTOFD | DCR_nINIT | DCR_SELECT; CHECK_EXTRA_BITS(p, mask, wm); CHECK_EXTRA_BITS(p, val, wm); __parport_ip32_frob_control(p, mask & wm, val & wm); return parport_ip32_read_control(p);}/** * parport_ip32_disable_irq - disable interrupts on the rising edge of nACK * @p: pointer to &struct parport */static inline void parport_ip32_disable_irq(struct parport *p){ __parport_ip32_frob_control(p, DCR_IRQ, 0);}/** * parport_ip32_enable_irq - enable interrupts on the rising edge of nACK * @p: pointer to &struct parport */static inline void parport_ip32_enable_irq(struct parport *p){ __parport_ip32_frob_control(p, DCR_IRQ, DCR_IRQ);}/** * parport_ip32_data_forward - enable host-to-peripheral communications * @p: pointer to &struct parport * * Enable the data line drivers, for 8-bit host-to-peripheral communications. */static inline void parport_ip32_data_forward(struct parport *p){ __parport_ip32_frob_control(p, DCR_DIR, 0);}/** * parport_ip32_data_reverse - enable peripheral-to-host communications * @p: pointer to &struct parport * * Place the data bus in a high impedance state, if @p->modes has the * PARPORT_MODE_TRISTATE bit set. */static inline void parport_ip32_data_reverse(struct parport *p){ __parport_ip32_frob_control(p, DCR_DIR, DCR_DIR);}/** * parport_ip32_init_state - for core parport code * @dev: pointer to &struct pardevice * @s: pointer to &struct parport_state to initialize */static void parport_ip32_init_state(struct pardevice *dev, struct parport_state *s){ s->u.ip32.dcr = DCR_SELECT | DCR_nINIT; s->u.ip32.ecr = ECR_MODE_PS2 | ECR_nERRINTR | ECR_SERVINTR;}/** * parport_ip32_save_state - for core parport code * @p: pointer to &struct parport * @s: pointer to &struct parport_state to save state to */static void parport_ip32_save_state(struct parport *p, struct parport_state *s){ s->u.ip32.dcr = __parport_ip32_read_control(p); s->u.ip32.ecr = parport_ip32_read_econtrol(p);}/** * parport_ip32_restore_state - for core parport code * @p: pointer to &struct parport * @s: pointer to &struct parport_state to restore state from */static void parport_ip32_restore_state(struct parport *p, struct parport_state *s){ parport_ip32_set_mode(p, s->u.ip32.ecr & ECR_MODE_MASK); parport_ip32_write_econtrol(p, s->u.ip32.ecr); __parport_ip32_write_control(p, s->u.ip32.dcr);}/*--- EPP mode functions -----------------------------------------------*//** * parport_ip32_clear_epp_timeout - clear Timeout bit in EPP mode * @p: pointer to &struct parport * * Returns 1 if the Timeout bit is clear, and 0 otherwise. */static unsigned int parport_ip32_clear_epp_timeout(struct parport *p){ struct parport_ip32_private * const priv = p->physport->private_data; unsigned int cleared; if (!(parport_ip32_read_status(p) & DSR_TIMEOUT)) cleared = 1; else { unsigned int r; /* To clear timeout some chips require double read */ parport_ip32_read_status(p); r = parport_ip32_read_status(p); /* Some reset by writing 1 */ writeb(r | DSR_TIMEOUT, priv->regs.dsr); /* Others by writing 0 */ writeb(r & ~DSR_TIMEOUT, priv->regs.dsr); r = parport_ip32_read_status(p); cleared = !(r & DSR_TIMEOUT); } pr_trace(p, "(): %s", cleared ? "cleared" : "failed"); return cleared;}/** * parport_ip32_epp_read - generic EPP read function * @eppreg: I/O register to read from * @p: pointer to &struct parport * @buf: buffer to store read data * @len: length of buffer @buf * @flags: may be PARPORT_EPP_FAST */static size_t parport_ip32_epp_read(void __iomem *eppreg, struct parport *p, void *buf, size_t len, int flags){ struct parport_ip32_private * const priv = p->physport->private_data; size_t got; parport_ip32_set_mode(p, ECR_MODE_EPP); parport_ip32_data_reverse(p); parport_ip32_write_control(p, DCR_nINIT); if ((flags & PARPORT_EPP_FAST) && (len > 1)) { readsb(eppreg, buf, len); if (readb(priv->regs.dsr) & DSR_TIMEOUT) { parport_ip32_clear_epp_timeout(p); return -EIO; } got = len; } else { u8 *bufp = buf; for (got = 0; got < len; got++) { *bufp++ = readb(eppreg); if (readb(priv->regs.dsr) & DSR_TIMEOUT) { parport_ip32_clear_epp_timeout(p); break; } } } parport_ip32_data_forward(p); parport_ip32_set_mode(p, ECR_MODE_PS2); return got;}/** * parport_ip32_epp_write - generic EPP write function * @eppreg: I/O register to write to * @p: pointer to &struct parport * @buf: buffer of data to write * @len: length of buffer @buf * @flags: may be PARPORT_EPP_FAST */static size_t parport_ip32_epp_write(void __iomem *eppreg, struct parport *p, const void *buf, size_t len, int flags){ struct parport_ip32_private * const priv = p->physport->private_data; size_t written; parport_ip32_set_mode(p, ECR_MODE_EPP); parport_ip32_data_forward(p); parport_ip32_write_control(p, DCR_nINIT); if ((flags & PARPORT_EPP_FAST) && (len > 1)) { writesb(eppreg, buf, len); if (readb(priv->regs.dsr) & DSR_TIMEOUT) { parport_ip32_clear_epp_timeout(p); return -EIO; } written = len; } else { const u8 *bufp = buf; for (written = 0; written < len; written++) { writeb(*bufp++, eppreg); if (readb(priv->regs.dsr) & DSR_TIMEOUT) { parport_ip32_clear_epp_timeout(p); break; } } } parport_ip32_set_mode(p, ECR_MODE_PS2); return written;}/** * parport_ip32_epp_read_data - read a block of data in EPP mode * @p: pointer to &struct parport * @buf: buffer to store read data * @len: length of buffer @buf * @flags: may be PARPORT_EPP_FAST */static size_t parport_ip32_epp_read_data(struct parport *p, void *buf, size_t len, int flags){ struct parport_ip32_private * const priv = p->physport->private_data; return parport_ip32_epp_read(priv->regs.eppData0, p, buf, len, flags);}/** * parport_ip32_epp_write_data - write a block of data in EPP mode * @p: pointer to &struct parport * @buf: buffer of data to write * @len: length of buffer @buf * @flags: may be PARPORT_EPP_FAST */static size_t parport_ip32_epp_write_data(struct parport *p, const void *buf, size_t len, int flags){ struct parport_ip32_private * const priv = p->physport->private_data; return parport_ip32_epp_write(priv->regs.eppData0, p, buf, len, flags);}/** * parport_ip32_epp_read_addr - read a block of addresses in EPP mode * @p: pointer to &struct parport * @buf: buffer to store read data * @len: length of buffer @buf * @flags: may be PARPORT_EPP_FAST */static size_t parport_ip32_epp_read_addr(struct parport *p, void *buf, size_t len, int flags){ struct parport_ip32_private * const priv = p->physport->private_data; return parport_ip32_epp_read(priv->regs.eppAddr, p, buf, len, flags);}/** * parport_ip32_epp_write_addr - write a block of addresses in EPP mode * @p: pointer to &struct parport * @buf: buffer of data to write * @len: length of buffer @buf * @flags: may be PARPORT_EPP_FAST */static size_t parport_ip32_epp_write_addr(struct parport *p, const void *buf, size_t len, int flags){ struct parport_ip32_private * const priv = p->physport->private_data; return parport_ip32_epp_write(priv->regs.eppAddr, p, buf, len, flags);}/*--- ECP mode functions (FIFO) ----------------------------------------*//** * parport_ip32_fifo_wait_break - check if the waiting function should return * @p: pointer to &struct parport * @expire: timeout expiring date, in jiffies * * parport_ip32_fifo_wait_break() checks if the waiting function should return * immediately or not. The break conditions are: * - expired timeout; * - a pending signal; * - nFault asserted low. * This function also calls cond_resched(). */static unsigned int parport_ip32_fifo_wait_break(struct parport *p, unsigned long expire){ cond_resched(); if (time_after(jiffies, expire)) { pr_debug1(PPIP32 "%s: FIFO write timed out\n", p->name); return 1; } if (signal_pending(current)) { pr_debug1(PPIP32 "%s: Signal pending\n", p->name); return 1; } if (!(parport_ip32_read_status(p) & DSR_nFAULT)) { pr_debug1(PPIP32 "%s: nFault asserted low\n", p->name); return 1; } return 0;}/** * parport_ip32_fwp_wait_polling - wait for FIFO to empty (polling) * @p: pointer to &struct parport * * Returns the number of bytes that can safely be written in the FIFO. A * return value of zero means that the calling function should terminate as * fast as possible. */static unsigned int parport_ip32_fwp_wait_polling(struct parport *p){ struct parport_ip32_private * const priv = p->physport->private_data; struct parport * const physport = p->physport; unsigned long expire; unsigned int count; unsigned int ecr;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -