diff options
Diffstat (limited to 'drivers/staging/fwserial/fwserial.c')
| -rw-r--r-- | drivers/staging/fwserial/fwserial.c | 372 |
1 files changed, 153 insertions, 219 deletions
diff --git a/drivers/staging/fwserial/fwserial.c b/drivers/staging/fwserial/fwserial.c index 5a6fb44f38a..384758b11e3 100644 --- a/drivers/staging/fwserial/fwserial.c +++ b/drivers/staging/fwserial/fwserial.c @@ -12,12 +12,10 @@ * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/sched.h> #include <linux/slab.h> #include <linux/device.h> @@ -101,13 +99,16 @@ struct fwtty_transaction { }; #define to_device(a, b) (a->b) -#define fwtty_err(p, s, v...) dev_err(to_device(p, device), s, ##v) -#define fwtty_info(p, s, v...) dev_info(to_device(p, device), s, ##v) -#define fwtty_notice(p, s, v...) dev_notice(to_device(p, device), s, ##v) -#define fwtty_dbg(p, s, v...) \ - dev_dbg(to_device(p, device), "%s: " s, __func__, ##v) -#define fwtty_err_ratelimited(p, s, v...) \ - dev_err_ratelimited(to_device(p, device), s, ##v) +#define fwtty_err(p, fmt, ...) \ + dev_err(to_device(p, device), fmt, ##__VA_ARGS__) +#define fwtty_info(p, fmt, ...) \ + dev_info(to_device(p, device), fmt, ##__VA_ARGS__) +#define fwtty_notice(p, fmt, ...) \ + dev_notice(to_device(p, device), fmt, ##__VA_ARGS__) +#define fwtty_dbg(p, fmt, ...) \ + dev_dbg(to_device(p, device), "%s: " fmt, __func__, ##__VA_ARGS__) +#define fwtty_err_ratelimited(p, fmt, ...) \ + dev_err_ratelimited(to_device(p, device), fmt, ##__VA_ARGS__) #ifdef DEBUG static inline void debug_short_write(struct fwtty_port *port, int c, int n) @@ -118,7 +119,7 @@ static inline void debug_short_write(struct fwtty_port *port, int c, int n) spin_lock_bh(&port->lock); avail = dma_fifo_avail(&port->tx_fifo); spin_unlock_bh(&port->lock); - fwtty_dbg(port, "short write: avail:%d req:%d wrote:%d", + fwtty_dbg(port, "short write: avail:%d req:%d wrote:%d\n", avail, c, n); } } @@ -131,14 +132,14 @@ static struct fwtty_peer *__fwserial_peer_by_node_id(struct fw_card *card, #ifdef FWTTY_PROFILING -static void profile_fifo_avail(struct fwtty_port *port, unsigned *stat) +static void fwtty_profile_fifo(struct fwtty_port *port, unsigned *stat) { spin_lock_bh(&port->lock); - profile_size_distrib(stat, dma_fifo_avail(&port->tx_fifo)); + fwtty_profile_data(stat, dma_fifo_avail(&port->tx_fifo)); spin_unlock_bh(&port->lock); } -static void dump_profile(struct seq_file *m, struct stats *stats) +static void fwtty_dump_profile(struct seq_file *m, struct stats *stats) { /* for each stat, print sum of 0 to 2^k, then individually */ int k = 4; @@ -178,8 +179,8 @@ static void dump_profile(struct seq_file *m, struct stats *stats) } #else -#define profile_fifo_avail(port, stat) -#define dump_profile(m, stats) +#define fwtty_profile_fifo(port, stat) +#define fwtty_dump_profile(m, stats) #endif /* @@ -197,22 +198,22 @@ static void fwtty_log_tx_error(struct fwtty_port *port, int rcode) { switch (rcode) { case RCODE_SEND_ERROR: - fwtty_err_ratelimited(port, "card busy"); + fwtty_err_ratelimited(port, "card busy\n"); break; case RCODE_ADDRESS_ERROR: - fwtty_err_ratelimited(port, "bad unit addr or write length"); + fwtty_err_ratelimited(port, "bad unit addr or write length\n"); break; case RCODE_DATA_ERROR: - fwtty_err_ratelimited(port, "failed rx"); + fwtty_err_ratelimited(port, "failed rx\n"); break; case RCODE_NO_ACK: - fwtty_err_ratelimited(port, "missing ack"); + fwtty_err_ratelimited(port, "missing ack\n"); break; case RCODE_BUSY: - fwtty_err_ratelimited(port, "remote busy"); + fwtty_err_ratelimited(port, "remote busy\n"); break; default: - fwtty_err_ratelimited(port, "failed tx: %d", rcode); + fwtty_err_ratelimited(port, "failed tx: %d\n", rcode); } } @@ -287,7 +288,7 @@ static void __fwtty_restart_tx(struct fwtty_port *port) schedule_delayed_work(&port->drain, 0); avail = dma_fifo_avail(&port->tx_fifo); - fwtty_dbg(port, "fifo len: %d avail: %d", len, avail); + fwtty_dbg(port, "fifo len: %d avail: %d\n", len, avail); } static void fwtty_restart_tx(struct fwtty_port *port) @@ -323,7 +324,7 @@ static void fwtty_update_port_status(struct fwtty_port *port, unsigned status) if (delta & TIOCM_CTS) ++port->icount.cts; - fwtty_dbg(port, "status: %x delta: %x", status, delta); + fwtty_dbg(port, "status: %x delta: %x\n", status, delta); if (delta & TIOCM_CAR) { tty = tty_port_tty_get(&port->port); @@ -451,16 +452,27 @@ static int fwtty_write_port_status(struct fwtty_port *port) return err; } -static void __fwtty_throttle(struct fwtty_port *port, struct tty_struct *tty) +static void fwtty_throttle_port(struct fwtty_port *port) { + struct tty_struct *tty; unsigned old; + tty = tty_port_tty_get(&port->port); + if (!tty) + return; + + spin_lock_bh(&port->lock); + old = port->mctrl; port->mctrl |= OOB_RX_THROTTLE; if (C_CRTSCTS(tty)) port->mctrl &= ~TIOCM_RTS; if (~old & OOB_RX_THROTTLE) __fwtty_write_port_status(port); + + spin_unlock_bh(&port->lock); + + tty_kref_put(tty); } /** @@ -509,12 +521,12 @@ static void fwtty_emit_breaks(struct work_struct *work) n = (elapsed * port->cps) / HZ + 1; port->break_last = now; - fwtty_dbg(port, "sending %d brks", n); + fwtty_dbg(port, "sending %d brks\n", n); while (n) { t = min(n, 16); c = tty_insert_flip_string_fixed_flag(&port->port, buf, - TTY_BREAK, t); + TTY_BREAK, t); n -= c; brk += c; if (c < t) @@ -527,80 +539,14 @@ static void fwtty_emit_breaks(struct work_struct *work) port->icount.brk += brk; } -static void fwtty_pushrx(struct work_struct *work) -{ - struct fwtty_port *port = to_port(work, push); - struct tty_struct *tty; - struct buffered_rx *buf, *next; - int n, c = 0; - - spin_lock_bh(&port->lock); - list_for_each_entry_safe(buf, next, &port->buf_list, list) { - n = tty_insert_flip_string_fixed_flag(&port->port, buf->data, - TTY_NORMAL, buf->n); - c += n; - port->buffered -= n; - if (n < buf->n) { - if (n > 0) { - memmove(buf->data, buf->data + n, buf->n - n); - buf->n -= n; - } - tty = tty_port_tty_get(&port->port); - if (tty) { - __fwtty_throttle(port, tty); - tty_kref_put(tty); - } - break; - } else { - list_del(&buf->list); - kfree(buf); - } - } - if (c > 0) - tty_flip_buffer_push(&port->port); - - if (list_empty(&port->buf_list)) - clear_bit(BUFFERING_RX, &port->flags); - spin_unlock_bh(&port->lock); -} - -static int fwtty_buffer_rx(struct fwtty_port *port, unsigned char *d, size_t n) -{ - struct buffered_rx *buf; - size_t size = (n + sizeof(struct buffered_rx) + 0xFF) & ~0xFF; - - if (port->buffered + n > HIGH_WATERMARK) { - fwtty_err_ratelimited(port, "overflowed rx buffer: buffered: %d new: %zu wtrmk: %d", - port->buffered, n, HIGH_WATERMARK); - return 0; - } - buf = kmalloc(size, GFP_ATOMIC); - if (!buf) - return 0; - INIT_LIST_HEAD(&buf->list); - buf->n = n; - memcpy(buf->data, d, n); - - spin_lock_bh(&port->lock); - list_add_tail(&buf->list, &port->buf_list); - port->buffered += n; - if (port->buffered > port->stats.watermark) - port->stats.watermark = port->buffered; - set_bit(BUFFERING_RX, &port->flags); - spin_unlock_bh(&port->lock); - - return n; -} - static int fwtty_rx(struct fwtty_port *port, unsigned char *data, size_t len) { - struct tty_struct *tty; int c, n = len; unsigned lsr; int err = 0; - fwtty_dbg(port, "%d", n); - profile_size_distrib(port->stats.reads, n); + fwtty_dbg(port, "%d\n", n); + fwtty_profile_data(port->stats.reads, n); if (port->write_only) { n = 0; @@ -631,31 +577,24 @@ static int fwtty_rx(struct fwtty_port *port, unsigned char *data, size_t len) goto out; } - if (!test_bit(BUFFERING_RX, &port->flags)) { - c = tty_insert_flip_string_fixed_flag(&port->port, data, - TTY_NORMAL, n); - if (c > 0) - tty_flip_buffer_push(&port->port); - n -= c; - - if (n) { - /* start buffering and throttling */ - n -= fwtty_buffer_rx(port, &data[c], n); - - tty = tty_port_tty_get(&port->port); - if (tty) { - spin_lock_bh(&port->lock); - __fwtty_throttle(port, tty); - spin_unlock_bh(&port->lock); - tty_kref_put(tty); - } - } - } else - n -= fwtty_buffer_rx(port, data, n); + c = tty_insert_flip_string_fixed_flag(&port->port, data, TTY_NORMAL, n); + if (c > 0) + tty_flip_buffer_push(&port->port); + n -= c; if (n) { port->overrun = true; err = -EIO; + fwtty_err_ratelimited(port, "flip buffer overrun\n"); + + } else { + /* throttle the sender if remaining flip buffer space has + * reached high watermark to avoid losing data which may be + * in-flight. Since the AR request context is 32k, that much + * data may have _already_ been acked. + */ + if (tty_buffer_space_avail(&port->port) < HIGH_WATERMARK) + fwtty_throttle_port(port); } out: @@ -689,15 +628,15 @@ static void fwtty_port_handler(struct fw_card *card, rcu_read_unlock(); if (!peer || peer != rcu_access_pointer(port->peer)) { rcode = RCODE_ADDRESS_ERROR; - fwtty_err_ratelimited(port, "ignoring unauthenticated data"); + fwtty_err_ratelimited(port, "ignoring unauthenticated data\n"); goto respond; } switch (tcode) { case TCODE_WRITE_QUADLET_REQUEST: - if (addr != port->rx_handler.offset || len != 4) + if (addr != port->rx_handler.offset || len != 4) { rcode = RCODE_ADDRESS_ERROR; - else { + } else { fwtty_update_port_status(port, *(unsigned *)data); rcode = RCODE_COMPLETE; } @@ -744,10 +683,9 @@ static void fwtty_tx_complete(struct fw_card *card, int rcode, struct fwtty_transaction *txn) { struct fwtty_port *port = txn->port; - struct tty_struct *tty; int len; - fwtty_dbg(port, "rcode: %d", rcode); + fwtty_dbg(port, "rcode: %d\n", rcode); switch (rcode) { case RCODE_COMPLETE: @@ -769,13 +707,8 @@ static void fwtty_tx_complete(struct fw_card *card, int rcode, port->stats.dropped += txn->dma_pended.len; } - if (len < WAKEUP_CHARS) { - tty = tty_port_tty_get(&port->port); - if (tty) { - tty_wakeup(tty); - tty_kref_put(tty); - } - } + if (len < WAKEUP_CHARS) + tty_port_tty_wakeup(&port->port); } static int fwtty_tx(struct fwtty_port *port, bool drain) @@ -804,7 +737,7 @@ static int fwtty_tx(struct fwtty_port *port, bool drain) /* try to write as many dma transactions out as possible */ n = -EAGAIN; while (!tty->stopped && !tty->hw_stopped && - !test_bit(STOP_TX, &port->flags)) { + !test_bit(STOP_TX, &port->flags)) { txn = kmem_cache_alloc(fwtty_txn_cache, GFP_ATOMIC); if (!txn) { n = -ENOMEM; @@ -815,22 +748,23 @@ static int fwtty_tx(struct fwtty_port *port, bool drain) n = dma_fifo_out_pend(&port->tx_fifo, &txn->dma_pended); spin_unlock_bh(&port->lock); - fwtty_dbg(port, "out: %u rem: %d", txn->dma_pended.len, n); + fwtty_dbg(port, "out: %u rem: %d\n", txn->dma_pended.len, n); if (n < 0) { kmem_cache_free(fwtty_txn_cache, txn); - if (n == -EAGAIN) + if (n == -EAGAIN) { ++port->stats.tx_stall; - else if (n == -ENODATA) - profile_size_distrib(port->stats.txns, 0); - else { + } else if (n == -ENODATA) { + fwtty_profile_data(port->stats.txns, 0); + } else { ++port->stats.fifo_errs; - fwtty_err_ratelimited(port, "fifo err: %d", n); + fwtty_err_ratelimited(port, "fifo err: %d\n", + n); } break; } - profile_size_distrib(port->stats.txns, txn->dma_pended.len); + fwtty_profile_data(port->stats.txns, txn->dma_pended.len); fwtty_send_txn_async(peer, txn, TCODE_WRITE_BLOCK_REQUEST, peer->fifo_addr, txn->dma_pended.data, @@ -883,7 +817,7 @@ static void fwtty_write_xchar(struct fwtty_port *port, char ch) ++port->stats.xchars; - fwtty_dbg(port, "%02x", ch); + fwtty_dbg(port, "%02x\n", ch); rcu_read_lock(); peer = rcu_dereference(port->peer); @@ -946,7 +880,7 @@ static void fwserial_destroy(struct kref *kref) for (j = 0; j < num_ports; ++i, ++j) { port_table_corrupt |= port_table[i] != ports[j]; WARN_ONCE(port_table_corrupt, "port_table[%d]: %p != ports[%d]: %p", - i, port_table[i], j, ports[j]); + i, port_table[i], j, ports[j]); port_table[i] = NULL; } @@ -970,7 +904,7 @@ static void fwtty_port_dtr_rts(struct tty_port *tty_port, int on) { struct fwtty_port *port = to_port(tty_port, port); - fwtty_dbg(port, "on/off: %d", on); + fwtty_dbg(port, "on/off: %d\n", on); spin_lock_bh(&port->lock); /* Don't change carrier state if this is a console */ @@ -998,7 +932,7 @@ static int fwtty_port_carrier_raised(struct tty_port *tty_port) rc = (port->mstatus & TIOCM_CAR); - fwtty_dbg(port, "%d", rc); + fwtty_dbg(port, "%d\n", rc); return rc; } @@ -1101,20 +1035,13 @@ static int fwtty_port_activate(struct tty_port *tty_port, static void fwtty_port_shutdown(struct tty_port *tty_port) { struct fwtty_port *port = to_port(tty_port, port); - struct buffered_rx *buf, *next; /* TODO: cancel outstanding transactions */ cancel_delayed_work_sync(&port->emit_breaks); cancel_delayed_work_sync(&port->drain); - cancel_work_sync(&port->push); spin_lock_bh(&port->lock); - list_for_each_entry_safe(buf, next, &port->buf_list, list) { - list_del(&buf->list); - kfree(buf); - } - port->buffered = 0; port->flags = 0; port->break_ctl = 0; port->overrun = 0; @@ -1183,8 +1110,8 @@ static int fwtty_write(struct tty_struct *tty, const unsigned char *buf, int c) struct fwtty_port *port = tty->driver_data; int n, len; - fwtty_dbg(port, "%d", c); - profile_size_distrib(port->stats.writes, c); + fwtty_dbg(port, "%d\n", c); + fwtty_profile_data(port->stats.writes, c); spin_lock_bh(&port->lock); n = dma_fifo_in(&port->tx_fifo, buf, c); @@ -1210,7 +1137,7 @@ static int fwtty_write_room(struct tty_struct *tty) n = dma_fifo_avail(&port->tx_fifo); spin_unlock_bh(&port->lock); - fwtty_dbg(port, "%d", n); + fwtty_dbg(port, "%d\n", n); return n; } @@ -1224,7 +1151,7 @@ static int fwtty_chars_in_buffer(struct tty_struct *tty) n = dma_fifo_level(&port->tx_fifo); spin_unlock_bh(&port->lock); - fwtty_dbg(port, "%d", n); + fwtty_dbg(port, "%d\n", n); return n; } @@ -1233,7 +1160,7 @@ static void fwtty_send_xchar(struct tty_struct *tty, char ch) { struct fwtty_port *port = tty->driver_data; - fwtty_dbg(port, "%02x", ch); + fwtty_dbg(port, "%02x\n", ch); fwtty_write_xchar(port, ch); } @@ -1260,11 +1187,9 @@ static void fwtty_unthrottle(struct tty_struct *tty) { struct fwtty_port *port = tty->driver_data; - fwtty_dbg(port, "CRTSCTS: %d", (C_CRTSCTS(tty) != 0)); - - profile_fifo_avail(port, port->stats.unthrottle); + fwtty_dbg(port, "CRTSCTS: %d\n", (C_CRTSCTS(tty) != 0)); - schedule_work(&port->push); + fwtty_profile_fifo(port, port->stats.unthrottle); spin_lock_bh(&port->lock); port->mctrl &= ~OOB_RX_THROTTLE; @@ -1328,15 +1253,16 @@ static int set_serial_info(struct fwtty_port *port, return -EFAULT; if (tmp.irq != 0 || tmp.port != 0 || tmp.custom_divisor != 0 || - tmp.baud_base != 400000000) + tmp.baud_base != 400000000) return -EPERM; if (!capable(CAP_SYS_ADMIN)) { if (((tmp.flags & ~ASYNC_USR_MASK) != (port->port.flags & ~ASYNC_USR_MASK))) return -EPERM; - } else + } else { port->port.close_delay = tmp.close_delay * HZ / 100; + } return 0; } @@ -1379,9 +1305,9 @@ static void fwtty_set_termios(struct tty_struct *tty, struct ktermios *old) spin_lock_bh(&port->lock); baud = set_termios(port, tty); - if ((baud == 0) && (old->c_cflag & CBAUD)) + if ((baud == 0) && (old->c_cflag & CBAUD)) { port->mctrl &= ~(TIOCM_DTR | TIOCM_RTS); - else if ((baud != 0) && !(old->c_cflag & CBAUD)) { + } else if ((baud != 0) && !(old->c_cflag & CBAUD)) { if (C_CRTSCTS(tty) || !test_bit(TTY_THROTTLED, &tty->flags)) port->mctrl |= TIOCM_DTR | TIOCM_RTS; else @@ -1415,7 +1341,7 @@ static int fwtty_break_ctl(struct tty_struct *tty, int state) struct fwtty_port *port = tty->driver_data; long ret; - fwtty_dbg(port, "%d", state); + fwtty_dbg(port, "%d\n", state); if (state == -1) { set_bit(STOP_TX, &port->flags); @@ -1452,7 +1378,7 @@ static int fwtty_tiocmget(struct tty_struct *tty) tiocm = (port->mctrl & MCTRL_MASK) | (port->mstatus & ~MCTRL_MASK); spin_unlock_bh(&port->lock); - fwtty_dbg(port, "%x", tiocm); + fwtty_dbg(port, "%x\n", tiocm); return tiocm; } @@ -1461,7 +1387,7 @@ static int fwtty_tiocmset(struct tty_struct *tty, unsigned set, unsigned clear) { struct fwtty_port *port = tty->driver_data; - fwtty_dbg(port, "set: %x clear: %x", set, clear); + fwtty_dbg(port, "set: %x clear: %x\n", set, clear); /* TODO: simulate loopback if TIOCM_LOOP set */ @@ -1523,15 +1449,14 @@ static void fwtty_debugfs_show_port(struct seq_file *m, struct fwtty_port *port) seq_printf(m, " dr:%d st:%d err:%d lost:%d", stats.dropped, stats.tx_stall, stats.fifo_errs, stats.lost); - seq_printf(m, " pkts:%d thr:%d wtrmk:%d", stats.sent, stats.throttled, - stats.watermark); + seq_printf(m, " pkts:%d thr:%d", stats.sent, stats.throttled); if (port->port.console) { - seq_printf(m, "\n "); + seq_puts(m, "\n "); (*port->fwcon_ops->proc_show)(m, port->con_data); } - dump_profile(m, &port->stats); + fwtty_dump_profile(m, &port->stats); } static void fwtty_debugfs_show_peer(struct seq_file *m, struct fwtty_peer *peer) @@ -1559,7 +1484,7 @@ static int fwtty_proc_show(struct seq_file *m, void *v) if (capable(CAP_SYS_ADMIN)) fwtty_proc_show_port(m, port); fwtty_port_put(port); - seq_printf(m, "\n"); + seq_puts(m, "\n"); } return 0; } @@ -1577,7 +1502,7 @@ static int fwtty_debugfs_stats_show(struct seq_file *m, void *v) fwtty_proc_show_port(m, port); fwtty_debugfs_show_port(m, port); fwtty_port_put(port); - seq_printf(m, "\n"); + seq_puts(m, "\n"); } } return 0; @@ -1781,7 +1706,7 @@ static void fwserial_virt_plug_complete(struct fwtty_peer *peer, if (port->port.console && port->fwcon_ops->notify != NULL) (*port->fwcon_ops->notify)(FWCON_NOTIFY_ATTACH, port->con_data); - fwtty_info(&peer->unit, "peer (guid:%016llx) connected on %s", + fwtty_info(&peer->unit, "peer (guid:%016llx) connected on %s\n", (unsigned long long)peer->guid, dev_name(port->device)); } @@ -1803,10 +1728,11 @@ static inline int fwserial_send_mgmt_sync(struct fwtty_peer *peer, pkt, be16_to_cpu(pkt->hdr.len)); if (rcode == RCODE_BUSY || rcode == RCODE_SEND_ERROR || rcode == RCODE_GENERATION) { - fwtty_dbg(&peer->unit, "mgmt write error: %d", rcode); + fwtty_dbg(&peer->unit, "mgmt write error: %d\n", rcode); continue; - } else + } else { break; + } } while (--tries > 0); return rcode; } @@ -1881,7 +1807,7 @@ static void fwserial_release_port(struct fwtty_port *port, bool reset) port->max_payload = link_speed_to_max_payload(SCODE_100); dma_fifo_change_tx_limit(&port->tx_fifo, port->max_payload); - rcu_assign_pointer(port->peer, NULL); + RCU_INIT_POINTER(port->peer, NULL); spin_unlock_bh(&port->lock); if (port->port.console && port->fwcon_ops->notify != NULL) @@ -1890,7 +1816,7 @@ static void fwserial_release_port(struct fwtty_port *port, bool reset) static void fwserial_plug_timeout(unsigned long data) { - struct fwtty_peer *peer = (struct fwtty_peer *) data; + struct fwtty_peer *peer = (struct fwtty_peer *)data; struct fwtty_port *port; spin_lock_bh(&peer->lock); @@ -1924,7 +1850,7 @@ static int fwserial_connect_peer(struct fwtty_peer *peer) port = fwserial_find_port(peer); if (!port) { - fwtty_err(&peer->unit, "avail ports in use"); + fwtty_err(&peer->unit, "avail ports in use\n"); err = -EBUSY; goto free_pkt; } @@ -2062,7 +1988,7 @@ static struct fwtty_peer *__fwserial_peer_by_node_id(struct fw_card *card, * has created its remote unit device before this driver has * been probed for any unit devices... */ - fwtty_err(card, "unknown card (guid %016llx)", + fwtty_err(card, "unknown card (guid %016llx)\n", (unsigned long long) card->guid); return NULL; } @@ -2090,8 +2016,8 @@ static void __dump_peer_list(struct fw_card *card) list_for_each_entry_rcu(peer, &serial->peer_list, list) { int g = peer->generation; smp_rmb(); - fwtty_dbg(card, "peer(%d:%x) guid: %016llx\n", g, - peer->node_id, (unsigned long long) peer->guid); + fwtty_dbg(card, "peer(%d:%x) guid: %016llx\n", + g, peer->node_id, (unsigned long long) peer->guid); } } #else @@ -2108,6 +2034,13 @@ static void fwserial_auto_connect(struct work_struct *work) schedule_delayed_work(&peer->connect, CONNECT_RETRY_DELAY); } +static void fwserial_peer_workfn(struct work_struct *work) +{ + struct fwtty_peer *peer = to_peer(work, work); + + peer->workfn(work); +} + /** * fwserial_add_peer - add a newly probed 'serial' unit device as a 'peer' * @serial: aggregate representing the specific fw_card to add the peer to @@ -2172,14 +2105,14 @@ static int fwserial_add_peer(struct fw_serial *serial, struct fw_unit *unit) peer->port = NULL; init_timer(&peer->timer); - INIT_WORK(&peer->work, NULL); + INIT_WORK(&peer->work, fwserial_peer_workfn); INIT_DELAYED_WORK(&peer->connect, fwserial_auto_connect); /* associate peer with specific fw_card */ peer->serial = serial; list_add_rcu(&peer->list, &serial->peer_list); - fwtty_info(&peer->unit, "peer added (guid:%016llx)", + fwtty_info(&peer->unit, "peer added (guid:%016llx)\n", (unsigned long long)peer->guid); /* identify the local unit & virt cable to loopback port */ @@ -2242,7 +2175,7 @@ static void fwserial_remove_peer(struct fwtty_peer *peer) list_del_rcu(&peer->list); - fwtty_info(&peer->unit, "peer removed (guid:%016llx)", + fwtty_info(&peer->unit, "peer removed (guid:%016llx)\n", (unsigned long long)peer->guid); spin_unlock_bh(&peer->lock); @@ -2297,18 +2230,17 @@ static int fwserial_create(struct fw_unit *unit) port->index = FWTTY_INVALID_INDEX; port->port.ops = &fwtty_port_ops; port->serial = serial; + tty_buffer_set_limit(&port->port, 128 * 1024); spin_lock_init(&port->lock); INIT_DELAYED_WORK(&port->drain, fwtty_drain_tx); INIT_DELAYED_WORK(&port->emit_breaks, fwtty_emit_breaks); INIT_WORK(&port->hangup, fwtty_do_hangup); - INIT_WORK(&port->push, fwtty_pushrx); - INIT_LIST_HEAD(&port->buf_list); init_waitqueue_head(&port->wait_tx); port->max_payload = link_speed_to_max_payload(SCODE_100); dma_fifo_init(&port->tx_fifo); - rcu_assign_pointer(port->peer, NULL); + RCU_INIT_POINTER(port->peer, NULL); serial->ports[i] = port; /* get unique bus addr region for port's status & recv fifo */ @@ -2330,7 +2262,7 @@ static int fwserial_create(struct fw_unit *unit) err = fwtty_ports_add(serial); if (err) { - fwtty_err(&unit, "no space in port table"); + fwtty_err(&unit, "no space in port table\n"); goto free_ports; } @@ -2341,7 +2273,8 @@ static int fwserial_create(struct fw_unit *unit) card->device); if (IS_ERR(tty_dev)) { err = PTR_ERR(tty_dev); - fwtty_err(&unit, "register tty device error (%d)", err); + fwtty_err(&unit, "register tty device error (%d)\n", + err); goto unregister_ttys; } @@ -2358,7 +2291,8 @@ static int fwserial_create(struct fw_unit *unit) card->device); if (IS_ERR(loop_dev)) { err = PTR_ERR(loop_dev); - fwtty_err(&unit, "create loop device failed (%d)", err); + fwtty_err(&unit, "create loop device failed (%d)\n", + err); goto unregister_ttys; } serial->ports[j]->device = loop_dev; @@ -2378,21 +2312,22 @@ static int fwserial_create(struct fw_unit *unit) list_add_rcu(&serial->list, &fwserial_list); - fwtty_notice(&unit, "TTY over FireWire on device %s (guid %016llx)", + fwtty_notice(&unit, "TTY over FireWire on device %s (guid %016llx)\n", dev_name(card->device), (unsigned long long) card->guid); err = fwserial_add_peer(serial, unit); if (!err) return 0; - fwtty_err(&unit, "unable to add peer unit device (%d)", err); + fwtty_err(&unit, "unable to add peer unit device (%d)\n", err); /* fall-through to error processing */ debugfs_remove_recursive(serial->debugfs); list_del_rcu(&serial->list); if (create_loop_dev) - tty_unregister_device(fwloop_driver, loop_idx(serial->ports[j])); + tty_unregister_device(fwloop_driver, + loop_idx(serial->ports[j])); unregister_ttys: for (--j; j >= 0; --j) tty_unregister_device(fwtty_driver, serial->ports[j]->index); @@ -2444,9 +2379,9 @@ free_ports: * last peer for a given fw_card triggering the destruction of the same * fw_serial for the same fw_card. */ -static int fwserial_probe(struct device *dev) +static int fwserial_probe(struct fw_unit *unit, + const struct ieee1394_device_id *id) { - struct fw_unit *unit = fw_unit(dev); struct fw_serial *serial; int err; @@ -2468,9 +2403,9 @@ static int fwserial_probe(struct device *dev) * specific fw_card). If this is the last peer being removed, then trigger * the destruction of the underlying TTYs. */ -static int fwserial_remove(struct device *dev) +static void fwserial_remove(struct fw_unit *unit) { - struct fwtty_peer *peer = dev_get_drvdata(dev); + struct fwtty_peer *peer = dev_get_drvdata(&unit->device); struct fw_serial *serial = peer->serial; int i; @@ -2490,8 +2425,6 @@ static int fwserial_remove(struct device *dev) kref_put(&serial->kref, fwserial_destroy); } mutex_unlock(&fwserial_list_mutex); - - return 0; } /** @@ -2536,10 +2469,10 @@ static struct fw_driver fwserial_driver = { .owner = THIS_MODULE, .name = KBUILD_MODNAME, .bus = &fw_bus_type, - .probe = fwserial_probe, - .remove = fwserial_remove, }, + .probe = fwserial_probe, .update = fwserial_update, + .remove = fwserial_remove, .id_table = fwserial_id_table, }; @@ -2627,7 +2560,7 @@ static void fwserial_handle_plug_req(struct work_struct *work) switch (peer->state) { case FWPS_NOT_ATTACHED: if (!port) { - fwtty_err(&peer->unit, "no more ports avail"); + fwtty_err(&peer->unit, "no more ports avail\n"); fill_plug_rsp_nack(pkt); } else { peer->port = port; @@ -2669,7 +2602,7 @@ static void fwserial_handle_plug_req(struct work_struct *work) fwtty_write_port_status(tmp); spin_lock_bh(&peer->lock); } else { - fwtty_err(&peer->unit, "PLUG_RSP error (%d)", rcode); + fwtty_err(&peer->unit, "PLUG_RSP error (%d)\n", rcode); port = peer_revert_state(peer); } } @@ -2721,7 +2654,8 @@ static void fwserial_handle_unplug_req(struct work_struct *work) spin_lock_bh(&peer->lock); if (peer->state == FWPS_UNPLUG_RESPONDING) { if (rcode != RCODE_COMPLETE) - fwtty_err(&peer->unit, "UNPLUG_RSP error (%d)", rcode); + fwtty_err(&peer->unit, "UNPLUG_RSP error (%d)\n", + rcode); port = peer_revert_state(peer); } cleanup: @@ -2756,24 +2690,24 @@ static int fwserial_parse_mgmt_write(struct fwtty_peer *peer, * already removed from the bus -- and the removal was * processed before we rec'd this transaction */ - fwtty_err(&peer->unit, "peer already removed"); + fwtty_err(&peer->unit, "peer already removed\n"); spin_unlock_bh(&peer->lock); return RCODE_ADDRESS_ERROR; } rcode = RCODE_COMPLETE; - fwtty_dbg(&peer->unit, "mgmt: hdr.code: %04hx", pkt->hdr.code); + fwtty_dbg(&peer->unit, "mgmt: hdr.code: %04hx\n", pkt->hdr.code); switch (be16_to_cpu(pkt->hdr.code) & FWSC_CODE_MASK) { case FWSC_VIRT_CABLE_PLUG: if (work_pending(&peer->work)) { - fwtty_err(&peer->unit, "plug req: busy"); + fwtty_err(&peer->unit, "plug req: busy\n"); rcode = RCODE_CONFLICT_ERROR; } else { peer->work_params.plug_req = pkt->plug_req; - PREPARE_WORK(&peer->work, fwserial_handle_plug_req); + peer->workfn = fwserial_handle_plug_req; queue_work(system_unbound_wq, &peer->work); } break; @@ -2783,7 +2717,7 @@ static int fwserial_parse_mgmt_write(struct fwtty_peer *peer, rcode = RCODE_CONFLICT_ERROR; } else if (be16_to_cpu(pkt->hdr.code) & FWSC_RSP_NACK) { - fwtty_notice(&peer->unit, "NACK plug rsp"); + fwtty_notice(&peer->unit, "NACK plug rsp\n"); port = peer_revert_state(peer); } else { @@ -2799,27 +2733,27 @@ static int fwserial_parse_mgmt_write(struct fwtty_peer *peer, case FWSC_VIRT_CABLE_UNPLUG: if (work_pending(&peer->work)) { - fwtty_err(&peer->unit, "unplug req: busy"); + fwtty_err(&peer->unit, "unplug req: busy\n"); rcode = RCODE_CONFLICT_ERROR; } else { - PREPARE_WORK(&peer->work, fwserial_handle_unplug_req); + peer->workfn = fwserial_handle_unplug_req; queue_work(system_unbound_wq, &peer->work); } break; case FWSC_VIRT_CABLE_UNPLUG_RSP: - if (peer->state != FWPS_UNPLUG_PENDING) + if (peer->state != FWPS_UNPLUG_PENDING) { rcode = RCODE_CONFLICT_ERROR; - else { + } else { if (be16_to_cpu(pkt->hdr.code) & FWSC_RSP_NACK) - fwtty_notice(&peer->unit, "NACK unplug?"); + fwtty_notice(&peer->unit, "NACK unplug?\n"); port = peer_revert_state(peer); reset = true; } break; default: - fwtty_err(&peer->unit, "unknown mgmt code %d", + fwtty_err(&peer->unit, "unknown mgmt code %d\n", be16_to_cpu(pkt->hdr.code)); rcode = RCODE_DATA_ERROR; } @@ -2853,7 +2787,7 @@ static void fwserial_mgmt_handler(struct fw_card *card, rcu_read_lock(); peer = __fwserial_peer_by_node_id(card, generation, source); if (!peer) { - fwtty_dbg(card, "peer(%d:%x) not found", generation, source); + fwtty_dbg(card, "peer(%d:%x) not found\n", generation, source); __dump_peer_list(card); rcode = RCODE_CONFLICT_ERROR; @@ -2903,7 +2837,7 @@ static int __init fwserial_init(void) err = tty_register_driver(fwtty_driver); if (err) { - driver_err("register tty driver failed (%d)", err); + pr_err("register tty driver failed (%d)\n", err); goto put_tty; } @@ -2928,7 +2862,7 @@ static int __init fwserial_init(void) err = tty_register_driver(fwloop_driver); if (err) { - driver_err("register loop driver failed (%d)", err); + pr_err("register loop driver failed (%d)\n", err); goto put_loop; } } @@ -2954,7 +2888,7 @@ static int __init fwserial_init(void) err = fw_core_add_address_handler(&fwserial_mgmt_addr_handler, &fwserial_mgmt_addr_region); if (err) { - driver_err("add management handler failed (%d)", err); + pr_err("add management handler failed (%d)\n", err); goto destroy_cache; } @@ -2962,13 +2896,13 @@ static int __init fwserial_init(void) FW_UNIT_ADDRESS(fwserial_mgmt_addr_handler.offset); err = fw_core_add_descriptor(&fwserial_unit_directory); if (err) { - driver_err("add unit descriptor failed (%d)", err); + pr_err("add unit descriptor failed (%d)\n", err); goto remove_handler; } err = driver_register(&fwserial_driver.driver); if (err) { - driver_err("register fwserial driver failed (%d)", err); + pr_err("register fwserial driver failed (%d)\n", err); goto remove_descriptor; } |
