From b0348b90a4a8149e5a0df312ab7810793ba7b3a4 Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Tue, 28 Mar 2006 17:19:50 +0200 Subject: [PATCH] smc91x: add support for LogicPD PXA270 platform This patch adds support for the smc91x on the LogicPD PXA270 to the smc91x driver. Signed-off-by: Lennert Buytenhek Signed-off-by: Jeff Garzik --- drivers/net/smc91x.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h index e1be1af51201..f72a4f57905a 100644 --- a/drivers/net/smc91x.h +++ b/drivers/net/smc91x.h @@ -129,6 +129,24 @@ #define SMC_insb(a, r, p, l) readsb((a) + (r), p, (l)) #define SMC_outsb(a, r, p, l) writesb((a) + (r), p, (l)) +#elif defined(CONFIG_MACH_LOGICPD_PXA270) + +#define SMC_CAN_USE_8BIT 0 +#define SMC_CAN_USE_16BIT 1 +#define SMC_CAN_USE_32BIT 0 +#define SMC_IO_SHIFT 0 +#define SMC_NOWAIT 1 +#define SMC_USE_PXA_DMA 1 + +#define SMC_inb(a, r) readb((a) + (r)) +#define SMC_inw(a, r) readw((a) + (r)) +#define SMC_inl(a, r) readl((a) + (r)) +#define SMC_outb(v, a, r) writeb(v, (a) + (r)) +#define SMC_outw(v, a, r) writew(v, (a) + (r)) +#define SMC_outl(v, a, r) writel(v, (a) + (r)) +#define SMC_insw(a, r, p, l) readsw((a) + (r), p, l) +#define SMC_outsw(a, r, p, l) writesw((a) + (r), p, l) + #elif defined(CONFIG_ARCH_INNOKOM) || \ defined(CONFIG_MACH_MAINSTONE) || \ defined(CONFIG_ARCH_PXA_IDP) || \ -- cgit v1.2.3 From 58a7ce64426394a46e80cdc9440cc1e7c195e85d Mon Sep 17 00:00:00 2001 From: Krzysztof Halasa Date: Thu, 30 Mar 2006 17:01:53 +0200 Subject: [PATCH] Goramo PCI200SYN WAN driver subsystem ID patch Goramo finally got PCI subsystem ID for their PCI200SYN card. The attached patch adds support for it - cards with old EEPROM data will emit a warning with URL for update tool. Signed-off-by: Krzysztof Halasa Signed-off-by: Jeff Garzik --- drivers/net/wan/pci200syn.c | 27 +++++++++++++++++---------- include/linux/pci_ids.h | 1 + 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/drivers/net/wan/pci200syn.c b/drivers/net/wan/pci200syn.c index eba8e5cfacc2..f485a97844cc 100644 --- a/drivers/net/wan/pci200syn.c +++ b/drivers/net/wan/pci200syn.c @@ -50,10 +50,6 @@ static const char* devname = "PCI200SYN"; static int pci_clock_freq = 33000000; #define CLOCK_BASE pci_clock_freq -#define PCI_VENDOR_ID_GORAMO 0x10B5 /* uses PLX:9050 ID - this card */ -#define PCI_DEVICE_ID_PCI200SYN 0x9050 /* doesn't have its own ID */ - - /* * PLX PCI9052 local configuration and shared runtime registers. * This structure can be used to access 9052 registers (memory mapped). @@ -262,7 +258,7 @@ static void pci200_pci_remove_one(struct pci_dev *pdev) int i; card_t *card = pci_get_drvdata(pdev); - for(i = 0; i < 2; i++) + for (i = 0; i < 2; i++) if (card->ports[i].card) { struct net_device *dev = port_to_dev(&card->ports[i]); unregister_hdlc_device(dev); @@ -385,6 +381,15 @@ static int __devinit pci200_pci_init_one(struct pci_dev *pdev, " %u RX packets rings\n", ramsize / 1024, ramphys, pdev->irq, card->tx_ring_buffers, card->rx_ring_buffers); + if (pdev->subsystem_device == PCI_DEVICE_ID_PLX_9050) { + printk(KERN_ERR "Detected PCI200SYN card with old " + "configuration data.\n"); + printk(KERN_ERR "See for update.\n"); + printk(KERN_ERR "The card will stop working with" + " future versions of Linux if not updated.\n"); + } + if (card->tx_ring_buffers < 1) { printk(KERN_ERR "pci200syn: RAM test failed\n"); pci200_pci_remove_one(pdev); @@ -396,7 +401,7 @@ static int __devinit pci200_pci_init_one(struct pci_dev *pdev, writew(readw(p) | 0x0040, p); /* Allocate IRQ */ - if(request_irq(pdev->irq, sca_intr, SA_SHIRQ, devname, card)) { + if (request_irq(pdev->irq, sca_intr, SA_SHIRQ, devname, card)) { printk(KERN_WARNING "pci200syn: could not allocate IRQ%d.\n", pdev->irq); pci200_pci_remove_one(pdev); @@ -406,7 +411,7 @@ static int __devinit pci200_pci_init_one(struct pci_dev *pdev, sca_init(card, 0); - for(i = 0; i < 2; i++) { + for (i = 0; i < 2; i++) { port_t *port = &card->ports[i]; struct net_device *dev = port_to_dev(port); hdlc_device *hdlc = dev_to_hdlc(dev); @@ -425,7 +430,7 @@ static int __devinit pci200_pci_init_one(struct pci_dev *pdev, hdlc->xmit = sca_xmit; port->settings.clock_type = CLOCK_EXT; port->card = card; - if(register_hdlc_device(dev)) { + if (register_hdlc_device(dev)) { printk(KERN_ERR "pci200syn: unable to register hdlc " "device\n"); port->card = NULL; @@ -445,8 +450,10 @@ static int __devinit pci200_pci_init_one(struct pci_dev *pdev, static struct pci_device_id pci200_pci_tbl[] __devinitdata = { - { PCI_VENDOR_ID_GORAMO, PCI_DEVICE_ID_PCI200SYN, PCI_ANY_ID, - PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, PCI_VENDOR_ID_PLX, + PCI_DEVICE_ID_PLX_9050, 0, 0, 0 }, + { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, PCI_VENDOR_ID_PLX, + PCI_DEVICE_ID_PLX_PCI200SYN, 0, 0, 0 }, { 0, } }; diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 870fe38378b1..6a1ef8b635c5 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -930,6 +930,7 @@ #define PCI_DEVICE_ID_PLX_DJINN_ITOO 0x1151 #define PCI_DEVICE_ID_PLX_R753 0x1152 #define PCI_DEVICE_ID_PLX_OLITEC 0x1187 +#define PCI_DEVICE_ID_PLX_PCI200SYN 0x3196 #define PCI_DEVICE_ID_PLX_9050 0x9050 #define PCI_DEVICE_ID_PLX_9080 0x9080 #define PCI_DEVICE_ID_PLX_GTEK_SERIAL2 0xa001 -- cgit v1.2.3 From d0e027db7861ef03de0ac08494a9a61984d8f8b0 Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Fri, 14 Apr 2006 19:04:40 -0700 Subject: e1000: Remove PM warning DPRINTKs breaking 2.4.x kernels remove DPRINTKs that were printing warnings about power management on 2.4 kernels. Since we really don't react differently these printk statements are not needed. This code was originally added to fix some compile time warnings that got fixed by newer kernels. Signed-off-by: Jesse Brandeburg Signed-off-by: Auke Kok Signed-off-by: John Ronciak --- drivers/net/e1000/e1000_main.c | 42 ++++++++++-------------------------------- 1 file changed, 10 insertions(+), 32 deletions(-) diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index add8dc4aa7b0..ac1e8387416b 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -4515,21 +4515,13 @@ e1000_suspend(struct pci_dev *pdev, pm_message_t state) E1000_WRITE_REG(&adapter->hw, WUC, E1000_WUC_PME_EN); E1000_WRITE_REG(&adapter->hw, WUFC, wufc); - retval = pci_enable_wake(pdev, PCI_D3hot, 1); - if (retval) - DPRINTK(PROBE, ERR, "Error enabling D3 wake\n"); - retval = pci_enable_wake(pdev, PCI_D3cold, 1); - if (retval) - DPRINTK(PROBE, ERR, "Error enabling D3 cold wake\n"); + pci_enable_wake(pdev, PCI_D3hot, 1); + pci_enable_wake(pdev, PCI_D3cold, 1); } else { E1000_WRITE_REG(&adapter->hw, WUC, 0); E1000_WRITE_REG(&adapter->hw, WUFC, 0); - retval = pci_enable_wake(pdev, PCI_D3hot, 0); - if (retval) - DPRINTK(PROBE, ERR, "Error enabling D3 wake\n"); - retval = pci_enable_wake(pdev, PCI_D3cold, 0); - if (retval) - DPRINTK(PROBE, ERR, "Error enabling D3 cold wake\n"); + pci_enable_wake(pdev, PCI_D3hot, 0); + pci_enable_wake(pdev, PCI_D3cold, 0); } if (adapter->hw.mac_type >= e1000_82540 && @@ -4538,13 +4530,8 @@ e1000_suspend(struct pci_dev *pdev, pm_message_t state) if (manc & E1000_MANC_SMBUS_EN) { manc |= E1000_MANC_ARP_EN; E1000_WRITE_REG(&adapter->hw, MANC, manc); - retval = pci_enable_wake(pdev, PCI_D3hot, 1); - if (retval) - DPRINTK(PROBE, ERR, "Error enabling D3 wake\n"); - retval = pci_enable_wake(pdev, PCI_D3cold, 1); - if (retval) - DPRINTK(PROBE, ERR, - "Error enabling D3 cold wake\n"); + pci_enable_wake(pdev, PCI_D3hot, 1); + pci_enable_wake(pdev, PCI_D3cold, 1); } } @@ -4554,9 +4541,7 @@ e1000_suspend(struct pci_dev *pdev, pm_message_t state) pci_disable_device(pdev); - retval = pci_set_power_state(pdev, pci_choose_state(pdev, state)); - if (retval) - DPRINTK(PROBE, ERR, "Error in setting power state\n"); + pci_set_power_state(pdev, pci_choose_state(pdev, state)); return 0; } @@ -4567,22 +4552,15 @@ e1000_resume(struct pci_dev *pdev) { struct net_device *netdev = pci_get_drvdata(pdev); struct e1000_adapter *adapter = netdev_priv(netdev); - int retval; uint32_t manc, ret_val; - retval = pci_set_power_state(pdev, PCI_D0); - if (retval) - DPRINTK(PROBE, ERR, "Error in setting power state\n"); + pci_set_power_state(pdev, PCI_D0); e1000_pci_restore_state(adapter); ret_val = pci_enable_device(pdev); pci_set_master(pdev); - retval = pci_enable_wake(pdev, PCI_D3hot, 0); - if (retval) - DPRINTK(PROBE, ERR, "Error enabling D3 wake\n"); - retval = pci_enable_wake(pdev, PCI_D3cold, 0); - if (retval) - DPRINTK(PROBE, ERR, "Error enabling D3 cold wake\n"); + pci_enable_wake(pdev, PCI_D3hot, 0); + pci_enable_wake(pdev, PCI_D3cold, 0); e1000_reset(adapter); E1000_WRITE_REG(&adapter->hw, WUS, ~0); -- cgit v1.2.3 From 4cc15f54991caf1572e03ffc65d9986e433007e2 Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Fri, 14 Apr 2006 19:04:46 -0700 Subject: e1000: Esb2 wol link cycle bug and uninitialized registers Esb2 link didn't return after wol disable. The code previously assumed that writing reset to PHY_CTRL phy register turned the phy back on. In the ESB2 phy case that didn't occur. Add ESB2 to acquire/release_hw functions upon review it was discovered that esb2 was skipped on these functions Signed-off-by: Jesse Brandeburg Signed-off-by: Auke Kok Signed-off-by: John Ronciak --- drivers/net/e1000/e1000_main.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index ac1e8387416b..8de9f9affae4 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -359,6 +359,7 @@ e1000_release_hw_control(struct e1000_adapter *adapter) switch (adapter->hw.mac_type) { case e1000_82571: case e1000_82572: + case e1000_80003es2lan: ctrl_ext = E1000_READ_REG(&adapter->hw, CTRL_EXT); E1000_WRITE_REG(&adapter->hw, CTRL_EXT, ctrl_ext & ~E1000_CTRL_EXT_DRV_LOAD); @@ -392,6 +393,7 @@ e1000_get_hw_control(struct e1000_adapter *adapter) switch (adapter->hw.mac_type) { case e1000_82571: case e1000_82572: + case e1000_80003es2lan: ctrl_ext = E1000_READ_REG(&adapter->hw, CTRL_EXT); E1000_WRITE_REG(&adapter->hw, CTRL_EXT, ctrl_ext | E1000_CTRL_EXT_DRV_LOAD); @@ -419,7 +421,7 @@ e1000_up(struct e1000_adapter *adapter) uint16_t mii_reg; e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &mii_reg); if (mii_reg & MII_CR_POWER_DOWN) - e1000_phy_reset(&adapter->hw); + e1000_phy_hw_reset(&adapter->hw); } e1000_set_multi(netdev); -- cgit v1.2.3 From e619d52349ab8c0044859c28ab05e4c7a410fe14 Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Fri, 14 Apr 2006 19:04:52 -0700 Subject: e1000: De-inline functions to benefit from compiler smartness De-inline functions to benefit from compiler smartness Signed-off-by: Jesse Brandeburg Signed-off-by: Auke Kok Signed-off-by: John Ronciak --- drivers/net/e1000/e1000_main.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 8de9f9affae4..5e7b4ee42ed9 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -208,8 +208,8 @@ static void e1000_leave_82542_rst(struct e1000_adapter *adapter); static void e1000_tx_timeout(struct net_device *dev); static void e1000_reset_task(struct net_device *dev); static void e1000_smartspeed(struct e1000_adapter *adapter); -static inline int e1000_82547_fifo_workaround(struct e1000_adapter *adapter, - struct sk_buff *skb); +static int e1000_82547_fifo_workaround(struct e1000_adapter *adapter, + struct sk_buff *skb); static void e1000_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp); static void e1000_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid); @@ -291,7 +291,7 @@ module_exit(e1000_exit_module); * @adapter: board private structure **/ -static inline void +static void e1000_irq_disable(struct e1000_adapter *adapter) { atomic_inc(&adapter->irq_sem); @@ -305,7 +305,7 @@ e1000_irq_disable(struct e1000_adapter *adapter) * @adapter: board private structure **/ -static inline void +static void e1000_irq_enable(struct e1000_adapter *adapter) { if (likely(atomic_dec_and_test(&adapter->irq_sem))) { @@ -349,7 +349,7 @@ e1000_update_mng_vlan(struct e1000_adapter *adapter) * **/ -static inline void +static void e1000_release_hw_control(struct e1000_adapter *adapter) { uint32_t ctrl_ext; @@ -384,7 +384,7 @@ e1000_release_hw_control(struct e1000_adapter *adapter) * **/ -static inline void +static void e1000_get_hw_control(struct e1000_adapter *adapter) { uint32_t ctrl_ext; @@ -1181,7 +1181,7 @@ e1000_close(struct net_device *netdev) * @start: address of beginning of memory * @len: length of memory **/ -static inline boolean_t +static boolean_t e1000_check_64k_bound(struct e1000_adapter *adapter, void *start, unsigned long len) { @@ -1807,7 +1807,7 @@ e1000_free_all_tx_resources(struct e1000_adapter *adapter) e1000_free_tx_resources(adapter, &adapter->tx_ring[i]); } -static inline void +static void e1000_unmap_and_free_tx_resource(struct e1000_adapter *adapter, struct e1000_buffer *buffer_info) { @@ -2400,7 +2400,7 @@ e1000_watchdog_task(struct e1000_adapter *adapter) #define E1000_TX_FLAGS_VLAN_MASK 0xffff0000 #define E1000_TX_FLAGS_VLAN_SHIFT 16 -static inline int +static int e1000_tso(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring, struct sk_buff *skb) { @@ -2480,7 +2480,7 @@ e1000_tso(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring, return FALSE; } -static inline boolean_t +static boolean_t e1000_tx_csum(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring, struct sk_buff *skb) { @@ -2516,7 +2516,7 @@ e1000_tx_csum(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring, #define E1000_MAX_TXD_PWR 12 #define E1000_MAX_DATA_PER_TXD (1<tx_fifo_size - adapter->tx_fifo_head; @@ -2716,7 +2716,7 @@ no_fifo_stall_required: } #define MINIMUM_DHCP_PACKET_SIZE 282 -static inline int +static int e1000_transfer_dhcp_info(struct e1000_adapter *adapter, struct sk_buff *skb) { struct e1000_hw *hw = &adapter->hw; @@ -3445,7 +3445,7 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter, * @sk_buff: socket buffer with received data **/ -static inline void +static void e1000_rx_checksum(struct e1000_adapter *adapter, uint32_t status_err, uint32_t csum, struct sk_buff *skb) -- cgit v1.2.3 From fe7fe28ea581e090d2908a0d78a2611ae6d43e2c Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Fri, 14 Apr 2006 19:04:59 -0700 Subject: e1000: Made an adapter struct variable into a local (txb2b) Made an adapter struct variable into a local (txb2b) Signed-off-by: Jesse Brandeburg Signed-off-by: Auke Kok Signed-off-by: John Ronciak --- drivers/net/e1000/e1000.h | 1 - drivers/net/e1000/e1000_main.c | 10 +++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h index 281de41d030a..764808f3702e 100644 --- a/drivers/net/e1000/e1000.h +++ b/drivers/net/e1000/e1000.h @@ -334,7 +334,6 @@ struct e1000_adapter { boolean_t have_msi; #endif /* to not mess up cache alignment, always add to the bottom */ - boolean_t txb2b; #ifdef NETIF_F_TSO boolean_t tso_force; #endif diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 5e7b4ee42ed9..2cc9955ba179 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -2247,6 +2247,7 @@ e1000_watchdog_task(struct e1000_adapter *adapter) if (link) { if (!netif_carrier_ok(netdev)) { + boolean_t txb2b = 1; e1000_get_speed_and_duplex(&adapter->hw, &adapter->link_speed, &adapter->link_duplex); @@ -2260,23 +2261,22 @@ e1000_watchdog_task(struct e1000_adapter *adapter) * and adjust the timeout factor */ netdev->tx_queue_len = adapter->tx_queue_len; adapter->tx_timeout_factor = 1; - adapter->txb2b = 1; switch (adapter->link_speed) { case SPEED_10: - adapter->txb2b = 0; + txb2b = 0; netdev->tx_queue_len = 10; adapter->tx_timeout_factor = 8; break; case SPEED_100: - adapter->txb2b = 0; + txb2b = 0; netdev->tx_queue_len = 100; /* maybe add some timeout factor ? */ break; } - if ((adapter->hw.mac_type == e1000_82571 || + if ((adapter->hw.mac_type == e1000_82571 || adapter->hw.mac_type == e1000_82572) && - adapter->txb2b == 0) { + txb2b == 0) { #define SPEED_MODE_BIT (1 << 21) uint32_t tarc0; tarc0 = E1000_READ_REG(&adapter->hw, TARC0); -- cgit v1.2.3 From 5d51b80f9224ca5b0ba1efc5a6348cd29b5c16b7 Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Fri, 14 Apr 2006 19:05:06 -0700 Subject: e1000: Update truesize with the length of the packet for packet split Update skb with the real packet size. Signed-off-by: Jesse Brandeburg Signed-off-by: Auke Kok Signed-off-by: John Ronciak --- drivers/net/e1000/e1000_main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 2cc9955ba179..7ba1b1668bf4 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -3770,6 +3770,7 @@ e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, ps_page->ps_page[j] = NULL; skb->len += length; skb->data_len += length; + skb->truesize += length; } copydone: -- cgit v1.2.3 From 6fc7a7eca70780dc1539ce68a6513f9b11891f3c Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Fri, 14 Apr 2006 19:05:12 -0700 Subject: e1000: Dead variable cleanup Removal of unused rx_dropped counter. Removed reference to E1000_CTRL_EXT_CANC which is no longer valid, replaced with E1000_CTRL_EXT_INT_TIMER_CLR Signed-off-by: Jesse Brandeburg Signed-off-by: Auke Kok Signed-off-by: John Ronciak --- drivers/net/e1000/e1000_main.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 7ba1b1668bf4..6d7ba0bb233a 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -1715,7 +1715,7 @@ e1000_configure_rx(struct e1000_adapter *adapter) if (hw->mac_type >= e1000_82571) { ctrl_ext = E1000_READ_REG(hw, CTRL_EXT); /* Reset delay timers after every interrupt */ - ctrl_ext |= E1000_CTRL_EXT_CANC; + ctrl_ext |= E1000_CTRL_EXT_INT_TIMER_CLR; #ifdef CONFIG_E1000_NAPI /* Auto-Mask interrupts upon ICR read. */ ctrl_ext |= E1000_CTRL_EXT_IAME; @@ -3165,7 +3165,6 @@ e1000_update_stats(struct e1000_adapter *adapter) adapter->stats.crcerrs + adapter->stats.algnerrc + adapter->stats.ruc + adapter->stats.roc + adapter->stats.cexterr; - adapter->net_stats.rx_dropped = 0; adapter->net_stats.rx_length_errors = adapter->stats.ruc + adapter->stats.roc; adapter->net_stats.rx_crc_errors = adapter->stats.crcerrs; -- cgit v1.2.3 From 9e2feace1acd38d7a3b1275f7f9f8a397d09040e Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Fri, 14 Apr 2006 19:05:18 -0700 Subject: e1000: Buffer optimizations for small MTU Remove multi-descriptor support from legacy recieve path Add memory usage efficiency by using more correct size descriptors for small MTU sizes and optimize using LPE for <= 1522 byte frame sizes An extra performance fix that effected our TCP window size growth as a receiver. Set our initial buffer to be 128 bytes instead of 256 to prevent over-socket charge when truesize is computed in the stack. old way: truesize = 256 + l1 = 256 + 1460 = 1716 new way: truesize = 128 + l1 = 128 + 1460 = 1588 The magic value that we can't cross is 1648. Signed-off-by: Jesse Brandeburg Signed-off-by: Auke Kok Signed-off-by: John Ronciak --- drivers/net/e1000/e1000.h | 2 + drivers/net/e1000/e1000_main.c | 87 ++++++++++++++++++++++++------------------ 2 files changed, 52 insertions(+), 37 deletions(-) diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h index 764808f3702e..2dfabdb29e7b 100644 --- a/drivers/net/e1000/e1000.h +++ b/drivers/net/e1000/e1000.h @@ -114,6 +114,8 @@ struct e1000_adapter; /* Supported Rx Buffer Sizes */ #define E1000_RXBUFFER_128 128 /* Used for packet split */ #define E1000_RXBUFFER_256 256 /* Used for packet split */ +#define E1000_RXBUFFER_512 512 +#define E1000_RXBUFFER_1024 1024 #define E1000_RXBUFFER_2048 2048 #define E1000_RXBUFFER_4096 4096 #define E1000_RXBUFFER_8192 8192 diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 6d7ba0bb233a..f604a1dea399 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -972,8 +972,8 @@ e1000_sw_init(struct e1000_adapter *adapter) pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word); - adapter->rx_buffer_len = E1000_RXBUFFER_2048; - adapter->rx_ps_bsize0 = E1000_RXBUFFER_256; + adapter->rx_buffer_len = MAXIMUM_ETHERNET_FRAME_SIZE; + adapter->rx_ps_bsize0 = E1000_RXBUFFER_128; hw->max_frame_size = netdev->mtu + ENET_HEADER_SIZE + ETHERNET_FCS_SIZE; hw->min_frame_size = MINIMUM_ETHERNET_FRAME_SIZE; @@ -1599,14 +1599,21 @@ e1000_setup_rctl(struct e1000_adapter *adapter) rctl |= E1000_RCTL_LPE; /* Setup buffer sizes */ - if (adapter->hw.mac_type >= e1000_82571) { - /* We can now specify buffers in 1K increments. - * BSIZE and BSEX are ignored in this case. */ - rctl |= adapter->rx_buffer_len << 0x11; - } else { - rctl &= ~E1000_RCTL_SZ_4096; - rctl |= E1000_RCTL_BSEX; - switch (adapter->rx_buffer_len) { + rctl &= ~E1000_RCTL_SZ_4096; + rctl |= E1000_RCTL_BSEX; + switch (adapter->rx_buffer_len) { + case E1000_RXBUFFER_256: + rctl |= E1000_RCTL_SZ_256; + rctl &= ~E1000_RCTL_BSEX; + break; + case E1000_RXBUFFER_512: + rctl |= E1000_RCTL_SZ_512; + rctl &= ~E1000_RCTL_BSEX; + break; + case E1000_RXBUFFER_1024: + rctl |= E1000_RCTL_SZ_1024; + rctl &= ~E1000_RCTL_BSEX; + break; case E1000_RXBUFFER_2048: default: rctl |= E1000_RCTL_SZ_2048; @@ -1621,7 +1628,6 @@ e1000_setup_rctl(struct e1000_adapter *adapter) case E1000_RXBUFFER_16384: rctl |= E1000_RCTL_SZ_16384; break; - } } #ifndef CONFIG_E1000_DISABLE_PACKET_SPLIT @@ -2982,8 +2988,7 @@ e1000_change_mtu(struct net_device *netdev, int new_mtu) /* Adapter-specific max frame size limits. */ switch (adapter->hw.mac_type) { - case e1000_82542_rev2_0: - case e1000_82542_rev2_1: + case e1000_undefined ... e1000_82542_rev2_1: if (max_frame > MAXIMUM_ETHERNET_FRAME_SIZE) { DPRINTK(PROBE, ERR, "Jumbo Frames not supported.\n"); return -EINVAL; @@ -3017,27 +3022,32 @@ e1000_change_mtu(struct net_device *netdev, int new_mtu) break; } - - if (adapter->hw.mac_type > e1000_82547_rev_2) { - adapter->rx_buffer_len = max_frame; - E1000_ROUNDUP(adapter->rx_buffer_len, 1024); - } else { - if(unlikely((adapter->hw.mac_type < e1000_82543) && - (max_frame > MAXIMUM_ETHERNET_FRAME_SIZE))) { - DPRINTK(PROBE, ERR, "Jumbo Frames not supported " - "on 82542\n"); - return -EINVAL; - } else { - if(max_frame <= E1000_RXBUFFER_2048) - adapter->rx_buffer_len = E1000_RXBUFFER_2048; - else if(max_frame <= E1000_RXBUFFER_4096) - adapter->rx_buffer_len = E1000_RXBUFFER_4096; - else if(max_frame <= E1000_RXBUFFER_8192) - adapter->rx_buffer_len = E1000_RXBUFFER_8192; - else if(max_frame <= E1000_RXBUFFER_16384) - adapter->rx_buffer_len = E1000_RXBUFFER_16384; - } - } + /* NOTE: dev_alloc_skb reserves 16 bytes, and typically NET_IP_ALIGN + * means we reserve 2 more, this pushes us to allocate from the next + * larger slab size + * i.e. RXBUFFER_2048 --> size-4096 slab */ + + if (max_frame <= E1000_RXBUFFER_256) + adapter->rx_buffer_len = E1000_RXBUFFER_256; + else if (max_frame <= E1000_RXBUFFER_512) + adapter->rx_buffer_len = E1000_RXBUFFER_512; + else if (max_frame <= E1000_RXBUFFER_1024) + adapter->rx_buffer_len = E1000_RXBUFFER_1024; + else if (max_frame <= E1000_RXBUFFER_2048) + adapter->rx_buffer_len = E1000_RXBUFFER_2048; + else if (max_frame <= E1000_RXBUFFER_4096) + adapter->rx_buffer_len = E1000_RXBUFFER_4096; + else if (max_frame <= E1000_RXBUFFER_8192) + adapter->rx_buffer_len = E1000_RXBUFFER_8192; + else if (max_frame <= E1000_RXBUFFER_16384) + adapter->rx_buffer_len = E1000_RXBUFFER_16384; + + /* adjust allocation if LPE protects us, and we aren't using SBP */ +#define MAXIMUM_ETHERNET_VLAN_SIZE 1522 + if (!adapter->hw.tbi_compatibility_on && + ((max_frame == MAXIMUM_ETHERNET_FRAME_SIZE) || + (max_frame == MAXIMUM_ETHERNET_VLAN_SIZE))) + adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE; netdev->mtu = new_mtu; @@ -3568,10 +3578,12 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter, flags); length--; } else { - dev_kfree_skb_irq(skb); + /* recycle */ + buffer_info->skb = skb; goto next_desc; } - } + } else + skb_put(skb, length); /* code added for copybreak, this should improve * performance for small packets with large amounts @@ -3676,6 +3688,7 @@ e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, i = rx_ring->next_to_clean; rx_desc = E1000_RX_DESC_PS(*rx_ring, i); staterr = le32_to_cpu(rx_desc->wb.middle.status_error); + buffer_info = &rx_ring->buffer_info[i]; while (staterr & E1000_RXD_STAT_DD) { buffer_info = &rx_ring->buffer_info[i]; @@ -3736,7 +3749,7 @@ e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, /* page alloc/put takes too long and effects small packet * throughput, so unsplit small packets and save the alloc/put*/ - if (l1 && ((length + l1) < E1000_CB_LENGTH)) { + if (l1 && ((length + l1) <= adapter->rx_ps_bsize0)) { u8 *vaddr; /* there is no documentation about how to call * kmap_atomic, so we can't hold the mapping -- cgit v1.2.3 From 77b2aad5b4fcb6e050b64bbda158ce528f933023 Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Fri, 14 Apr 2006 19:05:25 -0700 Subject: e1000: implement more efficient tx queue locking Implement more efficient locking (avoid the lock) when checking for a stopped queue. Also don't wake the queue unless the threshold is reached to avoid queue on/off thrash. Signed-off-by: Jesse Brandeburg Signed-off-by: Auke Kok Signed-off-by: John Ronciak --- drivers/net/e1000/e1000_main.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index f604a1dea399..3c37c40339fb 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -3400,13 +3400,15 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter, tx_ring->next_to_clean = i; - spin_lock(&tx_ring->tx_lock); - +#define TX_WAKE_THRESHOLD 32 if (unlikely(cleaned && netif_queue_stopped(netdev) && - netif_carrier_ok(netdev))) - netif_wake_queue(netdev); - - spin_unlock(&tx_ring->tx_lock); + netif_carrier_ok(netdev))) { + spin_lock(&tx_ring->tx_lock); + if (netif_queue_stopped(netdev) && + (E1000_DESC_UNUSED(tx_ring) >= TX_WAKE_THRESHOLD)) + netif_wake_queue(netdev); + spin_unlock(&tx_ring->tx_lock); + } if (adapter->detect_tx_hung) { /* Detect a transmit hang in hardware, this serializes the -- cgit v1.2.3 From 3d41e30aa3dde76c81ecbbf0e3a25392fcd90469 Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Fri, 14 Apr 2006 19:05:31 -0700 Subject: e1000: Version bump, contact fix, year string change Add the sourceforge project mailinglist to the contact information. Bump version to 7.0.38-k2 Update copyright string with the new year. Signed-off-by: Auke Kok Signed-off-by: John Ronciak --- drivers/net/e1000/Makefile | 1 + drivers/net/e1000/e1000.h | 3 ++- drivers/net/e1000/e1000_ethtool.c | 3 ++- drivers/net/e1000/e1000_hw.c | 3 ++- drivers/net/e1000/e1000_hw.h | 3 ++- drivers/net/e1000/e1000_main.c | 7 ++++--- drivers/net/e1000/e1000_osdep.h | 3 ++- drivers/net/e1000/e1000_param.c | 3 ++- 8 files changed, 17 insertions(+), 9 deletions(-) diff --git a/drivers/net/e1000/Makefile b/drivers/net/e1000/Makefile index ca9f89552da3..92823ac89d42 100644 --- a/drivers/net/e1000/Makefile +++ b/drivers/net/e1000/Makefile @@ -22,6 +22,7 @@ # # Contact Information: # Linux NICS +# e1000-devel Mailing List # Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 # ################################################################################ diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h index 2dfabdb29e7b..2bc34fbfa69c 100644 --- a/drivers/net/e1000/e1000.h +++ b/drivers/net/e1000/e1000.h @@ -1,7 +1,7 @@ /******************************************************************************* - Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. + Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free @@ -22,6 +22,7 @@ Contact Information: Linux NICS + e1000-devel Mailing List Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 *******************************************************************************/ diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c index ecccca35c6f4..e48dc578fde2 100644 --- a/drivers/net/e1000/e1000_ethtool.c +++ b/drivers/net/e1000/e1000_ethtool.c @@ -1,7 +1,7 @@ /******************************************************************************* - Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. + Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free @@ -22,6 +22,7 @@ Contact Information: Linux NICS + e1000-devel Mailing List Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 *******************************************************************************/ diff --git a/drivers/net/e1000/e1000_hw.c b/drivers/net/e1000/e1000_hw.c index 523c2c9fc0ac..4c796e54b840 100644 --- a/drivers/net/e1000/e1000_hw.c +++ b/drivers/net/e1000/e1000_hw.c @@ -1,7 +1,7 @@ /******************************************************************************* - Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. + Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free @@ -22,6 +22,7 @@ Contact Information: Linux NICS + e1000-devel Mailing List Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 *******************************************************************************/ diff --git a/drivers/net/e1000/e1000_hw.h b/drivers/net/e1000/e1000_hw.h index 150e45e30f87..03d07ebde4f7 100644 --- a/drivers/net/e1000/e1000_hw.h +++ b/drivers/net/e1000/e1000_hw.h @@ -1,7 +1,7 @@ /******************************************************************************* - Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. + Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free @@ -22,6 +22,7 @@ Contact Information: Linux NICS + e1000-devel Mailing List Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 *******************************************************************************/ diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 3c37c40339fb..82d443ba3612 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -1,7 +1,7 @@ /******************************************************************************* - Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. + Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free @@ -22,6 +22,7 @@ Contact Information: Linux NICS + e1000-devel Mailing List Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 *******************************************************************************/ @@ -74,9 +75,9 @@ static char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver"; #else #define DRIVERNAPI "-NAPI" #endif -#define DRV_VERSION "7.0.33-k2"DRIVERNAPI +#define DRV_VERSION "7.0.38-k2"DRIVERNAPI char e1000_driver_version[] = DRV_VERSION; -static char e1000_copyright[] = "Copyright (c) 1999-2005 Intel Corporation."; +static char e1000_copyright[] = "Copyright (c) 1999-2006 Intel Corporation."; /* e1000_pci_tbl - PCI Device ID Table * diff --git a/drivers/net/e1000/e1000_osdep.h b/drivers/net/e1000/e1000_osdep.h index 9790db974dc1..048d052be29d 100644 --- a/drivers/net/e1000/e1000_osdep.h +++ b/drivers/net/e1000/e1000_osdep.h @@ -1,7 +1,7 @@ /******************************************************************************* - Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. + Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free @@ -22,6 +22,7 @@ Contact Information: Linux NICS + e1000-devel Mailing List Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 *******************************************************************************/ diff --git a/drivers/net/e1000/e1000_param.c b/drivers/net/e1000/e1000_param.c index e0a4d37d1b85..e55f8969a0fb 100644 --- a/drivers/net/e1000/e1000_param.c +++ b/drivers/net/e1000/e1000_param.c @@ -1,7 +1,7 @@ /******************************************************************************* - Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. + Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free @@ -22,6 +22,7 @@ Contact Information: Linux NICS + e1000-devel Mailing List Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 *******************************************************************************/ -- cgit v1.2.3 From 99a1f9e88694b406b7c334153bacb56adfcf8388 Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Fri, 14 Apr 2006 19:05:38 -0700 Subject: {e100{,0},ixgb}: Add Auke Kok as new patch maintainer for e{100,1000} and ixgb This adds Auke Kok to the list of maintainers for the Intel NICs. Signed-off-by: Auke Kok Signed-off-by: John Ronciak --- MAINTAINERS | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index d00dea52123f..64242673c9b0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1395,6 +1395,8 @@ P: Jesse Brandeburg M: jesse.brandeburg@intel.com P: Jeff Kirsher M: jeffrey.t.kirsher@intel.com +P: Auke Kok +M: auke-jan.h.kok@intel.com W: http://sourceforge.net/projects/e1000/ S: Supported @@ -1407,6 +1409,8 @@ P: Jesse Brandeburg M: jesse.brandeburg@intel.com P: Jeff Kirsher M: jeffrey.t.kirsher@intel.com +P: Auke Kok +M: auke-jan.h.kok@intel.com W: http://sourceforge.net/projects/e1000/ S: Supported @@ -1419,6 +1423,8 @@ P: John Ronciak M: john.ronciak@intel.com P: Jesse Brandeburg M: jesse.brandeburg@intel.com +P: Auke Kok +M: auke-jan.h.kok@intel.com W: http://sourceforge.net/projects/e1000/ S: Supported -- cgit v1.2.3 From dc86d32ab51c4ad3086472457fb90b61249d91f5 Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Tue, 18 Apr 2006 12:30:51 -0700 Subject: e1000: fix mispatch for media type detect. Recent patch was mismerged in the miitool path. e1000_media_type_copper was being compared with the phy type instead of the media type. Signed-off-by: Jesse Brandeburg Signed-off-by: Auke Kok --- drivers/net/e1000/e1000_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 82d443ba3612..2b8bced0cf64 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -4174,7 +4174,7 @@ e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) spin_unlock_irqrestore(&adapter->stats_lock, flags); return -EIO; } - if (adapter->hw.phy_type == e1000_media_type_copper) { + if (adapter->hw.media_type == e1000_media_type_copper) { switch (data->reg_num) { case PHY_CTRL: if (mii_reg & MII_CR_POWER_DOWN) -- cgit v1.2.3 From 1cb5821f444cadbe94453282f9f4767cf8744a8e Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Tue, 18 Apr 2006 12:31:04 -0700 Subject: e1000: fix mismerge skb_put. Seems there was a bit of a fix needed to due a bad merge in the legacy receive path. Fixes a panic due to skb_over_panic. Signed-off-by: Jesse Brandeburg Signed-off-by: Auke Kok --- drivers/net/e1000/e1000_main.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 2b8bced0cf64..fb8cef619142 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -3585,8 +3585,7 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter, buffer_info->skb = skb; goto next_desc; } - } else - skb_put(skb, length); + } /* code added for copybreak, this should improve * performance for small packets with large amounts -- cgit v1.2.3 From 56347a2e7287377c35c2bac2e8643bf88690425f Mon Sep 17 00:00:00 2001 From: Frank Pavlic Date: Thu, 13 Apr 2006 20:19:12 +0200 Subject: [PATCH] s390: remove tty support from ctc network device driver [1/2] Hi jeff, after the first shot I sent to you did not apply I resend two new patches I've made today to remove tty from ctc network driver. Please apply .... Thank you ... Frank From: Peter Tiedemann [1/2]: tty support code will be removed from the ctc network device driver. Today we have a couple of alternatives which are performing much better. The second thing is that ctc should be a network device driver only. We should not mix tty and networking here. This first patch will remove the tty code from ctcmain.c . It also removes the build entry from the Makefile as well as TTY definitions from ctcmain.h. The second patch will remove two files, ctctty.c and ctctty.h. Signed-off-by: Frank Pavlic Signed-off-by: Jeff Garzik --- drivers/s390/net/Makefile | 3 ++- drivers/s390/net/ctcmain.c | 45 +++++++++------------------------------------ drivers/s390/net/ctcmain.h | 12 +++++------- 3 files changed, 16 insertions(+), 44 deletions(-) diff --git a/drivers/s390/net/Makefile b/drivers/s390/net/Makefile index 90d4d0ef3dd4..6775a837d646 100644 --- a/drivers/s390/net/Makefile +++ b/drivers/s390/net/Makefile @@ -2,7 +2,7 @@ # S/390 network devices # -ctc-objs := ctcmain.o ctctty.o ctcdbug.o +ctc-objs := ctcmain.o ctcdbug.o obj-$(CONFIG_IUCV) += iucv.o obj-$(CONFIG_NETIUCV) += netiucv.o fsm.o @@ -10,6 +10,7 @@ obj-$(CONFIG_SMSGIUCV) += smsgiucv.o obj-$(CONFIG_CTC) += ctc.o fsm.o cu3088.o obj-$(CONFIG_LCS) += lcs.o cu3088.o obj-$(CONFIG_CLAW) += claw.o cu3088.o +obj-$(CONFIG_MPC) += ctcmpc.o fsm.o cu3088.o qeth-y := qeth_main.o qeth_mpc.o qeth_sys.o qeth_eddp.o qeth-$(CONFIG_PROC_FS) += qeth_proc.o obj-$(CONFIG_QETH) += qeth.o diff --git a/drivers/s390/net/ctcmain.c b/drivers/s390/net/ctcmain.c index af9f212314b3..e2ccaf55961c 100644 --- a/drivers/s390/net/ctcmain.c +++ b/drivers/s390/net/ctcmain.c @@ -6,7 +6,7 @@ * Fixes by : Jochen Röhrig (roehrig@de.ibm.com) * Arnaldo Carvalho de Melo Peter Tiedemann (ptiedem@de.ibm.com) - * Driver Model stuff by : Cornelia Huck + * Driver Model stuff by : Cornelia Huck * * Documentation used: * - Principles of Operation (IBM doc#: SA22-7201-06) @@ -65,7 +65,6 @@ #include -#include "ctctty.h" #include "fsm.h" #include "cu3088.h" @@ -479,10 +478,7 @@ ctc_unpack_skb(struct channel *ch, struct sk_buff *pskb) skb->dev = pskb->dev; skb->protocol = pskb->protocol; pskb->ip_summed = CHECKSUM_UNNECESSARY; - if (ch->protocol == CTC_PROTO_LINUX_TTY) - ctc_tty_netif_rx(skb); - else - netif_rx_ni(skb); + netif_rx_ni(skb); /** * Successful rx; reset logflags */ @@ -557,8 +553,7 @@ ccw_unit_check(struct channel *ch, unsigned char sense) DBF_TEXT(trace, 5, __FUNCTION__); if (sense & SNS0_INTERVENTION_REQ) { if (sense & 0x01) { - if (ch->protocol != CTC_PROTO_LINUX_TTY) - ctc_pr_debug("%s: Interface disc. or Sel. reset " + ctc_pr_debug("%s: Interface disc. or Sel. reset " "(remote)\n", ch->id); fsm_event(ch->fsm, CH_EVENT_UC_RCRESET, ch); } else { @@ -2034,7 +2029,6 @@ static void dev_action_chup(fsm_instance * fi, int event, void *arg) { struct net_device *dev = (struct net_device *) arg; - struct ctc_priv *privptr = dev->priv; DBF_TEXT(trace, 3, __FUNCTION__); switch (fsm_getstate(fi)) { @@ -2049,8 +2043,6 @@ dev_action_chup(fsm_instance * fi, int event, void *arg) fsm_newstate(fi, DEV_STATE_RUNNING); ctc_pr_info("%s: connected with remote side\n", dev->name); - if (privptr->protocol == CTC_PROTO_LINUX_TTY) - ctc_tty_setcarrier(dev, 1); ctc_clear_busy(dev); } break; @@ -2059,8 +2051,6 @@ dev_action_chup(fsm_instance * fi, int event, void *arg) fsm_newstate(fi, DEV_STATE_RUNNING); ctc_pr_info("%s: connected with remote side\n", dev->name); - if (privptr->protocol == CTC_PROTO_LINUX_TTY) - ctc_tty_setcarrier(dev, 1); ctc_clear_busy(dev); } break; @@ -2086,14 +2076,10 @@ dev_action_chup(fsm_instance * fi, int event, void *arg) static void dev_action_chdown(fsm_instance * fi, int event, void *arg) { - struct net_device *dev = (struct net_device *) arg; - struct ctc_priv *privptr = dev->priv; DBF_TEXT(trace, 3, __FUNCTION__); switch (fsm_getstate(fi)) { case DEV_STATE_RUNNING: - if (privptr->protocol == CTC_PROTO_LINUX_TTY) - ctc_tty_setcarrier(dev, 0); if (event == DEV_EVENT_TXDOWN) fsm_newstate(fi, DEV_STATE_STARTWAIT_TX); else @@ -2397,8 +2383,6 @@ ctc_tx(struct sk_buff *skb, struct net_device * dev) */ if (fsm_getstate(privptr->fsm) != DEV_STATE_RUNNING) { fsm_event(privptr->fsm, DEV_EVENT_START, dev); - if (privptr->protocol == CTC_PROTO_LINUX_TTY) - return -EBUSY; dev_kfree_skb(skb); privptr->stats.tx_dropped++; privptr->stats.tx_errors++; @@ -2608,20 +2592,13 @@ ctc_netdev_unregister(struct net_device * dev) if (!dev) return; privptr = (struct ctc_priv *) dev->priv; - if (privptr->protocol != CTC_PROTO_LINUX_TTY) - unregister_netdev(dev); - else - ctc_tty_unregister_netdev(dev); + unregister_netdev(dev); } static int ctc_netdev_register(struct net_device * dev) { - struct ctc_priv *privptr = (struct ctc_priv *) dev->priv; - if (privptr->protocol != CTC_PROTO_LINUX_TTY) - return register_netdev(dev); - else - return ctc_tty_register_netdev(dev); + return register_netdev(dev); } static void @@ -2667,7 +2644,9 @@ ctc_proto_store(struct device *dev, struct device_attribute *attr, const char *b if (!priv) return -ENODEV; sscanf(buf, "%u", &value); - if ((value < 0) || (value > CTC_PROTO_MAX)) + if (!((value == CTC_PROTO_S390) || + (value == CTC_PROTO_LINUX) || + (value == CTC_PROTO_OS390))) return -EINVAL; priv->protocol = value; @@ -2897,10 +2876,7 @@ ctc_new_device(struct ccwgroup_device *cgdev) goto out; } - if (privptr->protocol == CTC_PROTO_LINUX_TTY) - strlcpy(dev->name, "ctctty%d", IFNAMSIZ); - else - strlcpy(dev->name, "ctc%d", IFNAMSIZ); + strlcpy(dev->name, "ctc%d", IFNAMSIZ); for (direction = READ; direction <= WRITE; direction++) { privptr->channel[direction] = @@ -3046,7 +3022,6 @@ ctc_exit(void) { DBF_TEXT(setup, 3, __FUNCTION__); unregister_cu3088_discipline(&ctc_group_driver); - ctc_tty_cleanup(); ctc_unregister_dbf_views(); ctc_pr_info("CTC driver unloaded\n"); } @@ -3073,10 +3048,8 @@ ctc_init(void) ctc_pr_crit("ctc_init failed with ctc_register_dbf_views rc = %d\n", ret); return ret; } - ctc_tty_init(); ret = register_cu3088_discipline(&ctc_group_driver); if (ret) { - ctc_tty_cleanup(); ctc_unregister_dbf_views(); } return ret; diff --git a/drivers/s390/net/ctcmain.h b/drivers/s390/net/ctcmain.h index d2e835c0c134..7f305d119f3d 100644 --- a/drivers/s390/net/ctcmain.h +++ b/drivers/s390/net/ctcmain.h @@ -35,7 +35,9 @@ #include #include -#include "ctctty.h" +#include +#include + #include "fsm.h" #include "cu3088.h" @@ -50,9 +52,7 @@ #define CTC_PROTO_S390 0 #define CTC_PROTO_LINUX 1 -#define CTC_PROTO_LINUX_TTY 2 #define CTC_PROTO_OS390 3 -#define CTC_PROTO_MAX 3 #define CTC_BUFSIZE_LIMIT 65535 #define CTC_BUFSIZE_DEFAULT 32768 @@ -257,15 +257,13 @@ static __inline__ void ctc_clear_busy(struct net_device * dev) { clear_bit(0, &(((struct ctc_priv *) dev->priv)->tbusy)); - if (((struct ctc_priv *)dev->priv)->protocol != CTC_PROTO_LINUX_TTY) - netif_wake_queue(dev); + netif_wake_queue(dev); } static __inline__ int ctc_test_and_set_busy(struct net_device * dev) { - if (((struct ctc_priv *)dev->priv)->protocol != CTC_PROTO_LINUX_TTY) - netif_stop_queue(dev); + netif_stop_queue(dev); return test_and_set_bit(0, &((struct ctc_priv *) dev->priv)->tbusy); } -- cgit v1.2.3 From 5ad05b990062c1b7a797f0ca293f6bdde62a50d9 Mon Sep 17 00:00:00 2001 From: Frank Pavlic Date: Thu, 13 Apr 2006 20:19:23 +0200 Subject: [PATCH] s390: remove tty support from ctc network device driver [2/2] Hi, here comes the second of the two patches ... Frank From: Peter Tiedemann [2/2]: remove ctctty.c and ctctty.h files . Signed-off-by: Frank Pavlic Signed-off-by: Jeff Garzik --- drivers/s390/net/ctctty.c | 1259 --------------------------------------------- drivers/s390/net/ctctty.h | 35 -- 2 files changed, 1294 deletions(-) delete mode 100644 drivers/s390/net/ctctty.c delete mode 100644 drivers/s390/net/ctctty.h diff --git a/drivers/s390/net/ctctty.c b/drivers/s390/net/ctctty.c deleted file mode 100644 index 5cdcdbf92962..000000000000 --- a/drivers/s390/net/ctctty.c +++ /dev/null @@ -1,1259 +0,0 @@ -/* - * CTC / ESCON network driver, tty interface. - * - * Copyright (C) 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation - * Author(s): Fritz Elfert (elfert@de.ibm.com, felfert@millenux.com) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * 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., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "ctctty.h" -#include "ctcdbug.h" - -#define CTC_TTY_MAJOR 43 -#define CTC_TTY_MAX_DEVICES 64 - -#define CTC_ASYNC_MAGIC 0x49344C01 /* for paranoia-checking */ -#define CTC_ASYNC_INITIALIZED 0x80000000 /* port was initialized */ -#define CTC_ASYNC_NORMAL_ACTIVE 0x20000000 /* Normal device active */ -#define CTC_ASYNC_CLOSING 0x08000000 /* Serial port is closing */ -#define CTC_ASYNC_CTS_FLOW 0x04000000 /* Do CTS flow control */ -#define CTC_ASYNC_CHECK_CD 0x02000000 /* i.e., CLOCAL */ -#define CTC_ASYNC_HUP_NOTIFY 0x0001 /* Notify tty on hangups/closes */ -#define CTC_ASYNC_NETDEV_OPEN 0x0002 /* Underlying netdev is open */ -#define CTC_ASYNC_TX_LINESTAT 0x0004 /* Must send line status */ -#define CTC_ASYNC_SPLIT_TERMIOS 0x0008 /* Sep. termios for dialin/out */ -#define CTC_TTY_XMIT_SIZE 1024 /* Default bufsize for write */ -#define CTC_SERIAL_XMIT_MAX 4000 /* Maximum bufsize for write */ - -/* Private data (similar to async_struct in ) */ -typedef struct { - int magic; - int flags; /* defined in tty.h */ - int mcr; /* Modem control register */ - int msr; /* Modem status register */ - int lsr; /* Line status register */ - int line; - int count; /* # of fd on device */ - int blocked_open; /* # of blocked opens */ - struct net_device *netdev; - struct sk_buff_head tx_queue; /* transmit queue */ - struct sk_buff_head rx_queue; /* receive queue */ - struct tty_struct *tty; /* Pointer to corresponding tty */ - wait_queue_head_t open_wait; - wait_queue_head_t close_wait; - struct semaphore write_sem; - struct tasklet_struct tasklet; - struct timer_list stoptimer; -} ctc_tty_info; - -/* Description of one CTC-tty */ -typedef struct { - struct tty_driver *ctc_tty_device; /* tty-device */ - ctc_tty_info info[CTC_TTY_MAX_DEVICES]; /* Private data */ -} ctc_tty_driver; - -static ctc_tty_driver *driver; - -/* Leave this unchanged unless you know what you do! */ -#define MODEM_PARANOIA_CHECK -#define MODEM_DO_RESTART - -#define CTC_TTY_NAME "ctctty" - -static __u32 ctc_tty_magic = CTC_ASYNC_MAGIC; -static int ctc_tty_shuttingdown = 0; - -static spinlock_t ctc_tty_lock; - -/* ctc_tty_try_read() is called from within ctc_tty_rcv_skb() - * to stuff incoming data directly into a tty's flip-buffer. If the - * flip buffer is full, the packet gets queued up. - * - * Return: - * 1 = Success - * 0 = Failure, data has to be buffered and later processed by - * ctc_tty_readmodem(). - */ -static int -ctc_tty_try_read(ctc_tty_info * info, struct sk_buff *skb) -{ - int len; - struct tty_struct *tty; - - DBF_TEXT(trace, 5, __FUNCTION__); - if ((tty = info->tty)) { - if (info->mcr & UART_MCR_RTS) { - len = skb->len; - tty_insert_flip_string(tty, skb->data, len); - tty_flip_buffer_push(tty); - kfree_skb(skb); - return 1; - } - } - return 0; -} - -/* ctc_tty_readmodem() is called periodically from within timer-interrupt. - * It tries getting received data from the receive queue an stuff it into - * the tty's flip-buffer. - */ -static int -ctc_tty_readmodem(ctc_tty_info *info) -{ - int ret = 1; - struct tty_struct *tty; - - DBF_TEXT(trace, 5, __FUNCTION__); - if ((tty = info->tty)) { - if (info->mcr & UART_MCR_RTS) { - struct sk_buff *skb; - - if ((skb = skb_dequeue(&info->rx_queue))) { - int len = skb->len; - tty_insert_flip_string(tty, skb->data, len); - skb_pull(skb, len); - tty_flip_buffer_push(tty); - if (skb->len > 0) - skb_queue_head(&info->rx_queue, skb); - else { - kfree_skb(skb); - ret = !skb_queue_empty(&info->rx_queue); - } - } - } - } - return ret; -} - -void -ctc_tty_setcarrier(struct net_device *netdev, int on) -{ - int i; - - DBF_TEXT(trace, 4, __FUNCTION__); - if ((!driver) || ctc_tty_shuttingdown) - return; - for (i = 0; i < CTC_TTY_MAX_DEVICES; i++) - if (driver->info[i].netdev == netdev) { - ctc_tty_info *info = &driver->info[i]; - if (on) - info->msr |= UART_MSR_DCD; - else - info->msr &= ~UART_MSR_DCD; - if ((info->flags & CTC_ASYNC_CHECK_CD) && (!on)) - tty_hangup(info->tty); - } -} - -void -ctc_tty_netif_rx(struct sk_buff *skb) -{ - int i; - ctc_tty_info *info = NULL; - - DBF_TEXT(trace, 5, __FUNCTION__); - if (!skb) - return; - if ((!skb->dev) || (!driver) || ctc_tty_shuttingdown) { - dev_kfree_skb(skb); - return; - } - for (i = 0; i < CTC_TTY_MAX_DEVICES; i++) - if (driver->info[i].netdev == skb->dev) { - info = &driver->info[i]; - break; - } - if (!info) { - dev_kfree_skb(skb); - return; - } - if (skb->len < 6) { - dev_kfree_skb(skb); - return; - } - if (memcmp(skb->data, &ctc_tty_magic, sizeof(__u32))) { - dev_kfree_skb(skb); - return; - } - skb_pull(skb, sizeof(__u32)); - - i = *((int *)skb->data); - skb_pull(skb, sizeof(info->mcr)); - if (i & UART_MCR_RTS) { - info->msr |= UART_MSR_CTS; - if (info->flags & CTC_ASYNC_CTS_FLOW) - info->tty->hw_stopped = 0; - } else { - info->msr &= ~UART_MSR_CTS; - if (info->flags & CTC_ASYNC_CTS_FLOW) - info->tty->hw_stopped = 1; - } - if (i & UART_MCR_DTR) - info->msr |= UART_MSR_DSR; - else - info->msr &= ~UART_MSR_DSR; - if (skb->len <= 0) { - kfree_skb(skb); - return; - } - /* Try to deliver directly via tty-flip-buf if queue is empty */ - if (skb_queue_empty(&info->rx_queue)) - if (ctc_tty_try_read(info, skb)) - return; - /* Direct deliver failed or queue wasn't empty. - * Queue up for later dequeueing via timer-irq. - */ - skb_queue_tail(&info->rx_queue, skb); - /* Schedule dequeuing */ - tasklet_schedule(&info->tasklet); -} - -static int -ctc_tty_tint(ctc_tty_info * info) -{ - struct sk_buff *skb = skb_dequeue(&info->tx_queue); - int stopped = (info->tty->hw_stopped || info->tty->stopped); - int wake = 1; - int rc; - - DBF_TEXT(trace, 4, __FUNCTION__); - if (!info->netdev) { - if (skb) - kfree_skb(skb); - return 0; - } - if (info->flags & CTC_ASYNC_TX_LINESTAT) { - int skb_res = info->netdev->hard_header_len + - sizeof(info->mcr) + sizeof(__u32); - /* If we must update line status, - * create an empty dummy skb and insert it. - */ - if (skb) - skb_queue_head(&info->tx_queue, skb); - - skb = dev_alloc_skb(skb_res); - if (!skb) { - printk(KERN_WARNING - "ctc_tty: Out of memory in %s%d tint\n", - CTC_TTY_NAME, info->line); - return 1; - } - skb_reserve(skb, skb_res); - stopped = 0; - wake = 0; - } - if (!skb) - return 0; - if (stopped) { - skb_queue_head(&info->tx_queue, skb); - return 1; - } -#if 0 - if (skb->len > 0) - printk(KERN_DEBUG "tint: %d %02x\n", skb->len, *(skb->data)); - else - printk(KERN_DEBUG "tint: %d STAT\n", skb->len); -#endif - memcpy(skb_push(skb, sizeof(info->mcr)), &info->mcr, sizeof(info->mcr)); - memcpy(skb_push(skb, sizeof(__u32)), &ctc_tty_magic, sizeof(__u32)); - rc = info->netdev->hard_start_xmit(skb, info->netdev); - if (rc) { - skb_pull(skb, sizeof(info->mcr) + sizeof(__u32)); - if (skb->len > 0) - skb_queue_head(&info->tx_queue, skb); - else - kfree_skb(skb); - } else { - struct tty_struct *tty = info->tty; - - info->flags &= ~CTC_ASYNC_TX_LINESTAT; - if (tty) { - tty_wakeup(tty); - } - } - return (skb_queue_empty(&info->tx_queue) ? 0 : 1); -} - -/************************************************************ - * - * Modem-functions - * - * mostly "stolen" from original Linux-serial.c and friends. - * - ************************************************************/ - -static inline int -ctc_tty_paranoia_check(ctc_tty_info * info, char *name, const char *routine) -{ -#ifdef MODEM_PARANOIA_CHECK - if (!info) { - printk(KERN_WARNING "ctc_tty: null info_struct for %s in %s\n", - name, routine); - return 1; - } - if (info->magic != CTC_ASYNC_MAGIC) { - printk(KERN_WARNING "ctc_tty: bad magic for info struct %s in %s\n", - name, routine); - return 1; - } -#endif - return 0; -} - -static void -ctc_tty_inject(ctc_tty_info *info, char c) -{ - int skb_res; - struct sk_buff *skb; - - DBF_TEXT(trace, 4, __FUNCTION__); - if (ctc_tty_shuttingdown) - return; - skb_res = info->netdev->hard_header_len + sizeof(info->mcr) + - sizeof(__u32) + 1; - skb = dev_alloc_skb(skb_res); - if (!skb) { - printk(KERN_WARNING - "ctc_tty: Out of memory in %s%d tx_inject\n", - CTC_TTY_NAME, info->line); - return; - } - skb_reserve(skb, skb_res); - *(skb_put(skb, 1)) = c; - skb_queue_head(&info->tx_queue, skb); - tasklet_schedule(&info->tasklet); -} - -static void -ctc_tty_transmit_status(ctc_tty_info *info) -{ - DBF_TEXT(trace, 5, __FUNCTION__); - if (ctc_tty_shuttingdown) - return; - info->flags |= CTC_ASYNC_TX_LINESTAT; - tasklet_schedule(&info->tasklet); -} - -static void -ctc_tty_change_speed(ctc_tty_info * info) -{ - unsigned int cflag; - unsigned int quot; - int i; - - DBF_TEXT(trace, 3, __FUNCTION__); - if (!info->tty || !info->tty->termios) - return; - cflag = info->tty->termios->c_cflag; - - quot = i = cflag & CBAUD; - if (i & CBAUDEX) { - i &= ~CBAUDEX; - if (i < 1 || i > 2) - info->tty->termios->c_cflag &= ~CBAUDEX; - else - i += 15; - } - if (quot) { - info->mcr |= UART_MCR_DTR; - info->mcr |= UART_MCR_RTS; - ctc_tty_transmit_status(info); - } else { - info->mcr &= ~UART_MCR_DTR; - info->mcr &= ~UART_MCR_RTS; - ctc_tty_transmit_status(info); - return; - } - - /* CTS flow control flag and modem status interrupts */ - if (cflag & CRTSCTS) { - info->flags |= CTC_ASYNC_CTS_FLOW; - } else - info->flags &= ~CTC_ASYNC_CTS_FLOW; - if (cflag & CLOCAL) - info->flags &= ~CTC_ASYNC_CHECK_CD; - else { - info->flags |= CTC_ASYNC_CHECK_CD; - } -} - -static int -ctc_tty_startup(ctc_tty_info * info) -{ - DBF_TEXT(trace, 3, __FUNCTION__); - if (info->flags & CTC_ASYNC_INITIALIZED) - return 0; -#ifdef CTC_DEBUG_MODEM_OPEN - printk(KERN_DEBUG "starting up %s%d ...\n", CTC_TTY_NAME, info->line); -#endif - /* - * Now, initialize the UART - */ - info->mcr = UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2; - if (info->tty) - clear_bit(TTY_IO_ERROR, &info->tty->flags); - /* - * and set the speed of the serial port - */ - ctc_tty_change_speed(info); - - info->flags |= CTC_ASYNC_INITIALIZED; - if (!(info->flags & CTC_ASYNC_NETDEV_OPEN)) - info->netdev->open(info->netdev); - info->flags |= CTC_ASYNC_NETDEV_OPEN; - return 0; -} - -static void -ctc_tty_stopdev(unsigned long data) -{ - ctc_tty_info *info = (ctc_tty_info *)data; - - if ((!info) || (!info->netdev) || - (info->flags & CTC_ASYNC_INITIALIZED)) - return; - info->netdev->stop(info->netdev); - info->flags &= ~CTC_ASYNC_NETDEV_OPEN; -} - -/* - * This routine will shutdown a serial port; interrupts are disabled, and - * DTR is dropped if the hangup on close termio flag is on. - */ -static void -ctc_tty_shutdown(ctc_tty_info * info) -{ - DBF_TEXT(trace, 3, __FUNCTION__); - if (!(info->flags & CTC_ASYNC_INITIALIZED)) - return; -#ifdef CTC_DEBUG_MODEM_OPEN - printk(KERN_DEBUG "Shutting down %s%d ....\n", CTC_TTY_NAME, info->line); -#endif - info->msr &= ~UART_MSR_RI; - if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) - info->mcr &= ~(UART_MCR_DTR | UART_MCR_RTS); - if (info->tty) - set_bit(TTY_IO_ERROR, &info->tty->flags); - mod_timer(&info->stoptimer, jiffies + (10 * HZ)); - skb_queue_purge(&info->tx_queue); - skb_queue_purge(&info->rx_queue); - info->flags &= ~CTC_ASYNC_INITIALIZED; -} - -/* ctc_tty_write() is the main send-routine. It is called from the upper - * levels within the kernel to perform sending data. Depending on the - * online-flag it either directs output to the at-command-interpreter or - * to the lower level. Additional tasks done here: - * - If online, check for escape-sequence (+++) - * - If sending audio-data, call ctc_tty_DLEdown() to parse DLE-codes. - * - If receiving audio-data, call ctc_tty_end_vrx() to abort if needed. - * - If dialing, abort dial. - */ -static int -ctc_tty_write(struct tty_struct *tty, const u_char * buf, int count) -{ - int c; - int total = 0; - ctc_tty_info *info = (ctc_tty_info *) tty->driver_data; - - DBF_TEXT(trace, 5, __FUNCTION__); - if (ctc_tty_shuttingdown) - goto ex; - if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_write")) - goto ex; - if (!tty) - goto ex; - if (!info->netdev) { - total = -ENODEV; - goto ex; - } - while (1) { - struct sk_buff *skb; - int skb_res; - - c = (count < CTC_TTY_XMIT_SIZE) ? count : CTC_TTY_XMIT_SIZE; - if (c <= 0) - break; - - skb_res = info->netdev->hard_header_len + sizeof(info->mcr) + - + sizeof(__u32); - skb = dev_alloc_skb(skb_res + c); - if (!skb) { - printk(KERN_WARNING - "ctc_tty: Out of memory in %s%d write\n", - CTC_TTY_NAME, info->line); - break; - } - skb_reserve(skb, skb_res); - memcpy(skb_put(skb, c), buf, c); - skb_queue_tail(&info->tx_queue, skb); - buf += c; - total += c; - count -= c; - } - if (!skb_queue_empty(&info->tx_queue)) { - info->lsr &= ~UART_LSR_TEMT; - tasklet_schedule(&info->tasklet); - } -ex: - DBF_TEXT(trace, 6, __FUNCTION__); - return total; -} - -static int -ctc_tty_write_room(struct tty_struct *tty) -{ - ctc_tty_info *info = (ctc_tty_info *) tty->driver_data; - - if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_write_room")) - return