From 126fa4b9ca5d9d7cb7d46f779ad3bd3631ca387c Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Thu, 12 May 2005 20:09:17 -0400 Subject: [PATCH] r8169: incoming frame length check The size of the incoming frame is not correctly checked. The RxMaxSize register (0xDA) does not work as expected and incoming frames whose size exceeds the MTU actually end spanning multiple descriptors. The first Rx descriptor contains the size of the whole frame (or some garbage in its place). The driver does not expect something above the space allocated to the current skb and crashes loudly when it issues a skb_put. The fix contains two parts: - disable hardware Rx size filtering: so far it only proved to be able to trigger some new fancy errors; - drop multi-descriptors frame: as the driver allocates MTU sized Rx buffers, it provides an adequate filtering. As a bonus, wrong descriptors were not returned to the asic after their processing. Signed-off-by: Francois Romieu Signed-off-by: Jeff Garzik --- drivers/net/r8169.c | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index c59507f8a76..b3768d84474 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -1585,8 +1585,8 @@ rtl8169_hw_start(struct net_device *dev) RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); RTL_W8(EarlyTxThres, EarlyTxThld); - /* For gigabit rtl8169, MTU + header + CRC + VLAN */ - RTL_W16(RxMaxSize, tp->rx_buf_sz); + /* Low hurts. Let's disable the filtering. */ + RTL_W16(RxMaxSize, 16383); /* Set Rx Config register */ i = rtl8169_rx_config | @@ -2127,6 +2127,11 @@ rtl8169_tx_interrupt(struct net_device *dev, struct rtl8169_private *tp, } } +static inline int rtl8169_fragmented_frame(u32 status) +{ + return (status & (FirstFrag | LastFrag)) != (FirstFrag | LastFrag); +} + static inline void rtl8169_rx_csum(struct sk_buff *skb, struct RxDesc *desc) { u32 opts1 = le32_to_cpu(desc->opts1); @@ -2177,27 +2182,41 @@ rtl8169_rx_interrupt(struct net_device *dev, struct rtl8169_private *tp, while (rx_left > 0) { unsigned int entry = cur_rx % NUM_RX_DESC; + struct RxDesc *desc = tp->RxDescArray + entry; u32 status; rmb(); - status = le32_to_cpu(tp->RxDescArray[entry].opts1); + status = le32_to_cpu(desc->opts1); if (status & DescOwn) break; if (status & RxRES) { - printk(KERN_INFO "%s: Rx ERROR!!!\n", dev->name); + printk(KERN_INFO "%s: Rx ERROR. status = %08x\n", + dev->name, status); tp->stats.rx_errors++; if (status & (RxRWT | RxRUNT)) tp->stats.rx_length_errors++; if (status & RxCRC) tp->stats.rx_crc_errors++; + rtl8169_mark_to_asic(desc, tp->rx_buf_sz); } else { - struct RxDesc *desc = tp->RxDescArray + entry; struct sk_buff *skb = tp->Rx_skbuff[entry]; int pkt_size = (status & 0x00001FFF) - 4; void (*pci_action)(struct pci_dev *, dma_addr_t, size_t, int) = pci_dma_sync_single_for_device; + /* + * The driver does not support incoming fragmented + * frames. They are seen as a symptom of over-mtu + * sized frames. + */ + if (unlikely(rtl8169_fragmented_frame(status))) { + tp->stats.rx_dropped++; + tp->stats.rx_length_errors++; + rtl8169_mark_to_asic(desc, tp->rx_buf_sz); + goto move_on; + } + rtl8169_rx_csum(skb, desc); pci_dma_sync_single_for_cpu(tp->pci_dev, @@ -2224,7 +2243,7 @@ rtl8169_rx_interrupt(struct net_device *dev, struct rtl8169_private *tp, tp->stats.rx_bytes += pkt_size; tp->stats.rx_packets++; } - +move_on: cur_rx++; rx_left--; } -- cgit v1.2.3-70-g09d2 From b9a6eaffe7ff3d3481efa9fa353b2c6a02eda756 Mon Sep 17 00:00:00 2001 From: Daniel Ritz Date: Sun, 10 Apr 2005 20:27:45 +0200 Subject: [PATCH] 3c574_cs: disable interrupts in el3_close 3c574_cs forgets to disable interrupts during el3_close(). fix it by doing what 3c59x does. Signed-off-by: Daniel Ritz --- drivers/net/pcmcia/3c574_cs.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c index 41e51711480..c6e8b25f968 100644 --- a/drivers/net/pcmcia/3c574_cs.c +++ b/drivers/net/pcmcia/3c574_cs.c @@ -1274,6 +1274,9 @@ static int el3_close(struct net_device *dev) spin_lock_irqsave(&lp->window_lock, flags); update_stats(dev); spin_unlock_irqrestore(&lp->window_lock, flags); + + /* force interrupts off */ + outw(SetIntrEnb | 0x0000, ioaddr + EL3_CMD); } link->open--; -- cgit v1.2.3-70-g09d2 From 07dd39b9f62e0532c6922459c3a26d54a07bc231 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Mon, 30 May 2005 13:15:52 -0400 Subject: libata: minor DocBook update --- Documentation/DocBook/libata.tmpl | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/Documentation/DocBook/libata.tmpl b/Documentation/DocBook/libata.tmpl index cf2fce7707d..773ae9fd99d 100644 --- a/Documentation/DocBook/libata.tmpl +++ b/Documentation/DocBook/libata.tmpl @@ -44,11 +44,26 @@ + + Introduction + + libATA is a library used inside the Linux kernel to support ATA host + controllers and devices. libATA provides an ATA driver API, class + transports for ATA and ATAPI devices, and SCSI<->ATA translation + for ATA devices according to the T10 SAT specification. + + + This Guide documents the libATA driver API, library functions, library + internals, and a couple sample ATA low-level drivers. + + + Thanks The bulk of the ATA knowledge comes thanks to long conversations with - Andre Hedrick (www.linux-ide.org). + Andre Hedrick (www.linux-ide.org), and long hours pondering the ATA + and SCSI specifications. Thanks to Alan Cox for pointing out similarities -- cgit v1.2.3-70-g09d2 From 780a87f71841932db8dbb0f1eb9daf3a973a6bd6 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Mon, 30 May 2005 15:41:05 -0400 Subject: libata: more doc updates Document recently-added ata_port_operations hooks. Fill several doc stubs in libata-core.c. --- Documentation/DocBook/libata.tmpl | 58 ++++++++++++++++++++++++++------------- drivers/scsi/libata-core.c | 57 +++++++++++++++++++++++++++++--------- 2 files changed, 83 insertions(+), 32 deletions(-) diff --git a/Documentation/DocBook/libata.tmpl b/Documentation/DocBook/libata.tmpl index 773ae9fd99d..41053aed41f 100644 --- a/Documentation/DocBook/libata.tmpl +++ b/Documentation/DocBook/libata.tmpl @@ -14,7 +14,7 @@ - 2003 + 2003-2005 Jeff Garzik @@ -144,15 +144,26 @@ void (*exec_command)(struct ata_port *ap, struct ata_taskfile *tf); ->tf_load(), to be initiated in hardware. + +int (*check_atapi_dma) (struct ata_queued_cmd *qc); + + + +Allow low-level driver to filter ATA PACKET commands, returning a status +indicating whether or not it is OK to use DMA for the supplied PACKET +command. + + u8 (*check_status)(struct ata_port *ap); -void (*dev_select)(struct ata_port *ap, unsigned int device); +u8 (*check_altstatus)(struct ata_port *ap); +u8 (*check_err)(struct ata_port *ap); - Reads the Status ATA shadow register from hardware. On some - hardware, this has the side effect of clearing the interrupt - condition. + Reads the Status/AltStatus/Error ATA shadow register from + hardware. On some hardware, reading the Status register has + the side effect of clearing the interrupt condition. @@ -162,7 +173,8 @@ void (*dev_select)(struct ata_port *ap, unsigned int device); Issues the low-level hardware command(s) that causes one of N hardware devices to be considered 'selected' (active and - available for use) on the ATA bus. + available for use) on the ATA bus. This generally has no +meaning on FIS-based devices. @@ -180,12 +192,20 @@ void (*phy_reset) (struct ata_port *ap); void (*bmdma_setup) (struct ata_queued_cmd *qc); void (*bmdma_start) (struct ata_queued_cmd *qc); +void (*bmdma_stop) (struct ata_port *ap); +u8 (*bmdma_status) (struct ata_port *ap); - When setting up an IDE BMDMA transaction, these hooks arm - (->bmdma_setup) and fire (->bmdma_start) the hardware's DMA - engine. +When setting up an IDE BMDMA transaction, these hooks arm +(->bmdma_setup), fire (->bmdma_start), and halt (->bmdma_stop) +the hardware's DMA engine. ->bmdma_status is used to read the standard +PCI IDE DMA Status register. + + + +These hooks are typically either no-ops, or simply not implemented, in +FIS-based drivers. @@ -205,9 +225,7 @@ int (*qc_issue) (struct ata_queued_cmd *qc); ->qc_issue is used to make a command active, once the hardware and S/G tables have been prepared. IDE BMDMA drivers use the helper function ata_qc_issue_prot() for taskfile protocol-based - dispatch. More advanced drivers roll their own ->qc_issue - implementation, using this as the "issue new ATA command to - hardware" hook. + dispatch. More advanced drivers implement their own ->qc_issue. @@ -215,8 +233,10 @@ void (*eng_timeout) (struct ata_port *ap); - This is a high level error handling function, called from the - error handling thread, when a command times out. +This is a high level error handling function, called from the +error handling thread, when a command times out. Most newer +hardware will implement its own error handling code here. IDE BMDMA +drivers may use the helper function ata_eng_timeout(). @@ -255,15 +275,15 @@ void (*host_stop) (struct ata_host_set *host_set); tasks. - ->host_stop() is called when the rmmod or hot unplug process - begins. The hook must stop all hardware interrupts, DMA - engines, etc. - - ->port_stop() is called after ->host_stop(). It's sole function is to release DMA/memory resources, now that they are no longer actively being used. + + ->host_stop() is called after all ->port_stop() calls +have completed. The hook must finalize hardware shutdown, release DMA +and other resources, etc. + diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index 63d3f70d06e..4d707d06a5d 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c @@ -1241,10 +1241,14 @@ void ata_port_probe(struct ata_port *ap) } /** - * __sata_phy_reset - - * @ap: + * __sata_phy_reset - Wake/reset a low-level SATA PHY + * @ap: SATA port associated with target SATA PHY. * - * LOCKING: + * This function issues commands to standard SATA Sxxx + * PHY registers, to wake up the phy (and device), and + * clear any reset condition. + * + * LOCKING: None. Serialized during ata_bus_probe(). * */ void __sata_phy_reset(struct ata_port *ap) @@ -1289,10 +1293,13 @@ void __sata_phy_reset(struct ata_port *ap) } /** - * __sata_phy_reset - - * @ap: + * sata_phy_reset - Reset SATA bus. + * @ap: SATA port associated with target SATA PHY. * - * LOCKING: + * This function resets the SATA bus, and then probes + * the bus for devices. + * + * LOCKING: None. Serialized during ata_bus_probe(). * */ void sata_phy_reset(struct ata_port *ap) @@ -1304,10 +1311,16 @@ void sata_phy_reset(struct ata_port *ap) } /** - * ata_port_disable - - * @ap: + * ata_port_disable - Disable port. + * @ap: Port to be disabled. * - * LOCKING: + * Modify @ap data structure such that the system + * thinks that the entire port is disabled, and should + * never attempt to probe or communicate with devices + * on this port. + * + * LOCKING: host_set lock, or some other form of + * serialization. */ void ata_port_disable(struct ata_port *ap) @@ -1416,7 +1429,9 @@ static void ata_host_set_dma(struct ata_port *ap, u8 xfer_mode, * ata_set_mode - Program timings and issue SET FEATURES - XFER * @ap: port on which timings will be programmed * - * LOCKING: + * Set ATA device disk transfer mode (PIO3, UDMA6, etc.). + * + * LOCKING: None. Serialized during ata_bus_probe(). * */ static void ata_set_mode(struct ata_port *ap) @@ -1467,7 +1482,10 @@ err_out: * @tmout_pat: impatience timeout * @tmout: overall timeout * - * LOCKING: + * Sleep until ATA Status register bit BSY clears, + * or a timeout occurs. + * + * LOCKING: None. * */ @@ -1556,7 +1574,7 @@ static void ata_bus_post_reset(struct ata_port *ap, unsigned int devmask) * ata_bus_edd - * @ap: * - * LOCKING: + * LOCKING: None. Serialized during ata_bus_probe(). * */ @@ -1909,7 +1927,10 @@ static int ata_choose_xfer_mode(struct ata_port *ap, * @ap: Port associated with device @dev * @dev: Device to which command will be sent * - * LOCKING: + * Issue SET FEATURES - XFER MODE command to device @dev + * on port @ap. + * + * LOCKING: None. Serialized during ata_bus_probe(). */ static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev) @@ -1981,7 +2002,11 @@ static void ata_sg_clean(struct ata_queued_cmd *qc) * ata_fill_sg - Fill PCI IDE PRD table * @qc: Metadata associated with taskfile to be transferred * + * Fill PCI IDE PRD (scatter-gather) table with segments + * associated with the current disk command. + * * LOCKING: + * spin_lock_irqsave(host_set lock) * */ static void ata_fill_sg(struct ata_queued_cmd *qc) @@ -2028,6 +2053,10 @@ static void ata_fill_sg(struct ata_queued_cmd *qc) * ata_check_atapi_dma - Check whether ATAPI DMA can be supported * @qc: Metadata associated with taskfile to check * + * Allow low-level driver to filter ATA PACKET commands, returning + * a status indicating whether or not it is OK to use DMA for the + * supplied PACKET command. + * * LOCKING: * RETURNS: 0 when ATAPI DMA can be used * nonzero otherwise @@ -2046,6 +2075,8 @@ int ata_check_atapi_dma(struct ata_queued_cmd *qc) * ata_qc_prep - Prepare taskfile for submission * @qc: Metadata associated with taskfile to be prepared * + * Prepare ATA taskfile for submission. + * * LOCKING: * spin_lock_irqsave(host_set lock) */ -- cgit v1.2.3-70-g09d2 From 0cba632b737fc2de76934137b8dccf92d9fa4d19 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Mon, 30 May 2005 19:49:12 -0400 Subject: libata: doc updates --- Documentation/DocBook/libata.tmpl | 40 +++++----- drivers/scsi/ata_piix.c | 16 ---- drivers/scsi/libata-core.c | 150 +++++++++++++++++++++++++++++--------- drivers/scsi/libata-scsi.c | 2 +- 4 files changed, 138 insertions(+), 70 deletions(-) diff --git a/Documentation/DocBook/libata.tmpl b/Documentation/DocBook/libata.tmpl index 41053aed41f..77b4a223a86 100644 --- a/Documentation/DocBook/libata.tmpl +++ b/Documentation/DocBook/libata.tmpl @@ -58,26 +58,6 @@ - - Thanks - - The bulk of the ATA knowledge comes thanks to long conversations with - Andre Hedrick (www.linux-ide.org), and long hours pondering the ATA - and SCSI specifications. - - - Thanks to Alan Cox for pointing out similarities - between SATA and SCSI, and in general for motivation to hack on - libata. - - - libata's device detection - method, ata_pio_devchk, and in general all the early probing was - based on extensive study of Hale Landis's probe/reset code in his - ATADRVR driver (www.ata-atapi.com). - - - libata Driver API @@ -314,4 +294,24 @@ and other resources, etc. !Idrivers/scsi/sata_sil.c + + Thanks + + The bulk of the ATA knowledge comes thanks to long conversations with + Andre Hedrick (www.linux-ide.org), and long hours pondering the ATA + and SCSI specifications. + + + Thanks to Alan Cox for pointing out similarities + between SATA and SCSI, and in general for motivation to hack on + libata. + + + libata's device detection + method, ata_pio_devchk, and in general all the early probing was + based on extensive study of Hale Landis's probe/reset code in his + ATADRVR driver (www.ata-atapi.com). + + + diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c index 3867f91ef8c..c2b00c9d40a 100644 --- a/drivers/scsi/ata_piix.c +++ b/drivers/scsi/ata_piix.c @@ -663,15 +663,6 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) return ata_pci_init_one(pdev, port_info, n_ports); } -/** - * piix_init - - * - * LOCKING: - * - * RETURNS: - * - */ - static int __init piix_init(void) { int rc; @@ -687,13 +678,6 @@ static int __init piix_init(void) return 0; } -/** - * piix_exit - - * - * LOCKING: - * - */ - static void __exit piix_exit(void) { pci_unregister_driver(&piix_pci_driver); diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index 4d707d06a5d..31b2984f379 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c @@ -1190,7 +1190,12 @@ err_out: * ata_bus_probe - Reset and probe ATA bus * @ap: Bus to probe * + * Master ATA bus probing function. Initiates a hardware-dependent + * bus reset, then attempts to identify any devices found on + * the bus. + * * LOCKING: + * PCI/etc. bus probe sem. * * RETURNS: * Zero on success, non-zero on error. @@ -1229,10 +1234,14 @@ err_out: } /** - * ata_port_probe - - * @ap: + * ata_port_probe - Mark port as enabled + * @ap: Port for which we indicate enablement * - * LOCKING: + * Modify @ap data structure such that the system + * thinks that the entire port is enabled. + * + * LOCKING: host_set lock, or some other form of + * serialization. */ void ata_port_probe(struct ata_port *ap) @@ -1248,7 +1257,8 @@ void ata_port_probe(struct ata_port *ap) * PHY registers, to wake up the phy (and device), and * clear any reset condition. * - * LOCKING: None. Serialized during ata_bus_probe(). + * LOCKING: + * PCI/etc. bus probe sem. * */ void __sata_phy_reset(struct ata_port *ap) @@ -1299,7 +1309,8 @@ void __sata_phy_reset(struct ata_port *ap) * This function resets the SATA bus, and then probes * the bus for devices. * - * LOCKING: None. Serialized during ata_bus_probe(). + * LOCKING: + * PCI/etc. bus probe sem. * */ void sata_phy_reset(struct ata_port *ap) @@ -1431,7 +1442,8 @@ static void ata_host_set_dma(struct ata_port *ap, u8 xfer_mode, * * Set ATA device disk transfer mode (PIO3, UDMA6, etc.). * - * LOCKING: None. Serialized during ata_bus_probe(). + * LOCKING: + * PCI/etc. bus probe sem. * */ static void ata_set_mode(struct ata_port *ap) @@ -1571,10 +1583,14 @@ static void ata_bus_post_reset(struct ata_port *ap, unsigned int devmask) } /** - * ata_bus_edd - - * @ap: + * ata_bus_edd - Issue EXECUTE DEVICE DIAGNOSTIC command. + * @ap: Port to reset and probe + * + * Use the EXECUTE DEVICE DIAGNOSTIC command to reset and + * probe the bus. Not often used these days. * - * LOCKING: None. Serialized during ata_bus_probe(). + * LOCKING: + * PCI/etc. bus probe sem. * */ @@ -1651,8 +1667,8 @@ static unsigned int ata_bus_softreset(struct ata_port *ap, * the device is ATA or ATAPI. * * LOCKING: - * Inherited from caller. Some functions called by this function - * obtain the host_set lock. + * PCI/etc. bus probe sem. + * Obtains host_set lock. * * SIDE EFFECTS: * Sets ATA_FLAG_PORT_DISABLED if bus reset fails. @@ -1894,7 +1910,11 @@ static int fgb(u32 bitmap) * @xfer_mode_out: (output) SET FEATURES - XFER MODE code * @xfer_shift_out: (output) bit shift that selects this mode * + * Based on host and device capabilities, determine the + * maximum transfer mode that is amenable to all. + * * LOCKING: + * PCI/etc. bus probe sem. * * RETURNS: * Zero on success, negative on error. @@ -1930,7 +1950,8 @@ static int ata_choose_xfer_mode(struct ata_port *ap, * Issue SET FEATURES - XFER MODE command to device @dev * on port @ap. * - * LOCKING: None. Serialized during ata_bus_probe(). + * LOCKING: + * PCI/etc. bus probe sem. */ static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev) @@ -1968,10 +1989,13 @@ static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev) } /** - * ata_sg_clean - - * @qc: + * ata_sg_clean - Unmap DMA memory associated with command + * @qc: Command containing DMA memory to be released + * + * Unmap all mapped DMA memory associated with this command. * * LOCKING: + * spin_lock_irqsave(host_set lock) */ static void ata_sg_clean(struct ata_queued_cmd *qc) @@ -2058,6 +2082,8 @@ static void ata_fill_sg(struct ata_queued_cmd *qc) * supplied PACKET command. * * LOCKING: + * spin_lock_irqsave(host_set lock) + * * RETURNS: 0 when ATAPI DMA can be used * nonzero otherwise */ @@ -2088,6 +2114,19 @@ void ata_qc_prep(struct ata_queued_cmd *qc) ata_fill_sg(qc); } +/** + * ata_sg_init_one - Associate command with memory buffer + * @qc: Command to be associated + * @buf: Memory buffer + * @buflen: Length of memory buffer, in bytes. + * + * Initialize the data-related elements of queued_cmd @qc + * to point to a single memory buffer, @buf of byte length @buflen. + * + * LOCKING: + * spin_lock_irqsave(host_set lock) + */ + void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf, unsigned int buflen) { struct scatterlist *sg; @@ -2105,6 +2144,20 @@ void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf, unsigned int buflen) sg->length = buflen; } +/** + * ata_sg_init - Associate command with scatter-gather table. + * @qc: Command to be associated + * @sg: Scatter-gather table. + * @n_elem: Number of elements in s/g table. + * + * Initialize the data-related elements of queued_cmd @qc + * to point to a scatter-gather table @sg, containing @n_elem + * elements. + * + * LOCKING: + * spin_lock_irqsave(host_set lock) + */ + void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg, unsigned int n_elem) { @@ -2114,14 +2167,16 @@ void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg, } /** - * ata_sg_setup_one - - * @qc: + * ata_sg_setup_one - DMA-map the memory buffer associated with a command. + * @qc: Command with memory buffer to be mapped. + * + * DMA-map the memory buffer associated with queued_cmd @qc. * * LOCKING: * spin_lock_irqsave(host_set lock) * * RETURNS: - * + * Zero on success, negative on error. */ static int ata_sg_setup_one(struct ata_queued_cmd *qc) @@ -2146,13 +2201,16 @@ static int ata_sg_setup_one(struct ata_queued_cmd *qc) } /** - * ata_sg_setup - - * @qc: + * ata_sg_setup - DMA-map the scatter-gather table associated with a command. + * @qc: Command with scatter-gather table to be mapped. + * + * DMA-map the scatter-gather table associated with queued_cmd @qc. * * LOCKING: * spin_lock_irqsave(host_set lock) * * RETURNS: + * Zero on success, negative on error. * */ @@ -2182,6 +2240,7 @@ static int ata_sg_setup(struct ata_queued_cmd *qc) * @ap: * * LOCKING: + * None. (executing in kernel thread context) * * RETURNS: * @@ -2229,6 +2288,7 @@ static unsigned long ata_pio_poll(struct ata_port *ap) * @ap: * * LOCKING: + * None. (executing in kernel thread context) */ static void ata_pio_complete (struct ata_port *ap) @@ -2446,6 +2506,7 @@ err_out: * @ap: * * LOCKING: + * None. (executing in kernel thread context) */ static void ata_pio_block(struct ata_port *ap) @@ -2614,6 +2675,7 @@ static void atapi_request_sense(struct ata_port *ap, struct ata_device *dev, * transaction completed successfully. * * LOCKING: + * Inherited from SCSI layer (none, can sleep) */ static void ata_qc_timeout(struct ata_queued_cmd *qc) @@ -2723,6 +2785,7 @@ out: * @dev: Device from whom we request an available command structure * * LOCKING: + * None. */ static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap) @@ -2748,6 +2811,7 @@ static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap) * @dev: Device from whom we request an available command structure * * LOCKING: + * None. */ struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap, @@ -2812,6 +2876,7 @@ static void __ata_qc_complete(struct ata_queued_cmd *qc) * in case something prevents using it. * * LOCKING: + * spin_lock_irqsave(host_set lock) * */ void ata_qc_free(struct ata_queued_cmd *qc) @@ -2825,9 +2890,13 @@ void ata_qc_free(struct ata_queued_cmd *qc) /** * ata_qc_complete - Complete an active ATA command * @qc: Command to complete - * @drv_stat: ATA status register contents + * @drv_stat: ATA Status register contents + * + * Indicate to the mid and upper layers that an ATA + * command has completed, with either an ok or not-ok status. * * LOCKING: + * spin_lock_irqsave(host_set lock) * */ @@ -3234,13 +3303,18 @@ idle_irq: /** * ata_interrupt - Default ATA host interrupt handler - * @irq: irq line - * @dev_instance: pointer to our host information structure + * @irq: irq line (unused) + * @dev_instance: pointer to our ata_host_set information structure * @regs: unused * + * Default interrupt handler for PCI IDE devices. Calls + * ata_host_intr() for each port that is not disabled. + * * LOCKING: + * Obtains host_set lock during operation. * * RETURNS: + * IRQ_NONE or IRQ_HANDLED. * */ @@ -3381,7 +3455,11 @@ static void ata_host_remove(struct ata_port *ap, unsigned int do_unregister) * @ent: Probe information provided by low-level driver * @port_no: Port number associated with this ata_port * + * Initialize a new ata_port structure, and its associated + * scsi_host. + * * LOCKING: + * Inherited from caller. * */ @@ -3436,9 +3514,13 @@ static void ata_host_init(struct ata_port *ap, struct Scsi_Host *host, * @host_set: Collections of ports to which we add * @port_no: Port number associated with this host * + * Attach low-level ATA driver to system. + * * LOCKING: + * PCI/etc. bus probe sem. * * RETURNS: + * New ata_port on success, for NULL on error. * */ @@ -3471,12 +3553,22 @@ err_out: } /** - * ata_device_add - - * @ent: + * ata_device_add - Register hardware device with ATA and SCSI layers + * @ent: Probe information describing hardware device to be registered + * + * This function processes the information provided in the probe + * information struct @ent, allocates the necessary ATA and SCSI + * host information structures, initializes them, and registers + * everything with requisite kernel subsystems. + * + * This function requests irqs, probes the ATA bus, and probes + * the SCSI bus. * * LOCKING: + * PCI/etc. bus probe sem. * * RETURNS: + * Number of ports registered. Zero on error (no ports registered). * */ @@ -3755,6 +3847,7 @@ ata_pci_init_legacy_mode(struct pci_dev *pdev, struct ata_port_info **port, * Inherited from PCI layer (may sleep). * * RETURNS: + * Zero on success, negative on errno-based value on error. * */ @@ -3974,15 +4067,6 @@ int pci_test_config_bits(struct pci_dev *pdev, struct pci_bits *bits) #endif /* CONFIG_PCI */ -/** - * ata_init - - * - * LOCKING: - * - * RETURNS: - * - */ - static int __init ata_init(void) { ata_wq = create_workqueue("ata"); diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c index 416ba67ba9e..7a4adc4c8f0 100644 --- a/drivers/scsi/libata-scsi.c +++ b/drivers/scsi/libata-scsi.c @@ -947,7 +947,7 @@ unsigned int ata_scsiop_inq_83(struct ata_scsi_args *args, u8 *rbuf, } /** - * ata_scsiop_noop - + * ata_scsiop_noop - Command handler that simply returns success. * @args: device IDENTIFY data / SCSI command of interest. * @rbuf: Response buffer, to which simulated SCSI cmd output is sent. * @buflen: Response buffer length. -- cgit v1.2.3-70-g09d2 From 92bab26be5544d8b495389646490fcfdca6dbcf2 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Tue, 31 May 2005 20:43:57 -0400 Subject: libata: more docs updates --- Documentation/DocBook/libata.tmpl | 57 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/Documentation/DocBook/libata.tmpl b/Documentation/DocBook/libata.tmpl index 77b4a223a86..6df1dfd18b6 100644 --- a/Documentation/DocBook/libata.tmpl +++ b/Documentation/DocBook/libata.tmpl @@ -60,9 +60,22 @@ libata Driver API + + struct ata_port_operations is defined for every low-level libata + hardware driver, and it controls how the low-level driver + interfaces with the ATA and SCSI layers. + + + FIS-based drivers will hook into the system with ->qc_prep() and + ->qc_issue() high-level hooks. Hardware which behaves in a manner + similar to PCI IDE hardware may utilize several generic helpers, + defining at a bare minimum the bus I/O addresses of the ATA shadow + register blocks. + struct ata_port_operations + Disable ATA port void (*port_disable) (struct ata_port *); @@ -73,6 +86,9 @@ void (*port_disable) (struct ata_port *); unplug). + + + Post-IDENTIFY device configuration void (*dev_config) (struct ata_port *, struct ata_device *); @@ -83,6 +99,9 @@ void (*dev_config) (struct ata_port *, struct ata_device *); issue of SET FEATURES - XFER MODE, and prior to operation. + + + Set PIO/DMA mode void (*set_piomode) (struct ata_port *, struct ata_device *); void (*set_dmamode) (struct ata_port *, struct ata_device *); @@ -103,6 +122,9 @@ void (*post_set_mode) (struct ata_port *ap); ->set_dma_mode() is only called if DMA is possible. + + + Taskfile read/write void (*tf_load) (struct ata_port *ap, struct ata_taskfile *tf); void (*tf_read) (struct ata_port *ap, struct ata_taskfile *tf); @@ -115,6 +137,9 @@ void (*tf_read) (struct ata_port *ap, struct ata_taskfile *tf); taskfile register values. + + + ATA command execute void (*exec_command)(struct ata_port *ap, struct ata_taskfile *tf); @@ -124,6 +149,9 @@ void (*exec_command)(struct ata_port *ap, struct ata_taskfile *tf); ->tf_load(), to be initiated in hardware. + + + Per-cmd ATAPI DMA capabilities filter int (*check_atapi_dma) (struct ata_queued_cmd *qc); @@ -134,6 +162,9 @@ indicating whether or not it is OK to use DMA for the supplied PACKET command. + + + Read specific ATA shadow registers u8 (*check_status)(struct ata_port *ap); u8 (*check_altstatus)(struct ata_port *ap); @@ -146,6 +177,9 @@ u8 (*check_err)(struct ata_port *ap); the side effect of clearing the interrupt condition. + + + Select ATA device on bus void (*dev_select)(struct ata_port *ap, unsigned int device); @@ -157,6 +191,9 @@ void (*dev_select)(struct ata_port *ap, unsigned int device); meaning on FIS-based devices. + + + Reset ATA bus void (*phy_reset) (struct ata_port *ap); @@ -169,6 +206,9 @@ void (*phy_reset) (struct ata_port *ap); functions ata_bus_reset() or sata_phy_reset() for this hook. + + + Control PCI IDE BMDMA engine void (*bmdma_setup) (struct ata_queued_cmd *qc); void (*bmdma_start) (struct ata_queued_cmd *qc); @@ -188,6 +228,9 @@ These hooks are typically either no-ops, or simply not implemented, in FIS-based drivers. + + + High-level taskfile hooks void (*qc_prep) (struct ata_queued_cmd *qc); int (*qc_issue) (struct ata_queued_cmd *qc); @@ -208,6 +251,9 @@ int (*qc_issue) (struct ata_queued_cmd *qc); dispatch. More advanced drivers implement their own ->qc_issue. + + + Timeout (error) handling void (*eng_timeout) (struct ata_port *ap); @@ -219,6 +265,9 @@ hardware will implement its own error handling code here. IDE BMDMA drivers may use the helper function ata_eng_timeout(). + + + Hardware interrupt handling irqreturn_t (*irq_handler)(int, void *, struct pt_regs *); void (*irq_clear) (struct ata_port *); @@ -231,6 +280,9 @@ void (*irq_clear) (struct ata_port *); is quiet. + + + SATA phy read/write u32 (*scr_read) (struct ata_port *ap, unsigned int sc_reg); void (*scr_write) (struct ata_port *ap, unsigned int sc_reg, @@ -242,6 +294,9 @@ void (*scr_write) (struct ata_port *ap, unsigned int sc_reg, if ->phy_reset hook called the sata_phy_reset() helper function. + + + Init and shutdown int (*port_start) (struct ata_port *ap); void (*port_stop) (struct ata_port *ap); @@ -265,6 +320,8 @@ have completed. The hook must finalize hardware shutdown, release DMA and other resources, etc. + + -- cgit v1.2.3-70-g09d2 From 1e86d1c648508fd50e6c9960576b87906a7906ad Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Thu, 2 Jun 2005 14:11:37 +1000 Subject: [PATCH] ppc64: Fix result code handling in prom_init prom_init(), the trampoline code that "talks" to Open Firmware during early boot, has various issues with managing OF result codes. Some of my recent fixups in fact made the problem worse on some platforms. This patch reworks it all. Tested on g5, Maple, POWER3 and POWER5. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Linus Torvalds --- arch/ppc64/kernel/prom_init.c | 102 +++++++++++++++++++++++++----------------- 1 file changed, 61 insertions(+), 41 deletions(-) diff --git a/arch/ppc64/kernel/prom_init.c b/arch/ppc64/kernel/prom_init.c index 3de950de367..1ac531ba705 100644 --- a/arch/ppc64/kernel/prom_init.c +++ b/arch/ppc64/kernel/prom_init.c @@ -211,13 +211,23 @@ struct { */ #define ADDR(x) (u32) ((unsigned long)(x) - offset) +/* + * Error results ... some OF calls will return "-1" on error, some + * will return 0, some will return either. To simplify, here are + * macros to use with any ihandle or phandle return value to check if + * it is valid + */ + +#define PROM_ERROR (-1u) +#define PHANDLE_VALID(p) ((p) != 0 && (p) != PROM_ERROR) +#define IHANDLE_VALID(i) ((i) != 0 && (i) != PROM_ERROR) + + /* This is the one and *ONLY* place where we actually call open * firmware from, since we need to make sure we're running in 32b * mode when we do. We switch back to 64b mode upon return. */ -#define PROM_ERROR (-1) - static int __init call_prom(const char *service, int nargs, int nret, ...) { int i; @@ -587,14 +597,13 @@ static void __init prom_send_capabilities(void) { unsigned long offset = reloc_offset(); ihandle elfloader; - int ret; elfloader = call_prom("open", 1, 1, ADDR("/packages/elf-loader")); if (elfloader == 0) { prom_printf("couldn't open /packages/elf-loader\n"); return; } - ret = call_prom("call-method", 3, 1, ADDR("process-elf-header"), + call_prom("call-method", 3, 1, ADDR("process-elf-header"), elfloader, ADDR(&fake_elf)); call_prom("close", 1, 0, elfloader); } @@ -646,7 +655,7 @@ static unsigned long __init alloc_up(unsigned long size, unsigned long align) base = _ALIGN_UP(base + 0x100000, align)) { prom_debug(" trying: 0x%x\n\r", base); addr = (unsigned long)prom_claim(base, size, 0); - if ((int)addr != PROM_ERROR) + if (addr != PROM_ERROR) break; addr = 0; if (align == 0) @@ -708,7 +717,7 @@ static unsigned long __init alloc_down(unsigned long size, unsigned long align, for(; base > RELOC(alloc_bottom); base = _ALIGN_DOWN(base - 0x100000, align)) { prom_debug(" trying: 0x%x\n\r", base); addr = (unsigned long)prom_claim(base, size, 0); - if ((int)addr != PROM_ERROR) + if (addr != PROM_ERROR) break; addr = 0; } @@ -902,18 +911,19 @@ static void __init prom_instantiate_rtas(void) { unsigned long offset = reloc_offset(); struct prom_t *_prom = PTRRELOC(&prom); - phandle prom_rtas, rtas_node; + phandle rtas_node; + ihandle rtas_inst; u32 base, entry = 0; u32 size = 0; prom_debug("prom_instantiate_rtas: start...\n"); - prom_rtas = call_prom("finddevice", 1, 1, ADDR("/rtas")); - prom_debug("prom_rtas: %x\n", prom_rtas); - if (prom_rtas == (phandle) -1) + rtas_node = call_prom("finddevice", 1, 1, ADDR("/rtas")); + prom_debug("rtas_node: %x\n", rtas_node); + if (!PHANDLE_VALID(rtas_node)) return; - prom_getprop(prom_rtas, "rtas-size", &size, sizeof(size)); + prom_getprop(rtas_node, "rtas-size", &size, sizeof(size)); if (size == 0) return; @@ -922,14 +932,18 @@ static void __init prom_instantiate_rtas(void) prom_printf("RTAS allocation failed !\n"); return; } - prom_printf("instantiating rtas at 0x%x", base); - rtas_node = call_prom("open", 1, 1, ADDR("/rtas")); - prom_printf("..."); + rtas_inst = call_prom("open", 1, 1, ADDR("/rtas")); + if (!IHANDLE_VALID(rtas_inst)) { + prom_printf("opening rtas package failed"); + return; + } + + prom_printf("instantiating rtas at 0x%x ...", base); if (call_prom("call-method", 3, 2, ADDR("instantiate-rtas"), - rtas_node, base) != PROM_ERROR) { + rtas_inst, base) != PROM_ERROR) { entry = (long)_prom->args.rets[1]; } if (entry == 0) { @@ -940,8 +954,8 @@ static void __init prom_instantiate_rtas(void) reserve_mem(base, size); - prom_setprop(prom_rtas, "linux,rtas-base", &base, sizeof(base)); - prom_setprop(prom_rtas, "linux,rtas-entry", &entry, sizeof(entry)); + prom_setprop(rtas_node, "linux,rtas-base", &base, sizeof(base)); + prom_setprop(rtas_node, "linux,rtas-entry", &entry, sizeof(entry)); prom_debug("rtas base = 0x%x\n", base); prom_debug("rtas entry = 0x%x\n", entry); @@ -1062,7 +1076,7 @@ static void __init prom_initialize_tce_table(void) prom_printf("opening PHB %s", path); phb_node = call_prom("open", 1, 1, path); - if ( (long)phb_node <= 0) + if (phb_node == 0) prom_printf("... failed\n"); else prom_printf("... done\n"); @@ -1279,12 +1293,12 @@ static void __init prom_init_client_services(unsigned long pp) /* get a handle for the stdout device */ _prom->chosen = call_prom("finddevice", 1, 1, ADDR("/chosen")); - if ((long)_prom->chosen <= 0) + if (!PHANDLE_VALID(_prom->chosen)) prom_panic("cannot find chosen"); /* msg won't be printed :( */ /* get device tree root */ _prom->root = call_prom("finddevice", 1, 1, ADDR("/")); - if ((long)_prom->root <= 0) + if (!PHANDLE_VALID(_prom->root)) prom_panic("cannot find device tree root"); /* msg won't be printed :( */ } @@ -1356,9 +1370,8 @@ static int __init prom_find_machine_type(void) } /* Default to pSeries. We need to know if we are running LPAR */ rtas = call_prom("finddevice", 1, 1, ADDR("/rtas")); - if (rtas != (phandle) -1) { - unsigned long x; - x = prom_getproplen(rtas, "ibm,hypertas-functions"); + if (!PHANDLE_VALID(rtas)) { + int x = prom_getproplen(rtas, "ibm,hypertas-functions"); if (x != PROM_ERROR) { prom_printf("Hypertas detected, assuming LPAR !\n"); return PLATFORM_PSERIES_LPAR; @@ -1426,12 +1439,13 @@ static void __init prom_check_displays(void) * leave some room at the end of the path for appending extra * arguments */ - if (call_prom("package-to-path", 3, 1, node, path, PROM_SCRATCH_SIZE-10) < 0) + if (call_prom("package-to-path", 3, 1, node, path, + PROM_SCRATCH_SIZE-10) == PROM_ERROR) continue; prom_printf("found display : %s, opening ... ", path); ih = call_prom("open", 1, 1, path); - if (ih == (ihandle)0 || ih == (ihandle)-1) { + if (ih == 0) { prom_printf("failed\n"); continue; } @@ -1514,6 +1528,12 @@ static unsigned long __init dt_find_string(char *str) return 0; } +/* + * The Open Firmware 1275 specification states properties must be 31 bytes or + * less, however not all firmwares obey this. Make it 64 bytes to be safe. + */ +#define MAX_PROPERTY_NAME 64 + static void __init scan_dt_build_strings(phandle node, unsigned long *mem_start, unsigned long *mem_end) { @@ -1527,10 +1547,12 @@ static void __init scan_dt_build_strings(phandle node, unsigned long *mem_start, /* get and store all property names */ prev_name = RELOC(""); for (;;) { - - /* 32 is max len of name including nul. */ - namep = make_room(mem_start, mem_end, 32, 1); - if (call_prom("nextprop", 3, 1, node, prev_name, namep) <= 0) { + int rc; + + /* 64 is max len of name including nul. */ + namep = make_room(mem_start, mem_end, MAX_PROPERTY_NAME, 1); + rc = call_prom("nextprop", 3, 1, node, prev_name, namep); + if (rc != 1) { /* No more nodes: unwind alloc */ *mem_start = (unsigned long)namep; break; @@ -1555,12 +1577,6 @@ static void __init scan_dt_build_strings(phandle node, unsigned long *mem_start, } } -/* - * The Open Firmware 1275 specification states properties must be 31 bytes or - * less, however not all firmwares obey this. Make it 64 bytes to be safe. - */ -#define MAX_PROPERTY_NAME 64 - static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start, unsigned long *mem_end) { @@ -1607,7 +1623,10 @@ static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start, prev_name = RELOC(""); sstart = (char *)RELOC(dt_string_start); for (;;) { - if (call_prom("nextprop", 3, 1, node, prev_name, pname) <= 0) + int rc; + + rc = call_prom("nextprop", 3, 1, node, prev_name, pname); + if (rc != 1) break; /* find string offset */ @@ -1623,7 +1642,7 @@ static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start, l = call_prom("getproplen", 2, 1, node, pname); /* sanity checks */ - if (l < 0) + if (l == PROM_ERROR) continue; if (l > MAX_PROPERTY_LENGTH) { prom_printf("WARNING: ignoring large property "); @@ -1771,17 +1790,18 @@ static void __init fixup_device_tree(void) /* Some G5s have a missing interrupt definition, fix it up here */ u3 = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000")); - if ((long)u3 <= 0) + if (!PHANDLE_VALID(u3)) return; i2c = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/i2c@f8001000")); - if ((long)i2c <= 0) + if (!PHANDLE_VALID(i2c)) return; mpic = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/mpic@f8040000")); - if ((long)mpic <= 0) + if (!PHANDLE_VALID(mpic)) return; /* check if proper rev of u3 */ - if (prom_getprop(u3, "device-rev", &u3_rev, sizeof(u3_rev)) <= 0) + if (prom_getprop(u3, "device-rev", &u3_rev, sizeof(u3_rev)) + == PROM_ERROR) return; if (u3_rev != 0x35) return; -- cgit v1.2.3-70-g09d2 From 64a6c7aa3836e357499d2e822388f30c11f13604 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Thu, 2 Jun 2005 13:02:25 -0700 Subject: [IPVS]: remove net/ipv4/ipvs/ip_vs_proto_icmp.c ip_vs_proto_icmp.c was never finished. Signed-off-by: Adrian Bunk Signed-off-by: David S. Miller --- net/ipv4/ipvs/Makefile | 2 +- net/ipv4/ipvs/ip_vs_proto.c | 3 - net/ipv4/ipvs/ip_vs_proto_icmp.c | 182 --------------------------------------- 3 files changed, 1 insertion(+), 186 deletions(-) delete mode 100644 net/ipv4/ipvs/ip_vs_proto_icmp.c diff --git a/net/ipv4/ipvs/Makefile b/net/ipv4/ipvs/Makefile index a788461a40c..30e85de9fff 100644 --- a/net/ipv4/ipvs/Makefile +++ b/net/ipv4/ipvs/Makefile @@ -11,7 +11,7 @@ ip_vs_proto-objs-$(CONFIG_IP_VS_PROTO_AH) += ip_vs_proto_ah.o ip_vs-objs := ip_vs_conn.o ip_vs_core.o ip_vs_ctl.o ip_vs_sched.o \ ip_vs_xmit.o ip_vs_app.o ip_vs_sync.o \ - ip_vs_est.o ip_vs_proto.o ip_vs_proto_icmp.o \ + ip_vs_est.o ip_vs_proto.o \ $(ip_vs_proto-objs-y) diff --git a/net/ipv4/ipvs/ip_vs_proto.c b/net/ipv4/ipvs/ip_vs_proto.c index 253c46252bd..867d4e9c659 100644 --- a/net/ipv4/ipvs/ip_vs_proto.c +++ b/net/ipv4/ipvs/ip_vs_proto.c @@ -216,9 +216,6 @@ int ip_vs_protocol_init(void) #ifdef CONFIG_IP_VS_PROTO_UDP REGISTER_PROTOCOL(&ip_vs_protocol_udp); #endif -#ifdef CONFIG_IP_VS_PROTO_ICMP - REGISTER_PROTOCOL(&ip_vs_protocol_icmp); -#endif #ifdef CONFIG_IP_VS_PROTO_AH REGISTER_PROTOCOL(&ip_vs_protocol_ah); #endif diff --git a/net/ipv4/ipvs/ip_vs_proto_icmp.c b/net/ipv4/ipvs/ip_vs_proto_icmp.c deleted file mode 100644 index 191e94aa1c1..00000000000 --- a/net/ipv4/ipvs/ip_vs_proto_icmp.c +++ /dev/null @@ -1,182 +0,0 @@ -/* - * ip_vs_proto_icmp.c: ICMP load balancing support for IP Virtual Server - * - * Authors: Julian Anastasov , March 2002 - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation; - * - */ - -#include -#include -#include -#include -#include - -#include - - -static int icmp_timeouts[1] = { 1*60*HZ }; - -static char * icmp_state_name_table[1] = { "ICMP" }; - -static struct ip_vs_conn * -icmp_conn_in_get(const struct sk_buff *skb, - struct ip_vs_protocol *pp, - const struct iphdr *iph, - unsigned int proto_off, - int inverse) -{ -#if 0 - struct ip_vs_conn *cp; - - if (likely(!inverse)) { - cp = ip_vs_conn_in_get(iph->protocol, - iph->saddr, 0, - iph->daddr, 0); - } else { - cp = ip_vs_conn_in_get(iph->protocol, - iph->daddr, 0, - iph->saddr, 0); - } - - return cp; - -#else - return NULL; -#endif -} - -static struct ip_vs_conn * -icmp_conn_out_get(const struct sk_buff *skb, - struct ip_vs_protocol *pp, - const struct iphdr *iph, - unsigned int proto_off, - int inverse) -{ -#if 0 - struct ip_vs_conn *cp; - - if (likely(!inverse)) { - cp = ip_vs_conn_out_get(iph->protocol, - iph->saddr, 0, - iph->daddr, 0); - } else { - cp = ip_vs_conn_out_get(IPPROTO_UDP, - iph->daddr, 0, - iph->saddr, 0); - } - - return cp; -#else - return NULL; -#endif -} - -static int -icmp_conn_schedule(struct sk_buff *skb, struct ip_vs_protocol *pp, - int *verdict, struct ip_vs_conn **cpp) -{ - *verdict = NF_ACCEPT; - return 0; -} - -static int -icmp_csum_check(struct sk_buff *skb, struct ip_vs_protocol *pp) -{ - if (!(skb->nh.iph->frag_off & __constant_htons(IP_OFFSET))) { - if (skb->ip_summed != CHECKSUM_UNNECESSARY) { - if (ip_vs_checksum_complete(skb, skb->nh.iph->ihl * 4)) { - IP_VS_DBG_RL_PKT(0, pp, skb, 0, "Failed checksum for"); - return 0; - } - } - } - return 1; -} - -static void -icmp_debug_packet(struct ip_vs_protocol *pp, - const struct sk_buff *skb, - int offset, - const char *msg) -{ - char buf[256]; - struct iphdr _iph, *ih; - - ih = skb_header_pointer(skb, offset, sizeof(_iph), &_iph); - if (ih == NULL) - sprintf(buf, "%s TRUNCATED", pp->name); - else if (ih->frag_off & __constant_htons(IP_OFFSET)) - sprintf(buf, "%s %u.%u.%u.%u->%u.%u.%u.%u frag", - pp->name, NIPQUAD(ih->saddr), - NIPQUAD(ih->daddr)); - else { - struct icmphdr _icmph, *ic; - - ic = skb_header_pointer(skb, offset + ih->ihl*4, - sizeof(_icmph), &_icmph); - if (ic == NULL) - sprintf(buf, "%s TRUNCATED to %u bytes\n", - pp->name, skb->len - offset); - else - sprintf(buf, "%s %u.%u.%u.%u->%u.%u.%u.%u T:%d C:%d", - pp->name, NIPQUAD(ih->saddr), - NIPQUAD(ih->daddr), - ic->type, ic->code); - } - printk(KERN_DEBUG "IPVS: %s: %s\n", msg, buf); -} - -static int -icmp_state_transition(struct ip_vs_conn *cp, int direction, - const struct sk_buff *skb, - struct ip_vs_protocol *pp) -{ - cp->timeout = pp->timeout_table[IP_VS_ICMP_S_NORMAL]; - return 1; -} - -static int -icmp_set_state_timeout(struct ip_vs_protocol *pp, char *sname, int to) -{ - int num; - char **names; - - num = IP_VS_ICMP_S_LAST; - names = icmp_state_name_table; - return ip_vs_set_state_timeout(pp->timeout_table, num, names, sname, to); -} - - -static void icmp_init(struct ip_vs_protocol *pp) -{ - pp->timeout_table = icmp_timeouts; -} - -static void icmp_exit(struct ip_vs_protocol *pp) -{ -} - -struct ip_vs_protocol ip_vs_protocol_icmp = { - .name = "ICMP", - .protocol = IPPROTO_ICMP, - .dont_defrag = 0, - .init = icmp_init, - .exit = icmp_exit, - .conn_schedule = icmp_conn_schedule, - .conn_in_get = icmp_conn_in_get, - .conn_out_get = icmp_conn_out_get, - .snat_handler = NULL, - .dnat_handler = NULL, - .csum_check = icmp_csum_check, - .state_transition = icmp_state_transition, - .register_app = NULL, - .unregister_app = NULL, - .app_conn_bind = NULL, - .debug_packet = icmp_debug_packet, - .timeout_change = NULL, - .set_state_timeout = icmp_set_state_timeout, -}; -- cgit v1.2.3-70-g09d2 From 3087e1ff8d64da7b6b527e89d0c0864ab36294b8 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Thu, 2 Jun 2005 13:03:15 -0700 Subject: [ATM]: fix ATM makefile for out-of-source-tree builds Signed-off-by: Jan Beulich Signed-off-by: Chas Williams Signed-off-by: David S. Miller --- drivers/atm/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/atm/Makefile b/drivers/atm/Makefile index d1dcd8eae3c..5b77188527a 100644 --- a/drivers/atm/Makefile +++ b/drivers/atm/Makefile @@ -39,7 +39,8 @@ ifeq ($(CONFIG_ATM_FORE200E_PCA),y) fore_200e-objs += fore200e_pca_fw.o # guess the target endianess to choose the right PCA-200E firmware image ifeq ($(CONFIG_ATM_FORE200E_PCA_DEFAULT_FW),y) - CONFIG_ATM_FORE200E_PCA_FW = $(shell if test -n "`$(CC) -E -dM $(src)/../../include/asm/byteorder.h | grep ' __LITTLE_ENDIAN '`"; then echo $(obj)/pca200e.bin; else echo $(obj)/pca200e_ecd.bin2; fi) + byteorder.h := include$(if $(patsubst $(srctree),,$(objtree)),2)/asm/byteorder.h + CONFIG_ATM_FORE200E_PCA_FW := $(obj)/pca200e$(if $(shell $(CC) -E -dM $(byteorder.h) | grep ' __LITTLE_ENDIAN '),.bin,_ecd.bin2) endif endif -- cgit v1.2.3-70-g09d2 From a2c1aa54746bace5d03cc66521fbf3bb6fb2f916 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Thu, 2 Jun 2005 13:04:07 -0700 Subject: [ATM]: [drivers] kill pointless NULL checks and casts before kfree() Signed-off-by: Jesper Juhl Signed-off-by: Chas Williams Signed-off-by: David S. Miller --- drivers/atm/fore200e.c | 6 ++---- drivers/atm/he.c | 6 ++---- drivers/atm/nicstar.c | 20 ++++++++++---------- drivers/atm/zatm.c | 11 ++++------- 4 files changed, 18 insertions(+), 25 deletions(-) diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c index 9e65bfb85ba..5f702199543 100644 --- a/drivers/atm/fore200e.c +++ b/drivers/atm/fore200e.c @@ -383,8 +383,7 @@ fore200e_shutdown(struct fore200e* fore200e) switch(fore200e->state) { case FORE200E_STATE_COMPLETE: - if (fore200e->stats) - kfree(fore200e->stats); + kfree(fore200e->stats); case FORE200E_STATE_IRQ: free_irq(fore200e->irq, fore200e->atm_dev); @@ -963,8 +962,7 @@ fore200e_tx_irq(struct fore200e* fore200e) entry, txq->tail, entry->vc_map, entry->skb); /* free copy of misaligned data */ - if (entry->data) - kfree(entry->data); + kfree(entry->data); /* remove DMA mapping */ fore200e->bus->dma_unmap(fore200e, entry->tpd->tsd[ 0 ].buffer, entry->tpd->tsd[ 0 ].length, diff --git a/drivers/atm/he.c b/drivers/atm/he.c index 3022c548a13..df2c83fd549 100644 --- a/drivers/atm/he.c +++ b/drivers/atm/he.c @@ -412,8 +412,7 @@ he_init_one(struct pci_dev *pci_dev, const struct pci_device_id *pci_ent) init_one_failure: if (atm_dev) atm_dev_deregister(atm_dev); - if (he_dev) - kfree(he_dev); + kfree(he_dev); pci_disable_device(pci_dev); return err; } @@ -2534,8 +2533,7 @@ he_open(struct atm_vcc *vcc) open_failed: if (err) { - if (he_vcc) - kfree(he_vcc); + kfree(he_vcc); clear_bit(ATM_VF_ADDR, &vcc->flags); } else diff --git a/drivers/atm/nicstar.c b/drivers/atm/nicstar.c index 85bf5c8442b..b2a7b754fd1 100644 --- a/drivers/atm/nicstar.c +++ b/drivers/atm/nicstar.c @@ -676,10 +676,10 @@ static int __devinit ns_init_card(int i, struct pci_dev *pcidev) PRINTK("nicstar%d: RSQ base at 0x%x.\n", i, (u32) card->rsq.base); /* Initialize SCQ0, the only VBR SCQ used */ - card->scq1 = (scq_info *) NULL; - card->scq2 = (scq_info *) NULL; + card->scq1 = NULL; + card->scq2 = NULL; card->scq0 = get_scq(VBR_SCQSIZE, NS_VRSCD0); - if (card->scq0 == (scq_info *) NULL) + if (card->scq0 == NULL) { printk("nicstar%d: can't get SCQ0.\n", i); error = 12; @@ -993,24 +993,24 @@ static scq_info *get_scq(int size, u32 scd) int i; if (size != VBR_SCQSIZE && size != CBR_SCQSIZE) - return (scq_info *) NULL; + return NULL; scq = (scq_info *) kmalloc(sizeof(scq_info), GFP_KERNEL); - if (scq == (scq_info *) NULL) - return (scq_info *) NULL; + if (scq == NULL) + return NULL; scq->org = kmalloc(2 * size, GFP_KERNEL); if (scq->org == NULL) { kfree(scq); - return (scq_info *) NULL; + return NULL; } scq->skb = (struct sk_buff **) kmalloc(sizeof(struct sk_buff *) * (size / NS_SCQE_SIZE), GFP_KERNEL); - if (scq->skb == (struct sk_buff **) NULL) + if (scq->skb == NULL) { kfree(scq->org); kfree(scq); - return (scq_info *) NULL; + return NULL; } scq->num_entries = size / NS_SCQE_SIZE; scq->base = (ns_scqe *) ALIGN_ADDRESS(scq->org, size); @@ -1498,7 +1498,7 @@ static int ns_open(struct atm_vcc *vcc) vc->cbr_scd = NS_FRSCD + frscdi * NS_FRSCD_SIZE; scq = get_scq(CBR_SCQSIZE, vc->cbr_scd); - if (scq == (scq_info *) NULL) + if (scq == NULL) { PRINTK("nicstar%d: can't get fixed rate SCQ.\n", card->index); card->scd2vc[frscdi] = NULL; diff --git a/drivers/atm/zatm.c b/drivers/atm/zatm.c index 47a800519ad..8d5e65cb975 100644 --- a/drivers/atm/zatm.c +++ b/drivers/atm/zatm.c @@ -902,7 +902,7 @@ static void close_tx(struct atm_vcc *vcc) zatm_dev->tx_bw += vcc->qos.txtp.min_pcr; dealloc_shaper(vcc->dev,zatm_vcc->shaper); } - if (zatm_vcc->ring) kfree(zatm_vcc->ring); + kfree(zatm_vcc->ring); } @@ -1339,12 +1339,9 @@ static int __init zatm_start(struct atm_dev *dev) return 0; out: for (i = 0; i < NR_MBX; i++) - if (zatm_dev->mbx_start[i] != 0) - kfree((void *) zatm_dev->mbx_start[i]); - if (zatm_dev->rx_map != NULL) - kfree(zatm_dev->rx_map); - if (zatm_dev->tx_map != NULL) - kfree(zatm_dev->tx_map); + kfree(zatm_dev->mbx_start[i]); + kfree(zatm_dev->rx_map); + kfree(zatm_dev->tx_map); free_irq(zatm_dev->irq, dev); return error; } -- cgit v1.2.3-70-g09d2 From 4fef0304eeaa4156db5625e3578f92ed94645a43 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Thu, 2 Jun 2005 13:06:36 -0700 Subject: [IPV6]: Kill export of fl6_sock_lookup. There is no usage of this EXPORT_SYMBOL in the kernel. Signed-off-by: Adrian Bunk Acked-by: Hideaki YOSHIFUJI Signed-off-by: David S. Miller --- net/ipv6/ipv6_syms.c | 1 - 1 file changed, 1 deletion(-) diff --git a/net/ipv6/ipv6_syms.c b/net/ipv6/ipv6_syms.c index 2f4c91ddc9a..5ade5a5d199 100644 --- a/net/ipv6/ipv6_syms.c +++ b/net/ipv6/ipv6_syms.c @@ -37,5 +37,4 @@ EXPORT_SYMBOL(in6_dev_finish_destroy); EXPORT_SYMBOL(xfrm6_rcv); #endif EXPORT_SYMBOL(rt6_lookup); -EXPORT_SYMBOL(fl6_sock_lookup); EXPORT_SYMBOL(ipv6_push_nfrag_opts); -- cgit v1.2.3-70-g09d2 From 00ea81459c279f14a7b344320a71c94f60f88929 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Thu, 2 Jun 2005 14:02:00 -0700 Subject: [PATCH] ext3: fix log_do_checkpoint() assertion failure Fix possible false assertion failure in log_do_checkpoint(). We might fail to detect that we actually made a progress when cleaning up the checkpoint lists if we don't retry after writing something to disk. The patch was confirmed to fix observed assertion failures for several users. When we flushed some buffers we need to retry scanning the list. Otherwise we can fail to detect our progress. Signed-off-by: Jan Kara Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/jbd/checkpoint.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fs/jbd/checkpoint.c b/fs/jbd/checkpoint.c index 98d830401c5..58133ab9457 100644 --- a/fs/jbd/checkpoint.c +++ b/fs/jbd/checkpoint.c @@ -339,8 +339,10 @@ int log_do_checkpoint(journal_t *journal) } } while (jh != last_jh && !retry); - if (batch_count) + if (batch_count) { __flush_batch(journal, bhs, &batch_count); + retry = 1; + } /* * If someone cleaned up this transaction while we slept, we're -- cgit v1.2.3-70-g09d2 From 7e3b11a9be6ac94bf4af81757b6a10e7e65b846f Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Thu, 2 Jun 2005 14:02:01 -0700 Subject: [PATCH] ext3: fix list scanning in __cleanup_transaction Fix a bug in list scanning that can cause us to skip the last buffer on the checkpoint list (and hence fail to do any progress under some rather unfavorable conditions). The problem is we first do jh=next_jh and then test } while (jh!=last_jh); Hence we skip the last buffer on the list (if it was not the only buffer on the list). As we already do jh=next_jh; in the beginning of the loop we are safe to just remove the assignment in the end. It can happen that 'jh' will be freed at the point we test jh != last_jh but that does not matter as we never *dereference* the pointer. Signed-off-by: Jan Kara Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/jbd/checkpoint.c | 1 - 1 file changed, 1 deletion(-) diff --git a/fs/jbd/checkpoint.c b/fs/jbd/checkpoint.c index 58133ab9457..5a97e346bd9 100644 --- a/fs/jbd/checkpoint.c +++ b/fs/jbd/checkpoint.c @@ -188,7 +188,6 @@ static int __cleanup_transaction(journal_t *journal, transaction_t *transaction) } else { jbd_unlock_bh_state(bh); } - jh = next_jh; } while (jh != last_jh); return ret; -- cgit v1.2.3-70-g09d2 From 79f1248962cfa1e11a5610e0349bc3515687516d Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Thu, 2 Jun 2005 14:02:02 -0700 Subject: [PATCH] ppc64: cleanup SPR definitions There are a bunch of irrelevant SPR definitions in asm/processer.h. Cut them down a bit, also add a DABR_TRANSLATION define which will be used shortly. Signed-off-by: Anton Blanchard Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-ppc64/processor.h | 159 +----------------------------------------- 1 file changed, 1 insertion(+), 158 deletions(-) diff --git a/include/asm-ppc64/processor.h b/include/asm-ppc64/processor.h index 0035efe2db2..5ba6aa45e1e 100644 --- a/include/asm-ppc64/processor.h +++ b/include/asm-ppc64/processor.h @@ -120,103 +120,18 @@ /* Special Purpose Registers (SPRNs)*/ -#define SPRN_CDBCR 0x3D7 /* Cache Debug Control Register */ #define SPRN_CTR 0x009 /* Count Register */ #define SPRN_DABR 0x3F5 /* Data Address Breakpoint Register */ -#define SPRN_DAC1 0x3F6 /* Data Address Compare 1 */ -#define SPRN_DAC2 0x3F7 /* Data Address Compare 2 */ +#define DABR_TRANSLATION (1UL << 2) #define SPRN_DAR 0x013 /* Data Address Register */ -#define SPRN_DBCR 0x3F2 /* Debug Control Regsiter */ -#define DBCR_EDM 0x80000000 -#define DBCR_IDM 0x40000000 -#define DBCR_RST(x) (((x) & 0x3) << 28) -#define DBCR_RST_NONE 0 -#define DBCR_RST_CORE 1 -#define DBCR_RST_CHIP 2 -#define DBCR_RST_SYSTEM 3 -#define DBCR_IC 0x08000000 /* Instruction Completion Debug Evnt */ -#define DBCR_BT 0x04000000 /* Branch Taken Debug Event */ -#define DBCR_EDE 0x02000000 /* Exception Debug Event */ -#define DBCR_TDE 0x01000000 /* TRAP Debug Event */ -#define DBCR_FER 0x00F80000 /* First Events Remaining Mask */ -#define DBCR_FT 0x00040000 /* Freeze Timers on Debug Event */ -#define DBCR_IA1 0x00020000 /* Instr. Addr. Compare 1 Enable */ -#define DBCR_IA2 0x00010000 /* Instr. Addr. Compare 2 Enable */ -#define DBCR_D1R 0x00008000 /* Data Addr. Compare 1 Read Enable */ -#define DBCR_D1W 0x00004000 /* Data Addr. Compare 1 Write Enable */ -#define DBCR_D1S(x) (((x) & 0x3) << 12) /* Data Adrr. Compare 1 Size */ -#define DAC_BYTE 0 -#define DAC_HALF 1 -#define DAC_WORD 2 -#define DAC_QUAD 3 -#define DBCR_D2R 0x00000800 /* Data Addr. Compare 2 Read Enable */ -#define DBCR_D2W 0x00000400 /* Data Addr. Compare 2 Write Enable */ -#define DBCR_D2S(x) (((x) & 0x3) << 8) /* Data Addr. Compare 2 Size */ -#define DBCR_SBT 0x00000040 /* Second Branch Taken Debug Event */ -#define DBCR_SED 0x00000020 /* Second Exception Debug Event */ -#define DBCR_STD 0x00000010 /* Second Trap Debug Event */ -#define DBCR_SIA 0x00000008 /* Second IAC Enable */ -#define DBCR_SDA 0x00000004 /* Second DAC Enable */ -#define DBCR_JOI 0x00000002 /* JTAG Serial Outbound Int. Enable */ -#define DBCR_JII 0x00000001 /* JTAG Serial Inbound Int. Enable */ -#define SPRN_DBCR0 0x3F2 /* Debug Control Register 0 */ -#define SPRN_DBCR1 0x3BD /* Debug Control Register 1 */ -#define SPRN_DBSR 0x3F0 /* Debug Status Register */ -#define SPRN_DCCR 0x3FA /* Data Cache Cacheability Register */ -#define DCCR_NOCACHE 0 /* Noncacheable */ -#define DCCR_CACHE 1 /* Cacheable */ -#define SPRN_DCMP 0x3D1 /* Data TLB Compare Register */ -#define SPRN_DCWR 0x3BA /* Data Cache Write-thru Register */ -#define DCWR_COPY 0 /* Copy-back */ -#define DCWR_WRITE 1 /* Write-through */ -#define SPRN_DEAR 0x3D5 /* Data Error Address Register */ #define SPRN_DEC 0x016 /* Decrement Register */ -#define SPRN_DMISS 0x3D0 /* Data TLB Miss Register */ #define SPRN_DSISR 0x012 /* Data Storage Interrupt Status Register */ #define DSISR_NOHPTE 0x40000000 /* no translation found */ #define DSISR_PROTFAULT 0x08000000 /* protection fault */ #define DSISR_ISSTORE 0x02000000 /* access was a store */ #define DSISR_DABRMATCH 0x00400000 /* hit data breakpoint */ #define DSISR_NOSEGMENT 0x00200000 /* STAB/SLB miss */ -#define SPRN_EAR 0x11A /* External Address Register */ -#define SPRN_ESR 0x3D4 /* Exception Syndrome Register */ -#define ESR_IMCP 0x80000000 /* Instr. Machine Check - Protection */ -#define ESR_IMCN 0x40000000 /* Instr. Machine Check - Non-config */ -#define ESR_IMCB 0x20000000 /* Instr. Machine Check - Bus error */ -#define ESR_IMCT 0x10000000 /* Instr. Machine Check - Timeout */ -#define ESR_PIL 0x08000000 /* Program Exception - Illegal */ -#define ESR_PPR 0x04000000 /* Program Exception - Priveleged */ -#define ESR_PTR 0x02000000 /* Program Exception - Trap */ -#define ESR_DST 0x00800000 /* Storage Exception - Data miss */ -#define ESR_DIZ 0x00400000 /* Storage Exception - Zone fault */ -#define SPRN_EVPR 0x3D6 /* Exception Vector Prefix Register */ -#define SPRN_HASH1 0x3D2 /* Primary Hash Address Register */ -#define SPRN_HASH2 0x3D3 /* Secondary Hash Address Resgister */ #define SPRN_HID0 0x3F0 /* Hardware Implementation Register 0 */ -#define HID0_EMCP (1<<31) /* Enable Machine Check pin */ -#define HID0_EBA (1<<29) /* Enable Bus Address Parity */ -#define HID0_EBD (1<<28) /* Enable Bus Data Parity */ -#define HID0_SBCLK (1<<27) -#define HID0_EICE (1<<26) -#define HID0_ECLK (1<<25) -#define HID0_PAR (1<<24) -#define HID0_DOZE (1<<23) -#define HID0_NAP (1<<22) -#define HID0_SLEEP (1<<21) -#define HID0_DPM (1<<20) -#define HID0_ICE (1<<15) /* Instruction Cache Enable */ -#define HID0_DCE (1<<14) /* Data Cache Enable */ -#define HID0_ILOCK (1<<13) /* Instruction Cache Lock */ -#define HID0_DLOCK (1<<12) /* Data Cache Lock */ -#define HID0_ICFI (1<<11) /* Instr. Cache Flash Invalidate */ -#define HID0_DCI (1<<10) /* Data Cache Invalidate */ -#define HID0_SPD (1<<9) /* Speculative disable */ -#define HID0_SGE (1<<7) /* Store Gathering Enable */ -#define HID0_SIED (1<<7) /* Serial Instr. Execution [Disable] */ -#define HID0_BTIC (1<<5) /* Branch Target Instruction Cache Enable */ -#define HID0_ABE (1<<3) /* Address Broadcast Enable */ -#define HID0_BHTE (1<<2) /* Branch History Table Enable */ -#define HID0_BTCD (1<<1) /* Branch target cache disable */ #define SPRN_MSRDORM 0x3F1 /* Hardware Implementation Register 1 */ #define SPRN_HID1 0x3F1 /* Hardware Implementation Register 1 */ #define SPRN_IABR 0x3F2 /* Instruction Address Breakpoint Register */ @@ -225,23 +140,8 @@ #define SPRN_HID5 0x3F6 /* 970 HID5 */ #define SPRN_TSC 0x3FD /* Thread switch control */ #define SPRN_TST 0x3FC /* Thread switch timeout */ -#define SPRN_IAC1 0x3F4 /* Instruction Address Compare 1 */ -#define SPRN_IAC2 0x3F5 /* Instruction Address Compare 2 */ -#define SPRN_ICCR 0x3FB /* Instruction Cache Cacheability Register */ -#define ICCR_NOCACHE 0 /* Noncacheable */ -#define ICCR_CACHE 1 /* Cacheable */ -#define SPRN_ICDBDR 0x3D3 /* Instruction Cache Debug Data Register */ -#define SPRN_ICMP 0x3D5 /* Instruction TLB Compare Register */ -#define SPRN_ICTC 0x3FB /* Instruction Cache Throttling Control Reg */ -#define SPRN_IMISS 0x3D4 /* Instruction TLB Miss Register */ -#define SPRN_IMMR 0x27E /* Internal Memory Map Register */ #define SPRN_L2CR 0x3F9 /* Level 2 Cache Control Regsiter */ #define SPRN_LR 0x008 /* Link Register */ -#define SPRN_PBL1 0x3FC /* Protection Bound Lower 1 */ -#define SPRN_PBL2 0x3FE /* Protection Bound Lower 2 */ -#define SPRN_PBU1 0x3FD /* Protection Bound Upper 1 */ -#define SPRN_PBU2 0x3FF /* Protection Bound Upper 2 */ -#define SPRN_PID 0x3B1 /* Process ID */ #define SPRN_PIR 0x3FF /* Processor Identification Register */ #define SPRN_PIT 0x3DB /* Programmable Interval Timer */ #define SPRN_PURR 0x135 /* Processor Utilization of Resources Register */ @@ -249,9 +149,6 @@ #define SPRN_RPA 0x3D6 /* Required Physical Address Register */ #define SPRN_SDA 0x3BF /* Sampled Data Address Register */ #define SPRN_SDR1 0x019 /* MMU Hash Base Register */ -#define SPRN_SGR 0x3B9 /* Storage Guarded Register */ -#define SGR_NORMAL 0 -#define SGR_GUARDED 1 #define SPRN_SIA 0x3BB /* Sampled Instruction Address Register */ #define SPRN_SPRG0 0x110 /* Special Purpose Register General 0 */ #define SPRN_SPRG1 0x111 /* Special Purpose Register General 1 */ @@ -264,49 +161,8 @@ #define SPRN_TBWL 0x11C /* Time Base Lower Register (super, W/O) */ #define SPRN_TBWU 0x11D /* Time Base Write Upper Register (super, W/O) */ #define SPRN_HIOR 0x137 /* 970 Hypervisor interrupt offset */ -#define SPRN_TCR 0x3DA /* Timer Control Register */ -#define TCR_WP(x) (((x)&0x3)<<30) /* WDT Period */ -#define WP_2_17 0 /* 2^17 clocks */ -#define WP_2_21 1 /* 2^21 clocks */ -#define WP_2_25 2 /* 2^25 clocks */ -#define WP_2_29 3 /* 2^29 clocks */ -#define TCR_WRC(x) (((x)&0x3)<<28) /* WDT Reset Control */ -#define WRC_NONE 0 /* No reset will occur */ -#define WRC_CORE 1 /* Core reset will occur */ -#define WRC_CHIP 2 /* Chip reset will occur */ -#define WRC_SYSTEM 3 /* System reset will occur */ -#define TCR_WIE 0x08000000 /* WDT Interrupt Enable */ -#define TCR_PIE 0x04000000 /* PIT Interrupt Enable */ -#define TCR_FP(x) (((x)&0x3)<<24) /* FIT Period */ -#define FP_2_9 0 /* 2^9 clocks */ -#define FP_2_13 1 /* 2^13 clocks */ -#define FP_2_17 2 /* 2^17 clocks */ -#define FP_2_21 3 /* 2^21 clocks */ -#define TCR_FIE 0x00800000 /* FIT Interrupt Enable */ -#define TCR_ARE 0x00400000 /* Auto Reload Enable */ -#define SPRN_THRM1 0x3FC /* Thermal Management Register 1 */ -#define THRM1_TIN (1<<0) -#define THRM1_TIV (1<<1) -#define THRM1_THRES (0x7f<<2) -#define THRM1_TID (1<<29) -#define THRM1_TIE (1<<30) -#define THRM1_V (1<<31) -#define SPRN_THRM2 0x3FD /* Thermal Management Register 2 */ -#define SPRN_THRM3 0x3FE /* Thermal Management Register 3 */ -#define THRM3_E (1<<31) -#define SPRN_TSR 0x3D8 /* Timer Status Register */ -#define TSR_ENW 0x80000000 /* Enable Next Watchdog */ -#define TSR_WIS 0x40000000 /* WDT Interrupt Status */ -#define TSR_WRS(x) (((x)&0x3)<<28) /* WDT Reset Status */ -#define WRS_NONE 0 /* No WDT reset occurred */ -#define WRS_CORE 1 /* WDT forced core reset */ -#define WRS_CHIP 2 /* WDT forced chip reset */ -#define WRS_SYSTEM 3 /* WDT forced system reset */ -#define TSR_PIS 0x08000000 /* PIT Interrupt Status */ -#define TSR_FIS 0x04000000 /* FIT Interrupt Status */ #define SPRN_USIA 0x3AB /* User Sampled Instruction Address Register */ #define SPRN_XER 0x001 /* Fixed Point Exception Register */ -#define SPRN_ZPR 0x3B0 /* Zone Protection Register */ #define SPRN_VRSAVE 0x100 /* Vector save */ /* Performance monitor SPRs */ @@ -352,28 +208,19 @@ #define CTR SPRN_CTR /* Counter Register */ #define DAR SPRN_DAR /* Data Address Register */ #define DABR SPRN_DABR /* Data Address Breakpoint Register */ -#define DCMP SPRN_DCMP /* Data TLB Compare Register */ #define DEC SPRN_DEC /* Decrement Register */ -#define DMISS SPRN_DMISS /* Data TLB Miss Register */ #define DSISR SPRN_DSISR /* Data Storage Interrupt Status Register */ -#define EAR SPRN_EAR /* External Address Register */ -#define HASH1 SPRN_HASH1 /* Primary Hash Address Register */ -#define HASH2 SPRN_HASH2 /* Secondary Hash Address Register */ #define HID0 SPRN_HID0 /* Hardware Implementation Register 0 */ #define MSRDORM SPRN_MSRDORM /* MSR Dormant Register */ #define NIADORM SPRN_NIADORM /* NIA Dormant Register */ #define TSC SPRN_TSC /* Thread switch control */ #define TST SPRN_TST /* Thread switch timeout */ #define IABR SPRN_IABR /* Instruction Address Breakpoint Register */ -#define ICMP SPRN_ICMP /* Instruction TLB Compare Register */ -#define IMISS SPRN_IMISS /* Instruction TLB Miss Register */ -#define IMMR SPRN_IMMR /* PPC 860/821 Internal Memory Map Register */ #define L2CR SPRN_L2CR /* PPC 750 L2 control register */ #define __LR SPRN_LR #define PVR SPRN_PVR /* Processor Version */ #define PIR SPRN_PIR /* Processor ID */ #define PURR SPRN_PURR /* Processor Utilization of Resource Register */ -//#define RPA SPRN_RPA /* Required Physical Address Register */ #define SDR1 SPRN_SDR1 /* MMU hash base register */ #define SPR0 SPRN_SPRG0 /* Supervisor Private Registers */ #define SPR1 SPRN_SPRG1 @@ -389,10 +236,6 @@ #define TBRU SPRN_TBRU /* Time Base Read Upper Register */ #define TBWL SPRN_TBWL /* Time Base Write Lower Register */ #define TBWU SPRN_TBWU /* Time Base Write Upper Register */ -#define ICTC 1019 -#define THRM1 SPRN_THRM1 /* Thermal Management Register 1 */ -#define THRM2 SPRN_THRM2 /* Thermal Management Register 2 */ -#define THRM3 SPRN_THRM3 /* Thermal Management Register 3 */ #define XER SPRN_XER /* Processor Version Register (PVR) field extraction */ -- cgit v1.2.3-70-g09d2 From 6dc2f0c7df6cefda5932ac8bcd9ca5ef45de36ee Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Thu, 2 Jun 2005 14:02:02 -0700 Subject: [PATCH] ppc64: cleanup iseries runlight support The iseries has a bar graph on the front panel that shows how busy it is. The operating system sets and clears a bit in the CTRL register to control it. Instead of going to the complexity of using a thread info bit, just set and clear it in the idle loop. Also create two helper functions, ppc64_runlatch_on and ppc64_runlatch_off. Finally don't use the short form of the SPR defines. Signed-off-by: Anton Blanchard Acked-by: Stephen Rothwell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc64/kernel/entry.S | 9 --------- arch/ppc64/kernel/head.S | 10 +++++----- arch/ppc64/kernel/idle.c | 8 +++----- arch/ppc64/kernel/process.c | 3 --- arch/ppc64/kernel/sysfs.c | 8 ++------ include/asm-ppc64/processor.h | 27 +++++++++++++++++++++------ include/asm-ppc64/thread_info.h | 4 ++-- 7 files changed, 33 insertions(+), 36 deletions(-) diff --git a/arch/ppc64/kernel/entry.S b/arch/ppc64/kernel/entry.S index d3604056e1a..b61572eb2a7 100644 --- a/arch/ppc64/kernel/entry.S +++ b/arch/ppc64/kernel/entry.S @@ -436,15 +436,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) REST_8GPRS(14, r1) REST_10GPRS(22, r1) -#ifdef CONFIG_PPC_ISERIES - clrrdi r7,r1,THREAD_SHIFT /* get current_thread_info() */ - ld r7,TI_FLAGS(r7) /* Get run light flag */ - mfspr r9,CTRLF - srdi r7,r7,TIF_RUN_LIGHT - insrdi r9,r7,1,63 /* Insert run light into CTRL */ - mtspr CTRLT,r9 -#endif - /* convert old thread to its task_struct for return value */ addi r3,r3,-THREAD ld r7,_NIP(r1) /* Return to _switch caller in new task */ diff --git a/arch/ppc64/kernel/head.S b/arch/ppc64/kernel/head.S index 92a744c31ab..346dbf606b5 100644 --- a/arch/ppc64/kernel/head.S +++ b/arch/ppc64/kernel/head.S @@ -626,10 +626,10 @@ system_reset_iSeries: lhz r24,PACAPACAINDEX(r13) /* Get processor # */ cmpwi 0,r24,0 /* Are we processor 0? */ beq .__start_initialization_iSeries /* Start up the first processor */ - mfspr r4,CTRLF - li r5,RUNLATCH /* Turn off the run light */ + mfspr r4,SPRN_CTRLF + li r5,CTRL_RUNLATCH /* Turn off the run light */ andc r4,r4,r5 - mtspr CTRLT,r4 + mtspr SPRN_CTRLT,r4 1: HMT_LOW @@ -2082,9 +2082,9 @@ _GLOBAL(hmt_start_secondary) mfspr r4, HID0 ori r4, r4, 0x1 mtspr HID0, r4 - mfspr r4, CTRLF + mfspr r4, SPRN_CTRLF oris r4, r4, 0x40 - mtspr CTRLT, r4 + mtspr SPRN_CTRLT, r4 blr #endif diff --git a/arch/ppc64/kernel/idle.c b/arch/ppc64/kernel/idle.c index 6abc621d3ba..f24ce2b8720 100644 --- a/arch/ppc64/kernel/idle.c +++ b/arch/ppc64/kernel/idle.c @@ -75,13 +75,9 @@ static int iSeries_idle(void) { struct paca_struct *lpaca; long oldval; - unsigned long CTRL; /* ensure iSeries run light will be out when idle */ - clear_thread_flag(TIF_RUN_LIGHT); - CTRL = mfspr(CTRLF); - CTRL &= ~RUNLATCH; - mtspr(CTRLT, CTRL); + ppc64_runlatch_off(); lpaca = get_paca(); @@ -111,7 +107,9 @@ static int iSeries_idle(void) } } + ppc64_runlatch_on(); schedule(); + ppc64_runlatch_off(); } return 0; diff --git a/arch/ppc64/kernel/process.c b/arch/ppc64/kernel/process.c index 8b068612273..cdfecbeb331 100644 --- a/arch/ppc64/kernel/process.c +++ b/arch/ppc64/kernel/process.c @@ -378,9 +378,6 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp, childregs->gpr[1] = sp + sizeof(struct pt_regs); p->thread.regs = NULL; /* no user register state */ clear_ti_thread_flag(p->thread_info, TIF_32BIT); -#ifdef CONFIG_PPC_ISERIES - set_ti_thread_flag(p->thread_info, TIF_RUN_LIGHT); -#endif } else { childregs->gpr[1] = usp; p->thread.regs = childregs; diff --git a/arch/ppc64/kernel/sysfs.c b/arch/ppc64/kernel/sysfs.c index 0925694c3ce..c8fa6569b2f 100644 --- a/arch/ppc64/kernel/sysfs.c +++ b/arch/ppc64/kernel/sysfs.c @@ -113,7 +113,6 @@ void ppc64_enable_pmcs(void) #ifdef CONFIG_PPC_PSERIES unsigned long set, reset; int ret; - unsigned int ctrl; #endif /* CONFIG_PPC_PSERIES */ /* Only need to enable them once */ @@ -167,11 +166,8 @@ void ppc64_enable_pmcs(void) * On SMT machines we have to set the run latch in the ctrl register * in order to make PMC6 spin. */ - if (cpu_has_feature(CPU_FTR_SMT)) { - ctrl = mfspr(CTRLF); - ctrl |= RUNLATCH; - mtspr(CTRLT, ctrl); - } + if (cpu_has_feature(CPU_FTR_SMT)) + ppc64_runlatch_on(); #endif /* CONFIG_PPC_PSERIES */ } diff --git a/include/asm-ppc64/processor.h b/include/asm-ppc64/processor.h index 5ba6aa45e1e..809c634ba1d 100644 --- a/include/asm-ppc64/processor.h +++ b/include/asm-ppc64/processor.h @@ -164,6 +164,9 @@ #define SPRN_USIA 0x3AB /* User Sampled Instruction Address Register */ #define SPRN_XER 0x001 /* Fixed Point Exception Register */ #define SPRN_VRSAVE 0x100 /* Vector save */ +#define SPRN_CTRLF 0x088 +#define SPRN_CTRLT 0x098 +#define CTRL_RUNLATCH 0x1 /* Performance monitor SPRs */ #define SPRN_SIAR 780 @@ -279,12 +282,6 @@ #define XGLUE(a,b) a##b #define GLUE(a,b) XGLUE(a,b) -/* iSeries CTRL register (for runlatch) */ - -#define CTRLT 0x098 -#define CTRLF 0x088 -#define RUNLATCH 0x0001 - #ifdef __ASSEMBLY__ #define _GLOBAL(name) \ @@ -499,6 +496,24 @@ static inline void prefetchw(const void *x) #define HAVE_ARCH_PICK_MMAP_LAYOUT +static inline void ppc64_runlatch_on(void) +{ + unsigned long ctrl; + + ctrl = mfspr(SPRN_CTRLF); + ctrl |= CTRL_RUNLATCH; + mtspr(SPRN_CTRLT, ctrl); +} + +static inline void ppc64_runlatch_off(void) +{ + unsigned long ctrl; + + ctrl = mfspr(SPRN_CTRLF); + ctrl &= ~CTRL_RUNLATCH; + mtspr(SPRN_CTRLT, ctrl); +} + #endif /* __KERNEL__ */ #endif /* __ASSEMBLY__ */ diff --git a/include/asm-ppc64/thread_info.h b/include/asm-ppc64/thread_info.h index 037b5e06083..48b7900e90e 100644 --- a/include/asm-ppc64/thread_info.h +++ b/include/asm-ppc64/thread_info.h @@ -96,7 +96,7 @@ static inline struct thread_info *current_thread_info(void) #define TIF_POLLING_NRFLAG 4 /* true if poll_idle() is polling TIF_NEED_RESCHED */ #define TIF_32BIT 5 /* 32 bit binary */ -#define TIF_RUN_LIGHT 6 /* iSeries run light */ +/* #define SPARE 6 */ #define TIF_ABI_PENDING 7 /* 32/64 bit switch needed */ #define TIF_SYSCALL_AUDIT 8 /* syscall auditing active */ #define TIF_SINGLESTEP 9 /* singlestepping active */ @@ -110,7 +110,7 @@ static inline struct thread_info *current_thread_info(void) #define _TIF_NEED_RESCHED (1< Date: Thu, 2 Jun 2005 14:02:03 -0700 Subject: [PATCH] ppc64: remove decr_overclock Now that we have HZ=1000 there is much less of a need for decr_overclock. Remove it. Leave spread_lpevents but move it into iSeries_setup.c. We should look at making event spreading the default some day. Signed-off-by: Anton Blanchard Acked-by: Stephen Rothwell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc64/kernel/iSeries_setup.c | 22 +++++++++++++++ arch/ppc64/kernel/setup.c | 56 +-------------------------------------- arch/ppc64/kernel/smp.c | 3 +-- 3 files changed, 24 insertions(+), 57 deletions(-) diff --git a/arch/ppc64/kernel/iSeries_setup.c b/arch/ppc64/kernel/iSeries_setup.c index da20120f226..6d06eb550a3 100644 --- a/arch/ppc64/kernel/iSeries_setup.c +++ b/arch/ppc64/kernel/iSeries_setup.c @@ -852,6 +852,28 @@ static int __init iSeries_src_init(void) late_initcall(iSeries_src_init); +static int set_spread_lpevents(char *str) +{ + unsigned long i; + unsigned long val = simple_strtoul(str, NULL, 0); + + /* + * The parameter is the number of processors to share in processing + * lp events. + */ + if (( val > 0) && (val <= NR_CPUS)) { + for (i = 1; i < val; ++i) + paca[i].lpqueue_ptr = paca[0].lpqueue_ptr; + + printk("lpevent processing spread over %ld processors\n", val); + } else { + printk("invalid spread_lpevents %ld\n", val); + } + + return 1; +} +__setup("spread_lpevents=", set_spread_lpevents); + void __init iSeries_early_setup(void) { iSeries_fixup_klimit(); diff --git a/arch/ppc64/kernel/setup.c b/arch/ppc64/kernel/setup.c index 21c57f539c2..dce198d3932 100644 --- a/arch/ppc64/kernel/setup.c +++ b/arch/ppc64/kernel/setup.c @@ -103,11 +103,6 @@ extern void unflatten_device_tree(void); extern void smp_release_cpus(void); -unsigned long decr_overclock = 1; -unsigned long decr_overclock_proc0 = 1; -unsigned long decr_overclock_set = 0; -unsigned long decr_overclock_proc0_set = 0; - int have_of = 1; int boot_cpuid = 0; int boot_cpuid_phys = 0; @@ -1120,64 +1115,15 @@ void ppc64_dump_msg(unsigned int src, const char *msg) printk("[dump]%04x %s\n", src, msg); } -int set_spread_lpevents( char * str ) -{ - /* The parameter is the number of processors to share in processing lp events */ - unsigned long i; - unsigned long val = simple_strtoul( str, NULL, 0 ); - if ( ( val > 0 ) && ( val <= NR_CPUS ) ) { - for ( i=1; idefault_decr = tb_ticks_per_jiffy / decr_overclock_proc0; + lpaca->default_decr = tb_ticks_per_jiffy; lpaca->next_jiffy_update_tb = get_tb() + tb_ticks_per_jiffy; } -int set_decr_overclock_proc0( char * str ) -{ - unsigned long val = simple_strtoul( str, NULL, 0 ); - if ( ( val >= 1 ) && ( val <= 48 ) ) { - decr_overclock_proc0_set = 1; - decr_overclock_proc0 = val; - printk("proc 0 decrementer overclock factor of %ld\n", val); - } - else - printk("invalid proc 0 decrementer overclock factor of %ld\n", val); - return 1; -} - -int set_decr_overclock( char * str ) -{ - unsigned long val = simple_strtoul( str, NULL, 0 ); - if ( ( val >= 1 ) && ( val <= 48 ) ) { - decr_overclock_set = 1; - decr_overclock = val; - printk("decrementer overclock factor of %ld\n", val); - } - else - printk("invalid decrementer overclock factor of %ld\n", val); - return 1; - -} - -__setup("spread_lpevents=", set_spread_lpevents ); -__setup("decr_overclock_proc0=", set_decr_overclock_proc0 ); -__setup("decr_overclock=", set_decr_overclock ); - #ifndef CONFIG_PPC_ISERIES /* * This function can be used by platforms to "find" legacy serial ports. diff --git a/arch/ppc64/kernel/smp.c b/arch/ppc64/kernel/smp.c index 3b906cd9403..9ef5d36d6b2 100644 --- a/arch/ppc64/kernel/smp.c +++ b/arch/ppc64/kernel/smp.c @@ -334,7 +334,6 @@ void smp_call_function_interrupt(void) } } -extern unsigned long decr_overclock; extern struct gettimeofday_struct do_gtod; struct thread_info *current_set[NR_CPUS]; @@ -491,7 +490,7 @@ int __devinit __cpu_up(unsigned int cpu) if (smp_ops->cpu_bootable && !smp_ops->cpu_bootable(cpu)) return -EINVAL; - paca[cpu].default_decr = tb_ticks_per_jiffy / decr_overclock; + paca[cpu].default_decr = tb_ticks_per_jiffy; if (!cpu_has_feature(CPU_FTR_SLB)) { void *tmp; -- cgit v1.2.3-70-g09d2 From 0fd56f67890acf7904c83e7de6cb71723eb1c962 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Thu, 2 Jun 2005 14:04:00 -0700 Subject: [PATCH] drivers/net/hamradio/baycom_epp.c: cleanups The times when tricky goto's produced better codes are long gone. This patch should express the same in a better way. (Also fixes the final gcc-4.0 x86 compile error) Signed-off-by: Adrian Bunk Cc: Jeff Garzik Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/net/hamradio/baycom_epp.c | 126 +++++++++++--------------------------- 1 file changed, 36 insertions(+), 90 deletions(-) diff --git a/drivers/net/hamradio/baycom_epp.c b/drivers/net/hamradio/baycom_epp.c index 1c563f905a5..a7f15d9f13e 100644 --- a/drivers/net/hamradio/baycom_epp.c +++ b/drivers/net/hamradio/baycom_epp.c @@ -374,29 +374,6 @@ static inline void do_kiss_params(struct baycom_state *bc, } /* --------------------------------------------------------------------- */ -/* - * high performance HDLC encoder - * yes, it's ugly, but generates pretty good code - */ - -#define ENCODEITERA(j) \ -({ \ - if (!(notbitstream & (0x1f0 << j))) \ - goto stuff##j; \ - encodeend##j: ; \ -}) - -#define ENCODEITERB(j) \ -({ \ - stuff##j: \ - bitstream &= ~(0x100 << j); \ - bitbuf = (bitbuf & (((2 << j) << numbit) - 1)) | \ - ((bitbuf & ~(((2 << j) << numbit) - 1)) << 1); \ - numbit++; \ - notbitstream = ~bitstream; \ - goto encodeend##j; \ -}) - static void encode_hdlc(struct baycom_state *bc) { @@ -405,6 +382,7 @@ static void encode_hdlc(struct baycom_state *bc) int pkt_len; unsigned bitstream, notbitstream, bitbuf, numbit, crc; unsigned char crcarr[2]; + int j; if (bc->hdlctx.bufcnt > 0) return; @@ -429,24 +407,14 @@ static void encode_hdlc(struct baycom_state *bc) pkt_len--; if (!pkt_len) bp = crcarr; - ENCODEITERA(0); - ENCODEITERA(1); - ENCODEITERA(2); - ENCODEITERA(3); - ENCODEITERA(4); - ENCODEITERA(5); - ENCODEITERA(6); - ENCODEITERA(7); - goto enditer; - ENCODEITERB(0); - ENCODEITERB(1); - ENCODEITERB(2); - ENCODEITERB(3); - ENCODEITERB(4); - ENCODEITERB(5); - ENCODEITERB(6); - ENCODEITERB(7); - enditer: + for (j = 0; j < 8; j++) + if (unlikely(!(notbitstream & (0x1f0 << j)))) { + bitstream &= ~(0x100 << j); + bitbuf = (bitbuf & (((2 << j) << numbit) - 1)) | + ((bitbuf & ~(((2 << j) << numbit) - 1)) << 1); + numbit++; + notbitstream = ~bitstream; + } numbit += 8; while (numbit >= 8) { *wp++ = bitbuf; @@ -610,37 +578,6 @@ static void do_rxpacket(struct net_device *dev) bc->stats.rx_packets++; } -#define DECODEITERA(j) \ -({ \ - if (!(notbitstream & (0x0fc << j))) /* flag or abort */ \ - goto flgabrt##j; \ - if ((bitstream & (0x1f8 << j)) == (0xf8 << j)) /* stuffed bit */ \ - goto stuff##j; \ - enditer##j: ; \ -}) - -#define DECODEITERB(j) \ -({ \ - flgabrt##j: \ - if (!(notbitstream & (0x1fc << j))) { /* abort received */ \ - state = 0; \ - goto enditer##j; \ - } \ - if ((bitstream & (0x1fe << j)) != (0x0fc << j)) /* flag received */ \ - goto enditer##j; \ - if (state) \ - do_rxpacket(dev); \ - bc->hdlcrx.bufcnt = 0; \ - bc->hdlcrx.bufptr = bc->hdlcrx.buf; \ - state = 1; \ - numbits = 7-j; \ - goto enditer##j; \ - stuff##j: \ - numbits--; \ - bitbuf = (bitbuf & ((~0xff) << j)) | ((bitbuf & ~((~0xff) << j)) << 1); \ - goto enditer##j; \ -}) - static int receive(struct net_device *dev, int cnt) { struct baycom_state *bc = netdev_priv(dev); @@ -649,6 +586,7 @@ static int receive(struct net_device *dev, int cnt) unsigned char tmp[128]; unsigned char *cp; int cnt2, ret = 0; + int j; numbits = bc->hdlcrx.numbits; state = bc->hdlcrx.state; @@ -669,24 +607,32 @@ static int receive(struct net_device *dev, int cnt) bitbuf |= (*cp) << 8; numbits += 8; notbitstream = ~bitstream; - DECODEITERA(0); - DECODEITERA(1); - DECODEITERA(2); - DECODEITERA(3); - DECODEITERA(4); - DECODEITERA(5); - DECODEITERA(6); - DECODEITERA(7); - goto enddec; - DECODEITERB(0); - DECODEITERB(1); - DECODEITERB(2); - DECODEITERB(3); - DECODEITERB(4); - DECODEITERB(5); - DECODEITERB(6); - DECODEITERB(7); - enddec: + for (j = 0; j < 8; j++) { + + /* flag or abort */ + if (unlikely(!(notbitstream & (0x0fc << j)))) { + + /* abort received */ + if (!(notbitstream & (0x1fc << j))) + state = 0; + + /* not flag received */ + else if (!(bitstream & (0x1fe << j)) != (0x0fc << j)) { + if (state) + do_rxpacket(dev); + bc->hdlcrx.bufcnt = 0; + bc->hdlcrx.bufptr = bc->hdlcrx.buf; + state = 1; + numbits = 7-j; + } + } + + /* stuffed bit */ + else if (unlikely((bitstream & (0x1f8 << j)) == (0xf8 << j))) { + numbits--; + bitbuf = (bitbuf & ((~0xff) << j)) | ((bitbuf & ~((~0xff) << j)) << 1); + } + } while (state && numbits >= 8) { if (bc->hdlcrx.bufcnt >= TXBUFFER_SIZE) { state = 0; -- cgit v1.2.3-70-g09d2 From d0d2f2df65ddea9a30ddd117f769bfff65d3fc56 Mon Sep 17 00:00:00 2001 From: Steve French Date: Thu, 2 Jun 2005 15:12:36 -0700 Subject: [CIFS] Update cifs version number and fix whitespace Signed-off-by: Steve French (sfrench@us.ibm.com) --- fs/cifs/cifsfs.h | 2 +- fs/cifs/inode.c | 34 +++++++++++++++++----------------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h index d00b3bfe1a5..78af5850c55 100644 --- a/fs/cifs/cifsfs.h +++ b/fs/cifs/cifsfs.h @@ -96,5 +96,5 @@ extern ssize_t cifs_getxattr(struct dentry *, const char *, void *, size_t); extern ssize_t cifs_listxattr(struct dentry *, char *, size_t); extern int cifs_ioctl (struct inode * inode, struct file * filep, unsigned int command, unsigned long arg); -#define CIFS_VERSION "1.34" +#define CIFS_VERSION "1.35" #endif /* _CIFSFS_H */ diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index b8b78cbb34c..8d336a90025 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -82,12 +82,12 @@ int cifs_get_inode_info_unix(struct inode **pinode, /* get new inode */ if (*pinode == NULL) { *pinode = new_inode(sb); - if(*pinode == NULL) + if (*pinode == NULL) return -ENOMEM; /* Is an i_ino of zero legal? */ /* Are there sanity checks we can use to ensure that the server is really filling in that field? */ - if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) { + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) { (*pinode)->i_ino = (unsigned long)findData.UniqueId; } /* note ino incremented to unique num in new_inode */ @@ -134,7 +134,7 @@ int cifs_get_inode_info_unix(struct inode **pinode, inode->i_gid = le64_to_cpu(findData.Gid); inode->i_nlink = le64_to_cpu(findData.Nlinks); - if(is_size_safe_to_change(cifsInfo)) { + if (is_size_safe_to_change(cifsInfo)) { /* can not safely change the file size here if the client is writing to it due to potential races */ @@ -162,7 +162,7 @@ int cifs_get_inode_info_unix(struct inode **pinode, if (S_ISREG(inode->i_mode)) { cFYI(1, (" File inode ")); inode->i_op = &cifs_file_inode_ops; - if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) inode->i_fop = &cifs_file_direct_ops; else inode->i_fop = &cifs_file_ops; @@ -198,17 +198,17 @@ int cifs_get_inode_info(struct inode **pinode, pTcon = cifs_sb->tcon; cFYI(1,("Getting info on %s ", search_path)); - if((pfindData == NULL) && (*pinode != NULL)) { - if(CIFS_I(*pinode)->clientCanCacheRead) { + if ((pfindData == NULL) && (*pinode != NULL)) { + if (CIFS_I(*pinode)->clientCanCacheRead) { cFYI(1,("No need to revalidate cached inode sizes")); return rc; } } /* if file info not passed in then get it from server */ - if(pfindData == NULL) { + if (pfindData == NULL) { buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); - if(buf == NULL) + if (buf == NULL) return -ENOMEM; pfindData = (FILE_ALL_INFO *)buf; /* could do find first instead but this returns more info */ @@ -268,7 +268,7 @@ int cifs_get_inode_info(struct inode **pinode, IndexNumber field is not guaranteed unique? */ #ifdef CONFIG_CIFS_EXPERIMENTAL - if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM){ + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM){ int rc1 = 0; __u64 inode_num; @@ -277,7 +277,7 @@ int cifs_get_inode_info(struct inode **pinode, cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); - if(rc1) { + if (rc1) { cFYI(1,("GetSrvInodeNum rc %d", rc1)); /* BB EOPNOSUPP disable SERVER_INUM? */ } else /* do we need cast or hash to ino? */ @@ -355,7 +355,7 @@ int cifs_get_inode_info(struct inode **pinode, if (S_ISREG(inode->i_mode)) { cFYI(1, (" File inode ")); inode->i_op = &cifs_file_inode_ops; - if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) inode->i_fop = &cifs_file_direct_ops; else inode->i_fop = &cifs_file_ops; @@ -422,7 +422,7 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry) cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); if (!rc) { - if(direntry->d_inode) + if (direntry->d_inode) direntry->d_inode->i_nlink--; } else if (rc == -ENOENT) { d_drop(direntry); @@ -441,7 +441,7 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry) cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); CIFSSMBClose(xid, pTcon, netfid); - if(direntry->d_inode) + if (direntry->d_inode) direntry->d_inode->i_nlink--; } } else if (rc == -EACCES) { @@ -496,7 +496,7 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry) cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); if (!rc) { - if(direntry->d_inode) + if (direntry->d_inode) direntry->d_inode->i_nlink--; } else if (rc == -ETXTBSY) { int oplock = FALSE; @@ -517,14 +517,14 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry) cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); CIFSSMBClose(xid, pTcon, netfid); - if(direntry->d_inode) + if (direntry->d_inode) direntry->d_inode->i_nlink--; } /* BB if rc = -ETXTBUSY goto the rename logic BB */ } } } - if(direntry->d_inode) { + if (direntry->d_inode) { cifsInode = CIFS_I(direntry->d_inode); cifsInode->time = 0; /* will force revalidate to get info when needed */ @@ -582,7 +582,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode) if (direntry->d_inode) direntry->d_inode->i_nlink = 2; if (cifs_sb->tcon->ses->capabilities & CAP_UNIX) - if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode, (__u64)current->euid, -- cgit v1.2.3-70-g09d2 From 0baab86b00cdf9785ac2bb2ce1ab63995b3866ca Mon Sep 17 00:00:00 2001 From: Edward Falk Date: Thu, 2 Jun 2005 18:17:13 -0400 Subject: libata: update inline source docs --- drivers/scsi/libata-core.c | 283 +++++++++++++++++++++++++++++++++++++++++++-- include/linux/libata.h | 58 ++++++++++ 2 files changed, 334 insertions(+), 7 deletions(-) diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index 31b2984f379..86e84ed87be 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c @@ -186,6 +186,28 @@ static void ata_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf) ata_wait_idle(ap); } + +/** + * ata_tf_load - send taskfile registers to host controller + * @ap: Port to which output is sent + * @tf: ATA taskfile register set + * + * Outputs ATA taskfile to standard ATA host controller using MMIO + * or PIO as indicated by the ATA_FLAG_MMIO flag. + * Writes the control, feature, nsect, lbal, lbam, and lbah registers. + * Optionally (ATA_TFLAG_LBA48) writes hob_feature, hob_nsect, + * hob_lbal, hob_lbam, and hob_lbah. + * + * This function waits for idle (!BUSY and !DRQ) after writing + * registers. If the control register has a new value, this + * function also waits for idle after writing control and before + * writing the remaining registers. + * + * May be used as the tf_load() entry in ata_port_operations. + * + * LOCKING: + * Inherited from caller. + */ void ata_tf_load(struct ata_port *ap, struct ata_taskfile *tf) { if (ap->flags & ATA_FLAG_MMIO) @@ -195,11 +217,11 @@ void ata_tf_load(struct ata_port *ap, struct ata_taskfile *tf) } /** - * ata_exec_command - issue ATA command to host controller + * ata_exec_command_pio - issue ATA command to host controller * @ap: port to which command is being issued * @tf: ATA taskfile register set * - * Issues PIO/MMIO write to ATA command register, with proper + * Issues PIO write to ATA command register, with proper * synchronization with interrupt handler / other threads. * * LOCKING: @@ -235,6 +257,18 @@ static void ata_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf) ata_pause(ap); } + +/** + * ata_exec_command - issue ATA command to host controller + * @ap: port to which command is being issued + * @tf: ATA taskfile register set + * + * Issues PIO/MMIO write to ATA command register, with proper + * synchronization with interrupt handler / other threads. + * + * LOCKING: + * spin_lock_irqsave(host_set lock) + */ void ata_exec_command(struct ata_port *ap, struct ata_taskfile *tf) { if (ap->flags & ATA_FLAG_MMIO) @@ -305,7 +339,7 @@ void ata_tf_to_host_nolock(struct ata_port *ap, struct ata_taskfile *tf) } /** - * ata_tf_read - input device's ATA taskfile shadow registers + * ata_tf_read_pio - input device's ATA taskfile shadow registers * @ap: Port from which input is read * @tf: ATA taskfile register set for storing input * @@ -368,6 +402,23 @@ static void ata_tf_read_mmio(struct ata_port *ap, struct ata_taskfile *tf) } } + +/** + * ata_tf_read - input device's ATA taskfile shadow registers + * @ap: Port from which input is read + * @tf: ATA taskfile register set for storing input + * + * Reads ATA taskfile registers for currently-selected device + * into @tf. + * + * Reads nsect, lbal, lbam, lbah, and device. If ATA_TFLAG_LBA48 + * is set, also reads the hob registers. + * + * May be used as the tf_read() entry in ata_port_operations. + * + * LOCKING: + * Inherited from caller. + */ void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf) { if (ap->flags & ATA_FLAG_MMIO) @@ -381,7 +432,7 @@ void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf) * @ap: port where the device is * * Reads ATA taskfile status register for currently-selected device - * and return it's value. This also clears pending interrupts + * and return its value. This also clears pending interrupts * from this device * * LOCKING: @@ -397,7 +448,7 @@ static u8 ata_check_status_pio(struct ata_port *ap) * @ap: port where the device is * * Reads ATA taskfile status register for currently-selected device - * via MMIO and return it's value. This also clears pending interrupts + * via MMIO and return its value. This also clears pending interrupts * from this device * * LOCKING: @@ -408,6 +459,20 @@ static u8 ata_check_status_mmio(struct ata_port *ap) return readb((void __iomem *) ap->ioaddr.status_addr); } + +/** + * ata_check_status - Read device status reg & clear interrupt + * @ap: port where the device is + * + * Reads ATA taskfile status register for currently-selected device + * and return its value. This also clears pending interrupts + * from this device + * + * May be used as the check_status() entry in ata_port_operations. + * + * LOCKING: + * Inherited from caller. + */ u8 ata_check_status(struct ata_port *ap) { if (ap->flags & ATA_FLAG_MMIO) @@ -415,6 +480,20 @@ u8 ata_check_status(struct ata_port *ap) return ata_check_status_pio(ap); } + +/** + * ata_altstatus - Read device alternate status reg + * @ap: port where the device is + * + * Reads ATA taskfile alternate status register for + * currently-selected device and return its value. + * + * Note: may NOT be used as the check_altstatus() entry in + * ata_port_operations. + * + * LOCKING: + * Inherited from caller. + */ u8 ata_altstatus(struct ata_port *ap) { if (ap->ops->check_altstatus) @@ -425,6 +504,20 @@ u8 ata_altstatus(struct ata_port *ap) return inb(ap->ioaddr.altstatus_addr); } + +/** + * ata_chk_err - Read device error reg + * @ap: port where the device is + * + * Reads ATA taskfile error register for + * currently-selected device and return its value. + * + * Note: may NOT be used as the check_err() entry in + * ata_port_operations. + * + * LOCKING: + * Inherited from caller. + */ u8 ata_chk_err(struct ata_port *ap) { if (ap->ops->check_err) @@ -873,10 +966,24 @@ void ata_dev_id_string(u16 *id, unsigned char *s, } } + +/** + * ata_noop_dev_select - Select device 0/1 on ATA bus + * @ap: ATA channel to manipulate + * @device: ATA device (numbered from zero) to select + * + * This function performs no actual function. + * + * May be used as the dev_select() entry in ata_port_operations. + * + * LOCKING: + * caller. + */ void ata_noop_dev_select (struct ata_port *ap, unsigned int device) { } + /** * ata_std_dev_select - Select device 0/1 on ATA bus * @ap: ATA channel to manipulate @@ -884,7 +991,9 @@ void ata_noop_dev_select (struct ata_port *ap, unsigned int device) * * Use the method defined in the ATA specification to * make either device 0, or device 1, active on the - * ATA channel. + * ATA channel. Works with both PIO and MMIO. + * + * May be used as the dev_select() entry in ata_port_operations. * * LOCKING: * caller. @@ -2127,6 +2236,19 @@ void ata_qc_prep(struct ata_queued_cmd *qc) * spin_lock_irqsave(host_set lock) */ + + +/** + * ata_sg_init_one - Prepare a one-entry scatter-gather list. + * @qc: Queued command + * @buf: transfer buffer + * @buflen: length of buf + * + * Builds a single-entry scatter-gather list to initiate a + * transfer utilizing the specified buffer. + * + * LOCKING: + */ void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf, unsigned int buflen) { struct scatterlist *sg; @@ -2158,6 +2280,18 @@ void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf, unsigned int buflen) * spin_lock_irqsave(host_set lock) */ + +/** + * ata_sg_init - Assign a scatter gather list to a queued command + * @qc: Queued command + * @sg: Scatter-gather list + * @n_elem: length of sg list + * + * Attaches a scatter-gather list to a queued command. + * + * LOCKING: + */ + void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg, unsigned int n_elem) { @@ -2331,6 +2465,18 @@ static void ata_pio_complete (struct ata_port *ap) ata_qc_complete(qc, drv_stat); } + +/** + * swap_buf_le16 - + * @buf: Buffer to swap + * @buf_words: Number of 16-bit words in buffer. + * + * Swap halves of 16-bit words if needed to convert from + * little-endian byte order to native cpu byte order, or + * vice-versa. + * + * LOCKING: + */ void swap_buf_le16(u16 *buf, unsigned int buf_words) { #ifdef __BIG_ENDIAN @@ -2992,6 +3138,7 @@ err_out: return -1; } + /** * ata_qc_issue_prot - issue taskfile to device in proto-dependent manner * @qc: command to issue to device @@ -3001,6 +3148,8 @@ err_out: * classes called "protocols", and issuing each type of protocol * is slightly different. * + * May be used as the qc_issue() entry in ata_port_operations. + * * LOCKING: * spin_lock_irqsave(host_set lock) * @@ -3058,7 +3207,7 @@ int ata_qc_issue_prot(struct ata_queued_cmd *qc) } /** - * ata_bmdma_setup - Set up PCI IDE BMDMA transaction + * ata_bmdma_setup_mmio - Set up PCI IDE BMDMA transaction * @qc: Info associated with this ATA transaction. * * LOCKING: @@ -3165,6 +3314,18 @@ static void ata_bmdma_start_pio (struct ata_queued_cmd *qc) ap->ioaddr.bmdma_addr + ATA_DMA_CMD); } + +/** + * ata_bmdma_start - Start a PCI IDE BMDMA transaction + * @qc: Info associated with this ATA transaction. + * + * Writes the ATA_DMA_START flag to the DMA command register. + * + * May be used as the bmdma_start() entry in ata_port_operations. + * + * LOCKING: + * spin_lock_irqsave(host_set lock) + */ void ata_bmdma_start(struct ata_queued_cmd *qc) { if (qc->ap->flags & ATA_FLAG_MMIO) @@ -3173,6 +3334,20 @@ void ata_bmdma_start(struct ata_queued_cmd *qc) ata_bmdma_start_pio(qc); } + +/** + * ata_bmdma_setup - Set up PCI IDE BMDMA transaction + * @qc: Info associated with this ATA transaction. + * + * Writes address of PRD table to device's PRD Table Address + * register, sets the DMA control register, and calls + * ops->exec_command() to start the transfer. + * + * May be used as the bmdma_setup() entry in ata_port_operations. + * + * LOCKING: + * spin_lock_irqsave(host_set lock) + */ void ata_bmdma_setup(struct ata_queued_cmd *qc) { if (qc->ap->flags & ATA_FLAG_MMIO) @@ -3181,6 +3356,19 @@ void ata_bmdma_setup(struct ata_queued_cmd *qc) ata_bmdma_setup_pio(qc); } + +/** + * ata_bmdma_irq_clear - Clear PCI IDE BMDMA interrupt. + * @qc: Info associated with this ATA transaction. + * + * Clear interrupt and error flags in DMA status register. + * + * May be used as the irq_clear() entry in ata_port_operations. + * + * LOCKING: + * spin_lock_irqsave(host_set lock) + */ + void ata_bmdma_irq_clear(struct ata_port *ap) { if (ap->flags & ATA_FLAG_MMIO) { @@ -3193,6 +3381,19 @@ void ata_bmdma_irq_clear(struct ata_port *ap) } + +/** + * ata_bmdma_status - Read PCI IDE BMDMA status + * @qc: Info associated with this ATA transaction. + * + * Read and return BMDMA status register. + * + * May be used as the bmdma_status() entry in ata_port_operations. + * + * LOCKING: + * spin_lock_irqsave(host_set lock) + */ + u8 ata_bmdma_status(struct ata_port *ap) { u8 host_stat; @@ -3204,6 +3405,19 @@ u8 ata_bmdma_status(struct ata_port *ap) return host_stat; } + +/** + * ata_bmdma_stop - Stop PCI IDE BMDMA transfer + * @qc: Info associated with this ATA transaction. + * + * Clears the ATA_DMA_START flag in the dma control register + * + * May be used as the bmdma_stop() entry in ata_port_operations. + * + * LOCKING: + * spin_lock_irqsave(host_set lock) + */ + void ata_bmdma_stop(struct ata_port *ap) { if (ap->flags & ATA_FLAG_MMIO) { @@ -3407,6 +3621,19 @@ err_out: ata_qc_complete(qc, ATA_ERR); } + +/** + * ata_port_start - Set port up for dma. + * @ap: Port to initialize + * + * Called just after data structures for each port are + * initialized. Allocates space for PRD table. + * + * May be used as the port_start() entry in ata_port_operations. + * + * LOCKING: + */ + int ata_port_start (struct ata_port *ap) { struct device *dev = ap->host_set->dev; @@ -3420,6 +3647,18 @@ int ata_port_start (struct ata_port *ap) return 0; } + +/** + * ata_port_stop - Undo ata_port_start() + * @ap: Port to shut down + * + * Frees the PRD table. + * + * May be used as the port_stop() entry in ata_port_operations. + * + * LOCKING: + */ + void ata_port_stop (struct ata_port *ap) { struct device *dev = ap->host_set->dev; @@ -3720,7 +3959,15 @@ int ata_scsi_release(struct Scsi_Host *host) /** * ata_std_ports - initialize ioaddr with standard port offsets. * @ioaddr: IO address structure to be initialized + * + * Utility function which initializes data_addr, error_addr, + * feature_addr, nsect_addr, lbal_addr, lbam_addr, lbah_addr, + * device_addr, status_addr, and command_addr to standard offsets + * relative to cmd_addr. + * + * Does not set ctl_addr, altstatus_addr, bmdma_addr, or scr_addr. */ + void ata_std_ports(struct ata_ioports *ioaddr) { ioaddr->data_addr = ioaddr->cmd_addr + ATA_REG_DATA; @@ -3762,6 +4009,20 @@ ata_probe_ent_alloc(struct device *dev, struct ata_port_info *port) return probe_ent; } + + +/** + * ata_pci_init_native_mode - Initialize native-mode driver + * @pdev: pci device to be initialized + * @port: array[2] of pointers to port info structures. + * + * Utility function which allocates and initializes an + * ata_probe_ent structure for a standard dual-port + * PIO-based IDE controller. The returned ata_probe_ent + * structure can be passed to ata_device_add(). The returned + * ata_probe_ent structure should then be freed with kfree(). + */ + #ifdef CONFIG_PCI struct ata_probe_ent * ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port) @@ -3843,6 +4104,14 @@ ata_pci_init_legacy_mode(struct pci_dev *pdev, struct ata_port_info **port, * @port_info: Information from low-level host driver * @n_ports: Number of ports attached to host controller * + * This is a helper function which can be called from a driver's + * xxx_init_one() probe function if the hardware uses traditional + * IDE taskfile registers. + * + * This function calls pci_enable_device(), reserves its register + * regions, sets the dma mask, enables bus master mode, and calls + * ata_device_add() + * * LOCKING: * Inherited from PCI layer (may sleep). * diff --git a/include/linux/libata.h b/include/linux/libata.h index 1f7e2039a04..ad410590664 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -466,12 +466,34 @@ static inline u8 ata_chk_status(struct ata_port *ap) return ap->ops->check_status(ap); } + +/** + * ata_pause - Flush writes and pause 400 nanoseconds. + * @ap: Port to wait for. + * + * LOCKING: + * Inherited from caller. + */ + static inline void ata_pause(struct ata_port *ap) { ata_altstatus(ap); ndelay(400); } + +/** + * ata_busy_wait - Wait for a port status register + * @ap: Port to wait for. + * + * Waits up to max*10 microseconds for the selected bits in the port's + * status register to be cleared. + * Returns final value of status register. + * + * LOCKING: + * Inherited from caller. + */ + static inline u8 ata_busy_wait(struct ata_port *ap, unsigned int bits, unsigned int max) { @@ -486,6 +508,18 @@ static inline u8 ata_busy_wait(struct ata_port *ap, unsigned int bits, return status; } + +/** + * ata_wait_idle - Wait for a port to be idle. + * @ap: Port to wait for. + * + * Waits up to 10ms for port's BUSY and DRQ signals to clear. + * Returns final value of status register. + * + * LOCKING: + * Inherited from caller. + */ + static inline u8 ata_wait_idle(struct ata_port *ap) { u8 status = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000); @@ -524,6 +558,18 @@ static inline void ata_tf_init(struct ata_port *ap, struct ata_taskfile *tf, uns tf->device = ATA_DEVICE_OBS | ATA_DEV1; } + +/** + * ata_irq_on - Enable interrupts on a port. + * @ap: Port on which interrupts are enabled. + * + * Enable interrupts on a legacy IDE device using MMIO or PIO, + * wait for idle, clear any pending interrupts. + * + * LOCKING: + * Inherited from caller. + */ + static inline u8 ata_irq_on(struct ata_port *ap) { struct ata_ioports *ioaddr = &ap->ioaddr; @@ -543,6 +589,18 @@ static inline u8 ata_irq_on(struct ata_port *ap) return tmp; } + +/** + * ata_irq_ack - Acknowledge a device interrupt. + * @ap: Port on which interrupts are enabled. + * + * Wait up to 10 ms for legacy IDE device to become idle (BUSY + * or BUSY+DRQ clear). Obtain dma status and port status from + * device. Clear the interrupt. Return port status. + * + * LOCKING: + */ + static inline u8 ata_irq_ack(struct ata_port *ap, unsigned int chk_drq) { unsigned int bits = chk_drq ? ATA_BUSY | ATA_DRQ : ATA_BUSY; -- cgit v1.2.3-70-g09d2 From decc6d0b68f27bbb8a0357fccf41936a3c196b03 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Thu, 2 Jun 2005 18:42:33 -0400 Subject: libata: kernel-doc warning fixes --- drivers/scsi/libata-core.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index 86e84ed87be..a5d7c33a434 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c @@ -3359,7 +3359,7 @@ void ata_bmdma_setup(struct ata_queued_cmd *qc) /** * ata_bmdma_irq_clear - Clear PCI IDE BMDMA interrupt. - * @qc: Info associated with this ATA transaction. + * @ap: Port associated with this ATA transaction. * * Clear interrupt and error flags in DMA status register. * @@ -3384,7 +3384,7 @@ void ata_bmdma_irq_clear(struct ata_port *ap) /** * ata_bmdma_status - Read PCI IDE BMDMA status - * @qc: Info associated with this ATA transaction. + * @ap: Port associated with this ATA transaction. * * Read and return BMDMA status register. * @@ -3408,7 +3408,7 @@ u8 ata_bmdma_status(struct ata_port *ap) /** * ata_bmdma_stop - Stop PCI IDE BMDMA transfer - * @qc: Info associated with this ATA transaction. + * @ap: Port associated with this ATA transaction. * * Clears the ATA_DMA_START flag in the dma control register * -- cgit v1.2.3-70-g09d2 From b597ef4712c05c962640a655386a7f06cc1a1fbc Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 2 Jun 2005 16:36:00 -0700 Subject: [NET]: Fix locking in shaper driver. o use a semaphore instead of an opencoded and racy lock o move locking out of shaper_kick and into the callers - most just released the lock before calling shaper_kick o remove in_interrupt() tests. from ->close we can always block, from ->hard_start_xmit and timer context never Signed-off-by: Christoph Hellwig Signed-off-by: David S. Miller --- drivers/net/shaper.c | 86 +++++++++++------------------------------------ include/linux/if_shaper.h | 3 +- 2 files changed, 20 insertions(+), 69 deletions(-) diff --git a/drivers/net/shaper.c b/drivers/net/shaper.c index e68cf5fb492..20edeb34579 100644 --- a/drivers/net/shaper.c +++ b/drivers/net/shaper.c @@ -100,35 +100,8 @@ static int sh_debug; /* Debug flag */ #define SHAPER_BANNER "CymruNet Traffic Shaper BETA 0.04 for Linux 2.1\n" -/* - * Locking - */ - -static int shaper_lock(struct shaper *sh) -{ - /* - * Lock in an interrupt must fail - */ - while (test_and_set_bit(0, &sh->locked)) - { - if (!in_interrupt()) - sleep_on(&sh->wait_queue); - else - return 0; - - } - return 1; -} - static void shaper_kick(struct shaper *sh); -static void shaper_unlock(struct shaper *sh) -{ - clear_bit(0, &sh->locked); - wake_up(&sh->wait_queue); - shaper_kick(sh); -} - /* * Compute clocks on a buffer */ @@ -157,17 +130,15 @@ static void shaper_setspeed(struct shaper *shaper, int bitspersec) * Throw a frame at a shaper. */ -static int shaper_qframe(struct shaper *shaper, struct sk_buff *skb) + +static int shaper_start_xmit(struct sk_buff *skb, struct net_device *dev) { + struct shaper *shaper = dev->priv; struct sk_buff *ptr; - /* - * Get ready to work on this shaper. Lock may fail if its - * an interrupt and locked. - */ - - if(!shaper_lock(shaper)) - return -1; + if (down_trylock(&shaper->sem)) + return -1; + ptr=shaper->sendq.prev; /* @@ -260,7 +231,8 @@ static int shaper_qframe(struct shaper *shaper, struct sk_buff *skb) dev_kfree_skb(ptr); shaper->stats.collisions++; } - shaper_unlock(shaper); + shaper_kick(shaper); + up(&shaper->sem); return 0; } @@ -297,8 +269,13 @@ static void shaper_queue_xmit(struct shaper *shaper, struct sk_buff *skb) static void shaper_timer(unsigned long data) { - struct shaper *sh=(struct shaper *)data; - shaper_kick(sh); + struct shaper *shaper = (struct shaper *)data; + + if (!down_trylock(&shaper->sem)) { + shaper_kick(shaper); + up(&shaper->sem); + } else + mod_timer(&shaper->timer, jiffies); } /* @@ -310,19 +287,6 @@ static void shaper_kick(struct shaper *shaper) { struct sk_buff *skb; - /* - * Shaper unlock will kick - */ - - if (test_and_set_bit(0, &shaper->locked)) - { - if(sh_debug) - printk("Shaper locked.\n"); - mod_timer(&shaper->timer, jiffies); - return; - } - - /* * Walk the list (may be empty) */ @@ -364,8 +328,6 @@ static void shaper_kick(struct shaper *shaper) if(skb!=NULL) mod_timer(&shaper->timer, SHAPERCB(skb)->shapeclock); - - clear_bit(0, &shaper->locked); } @@ -376,14 +338,12 @@ static void shaper_kick(struct shaper *shaper) static void shaper_flush(struct shaper *shaper) { struct sk_buff *skb; - if(!shaper_lock(shaper)) - { - printk(KERN_ERR "shaper: shaper_flush() called by an irq!\n"); - return; - } + + down(&shaper->sem); while((skb=skb_dequeue(&shaper->sendq))!=NULL) dev_kfree_skb(skb); - shaper_unlock(shaper); + shaper_kick(shaper); + up(&shaper->sem); } /* @@ -426,13 +386,6 @@ static int shaper_close(struct net_device *dev) * ARP and other resolutions and not before. */ - -static int shaper_start_xmit(struct sk_buff *skb, struct net_device *dev) -{ - struct shaper *sh=dev->priv; - return shaper_qframe(sh, skb); -} - static struct net_device_stats *shaper_get_stats(struct net_device *dev) { struct shaper *sh=dev->priv; @@ -623,7 +576,6 @@ static void shaper_init_priv(struct net_device *dev) init_timer(&sh->timer); sh->timer.function=shaper_timer; sh->timer.data=(unsigned long)sh; - init_waitqueue_head(&sh->wait_queue); } /* diff --git a/include/linux/if_shaper.h b/include/linux/if_shaper.h index 0485b256d04..004e6f09a6e 100644 --- a/include/linux/if_shaper.h +++ b/include/linux/if_shaper.h @@ -23,7 +23,7 @@ struct shaper __u32 shapeclock; unsigned long recovery; /* Time we can next clock a packet out on an empty queue */ - unsigned long locked; + struct semaphore sem; struct net_device_stats stats; struct net_device *dev; int (*hard_start_xmit) (struct sk_buff *skb, @@ -38,7 +38,6 @@ struct shaper int (*hard_header_cache)(struct neighbour *neigh, struct hh_cache *hh); void (*header_cache_update)(struct hh_cache *hh, struct net_device *dev, unsigned char * haddr); struct net_device_stats* (*get_stats)(struct net_device *dev); - wait_queue_head_t wait_queue; struct timer_list timer; }; -- cgit v1.2.3-70-g09d2 From 5ba0eac6e0b7e2889649a1105d97c600595e2bb1 Mon Sep 17 00:00:00 2001 From: Jiri Benc Date: Thu, 2 Jun 2005 16:48:05 -0700 Subject: [NET]: Fix HH_DATA_OFF. When the hardware header size is a multiple of HH_DATA_MOD, HH_DATA_OFF() incorrectly returns HH_DATA_MOD (instead of 0). This affects ieee80211 layer as 802.11 header is 32 bytes long. Signed-off-by: Jiri Benc Signed-off-by: David S. Miller --- include/linux/netdevice.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 470af8c1a4a..ba5d1236aa1 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -204,7 +204,7 @@ struct hh_cache /* cached hardware header; allow for machine alignment needs. */ #define HH_DATA_MOD 16 #define HH_DATA_OFF(__len) \ - (HH_DATA_MOD - ((__len) & (HH_DATA_MOD - 1))) + (HH_DATA_MOD - (((__len - 1) & (HH_DATA_MOD - 1)) + 1)) #define HH_DATA_ALIGN(__len) \ (((__len)+(HH_DATA_MOD-1))&~(HH_DATA_MOD - 1)) unsigned long hh_data[HH_DATA_ALIGN(LL_MAX_HEADER) / sizeof(long)]; -- cgit v1.2.3-70-g09d2 From f4800078d9ed4bd20b1b27f56e7b68cfa0d73038 Mon Sep 17 00:00:00 2001 From: Pete Zaitcev Date: Sun, 1 May 2005 16:05:40 -0700 Subject: [PATCH] USB: Support multiply-LUN devices in ub Signed-off-by: Pete Zaitcev Signed-off-by: Greg Kroah-Hartman diff -urp -X dontdiff linux-2.6.12-rc3/drivers/block/ub.c linux-2.6.12-rc3-lem/drivers/block/ub.c --- drivers/block/ub.c | 598 ++++++++++++++++++++++++++++++++--------------------- 1 file changed, 363 insertions(+), 235 deletions(-) diff --git a/drivers/block/ub.c b/drivers/block/ub.c index ce42889f98f..adc4dcc306f 100644 --- a/drivers/block/ub.c +++ b/drivers/block/ub.c @@ -8,13 +8,12 @@ * and is not licensed separately. See file COPYING for details. * * TODO (sorted by decreasing priority) + * -- Kill first_open (Al Viro fixed the block layer now) * -- Do resets with usb_device_reset (needs a thread context, use khubd) * -- set readonly flag for CDs, set removable flag for CF readers * -- do inquiry and verify we got a disk and not a tape (for LUN mismatch) - * -- support pphaneuf's SDDR-75 with two LUNs (also broken capacity...) * -- special case some senses, e.g. 3a/0 -> no media present, reduce retries * -- verify the 13 conditions and do bulk resets - * -- normal pool of commands instead of cmdv[]? * -- kill last_pipe and simply do two-state clearing on both pipes * -- verify protocol (bulk) from USB descriptors (maybe...) * -- highmem and sg @@ -49,7 +48,14 @@ #define US_SC_SCSI 0x06 /* Transparent */ /* + * This many LUNs per USB device. + * Every one of them takes a host, see UB_MAX_HOSTS. */ +#define UB_MAX_LUNS 4 + +/* + */ + #define UB_MINORS_PER_MAJOR 8 #define UB_MAX_CDB_SIZE 16 /* Corresponds to Bulk */ @@ -65,7 +71,7 @@ struct bulk_cb_wrap { u32 Tag; /* unique per command id */ __le32 DataTransferLength; /* size of data */ u8 Flags; /* direction in bit 0 */ - u8 Lun; /* LUN normally 0 */ + u8 Lun; /* LUN */ u8 Length; /* of of the CDB */ u8 CDB[UB_MAX_CDB_SIZE]; /* max command */ }; @@ -168,6 +174,7 @@ struct ub_scsi_cmd { unsigned int len; /* Requested length */ // struct scatterlist sgv[UB_MAX_REQ_SG]; + struct ub_lun *lun; void (*done)(struct ub_dev *, struct ub_scsi_cmd *); void *back; }; @@ -252,25 +259,47 @@ struct ub_scsi_cmd_queue { }; /* - * The UB device instance. + * The block device instance (one per LUN). + */ +struct ub_lun { + struct ub_dev *udev; + struct list_head link; + struct gendisk *disk; + int id; /* Host index */ + int num; /* LUN number */ + char name[16]; + + int changed; /* Media was changed */ + int removable; + int readonly; + int first_open; /* Kludge. See ub_bd_open. */ + + /* Use Ingo's mempool if or when we have more than one command. */ + /* + * Currently we never need more than one command for the whole device. + * However, giving every LUN a command is a cheap and automatic way + * to enforce fairness between them. + */ + int cmda[1]; + struct ub_scsi_cmd cmdv[1]; + + struct ub_capacity capacity; +}; + +/* + * The USB device instance. */ struct ub_dev { spinlock_t lock; - int id; /* Number among ub's */ atomic_t poison; /* The USB device is disconnected */ int openc; /* protected by ub_lock! */ /* kref is too implicit for our taste */ unsigned int tagcnt; - int changed; /* Media was changed */ - int removable; - int readonly; - int first_open; /* Kludge. See ub_bd_open. */ - char name[8]; + char name[12]; struct usb_device *dev; struct usb_interface *intf; - struct ub_capacity capacity; - struct gendisk *disk; + struct list_head luns; unsigned int send_bulk_pipe; /* cached pipe values */ unsigned int recv_bulk_pipe; @@ -279,10 +308,6 @@ struct ub_dev { struct tasklet_struct tasklet; - /* XXX Use Ingo's mempool (once we have more than one) */ - int cmda[1]; - struct ub_scsi_cmd cmdv[1]; - struct ub_scsi_cmd_queue cmd_queue; struct ub_scsi_cmd top_rqs_cmd; /* REQUEST SENSE */ unsigned char top_sense[UB_SENSE_SIZE]; @@ -301,9 +326,9 @@ struct ub_dev { /* */ static void ub_cleanup(struct ub_dev *sc); -static int ub_bd_rq_fn_1(struct ub_dev *sc, struct request *rq); -static int ub_cmd_build_block(struct ub_dev *sc, struct ub_scsi_cmd *cmd, - struct request *rq); +static int ub_bd_rq_fn_1(struct ub_lun *lun, struct request *rq); +static int ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun, + struct ub_scsi_cmd *cmd, struct request *rq); static int ub_cmd_build_packet(struct ub_dev *sc, struct ub_scsi_cmd *cmd, struct request *rq); static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd); @@ -320,8 +345,10 @@ static void ub_state_sense(struct ub_dev *sc, struct ub_scsi_cmd *cmd); static int ub_submit_clear_stall(struct ub_dev *sc, struct ub_scsi_cmd *cmd, int stalled_pipe); static void ub_top_sense_done(struct ub_dev *sc, struct ub_scsi_cmd *scmd); -static int ub_sync_tur(struct ub_dev *sc); -static int ub_sync_read_cap(struct ub_dev *sc, struct ub_capacity *ret); +static int ub_sync_tur(struct ub_dev *sc, struct ub_lun *lun); +static int ub_sync_read_cap(struct ub_dev *sc, struct ub_lun *lun, + struct ub_capacity *ret); +static int ub_probe_lun(struct ub_dev *sc, int lnum); /* */ @@ -342,6 +369,7 @@ MODULE_DEVICE_TABLE(usb, ub_usb_ids); */ #define UB_MAX_HOSTS 26 static char ub_hostv[UB_MAX_HOSTS]; + static DEFINE_SPINLOCK(ub_lock); /* Locks globals and ->openc */ /* @@ -406,6 +434,8 @@ static ssize_t ub_diag_show(struct device *dev, char *page) { struct usb_interface *intf; struct ub_dev *sc; + struct list_head *p; + struct ub_lun *lun; int cnt; unsigned long flags; int nc, nh; @@ -421,9 +451,15 @@ static ssize_t ub_diag_show(struct device *dev, char *page) spin_lock_irqsave(&sc->lock, flags); cnt += sprintf(page + cnt, - "qlen %d qmax %d changed %d removable %d readonly %d\n", - sc->cmd_queue.qlen, sc->cmd_queue.qmax, - sc->changed, sc->removable, sc->readonly); + "qlen %d qmax %d\n", + sc->cmd_queue.qlen, sc->cmd_queue.qmax); + + list_for_each (p, &sc->luns) { + lun = list_entry(p, struct ub_lun, link); + cnt += sprintf(page + cnt, + "lun %u changed %d removable %d readonly %d\n", + lun->num, lun->changed, lun->removable, lun->readonly); + } if ((nc = sc->tr.cur + 1) == SCMD_TRACE_SZ) nc = 0; for (j = 0; j < SCMD_TRACE_SZ; j++) { @@ -523,53 +559,63 @@ static void ub_put(struct ub_dev *sc) */ static void ub_cleanup(struct ub_dev *sc) { + struct list_head *p; + struct ub_lun *lun; request_queue_t *q; - /* I don't think queue can be NULL. But... Stolen from sx8.c */ - if ((q = sc->disk->queue) != NULL) - blk_cleanup_queue(q); + while (!list_empty(&sc->luns)) { + p = sc->luns.next; + lun = list_entry(p, struct ub_lun, link); + list_del(p); - /* - * If we zero disk->private_data BEFORE put_disk, we have to check - * for NULL all over the place in open, release, check_media and - * revalidate, because the block level semaphore is well inside the - * put_disk. But we cannot zero after the call, because *disk is gone. - * The sd.c is blatantly racy in this area. - */ - /* disk->private_data = NULL; */ - put_disk(sc->disk); - sc->disk = NULL; + /* I don't think queue can be NULL. But... Stolen from sx8.c */ + if ((q = lun->disk->queue) != NULL) + blk_cleanup_queue(q); + /* + * If we zero disk->private_data BEFORE put_disk, we have + * to check for NULL all over the place in open, release, + * check_media and revalidate, because the block level + * semaphore is well inside the put_disk. + * But we cannot zero after the call, because *disk is gone. + * The sd.c is blatantly racy in this area. + */ + /* disk->private_data = NULL; */ + put_disk(lun->disk); + lun->disk = NULL; + + ub_id_put(lun->id); + kfree(lun); + } - ub_id_put(sc->id); kfree(sc); } /* * The "command allocator". */ -static struct ub_scsi_cmd *ub_get_cmd(struct ub_dev *sc) +static struct ub_scsi_cmd *ub_get_cmd(struct ub_lun *lun) { struct ub_scsi_cmd *ret; - if (sc->cmda[0]) + if (lun->cmda[0]) return NULL; - ret = &sc->cmdv[0]; - sc->cmda[0] = 1; + ret = &lun->cmdv[0]; + lun->cmda[0] = 1; return ret; } -static void ub_put_cmd(struct ub_dev *sc, struct ub_scsi_cmd *cmd) +static void ub_put_cmd(struct ub_lun *lun, struct ub_scsi_cmd *cmd) { - if (cmd != &sc->cmdv[0]) { + if (cmd != &lun->cmdv[0]) { printk(KERN_WARNING "%s: releasing a foreign cmd %p\n", - sc->name, cmd); + lun->name, cmd); return; } - if (!sc->cmda[0]) { - printk(KERN_WARNING "%s: releasing a free cmd\n", sc->name); + if (!lun->cmda[0]) { + printk(KERN_WARNING "%s: releasing a free cmd\n", lun->name); return; } - sc->cmda[0] = 0; + lun->cmda[0] = 0; } /* @@ -630,29 +676,30 @@ static struct ub_scsi_cmd *ub_cmdq_pop(struct ub_dev *sc) static void ub_bd_rq_fn(request_queue_t *q) { - struct ub_dev *sc = q->queuedata; + struct ub_lun *lun = q->queuedata; struct request *rq; while ((rq = elv_next_request(q)) != NULL) { - if (ub_bd_rq_fn_1(sc, rq) != 0) { + if (ub_bd_rq_fn_1(lun, rq) != 0) { blk_stop_queue(q); break; } } } -static int ub_bd_rq_fn_1(struct ub_dev *sc, struct request *rq) +static int ub_bd_rq_fn_1(struct ub_lun *lun, struct request *rq) { + struct ub_dev *sc = lun->udev; struct ub_scsi_cmd *cmd; int rc; - if (atomic_read(&sc->poison) || sc->changed) { + if (atomic_read(&sc->poison) || lun->changed) { blkdev_dequeue_request(rq); ub_end_rq(rq, 0); return 0; } - if ((cmd = ub_get_cmd(sc)) == NULL) + if ((cmd = ub_get_cmd(lun)) == NULL) return -1; memset(cmd, 0, sizeof(struct ub_scsi_cmd)); @@ -661,32 +708,30 @@ static int ub_bd_rq_fn_1(struct ub_dev *sc, struct request *rq) if (blk_pc_request(rq)) { rc = ub_cmd_build_packet(sc, cmd, rq); } else { - rc = ub_cmd_build_block(sc, cmd, rq); + rc = ub_cmd_build_block(sc, lun, cmd, rq); } if (rc != 0) { - ub_put_cmd(sc, cmd); + ub_put_cmd(lun, cmd); ub_end_rq(rq, 0); - blk_start_queue(sc->disk->queue); return 0; } - cmd->state = UB_CMDST_INIT; + cmd->lun = lun; cmd->done = ub_rw_cmd_done; cmd->back = rq; cmd->tag = sc->tagcnt++; if ((rc = ub_submit_scsi(sc, cmd)) != 0) { - ub_put_cmd(sc, cmd); + ub_put_cmd(lun, cmd); ub_end_rq(rq, 0); - blk_start_queue(sc->disk->queue); return 0; } return 0; } -static int ub_cmd_build_block(struct ub_dev *sc, struct ub_scsi_cmd *cmd, - struct request *rq) +static int ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun, + struct ub_scsi_cmd *cmd, struct request *rq) { int ub_dir; #if 0 /* We use rq->buffer for now */ @@ -707,7 +752,7 @@ static int ub_cmd_build_block(struct ub_dev *sc, struct ub_scsi_cmd *cmd, sg = &cmd->sgv[0]; n_elem = blk_rq_map_sg(q, rq, sg); if (n_elem <= 0) { - ub_put_cmd(sc, cmd); + ub_put_cmd(lun, cmd); ub_end_rq(rq, 0); blk_start_queue(q); return 0; /* request with no s/g entries? */ @@ -716,7 +761,7 @@ static int ub_cmd_build_block(struct ub_dev *sc, struct ub_scsi_cmd *cmd, if (n_elem != 1) { /* Paranoia */ printk(KERN_WARNING "%s: request with %d segments\n", sc->name, n_elem); - ub_put_cmd(sc, cmd); + ub_put_cmd(lun, cmd); ub_end_rq(rq, 0); blk_start_queue(q); return 0; @@ -748,8 +793,8 @@ static int ub_cmd_build_block(struct ub_dev *sc, struct ub_scsi_cmd *cmd, * The call to blk_queue_hardsect_size() guarantees that request * is aligned, but it is given in terms of 512 byte units, always. */ - block = rq->sector >> sc->capacity.bshift; - nblks = rq->nr_sectors >> sc->capacity.bshift; + block = rq->sector >> lun->capacity.bshift; + nblks = rq->nr_sectors >> lun->capacity.bshift; cmd->cdb[0] = (ub_dir == UB_DIR_READ)? READ_10: WRITE_10; /* 10-byte uses 4 bytes of LBA: 2147483648KB, 2097152MB, 2048GB */ @@ -803,7 +848,8 @@ static int ub_cmd_build_packet(struct ub_dev *sc, struct ub_scsi_cmd *cmd, static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd) { struct request *rq = cmd->back; - struct gendisk *disk = sc->disk; + struct ub_lun *lun = cmd->lun; + struct gendisk *disk = lun->disk; request_queue_t *q = disk->queue; int uptodate; @@ -818,7 +864,7 @@ static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd) else uptodate = 0; - ub_put_cmd(sc, cmd); + ub_put_cmd(lun, cmd); ub_end_rq(rq, uptodate); blk_start_queue(q); } @@ -887,7 +933,7 @@ static int ub_scsi_cmd_start(struct ub_dev *sc, struct ub_scsi_cmd *cmd) bcb->Tag = cmd->tag; /* Endianness is not important */ bcb->DataTransferLength = cpu_to_le32(cmd->len); bcb->Flags = (cmd->dir == UB_DIR_READ) ? 0x80 : 0; - bcb->Lun = 0; /* No multi-LUN yet */ + bcb->Lun = (cmd->lun != NULL) ? cmd->lun->num : 0; bcb->Length = cmd->cdb_len; /* copy the command payload */ @@ -1002,9 +1048,8 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) * The control pipe clears itself - nothing to do. * XXX Might try to reset the device here and retry. */ - printk(KERN_NOTICE "%s: " - "stall on control pipe for device %u\n", - sc->name, sc->dev->devnum); + printk(KERN_NOTICE "%s: stall on control pipe\n", + sc->name); goto Bad_End; } @@ -1025,9 +1070,8 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) * The control pipe clears itself - nothing to do. * XXX Might try to reset the device here and retry. */ - printk(KERN_NOTICE "%s: " - "stall on control pipe for device %u\n", - sc->name, sc->dev->devnum); + printk(KERN_NOTICE "%s: stall on control pipe\n", + sc->name); goto Bad_End; } @@ -1046,9 +1090,8 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) rc = ub_submit_clear_stall(sc, cmd, sc->last_pipe); if (rc != 0) { printk(KERN_NOTICE "%s: " - "unable to submit clear for device %u" - " (code %d)\n", - sc->name, sc->dev->devnum, rc); + "unable to submit clear (%d)\n", + sc->name, rc); /* * This is typically ENOMEM or some other such shit. * Retrying is pointless. Just do Bad End on it... @@ -1107,9 +1150,8 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) rc = ub_submit_clear_stall(sc, cmd, sc->last_pipe); if (rc != 0) { printk(KERN_NOTICE "%s: " - "unable to submit clear for device %u" - " (code %d)\n", - sc->name, sc->dev->devnum, rc); + "unable to submit clear (%d)\n", + sc->name, rc); /* * This is typically ENOMEM or some other such shit. * Retrying is pointless. Just do Bad End on it... @@ -1140,9 +1182,8 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) rc = ub_submit_clear_stall(sc, cmd, sc->last_pipe); if (rc != 0) { printk(KERN_NOTICE "%s: " - "unable to submit clear for device %u" - " (code %d)\n", - sc->name, sc->dev->devnum, rc); + "unable to submit clear (%d)\n", + sc->name, rc); /* * This is typically ENOMEM or some other such shit. * Retrying is pointless. Just do Bad End on it... @@ -1164,9 +1205,8 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) * encounter such a thing, try to read the CSW again. */ if (++cmd->stat_count >= 4) { - printk(KERN_NOTICE "%s: " - "unable to get CSW on device %u\n", - sc->name, sc->dev->devnum); + printk(KERN_NOTICE "%s: unable to get CSW\n", + sc->name); goto Bad_End; } __ub_state_stat(sc, cmd); @@ -1207,10 +1247,8 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) */ if (++cmd->stat_count >= 4) { printk(KERN_NOTICE "%s: " - "tag mismatch orig 0x%x reply 0x%x " - "on device %u\n", - sc->name, cmd->tag, bcs->Tag, - sc->dev->devnum); + "tag mismatch orig 0x%x reply 0x%x\n", + sc->name, cmd->tag, bcs->Tag); goto Bad_End; } __ub_state_stat(sc, cmd); @@ -1244,8 +1282,8 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) } else { printk(KERN_WARNING "%s: " - "wrong command state %d on device %u\n", - sc->name, cmd->state, sc->dev->devnum); + "wrong command state %d\n", + sc->name, cmd->state); goto Bad_End; } return; @@ -1288,7 +1326,6 @@ static void __ub_state_stat(struct ub_dev *sc, struct ub_scsi_cmd *cmd) if ((rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC)) != 0) { /* XXX Clear stalls */ - printk("%s: CSW #%d submit failed (%d)\n", sc->name, cmd->tag, rc); /* P3 */ ub_complete(&sc->work_done); ub_state_done(sc, cmd, rc); return; @@ -1333,6 +1370,7 @@ static void ub_state_sense(struct ub_dev *sc, struct ub_scsi_cmd *cmd) scmd->state = UB_CMDST_INIT; scmd->data = sc->top_sense; scmd->len = UB_SENSE_SIZE; + scmd->lun = cmd->lun; scmd->done = ub_top_sense_done; scmd->back = cmd; @@ -1411,14 +1449,14 @@ static void ub_top_sense_done(struct ub_dev *sc, struct ub_scsi_cmd *scmd) } if (cmd != scmd->back) { printk(KERN_WARNING "%s: " - "sense done for wrong command 0x%x on device %u\n", - sc->name, cmd->tag, sc->dev->devnum); + "sense done for wrong command 0x%x\n", + sc->name, cmd->tag); return; } if (cmd->state != UB_CMDST_SENSE) { printk(KERN_WARNING "%s: " - "sense done with bad cmd state %d on device %u\n", - sc->name, cmd->state, sc->dev->devnum); + "sense done with bad cmd state %d\n", + sc->name, cmd->state); return; } @@ -1429,68 +1467,32 @@ static void ub_top_sense_done(struct ub_dev *sc, struct ub_scsi_cmd *scmd) ub_scsi_urb_compl(sc, cmd); } -#if 0 -/* Determine what the maximum LUN supported is */ -int usb_stor_Bulk_max_lun(struct us_data *us) -{ - int result; - - /* issue the command */ - result = usb_stor_control_msg(us, us->recv_ctrl_pipe, - US_BULK_GET_MAX_LUN, - USB_DIR_IN | USB_TYPE_CLASS | - USB_RECIP_INTERFACE, - 0, us->ifnum, us->iobuf, 1, HZ); - - /* - * Some devices (i.e. Iomega Zip100) need this -- apparently - * the bulk pipes get STALLed when the GetMaxLUN request is - * processed. This is, in theory, harmless to all other devices - * (regardless of if they stall or not). - */ - if (result < 0) { - usb_stor_clear_halt(us, us->recv_bulk_pipe); - usb_stor_clear_halt(us, us->send_bulk_pipe); - } - - US_DEBUGP("GetMaxLUN command result is %d, data is %d\n", - result, us->iobuf[0]); - - /* if we have a successful request, return the result */ - if (result == 1) - return us->iobuf[0]; - - /* return the default -- no LUNs */ - return 0; -} -#endif - /* * This is called from a process context. */ -static void ub_revalidate(struct ub_dev *sc) +static void ub_revalidate(struct ub_dev *sc, struct ub_lun *lun) { - sc->readonly = 0; /* XXX Query this from the device */ + lun->readonly = 0; /* XXX Query this from the device */ - sc->capacity.nsec = 0; - sc->capacity.bsize = 512; - sc->capacity.bshift = 0; + lun->capacity.nsec = 0; + lun->capacity.bsize = 512; + lun->capacity.bshift = 0; - if (ub_sync_tur(sc) != 0) + if (ub_sync_tur(sc, lun) != 0) return; /* Not ready */ - sc->changed = 0; + lun->changed = 0; - if (ub_sync_read_cap(sc, &sc->capacity) != 0) { + if (ub_sync_read_cap(sc, lun, &lun->capacity) != 0) { /* * The retry here means something is wrong, either with the * device, with the transport, or with our code. * We keep this because sd.c has retries for capacity. */ - if (ub_sync_read_cap(sc, &sc->capacity) != 0) { - sc->capacity.nsec = 0; - sc->capacity.bsize = 512; - sc->capacity.bshift = 0; + if (ub_sync_read_cap(sc, lun, &lun->capacity) != 0) { + lun->capacity.nsec = 0; + lun->capacity.bsize = 512; + lun->capacity.bshift = 0; } } } @@ -1503,12 +1505,15 @@ static void ub_revalidate(struct ub_dev *sc) static int ub_bd_open(struct inode *inode, struct file *filp) { struct gendisk *disk = inode->i_bdev->bd_disk; + struct ub_lun *lun; struct ub_dev *sc; unsigned long flags; int rc; - if ((sc = disk->private_data) == NULL) + if ((lun = disk->private_data) == NULL) return -ENXIO; + sc = lun->udev; + spin_lock_irqsave(&ub_lock, flags); if (atomic_read(&sc->poison)) { spin_unlock_irqrestore(&ub_lock, flags); @@ -1529,15 +1534,15 @@ static int ub_bd_open(struct inode *inode, struct file *filp) * The bottom line is, Al Viro says that we should not allow * bdev->bd_invalidated to be set when doing add_disk no matter what. */ - if (sc->first_open) { - if (sc->changed) { - sc->first_open = 0; + if (lun->first_open) { + lun->first_open = 0; + if (lun->changed) { rc = -ENOMEDIUM; goto err_open; } } - if (sc->removable || sc->readonly) + if (lun->removable || lun->readonly) check_disk_change(inode->i_bdev); /* @@ -1545,12 +1550,12 @@ static int ub_bd_open(struct inode *inode, struct file *filp) * under some pretty murky conditions (a failure of READ CAPACITY). * We may need it one day. */ - if (sc->removable && sc->changed && !(filp->f_flags & O_NDELAY)) { + if (lun->removable && lun->changed && !(filp->f_flags & O_NDELAY)) { rc = -ENOMEDIUM; goto err_open; } - if (sc->readonly && (filp->f_mode & FMODE_WRITE)) { + if (lun->readonly && (filp->f_mode & FMODE_WRITE)) { rc = -EROFS; goto err_open; } @@ -1567,7 +1572,8 @@ err_open: static int ub_bd_release(struct inode *inode, struct file *filp) { struct gendisk *disk = inode->i_bdev->bd_disk; - struct ub_dev *sc = disk->private_data; + struct ub_lun *lun = disk->private_data; + struct ub_dev *sc = lun->udev; ub_put(sc); return 0; @@ -1597,20 +1603,14 @@ static int ub_bd_ioctl(struct inode *inode, struct file *filp, */ static int ub_bd_revalidate(struct gendisk *disk) { - struct ub_dev *sc = disk->private_data; - - ub_revalidate(sc); - /* This is pretty much a long term P3 */ - if (!atomic_read(&sc->poison)) { /* Cover sc->dev */ - printk(KERN_INFO "%s: device %u capacity nsec %ld bsize %u\n", - sc->name, sc->dev->devnum, - sc->capacity.nsec, sc->capacity.bsize); - } + struct ub_lun *lun = disk->private_data; + + ub_revalidate(lun->udev, lun); /* XXX Support sector size switching like in sr.c */ - blk_queue_hardsect_size(disk->queue, sc->capacity.bsize); - set_capacity(disk, sc->capacity.nsec); - // set_disk_ro(sdkp->disk, sc->readonly); + blk_queue_hardsect_size(disk->queue, lun->capacity.bsize); + set_capacity(disk, lun->capacity.nsec); + // set_disk_ro(sdkp->disk, lun->readonly); return 0; } @@ -1626,9 +1626,9 @@ static int ub_bd_revalidate(struct gendisk *disk) */ static int ub_bd_media_changed(struct gendisk *disk) { - struct ub_dev *sc = disk->private_data; + struct ub_lun *lun = disk->private_data; - if (!sc->removable) + if (!lun->removable) return 0; /* @@ -1640,12 +1640,12 @@ static int ub_bd_media_changed(struct gendisk *disk) * will fail, then block layer discards the data. Since we never * spin drives up, such devices simply cannot be used with ub anyway. */ - if (ub_sync_tur(sc) != 0) { - sc->changed = 1; + if (ub_sync_tur(lun->udev, lun) != 0) { + lun->changed = 1; return 1; } - return sc->changed; + return lun->changed; } static struct block_device_operations ub_bd_fops = { @@ -1669,7 +1669,7 @@ static void ub_probe_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd) /* * Test if the device has a check condition on it, synchronously. */ -static int ub_sync_tur(struct ub_dev *sc) +static int ub_sync_tur(struct ub_dev *sc, struct ub_lun *lun) { struct ub_scsi_cmd *cmd; enum { ALLOC_SIZE = sizeof(struct ub_scsi_cmd) }; @@ -1688,6 +1688,7 @@ static int ub_sync_tur(struct ub_dev *sc) cmd->cdb_len = 6; cmd->dir = UB_DIR_NONE; cmd->state = UB_CMDST_INIT; + cmd->lun = lun; /* This may be NULL, but that's ok */ cmd->done = ub_probe_done; cmd->back = &compl; @@ -1718,7 +1719,8 @@ err_alloc: /* * Read the SCSI capacity synchronously (for probing). */ -static int ub_sync_read_cap(struct ub_dev *sc, struct ub_capacity *ret) +static int ub_sync_read_cap(struct ub_dev *sc, struct ub_lun *lun, + struct ub_capacity *ret) { struct ub_scsi_cmd *cmd; char *p; @@ -1743,6 +1745,7 @@ static int ub_sync_read_cap(struct ub_dev *sc, struct ub_capacity *ret) cmd->state = UB_CMDST_INIT; cmd->data = p; cmd->len = 8; + cmd->lun = lun; cmd->done = ub_probe_done; cmd->back = &compl; @@ -1811,6 +1814,90 @@ static void ub_probe_timeout(unsigned long arg) complete(cop); } +/* + * Get number of LUNs by the way of Bulk GetMaxLUN command. + */ +static int ub_sync_getmaxlun(struct ub_dev *sc) +{ + int ifnum = sc->intf->cur_altsetting->desc.bInterfaceNumber; + unsigned char *p; + enum { ALLOC_SIZE = 1 }; + struct usb_ctrlrequest *cr; + struct completion compl; + struct timer_list timer; + int nluns; + int rc; + + init_completion(&compl); + + rc = -ENOMEM; + if ((p = kmalloc(ALLOC_SIZE, GFP_KERNEL)) == NULL) + goto err_alloc; + *p = 55; + + cr = &sc->work_cr; + cr->bRequestType = USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE; + cr->bRequest = US_BULK_GET_MAX_LUN; + cr->wValue = cpu_to_le16(0); + cr->wIndex = cpu_to_le16(ifnum); + cr->wLength = cpu_to_le16(1); + + usb_fill_control_urb(&sc->work_urb, sc->dev, sc->recv_ctrl_pipe, + (unsigned char*) cr, p, 1, ub_probe_urb_complete, &compl); + sc->work_urb.transfer_flags = 0; + sc->work_urb.actual_length = 0; + sc->work_urb.error_count = 0; + sc->work_urb.status = 0; + + if ((rc = usb_submit_urb(&sc->work_urb, GFP_KERNEL)) != 0) { + if (rc == -EPIPE) { + printk("%s: Stall at GetMaxLUN, using 1 LUN\n", + sc->name); /* P3 */ + } else { + printk(KERN_WARNING + "%s: Unable to submit GetMaxLUN (%d)\n", + sc->name, rc); + } + goto err_submit; + } + + init_timer(&timer); + timer.function = ub_probe_timeout; + timer.data = (unsigned long) &compl; + timer.expires = jiffies + UB_CTRL_TIMEOUT; + add_timer(&timer); + + wait_for_completion(&compl); + + del_timer_sync(&timer); + usb_kill_urb(&sc->work_urb); + + if (sc->work_urb.actual_length != 1) { + printk("%s: GetMaxLUN returned %d bytes\n", sc->name, + sc->work_urb.actual_length); /* P3 */ + nluns = 0; + } else { + if ((nluns = *p) == 55) { + nluns = 0; + } else { + /* GetMaxLUN returns the maximum LUN number */ + nluns += 1; + if (nluns > UB_MAX_LUNS) + nluns = UB_MAX_LUNS; + } + printk("%s: GetMaxLUN returned %d, using %d LUNs\n", sc->name, + *p, nluns); /* P3 */ + } + + kfree(p); + return nluns; + +err_submit: + kfree(p); +err_alloc: + return rc; +} + /* * Clear initial stalls. */ @@ -1897,8 +1984,8 @@ static int ub_get_pipes(struct ub_dev *sc, struct usb_device *dev, } if (ep_in == NULL || ep_out == NULL) { - printk(KERN_NOTICE "%s: device %u failed endpoint check\n", - sc->name, sc->dev->devnum); + printk(KERN_NOTICE "%s: failed endpoint check\n", + sc->name); return -EIO; } @@ -1921,8 +2008,7 @@ static int ub_probe(struct usb_interface *intf, const struct usb_device_id *dev_id) { struct ub_dev *sc; - request_queue_t *q; - struct gendisk *disk; + int nluns; int rc; int i; @@ -1931,6 +2017,7 @@ static int ub_probe(struct usb_interface *intf, goto err_core; memset(sc, 0, sizeof(struct ub_dev)); spin_lock_init(&sc->lock); + INIT_LIST_HEAD(&sc->luns); usb_init_urb(&sc->work_urb); tasklet_init(&sc->tasklet, ub_scsi_action, (unsigned long)sc); atomic_set(&sc->poison, 0); @@ -1942,19 +2029,16 @@ static int ub_probe(struct usb_interface *intf, ub_init_completion(&sc->work_done); sc->work_done.done = 1; /* A little yuk, but oh well... */ - rc = -ENOSR; - if ((sc->id = ub_id_get()) == -1) - goto err_id; - snprintf(sc->name, 8, DRV_NAME "%c", sc->id + 'a'); - sc->dev = interface_to_usbdev(intf); sc->intf = intf; // sc->ifnum = intf->cur_altsetting->desc.bInterfaceNumber; - usb_set_intfdata(intf, sc); usb_get_dev(sc->dev); // usb_get_intf(sc->intf); /* Do we need this? */ + snprintf(sc->name, 12, DRV_NAME "(%d.%d)", + sc->dev->bus->busnum, sc->dev->devnum); + /* XXX Verify that we can handle the device (from descriptors) */ ub_get_pipes(sc, sc->dev, intf); @@ -1992,35 +2076,88 @@ static int ub_probe(struct usb_interface *intf, * In any case it's not our business how revaliadation is implemented. */ for (i = 0; i < 3; i++) { /* Retries for benh's key */ - if ((rc = ub_sync_tur(sc)) <= 0) break; + if ((rc = ub_sync_tur(sc, NULL)) <= 0) break; if (rc != 0x6) break; msleep(10); } - sc->removable = 1; /* XXX Query this from the device */ - sc->changed = 1; /* ub_revalidate clears only */ - sc->first_open = 1; + nluns = 1; + for (i = 0; i < 3; i++) { + if ((rc = ub_sync_getmaxlun(sc)) < 0) { + /* + * Some devices (i.e. Iomega Zip100) need this -- + * apparently the bulk pipes get STALLed when the + * GetMaxLUN request is processed. + * XXX I have a ZIP-100, verify it does this. + */ + if (rc == -EPIPE) { + ub_probe_clear_stall(sc, sc->recv_bulk_pipe); + ub_probe_clear_stall(sc, sc->send_bulk_pipe); + } + break; + } + if (rc != 0) { + nluns = rc; + break; + } + mdelay(100); + } - ub_revalidate(sc); - /* This is pretty much a long term P3 */ - printk(KERN_INFO "%s: device %u capacity nsec %ld bsize %u\n", - sc->name, sc->dev->devnum, sc->capacity.nsec, sc->capacity.bsize); + for (i = 0; i < nluns; i++) { + ub_probe_lun(sc, i); + } + return 0; + + /* device_remove_file(&sc->intf->dev, &dev_attr_diag); */ +err_diag: + usb_set_intfdata(intf, NULL); + // usb_put_intf(sc->intf); + usb_put_dev(sc->dev); + kfree(sc); +err_core: + return rc; +} + +static int ub_probe_lun(struct ub_dev *sc, int lnum) +{ + struct ub_lun *lun; + request_queue_t *q; + struct gendisk *disk; + int rc; + + rc = -ENOMEM; + if ((lun = kmalloc(sizeof(struct ub_lun), GFP_KERNEL)) == NULL) + goto err_alloc; + memset(lun, 0, sizeof(struct ub_lun)); + lun->num = lnum; + + rc = -ENOSR; + if ((lun->id = ub_id_get()) == -1) + goto err_id; + + lun->udev = sc; + list_add(&lun->link, &sc->luns); + + snprintf(lun->name, 16, DRV_NAME "%c(%d.%d.%d)", + lun->id + 'a', sc->dev->bus->busnum, sc->dev->devnum, lun->num); + + lun->removable = 1; /* XXX Query this from the device */ + lun->changed = 1; /* ub_revalidate clears only */ + lun->first_open = 1; + ub_revalidate(sc, lun); - /* - * Just one disk per sc currently, but maybe more. - */ rc = -ENOMEM; if ((disk = alloc_disk(UB_MINORS_PER_MAJOR)) == NULL) goto err_diskalloc; - sc->disk = disk; - sprintf(disk->disk_name, DRV_NAME "%c", sc->id + 'a'); - sprintf(disk->devfs_name, DEVFS_NAME "/%c", sc->id + 'a'); + lun->disk = disk; + sprintf(disk->disk_name, DRV_NAME "%c", lun->id + 'a'); + sprintf(disk->devfs_name, DEVFS_NAME "/%c", lun->id + 'a'); disk->major = UB_MAJOR; - disk->first_minor = sc->id * UB_MINORS_PER_MAJOR; + disk->first_minor = lun->id * UB_MINORS_PER_MAJOR; disk->fops = &ub_bd_fops; - disk->private_data = sc; - disk->driverfs_dev = &intf->dev; + disk->private_data = lun; + disk->driverfs_dev = &sc->intf->dev; /* XXX Many to one ok? */ rc = -ENOMEM; if ((q = blk_init_queue(ub_bd_rq_fn, &sc->lock)) == NULL) @@ -2028,28 +2165,17 @@ static int ub_probe(struct usb_interface *intf, disk->queue = q; - // blk_queue_bounce_limit(q, hba[i]->pdev->dma_mask); + blk_queue_bounce_limit(q, BLK_BOUNCE_HIGH); blk_queue_max_hw_segments(q, UB_MAX_REQ_SG); blk_queue_max_phys_segments(q, UB_MAX_REQ_SG); - // blk_queue_segment_boundary(q, CARM_SG_BOUNDARY); + blk_queue_segment_boundary(q, 0xffffffff); /* Dubious. */ blk_queue_max_sectors(q, UB_MAX_SECTORS); - blk_queue_hardsect_size(q, sc->capacity.bsize); - - /* - * This is a serious infraction, caused by a deficiency in the - * USB sg interface (usb_sg_wait()). We plan to remove this once - * we get mileage on the driver and can justify a change to USB API. - * See blk_queue_bounce_limit() to understand this part. - * - * XXX And I still need to be aware of the DMA mask in the HC. - */ - q->bounce_pfn = blk_max_low_pfn; - q->bounce_gfp = GFP_NOIO; + blk_queue_hardsect_size(q, lun->capacity.bsize); - q->queuedata = sc; + q->queuedata = lun; - set_capacity(disk, sc->capacity.nsec); - if (sc->removable) + set_capacity(disk, lun->capacity.nsec); + if (lun->removable) disk->flags |= GENHD_FL_REMOVABLE; add_disk(disk); @@ -2059,22 +2185,20 @@ static int ub_probe(struct usb_interface *intf, err_blkqinit: put_disk(disk); err_diskalloc: - device_remove_file(&sc->intf->dev, &dev_attr_diag); -err_diag: - usb_set_intfdata(intf, NULL); - // usb_put_intf(sc->intf); - usb_put_dev(sc->dev); - ub_id_put(sc->id); + list_del(&lun->link); + ub_id_put(lun->id); err_id: - kfree(sc); -err_core: + kfree(lun); +err_alloc: return rc; } static void ub_disconnect(struct usb_interface *intf) { struct ub_dev *sc = usb_get_intfdata(intf); - struct gendisk *disk = sc->disk; + struct list_head *p; + struct ub_lun *lun; + struct gendisk *disk; unsigned long flags; /* @@ -2124,14 +2248,18 @@ static void ub_disconnect(struct usb_interface *intf) /* * Unregister the upper layer. */ - if (disk->flags & GENHD_FL_UP) - del_gendisk(disk); - /* - * I wish I could do: - * set_bit(QUEUE_FLAG_DEAD, &q->queue_flags); - * As it is, we rely on our internal poisoning and let - * the upper levels to spin furiously failing all the I/O. - */ + list_for_each (p, &sc->luns) { + lun = list_entry(p, struct ub_lun, link); + disk = lun->disk; + if (disk->flags & GENHD_FL_UP) + del_gendisk(disk); + /* + * I wish I could do: + * set_bit(QUEUE_FLAG_DEAD, &q->queue_flags); + * As it is, we rely on our internal poisoning and let + * the upper levels to spin furiously failing all the I/O. + */ + } /* * Taking a lock on a structure which is about to be freed @@ -2182,8 +2310,8 @@ static int __init ub_init(void) { int rc; - /* P3 */ printk("ub: sizeof ub_scsi_cmd %zu ub_dev %zu\n", - sizeof(struct ub_scsi_cmd), sizeof(struct ub_dev)); + /* P3 */ printk("ub: sizeof ub_scsi_cmd %zu ub_dev %zu ub_lun %zu\n", + sizeof(struct ub_scsi_cmd), sizeof(struct ub_dev), sizeof(struct ub_lun)); if ((rc = register_blkdev(UB_MAJOR, DRV_NAME)) != 0) goto err_regblkdev; -- cgit v1.2.3-70-g09d2 From d7771a33bf2b23fc6d0b9c133fb0c00670154f10 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Thu, 5 May 2005 18:49:59 +0200 Subject: [PATCH] USB: remove drivers/usb/media/pwc/ChangeLog This patch removes the outdated ChangeLog file for this driver. Signed-off-by: Adrian Bunk Signed-off-by: Greg Kroah-Hartman --- drivers/usb/media/pwc/ChangeLog | 143 ---------------------------------------- 1 file changed, 143 deletions(-) delete mode 100644 drivers/usb/media/pwc/ChangeLog diff --git a/drivers/usb/media/pwc/ChangeLog b/drivers/usb/media/pwc/ChangeLog deleted file mode 100644 index b2eb71a9afb..00000000000 --- a/drivers/usb/media/pwc/ChangeLog +++ /dev/null @@ -1,143 +0,0 @@ -9.0.2 - -* Adding #ifdef to compile PWC before and after 2.6.5 - -9.0.1 - -9.0 - - -8.12 - -* Implement motorized pan/tilt feature for Logitech QuickCam Orbit/Spere. - -8.11.1 - -* Fix for PCVC720/40, would not be able to set videomode -* Fix for Samsung MPC models, appearantly they are based on a newer chipset - -8.11 - -* 20 dev_hints (per request) -* Hot unplugging should be better, no more dangling pointers or memory leaks -* Added reserved Logitech webcam IDs -* Device now remembers size & fps between close()/open() -* Removed palette stuff altogether - -8.10.1 - -* Added IDs for PCVC720K/40 and Creative Labs Webcam Pro - -8.10 - -* Fixed ID for QuickCam Notebook pro -* Added GREALSIZE ioctl() call -* Fixed bug in case PWCX was not loaded and invalid size was set - -8.9 - -* Merging with kernel 2.5.49 -* Adding IDs for QuickCam Zoom & QuickCam Notebook - -8.8 - -* Fixing 'leds' parameter -* Adding IDs for Logitech QuickCam Pro 4000 -* Making URB init/cleanup a little nicer - -8.7 - -* Incorporating changes in ioctl() parameter passing -* Also changes to URB mechanism - -8.6 - -* Added ID's for Visionite VCS UM100 and UC300 -* Removed YUV420-interlaced palette altogether (was confusing) -* Removed MIRROR stuff as it didn't work anyway -* Fixed a problem with the 'leds' parameter (wouldn't blink) -* Added ioctl()s for advanced features: 'extended' whitebalance ioctl()s, - CONTOUR, BACKLIGHT, FLICKER, DYNNOISE. -* VIDIOCGCAP.name now contains real camera model name instead of - 'Philips xxx webcam' -* Added PROBE ioctl (see previous point & API doc) - -8.5 - -* Adding IDs for Creative Labs Webcam 5 -* Adding IDs for SOTEC CMS-001 webcam -* Solving possible hang in VIDIOCSYNC when unplugging the cam -* Forgot to return structure in VIDIOCPWCGAWB, oops -* Time interval for the LEDs are now in milliseconds - -8.4 - -* Fixing power_save option for Vesta range -* Handling new error codes in ISOC callback -* Adding dev_hint module parameter, to specify /dev/videoX device nodes - -8.3 - -* Adding Samsung C10 and C30 cameras -* Removing palette module parameter -* Fixed typo in ID of QuickCam 3000 Pro -* Adding LED settings (blinking while in use) for ToUCam cameras. -* Turns LED off when camera is not in use. - -8.2 - -* Making module more silent when trace = 0 -* Adding QuickCam 3000 Pro IDs -* Chrominance control for the Vesta cameras -* Hopefully fixed problems on machines with BIGMEM and > 1GB of RAM -* Included Oliver Neukem's lock_kernel() patch -* Allocates less memory for image buffers -* Adds ioctl()s for the whitebalancing - -8.1 - -* Adding support for 750 -* Adding V4L GAUDIO/SAUDIO/UNIT ioctl() calls - -8.0 -* 'damage control' after inclusion in 2.4.5. -* Changed wait-queue mechanism in read/mmap/poll according to the book. -* Included YUV420P palette. -* Changed interface to decompressor module. -* Cleaned up pwc structure a bit. - -7.0 - -* Fixed bug in vcvt_420i_yuyv; extra variables on stack were misaligned. -* There is now a clear error message when an image size is selected that - is only supported using the decompressor, and the decompressor isn't - loaded. -* When the decompressor wasn't loaded, selecting large image size - would create skewed or double images. - -6.3 - -* Introduced spinlocks for the buffer pointer manipulation; a number of - reports seem to suggest the down()/up() semaphores were the cause of - lockups, since they are not suitable for interrupt/user locking. -* Separated decompressor and core code into 2 modules. - -6.2 - -* Non-integral image sizes are now padded with gray or black. -* Added SHUTTERSPEED ioctl(). -* Fixed buglet in VIDIOCPWCSAGC; the function would always return an error, - even though the call succeeded. -* Added hotplug support for 2.4.*. -* Memory: the 645/646 uses less memory now. - -6.1 - -* VIDIOCSPICT returns -EINVAL with invalid palettes. -* Added saturation control. -* Split decompressors from rest. -* Fixed bug that would reset the framerate to the default framerate if - the rate field was set to 0 (which is not what I intended, nl. do not - change the framerate!). -* VIDIOCPWCSCQUAL (setting compression quality) now takes effect immediately. -* Workaround for a bug in the 730 sensor. -- cgit v1.2.3-70-g09d2 From 5ce0482e18193a15223911515ee44373cffb35b8 Mon Sep 17 00:00:00 2001 From: Ping Cheng Date: Thu, 5 May 2005 15:12:57 -0700 Subject: [PATCH] USB: add new wacom device to usb hid-core list - add Intuos3 and Cintiq 21UX Signed-off-by: Ping Cheng Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/usb/input/hid-core.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c index 869ff73690a..d972cb4cb19 100644 --- a/drivers/usb/input/hid-core.c +++ b/drivers/usb/input/hid-core.c @@ -1315,6 +1315,8 @@ void hid_init_reports(struct hid_device *hid) #define USB_DEVICE_ID_WACOM_INTUOS2 0x0040 #define USB_DEVICE_ID_WACOM_VOLITO 0x0060 #define USB_DEVICE_ID_WACOM_PTU 0x0003 +#define USB_DEVICE_ID_WACOM_INTUOS3 0x00B0 +#define USB_DEVICE_ID_WACOM_CINTIQ 0x003F #define USB_VENDOR_ID_KBGEAR 0x084e #define USB_DEVICE_ID_KBGEAR_JAMSTUDIO 0x1001 @@ -1481,6 +1483,10 @@ static struct hid_blacklist { { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 7, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_VOLITO, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PTU, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3 + 1, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3 + 2, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_CINTIQ, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_4_PHIDGETSERVO_20, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_1_PHIDGETSERVO_20, HID_QUIRK_IGNORE }, -- cgit v1.2.3-70-g09d2 From dc1d1003e8309ef8e5153ce0c00cce76144abbdb Mon Sep 17 00:00:00 2001 From: Lonnie Mendez Date: Tue, 10 May 2005 00:17:17 -0500 Subject: [PATCH] USB: hid-core: add Earthmate lt-20 productid to blacklist table This patch adds the DeLorme Earthmate lt-20 productid to the hid blacklist table. This patch ensures the lt-20 can be claimed by the appropriate driver (cypress_m8). Adds the product id 0x200, of the DeLorme Earthmate lt-20, to the hid blacklist table. Signed-off-by: Lonnie Mendez Signed-off-by: Greg Kroah-Hartman --- drivers/usb/input/hid-core.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c index d972cb4cb19..b6e061af3e3 100644 --- a/drivers/usb/input/hid-core.c +++ b/drivers/usb/input/hid-core.c @@ -1403,6 +1403,7 @@ void hid_init_reports(struct hid_device *hid) #define USB_VENDOR_ID_DELORME 0x1163 #define USB_DEVICE_ID_DELORME_EARTHMATE 0x0100 +#define USB_DEVICE_ID_DELORME_EM_LT20 0x0200 #define USB_VENDOR_ID_MCC 0x09db #define USB_DEVICE_ID_MCC_PMD1024LS 0x0076 @@ -1439,6 +1440,7 @@ static struct hid_blacklist { { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW28, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_HIDCOM, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EARTHMATE, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EM_LT20, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_4_PHIDGETSERVO_30, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_1_PHIDGETSERVO_30, HID_QUIRK_IGNORE }, -- cgit v1.2.3-70-g09d2 From 4871d3be13ea2b33edc9ba6fbcc30fc047087be7 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 2 Jun 2005 22:18:12 -0700 Subject: [PATCH] USB: add Vernier devices to HID blacklist They aren't really HID devices. Damm microsoft HID driver, that thing has caused more companies to have to do this kind of hack... Signed-off-by: Greg Kroah-Hartman --- drivers/usb/input/hid-core.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c index b6e061af3e3..2d8bd9dcc6e 100644 --- a/drivers/usb/input/hid-core.c +++ b/drivers/usb/input/hid-core.c @@ -1415,6 +1415,12 @@ void hid_init_reports(struct hid_device *hid) #define USB_VENDOR_ID_BTC 0x046e #define USB_DEVICE_ID_BTC_KEYBOARD 0x5303 +#define USB_VENDOR_ID_VERNIER 0x08f7 +#define USB_DEVICE_ID_VERNIER_LABPRO 0x0001 +#define USB_DEVICE_ID_VERNIER_GOTEMP 0x0002 +#define USB_DEVICE_ID_VERNIER_SKIP 0x0003 +#define USB_DEVICE_ID_VERNIER_CYCLOPS 0x0004 + /* * Alphabetically sorted blacklist by quirk type. @@ -1460,6 +1466,10 @@ static struct hid_blacklist { { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 300, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 400, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 500, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LABPRO, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_GOTEMP, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_CYCLOPS, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PENPARTNER, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE + 1, HID_QUIRK_IGNORE }, -- cgit v1.2.3-70-g09d2 From 58cfe9113e485f7e04bd0eac4fc4251b330af501 Mon Sep 17 00:00:00 2001 From: Matthias Urlichs Date: Mon, 23 May 2005 17:00:48 -0700 Subject: [PATCH] USB: add Option Card driver This patch adds a new driver for "Option" cards. This is a GSM data card, controlled by three "serial ports" which are connected via an OHCI adapter, all located on an oversized PC-Card. It's sold by several GSM service providers. Traditionally, this card has been accessed via the standard serial driver and appropriate vendor= and product= options. However, testing has revealed several problems with this approach, including hung data transfers and lost data blocks when receiving. Therefore, I've written a separate driver. Signed-off-by: Matthias Urlichs Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/Kconfig | 11 + drivers/usb/serial/Makefile | 1 + drivers/usb/serial/option.c | 729 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 741 insertions(+) create mode 100644 drivers/usb/serial/option.c diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig index bc798edf035..9438909e87a 100644 --- a/drivers/usb/serial/Kconfig +++ b/drivers/usb/serial/Kconfig @@ -455,6 +455,17 @@ config USB_SERIAL_XIRCOM To compile this driver as a module, choose M here: the module will be called keyspan_pda. +config USB_SERIAL_OPTION + tristate "USB Option PCMCIA serial driver" + depends on USB_SERIAL && USB_OHCI_HCD && PCCARD + help + Say Y here if you want to use an Option card. This is a + GSM card, controlled by three serial ports which are connected + via an OHCI adapter located on a PC card. + + To compile this driver as a module, choose M here: the + module will be called option. + config USB_SERIAL_OMNINET tristate "USB ZyXEL omni.net LCD Plus Driver (EXPERIMENTAL)" depends on USB_SERIAL && EXPERIMENTAL diff --git a/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile index d56ff6d86cc..6c7cdcc99a9 100644 --- a/drivers/usb/serial/Makefile +++ b/drivers/usb/serial/Makefile @@ -32,6 +32,7 @@ obj-$(CONFIG_USB_SERIAL_KLSI) += kl5kusb105.o obj-$(CONFIG_USB_SERIAL_KOBIL_SCT) += kobil_sct.o obj-$(CONFIG_USB_SERIAL_MCT_U232) += mct_u232.o obj-$(CONFIG_USB_SERIAL_OMNINET) += omninet.o +obj-$(CONFIG_USB_SERIAL_OPTION) += option.o obj-$(CONFIG_USB_SERIAL_PL2303) += pl2303.o obj-$(CONFIG_USB_SERIAL_SAFE) += safe_serial.o obj-$(CONFIG_USB_SERIAL_TI) += ti_usb_3410_5052.o diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c new file mode 100644 index 00000000000..b722175f108 --- /dev/null +++ b/drivers/usb/serial/option.c @@ -0,0 +1,729 @@ +/* + Option Card (PCMCIA to) USB to Serial Driver + + Copyright (C) 2005 Matthias Urlichs + + This driver is free software; you can redistribute it and/or modify + it under the terms of Version 2 of the GNU General Public License as + published by the Free Software Foundation. + + Portions copied from the Keyspan driver by Hugh Blemings + + History: + + 2005-05-19 v0.1 Initial version, based on incomplete docs + and analysis of misbehavior of the standard driver + 2005-05-20 v0.2 Extended the input buffer to avoid losing + random 64-byte chunks of data + 2005-05-21 v0.3 implemented chars_in_buffer() + turned on low_latency + simplified the code somewhat +*/ +#define DRIVER_VERSION "v0.3" +#define DRIVER_AUTHOR "Matthias Urlichs " +#define DRIVER_DESC "Option Card (PC-Card to) USB to Serial Driver" + +#include +#include +#include +#include +#include +#include +#include +#include +#include "usb-serial.h" + +/* Function prototypes */ +static int option_open (struct usb_serial_port *port, struct file *filp); +static void option_close (struct usb_serial_port *port, struct file *filp); +static int option_startup (struct usb_serial *serial); +static void option_shutdown (struct usb_serial *serial); +static void option_rx_throttle (struct usb_serial_port *port); +static void option_rx_unthrottle (struct usb_serial_port *port); +static int option_write_room (struct usb_serial_port *port); + +static void option_instat_callback(struct urb *urb, struct pt_regs *regs); + + +static int option_write (struct usb_serial_port *port, + const unsigned char *buf, int count); + +static int option_chars_in_buffer (struct usb_serial_port *port); +static int option_ioctl (struct usb_serial_port *port, struct file *file, + unsigned int cmd, unsigned long arg); +static void option_set_termios (struct usb_serial_port *port, + struct termios *old); +static void option_break_ctl (struct usb_serial_port *port, int break_state); +static int option_tiocmget (struct usb_serial_port *port, struct file *file); +static int option_tiocmset (struct usb_serial_port *port, struct file *file, + unsigned int set, unsigned int clear); +static int option_send_setup (struct usb_serial_port *port); + +/* Vendor and product IDs */ +#define OPTION_VENDOR_ID 0x0AF0 + +#define OPTION_PRODUCT_OLD 0x5000 +#define OPTION_PRODUCT_WLAN 0x6000 + +static struct usb_device_id option_ids[] = { + { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_OLD) }, + { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_WLAN) }, + { } /* Terminating entry */ +}; + +MODULE_DEVICE_TABLE(usb, option_ids); + +static struct usb_driver option_driver = { + .owner = THIS_MODULE, + .name = "option", + .probe = usb_serial_probe, + .disconnect = usb_serial_disconnect, + .id_table = option_ids, +}; + +/* The card has three separate interfaces, wich the serial driver + * recognizes separately, thus num_port=1. + */ +static struct usb_serial_device_type option_3port_device = { + .owner = THIS_MODULE, + .name = "Option 3-port card", + .short_name = "option", + .id_table = option_ids, + .num_interrupt_in = NUM_DONT_CARE, + .num_bulk_in = NUM_DONT_CARE, + .num_bulk_out = NUM_DONT_CARE, + .num_ports = 1, /* 3 */ + .open = option_open, + .close = option_close, + .write = option_write, + .write_room = option_write_room, + .chars_in_buffer = option_chars_in_buffer, + .throttle = option_rx_throttle, + .unthrottle = option_rx_unthrottle, + .ioctl = option_ioctl, + .set_termios = option_set_termios, + .break_ctl = option_break_ctl, + .tiocmget = option_tiocmget, + .tiocmset = option_tiocmset, + .attach = option_startup, + .shutdown = option_shutdown, + .read_int_callback = option_instat_callback, +}; + +static int debug; + +/* per port private data */ + +#define N_IN_URB 4 +#define N_OUT_URB 1 +#define IN_BUFLEN 1024 +#define OUT_BUFLEN 1024 + +struct option_port_private { + /* Input endpoints and buffer for this port */ + struct urb *in_urbs[N_IN_URB]; + char in_buffer[N_IN_URB][IN_BUFLEN]; + /* Output endpoints and buffer for this port */ + struct urb *out_urbs[N_OUT_URB]; + char out_buffer[N_OUT_URB][OUT_BUFLEN]; + + /* Settings for the port */ + int rts_state; /* Handshaking pins (outputs) */ + int dtr_state; + int cts_state; /* Handshaking pins (inputs) */ + int dsr_state; + int dcd_state; + int ri_state; + // int break_on; + + unsigned long tx_start_time[N_OUT_URB]; +}; + + +/* Functions used by new usb-serial code. */ +static int __init +option_init (void) +{ + int retval; + retval = usb_serial_register(&option_3port_device); + if (retval) + goto failed_3port_device_register; + retval = usb_register(&option_driver); + if (retval) + goto failed_driver_register; + + info(DRIVER_DESC ": " DRIVER_VERSION); + + return 0; + +failed_driver_register: + usb_serial_deregister (&option_3port_device); +failed_3port_device_register: + return retval; +} + +static void __exit +option_exit (void) +{ + usb_deregister (&option_driver); + usb_serial_deregister (&option_3port_device); +} + +module_init(option_init); +module_exit(option_exit); + +static void +option_rx_throttle (struct usb_serial_port *port) +{ + dbg("%s", __FUNCTION__); +} + + +static void +option_rx_unthrottle (struct usb_serial_port *port) +{ + dbg("%s", __FUNCTION__); +} + + +static void +option_break_ctl (struct usb_serial_port *port, int break_state) +{ + /* Unfortunately, I don't know how to send a break */ + dbg("%s", __FUNCTION__); +} + + +static void +option_set_termios (struct usb_serial_port *port, + struct termios *old_termios) +{ + dbg("%s", __FUNCTION__); + + option_send_setup(port); +} + +static int +option_tiocmget(struct usb_serial_port *port, struct file *file) +{ + unsigned int value; + struct option_port_private *portdata; + + portdata = usb_get_serial_port_data(port); + + value = ((portdata->rts_state) ? TIOCM_RTS : 0) | + ((portdata->dtr_state) ? TIOCM_DTR : 0) | + ((portdata->cts_state) ? TIOCM_CTS : 0) | + ((portdata->dsr_state) ? TIOCM_DSR : 0) | + ((portdata->dcd_state) ? TIOCM_CAR : 0) | + ((portdata->ri_state) ? TIOCM_RNG : 0); + + return value; +} + +static int +option_tiocmset (struct usb_serial_port *port, struct file *file, + unsigned int set, unsigned int clear) +{ + struct option_port_private *portdata; + + portdata = usb_get_serial_port_data(port); + + if (set & TIOCM_RTS) + portdata->rts_state = 1; + if (set & TIOCM_DTR) + portdata->dtr_state = 1; + + if (clear & TIOCM_RTS) + portdata->rts_state = 0; + if (clear & TIOCM_DTR) + portdata->dtr_state = 0; + return option_send_setup(port); +} + +static int +option_ioctl (struct usb_serial_port *port, struct file *file, + unsigned int cmd, unsigned long arg) +{ + return -ENOIOCTLCMD; +} + +/* Write */ +static int +option_write(struct usb_serial_port *port, + const unsigned char *buf, int count) +{ + struct option_port_private *portdata; + int i; + int left, todo; + struct urb *this_urb = NULL; /* spurious */ + int err; + + portdata = usb_get_serial_port_data(port); + + dbg("%s: write (%d chars)", __FUNCTION__, count); + +#if 0 + spin_lock(&port->lock); + if (port->write_urb_busy) { + spin_unlock(&port->lock); + dbg("%s: already writing", __FUNCTION__); + return 0; + } + port->write_urb_busy = 1; + spin_unlock(&port->lock); +#endif + + i = 0; + left = count; + while (left>0) { + todo = left; + if (todo > OUT_BUFLEN) + todo = OUT_BUFLEN; + + for (;i < N_OUT_URB; i++) { + /* Check we have a valid urb/endpoint before we use it... */ + this_urb = portdata->out_urbs[i]; + if (this_urb->status != -EINPROGRESS) + break; + if (this_urb->transfer_flags & URB_ASYNC_UNLINK) + continue; + if (time_before(jiffies, portdata->tx_start_time[i] + 10 * HZ)) + continue; + this_urb->transfer_flags |= URB_ASYNC_UNLINK; + usb_unlink_urb(this_urb); + } + + if (i == N_OUT_URB) { + /* no bulk out free! */ + dbg("%s: no output urb -- left %d", __FUNCTION__,count-left); +#if 0 + port->write_urb_busy = 0; +#endif + return count-left; + } + + dbg("%s: endpoint %d buf %d", __FUNCTION__, usb_pipeendpoint(this_urb->pipe), i); + + memcpy (this_urb->transfer_buffer, buf, todo); + + /* send the data out the bulk port */ + this_urb->transfer_buffer_length = todo; + + this_urb->transfer_flags &= ~URB_ASYNC_UNLINK; + this_urb->dev = port->serial->dev; + err = usb_submit_urb(this_urb, GFP_ATOMIC); + if (err) { + dbg("usb_submit_urb %p (write bulk) failed (%d,, has %d)", this_urb, err, this_urb->status); + continue; + } + portdata->tx_start_time[i] = jiffies; + buf += todo; + left -= todo; + } + + count -= left; +#if 0 + port->write_urb_busy = 0; +#endif + dbg("%s: wrote (did %d)", __FUNCTION__, count); + return count; +} + +static void +option_indat_callback (struct urb *urb, struct pt_regs *regs) +{ + int i, err; + int endpoint; + struct usb_serial_port *port; + struct tty_struct *tty; + unsigned char *data = urb->transfer_buffer; + + dbg("%s: %p", __FUNCTION__, urb); + + endpoint = usb_pipeendpoint(urb->pipe); + port = (struct usb_serial_port *) urb->context; + + if (urb->status) { + dbg("%s: nonzero status: %d on endpoint %02x.", + __FUNCTION__, urb->status, endpoint); + } else { + tty = port->tty; + if (urb->actual_length) { + for (i = 0; i < urb->actual_length ; ++i) { + if (tty->flip.count >= TTY_FLIPBUF_SIZE) + tty_flip_buffer_push(tty); + tty_insert_flip_char(tty, data[i], 0); + } + tty_flip_buffer_push(tty); + } else { + dbg("%s: empty read urb received", __FUNCTION__); + } + + /* Resubmit urb so we continue receiving */ + if (port->open_count && urb->status != -ESHUTDOWN) { + err = usb_submit_urb(urb, GFP_ATOMIC); + if (err) + printk(KERN_ERR "%s: resubmit read urb failed. (%d)", __FUNCTION__, err); + } + } + return; +} + +static void +option_outdat_callback (struct urb *urb, struct pt_regs *regs) +{ + struct usb_serial_port *port; + + dbg("%s", __FUNCTION__); + + port = (struct usb_serial_port *) urb->context; + + if (port->open_count) + schedule_work(&port->work); +} + +static void +option_instat_callback (struct urb *urb, struct pt_regs *regs) +{ + int err; + struct usb_serial_port *port = (struct usb_serial_port *) urb->context; + struct option_port_private *portdata = usb_get_serial_port_data(port); + struct usb_serial *serial = port->serial; + + dbg("%s", __FUNCTION__); + dbg("%s: urb %p port %p has data %p", __FUNCTION__,urb,port,portdata); + + if (urb->status == 0) { + struct usb_ctrlrequest *req_pkt = + (struct usb_ctrlrequest *)urb->transfer_buffer; + + if (!req_pkt) { + dbg("%s: NULL req_pkt\n", __FUNCTION__); + return; + } + if ((req_pkt->bRequestType == 0xA1) && (req_pkt->bRequest == 0x20)) { + int old_dcd_state; + unsigned char signals = *((unsigned char *) + urb->transfer_buffer + sizeof(struct usb_ctrlrequest)); + + dbg("%s: signal x%x", __FUNCTION__, signals); + + old_dcd_state = portdata->dcd_state; + portdata->cts_state = 1; + portdata->dcd_state = ((signals & 0x01) ? 1 : 0); + portdata->dsr_state = ((signals & 0x02) ? 1 : 0); + portdata->ri_state = ((signals & 0x08) ? 1 : 0); + + if (port->tty && !C_CLOCAL(port->tty) + && old_dcd_state && !portdata->dcd_state) { + tty_hangup(port->tty); + } + } else + dbg("%s: type %x req %x", __FUNCTION__, req_pkt->bRequestType,req_pkt->bRequest); + } else + dbg("%s: error %d", __FUNCTION__, urb->status); + + /* Resubmit urb so we continue receiving IRQ data */ + if (urb->status != -ESHUTDOWN) { + urb->dev = serial->dev; + err = usb_submit_urb(urb, GFP_ATOMIC); + if (err) + dbg("%s: resubmit intr urb failed. (%d)", __FUNCTION__, err); + } +} + + +static int +option_write_room (struct usb_serial_port *port) +{ + struct option_port_private *portdata; + int i; + int data_len = 0; + struct urb *this_urb; + + portdata = usb_get_serial_port_data(port); + + for (i=0; i < N_OUT_URB; i++) + this_urb = portdata->out_urbs[i]; + if (this_urb && this_urb->status != -EINPROGRESS) + data_len += OUT_BUFLEN; + + dbg("%s: %d", __FUNCTION__, data_len); + return data_len; +} + + +static int +option_chars_in_buffer (struct usb_serial_port *port) +{ + struct option_port_private *portdata; + int i; + int data_len = 0; + struct urb *this_urb; + + portdata = usb_get_serial_port_data(port); + + for (i=0; i < N_OUT_URB; i++) + this_urb = portdata->out_urbs[i]; + if (this_urb && this_urb->status == -EINPROGRESS) + data_len += this_urb->transfer_buffer_length; + + dbg("%s: %d", __FUNCTION__, data_len); + return data_len; +} + + +static int +option_open (struct usb_serial_port *port, struct file *filp) +{ + struct option_port_private *portdata; + struct usb_serial *serial = port->serial; + int i, err; + struct urb *urb; + + portdata = usb_get_serial_port_data(port); + + dbg("%s", __FUNCTION__); + + /* Set some sane defaults */ + portdata->rts_state = 1; + portdata->dtr_state = 1; + + /* Reset low level data toggle and start reading from endpoints */ + for (i = 0; i < N_IN_URB; i++) { + urb = portdata->in_urbs[i]; + if (! urb) + continue; + if (urb->dev != serial->dev) { + dbg("%s: dev %p != %p", __FUNCTION__, urb->dev, serial->dev); + continue; + } + + /* make sure endpoint data toggle is synchronized with the device */ + + usb_clear_halt(urb->dev, urb->pipe); + + err = usb_submit_urb(urb, GFP_KERNEL); + if (err) { + dbg("%s: submit urb %d failed (%d) %d", __FUNCTION__, i, err, + urb->transfer_buffer_length); + } + } + + /* Reset low level data toggle on out endpoints */ + for (i = 0; i < N_OUT_URB; i++) { + urb = portdata->out_urbs[i]; + if (! urb) + continue; + urb->dev = serial->dev; + /* usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe), 0); */ + } + + port->tty->low_latency = 1; + + option_send_setup(port); + + return (0); +} + +static inline void +stop_urb(struct urb *urb) +{ + if (urb && urb->status == -EINPROGRESS) { + urb->transfer_flags &= ~URB_ASYNC_UNLINK; + usb_kill_urb(urb); + } +} + +static void +option_close(struct usb_serial_port *port, struct file *filp) +{ + int i; + struct usb_serial *serial = port->serial; + struct option_port_private *portdata; + + dbg("%s", __FUNCTION__); + portdata = usb_get_serial_port_data(port); + + portdata->rts_state = 0; + portdata->dtr_state = 0; + + if (serial->dev) { + option_send_setup(port); + + /* Stop reading/writing urbs */ + for (i = 0; i < N_IN_URB; i++) + stop_urb(portdata->in_urbs[i]); + for (i = 0; i < N_OUT_URB; i++) + stop_urb(portdata->out_urbs[i]); + } + port->tty = NULL; +} + + +/* Helper functions used by option_setup_urbs */ +static struct urb * +option_setup_urb (struct usb_serial *serial, int endpoint, + int dir, void *ctx, char *buf, int len, + void (*callback)(struct urb *, struct pt_regs *regs)) +{ + struct urb *urb; + + if (endpoint == -1) + return NULL; /* endpoint not needed */ + + urb = usb_alloc_urb(0, GFP_KERNEL); /* No ISO */ + if (urb == NULL) { + dbg("%s: alloc for endpoint %d failed.", __FUNCTION__, endpoint); + return NULL; + } + + /* Fill URB using supplied data. */ + usb_fill_bulk_urb(urb, serial->dev, + usb_sndbulkpipe(serial->dev, endpoint) | dir, + buf, len, callback, ctx); + + return urb; +} + +/* Setup urbs */ +static void +option_setup_urbs(struct usb_serial *serial) +{ + int j; + struct usb_serial_port *port; + struct option_port_private *portdata; + + dbg("%s", __FUNCTION__); + + port = serial->port[0]; + portdata = usb_get_serial_port_data(port); + + /* Do indat endpoints first */ + for (j = 0; j <= N_IN_URB; ++j) { + portdata->in_urbs[j] = option_setup_urb (serial, + port->bulk_in_endpointAddress, USB_DIR_IN, port, + portdata->in_buffer[j], IN_BUFLEN, option_indat_callback); + } + + /* outdat endpoints */ + for (j = 0; j <= N_OUT_URB; ++j) { + portdata->out_urbs[j] = option_setup_urb (serial, + port->bulk_out_endpointAddress, USB_DIR_OUT, port, + portdata->out_buffer[j], OUT_BUFLEN, option_outdat_callback); + } +} + + +static int +option_send_setup(struct usb_serial_port *port) +{ + struct usb_serial *serial = port->serial; + struct option_port_private *portdata; + + dbg("%s", __FUNCTION__); + + portdata = usb_get_serial_port_data(port); + + if (port->tty) { + int val = 0; + if (portdata->dtr_state) + val |= 0x01; + if (portdata->rts_state) + val |= 0x02; + + return usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), + 0x22,0x21,val,0,NULL,0,USB_CTRL_SET_TIMEOUT); + } + + return 0; +} + + +static int +option_startup (struct usb_serial *serial) +{ + int i, err; + struct usb_serial_port *port; + struct option_port_private *portdata; + + dbg("%s", __FUNCTION__); + + /* Now setup per port private data */ + for (i = 0; i < serial->num_ports; i++) { + port = serial->port[i]; + portdata = kmalloc(sizeof(struct option_port_private), GFP_KERNEL); + if (!portdata) { + dbg("%s: kmalloc for option_port_private (%d) failed!.", __FUNCTION__, i); + return (1); + } + memset(portdata, 0, sizeof(struct option_port_private)); + + usb_set_serial_port_data(port, portdata); + + if (! port->interrupt_in_urb) + continue; + err = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); + if (err) + dbg("%s: submit irq_in urb failed %d", __FUNCTION__, err); + } + + option_setup_urbs(serial); + + return (0); +} + +static void +option_shutdown (struct usb_serial *serial) +{ + int i, j; + struct usb_serial_port *port; + struct option_port_private *portdata; + + dbg("%s", __FUNCTION__); + + /* Stop reading/writing urbs */ + for (i = 0; i < serial->num_ports; ++i) { + port = serial->port[i]; + portdata = usb_get_serial_port_data(port); + for (j = 0; j < N_IN_URB; j++) + stop_urb(portdata->in_urbs[j]); + for (j = 0; j < N_OUT_URB; j++) + stop_urb(portdata->out_urbs[j]); + } + + /* Now free them */ + for (i = 0; i < serial->num_ports; ++i) { + port = serial->port[i]; + portdata = usb_get_serial_port_data(port); + + for (j = 0; j < N_IN_URB; j++) { + if (portdata->in_urbs[j]) { + usb_free_urb(portdata->in_urbs[j]); + portdata->in_urbs[j] = NULL; + } + } + for (j = 0; j < N_OUT_URB; j++) { + if (portdata->out_urbs[j]) { + usb_free_urb(portdata->out_urbs[j]); + portdata->out_urbs[j] = NULL; + } + } + } + + /* Now free per port private data */ + for (i = 0; i < serial->num_ports; i++) { + port = serial->port[i]; + kfree(usb_get_serial_port_data(port)); + } +} + +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_VERSION(DRIVER_VERSION); +MODULE_LICENSE("GPL"); + +module_param(debug, bool, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(debug, "Debug messages"); + -- cgit v1.2.3-70-g09d2 From 77ddecc3c047e4e9bd7332d3173def93ea2de1ad Mon Sep 17 00:00:00 2001 From: Paulo Marques Date: Wed, 18 May 2005 13:12:49 +0100 Subject: [PATCH] USB: make MODALIAS code a bit smaller devices This patch makes the code to provide modalias in sysfs for usb devices 56 bytes smaller in i386, while making it clear that the first part of the modalias string is the same no matter what the device class is. Signed-Off-By: Paulo Marques Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/sysfs.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index 4ab50009291..4d0c9e65cd0 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c @@ -290,32 +290,30 @@ static ssize_t show_modalias(struct device *dev, char *buf) { struct usb_interface *intf; struct usb_device *udev; + int len; intf = to_usb_interface(dev); udev = interface_to_usbdev(intf); - if (udev->descriptor.bDeviceClass == 0) { - struct usb_host_interface *alt = intf->cur_altsetting; - return sprintf(buf, "usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02X\n", + len = sprintf(buf, "usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic", le16_to_cpu(udev->descriptor.idVendor), le16_to_cpu(udev->descriptor.idProduct), le16_to_cpu(udev->descriptor.bcdDevice), udev->descriptor.bDeviceClass, udev->descriptor.bDeviceSubClass, - udev->descriptor.bDeviceProtocol, + udev->descriptor.bDeviceProtocol); + buf += len; + + if (udev->descriptor.bDeviceClass == 0) { + struct usb_host_interface *alt = intf->cur_altsetting; + + return len + sprintf(buf, "%02Xisc%02Xip%02X\n", alt->desc.bInterfaceClass, alt->desc.bInterfaceSubClass, alt->desc.bInterfaceProtocol); } else { - return sprintf(buf, "usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic*isc*ip*\n", - le16_to_cpu(udev->descriptor.idVendor), - le16_to_cpu(udev->descriptor.idProduct), - le16_to_cpu(udev->descriptor.bcdDevice), - udev->descriptor.bDeviceClass, - udev->descriptor.bDeviceSubClass, - udev->descriptor.bDeviceProtocol); + return len + sprintf(buf, "*isc*ip*\n"); } - } static DEVICE_ATTR(modalias, S_IRUGO, show_modalias, NULL); -- cgit v1.2.3-70-g09d2 From 1724757e5ab5219b46876ac6e4e362a4b2dcfa86 Mon Sep 17 00:00:00 2001 From: Phil Dibowitz Date: Sat, 21 May 2005 00:45:55 -0700 Subject: [PATCH] USB Storage: Add unusual_devs for Trumpion Voice Recorder The original entry of this patch was submitted by Filippo Bardelli , with cleanups and patch-ification by me. This corrects the subclass that the device reports. Signed-off-by: Phil Dibowitz Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/unusual_devs.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index d2891f47579..9fcc7bd1fbe 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -862,6 +862,15 @@ UNUSUAL_DEV( 0x090a, 0x1001, 0x0100, 0x0100, US_SC_DEVICE, US_PR_BULK, NULL, US_FL_NEED_OVERRIDE ), +/* Reported by Filippo Bardelli + * The device reports a subclass of RBC, which is wrong. + */ +UNUSUAL_DEV( 0x090a, 0x1050, 0x0100, 0x0100, + "Trumpion Microelectronics, Inc.", + "33520 USB Digital Voice Recorder", + US_SC_UFI, US_PR_DEVICE, NULL, + 0), + /* Trumpion Microelectronics MP3 player (felipe_alfaro@linuxmail.org) */ UNUSUAL_DEV( 0x090a, 0x1200, 0x0000, 0x9999, "Trumpion", -- cgit v1.2.3-70-g09d2 From 719df469cb51199316ae2a11c75a8046be34b899 Mon Sep 17 00:00:00 2001 From: Roman Kagan Date: Fri, 6 May 2005 00:55:56 +0400 Subject: [PATCH] USB: update urb documentation On Wed, May 04, 2005 at 01:37:30PM -0700, David Brownell wrote: > On Wednesday 04 May 2005 12:19 pm, Roman Kagan wrote: > > struct urb { > > /* private, usb core and host controller only fields in the urb */ > > ... > > struct list_head urb_list; /* list pointer to all active urbs */ > > ... > > }; > > > > Is it safe to use it for driver's purposes when the driver owns the urb, > > that is, starting from the completion routine until the urb is submitted > > with usb_submit_urb()? > > Right now, it should be. Great! FWIW I've briefly tested a modified version of usbatm using the list head in struct urb instead of creating a wrapper struct, and I haven't seen any failures yet. So I tend to believe that your "should be" actually means "is" :) > > If it is, can it be guaranteed in future, e.g. > > by moving the list head into the public section of struct urb? > > In fact I'm not sure why it ever got called "private" to usbcore/hcds. > I thought the idea was that it should be like urb->status, reserved for > whoever controls the URB. OK then how about the following (essentially documentation) patch? Signed-off-by: Roman Kagan Acked-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- include/linux/usb.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/include/linux/usb.h b/include/linux/usb.h index 41d1a644c9d..2d1ac505853 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -796,6 +796,10 @@ typedef void (*usb_complete_t)(struct urb *, struct pt_regs *); * of the iso_frame_desc array, and the number of errors is reported in * error_count. Completion callbacks for ISO transfers will normally * (re)submit URBs to ensure a constant transfer rate. + * + * Note that even fields marked "public" should not be touched by the driver + * when the urb is owned by the hcd, that is, since the call to + * usb_submit_urb() till the entry into the completion routine. */ struct urb { @@ -803,12 +807,12 @@ struct urb struct kref kref; /* reference count of the URB */ spinlock_t lock; /* lock for the URB */ void *hcpriv; /* private data for host controller */ - struct list_head urb_list; /* list pointer to all active urbs */ int bandwidth; /* bandwidth for INT/ISO request */ atomic_t use_count; /* concurrent submissions counter */ u8 reject; /* submissions will fail */ /* public, documented fields in the urb that can be used by drivers */ + struct list_head urb_list; /* list head for use by the urb owner */ struct usb_device *dev; /* (in) pointer to associated device */ unsigned int pipe; /* (in) pipe information */ int status; /* (return) non-ISO status */ -- cgit v1.2.3-70-g09d2 From 39a66b8d22a36cfa1a48f7f59c6a4639d9c99653 Mon Sep 17 00:00:00 2001 From: Craig Shelley Date: Fri, 27 May 2005 00:09:56 +0100 Subject: [PATCH] USB: CP2101 Add support for flow control Added support to get/set flow control line levels using TIOCMGET and TIOCMSET. Added support for RTSCTS hardware flow control. cp2101_get_config and cp2101_set_config modified to support long request strings, required for configuring flow control. Signed-off-by: Craig Shelley craig@microtron.org.uk Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/cp2101.c | 363 +++++++++++++++++++++++++++++++++----------- 1 file changed, 275 insertions(+), 88 deletions(-) diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c index 7e9bb63eb46..4ace9964fc6 100644 --- a/drivers/usb/serial/cp2101.c +++ b/drivers/usb/serial/cp2101.c @@ -7,6 +7,14 @@ * modify it under the terms of the GNU General Public License version * 2 as published by the Free Software Foundation. * + * Support to set flow control line levels using TIOCMGET and TIOCMSET + * thanks to Karl Hiramoto karl@hiramoto.org. RTSCTS hardware flow + * control thanks to Munir Nassar nassarmu@real-time.com + * + * Outstanding Issues: + * Buffers are not flushed when the port is opened. + * Multiple calls to write() may fail with "Resource temporarily unavailable" + * */ #include @@ -24,7 +32,7 @@ /* * Version Information */ -#define DRIVER_VERSION "v0.03" +#define DRIVER_VERSION "v0.04" #define DRIVER_DESC "Silicon Labs CP2101/CP2102 RS232 serial adaptor driver" /* @@ -35,6 +43,9 @@ static void cp2101_cleanup(struct usb_serial_port*); static void cp2101_close(struct usb_serial_port*, struct file*); static void cp2101_get_termios(struct usb_serial_port*); static void cp2101_set_termios(struct usb_serial_port*, struct termios*); +static int cp2101_tiocmget (struct usb_serial_port *, struct file *); +static int cp2101_tiocmset (struct usb_serial_port *, struct file *, + unsigned int, unsigned int); static void cp2101_break_ctl(struct usb_serial_port*, int); static int cp2101_startup (struct usb_serial *); static void cp2101_shutdown(struct usb_serial*); @@ -43,9 +54,10 @@ static void cp2101_shutdown(struct usb_serial*); static int debug; static struct usb_device_id id_table [] = { - {USB_DEVICE(0x10c4, 0xea60) }, /*Silicon labs factory default*/ - {USB_DEVICE(0x10ab, 0x10c5) }, /*Siemens MC60 Cable*/ - { } /* Terminating Entry*/ + { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ + { USB_DEVICE(0x10C4, 0x80CA) }, /* Degree Controls Inc */ + { USB_DEVICE(0x10AB, 0x10C5) }, /* Siemens MC60 Cable */ + { } /* Terminating Entry */ }; MODULE_DEVICE_TABLE (usb, id_table); @@ -70,32 +82,35 @@ static struct usb_serial_device_type cp2101_device = { .close = cp2101_close, .break_ctl = cp2101_break_ctl, .set_termios = cp2101_set_termios, + .tiocmget = cp2101_tiocmget, + .tiocmset = cp2101_tiocmset, .attach = cp2101_startup, .shutdown = cp2101_shutdown, }; -/*Config request types*/ +/* Config request types */ #define REQTYPE_HOST_TO_DEVICE 0x41 #define REQTYPE_DEVICE_TO_HOST 0xc1 -/*Config SET requests. To GET, add 1 to the request number*/ -#define CP2101_UART 0x00 /*Enable / Disable*/ -#define CP2101_BAUDRATE 0x01 /*(BAUD_RATE_GEN_FREQ / baudrate)*/ -#define CP2101_BITS 0x03 /*0x(0)(data bits)(parity)(stop bits)*/ -#define CP2101_BREAK 0x05 /*On / Off*/ -#define CP2101_DTRRTS 0x07 /*101 / 202 ???*/ -#define CP2101_CONFIG_16 0x13 /*16 bytes of config data ???*/ -#define CP2101_CONFIG_6 0x19 /*6 bytes of config data ???*/ +/* Config SET requests. To GET, add 1 to the request number */ +#define CP2101_UART 0x00 /* Enable / Disable */ +#define CP2101_BAUDRATE 0x01 /* (BAUD_RATE_GEN_FREQ / baudrate) */ +#define CP2101_BITS 0x03 /* 0x(0)(databits)(parity)(stopbits) */ +#define CP2101_BREAK 0x05 /* On / Off */ +#define CP2101_CONTROL 0x07 /* Flow control line states */ +#define CP2101_MODEMCTL 0x13 /* Modem controls */ +#define CP2101_CONFIG_6 0x19 /* 6 bytes of config data ??? */ -/*CP2101_UART*/ +/* CP2101_UART */ #define UART_ENABLE 0x0001 #define UART_DISABLE 0x0000 -/*CP2101_BAUDRATE*/ +/* CP2101_BAUDRATE */ #define BAUD_RATE_GEN_FREQ 0x384000 -/*CP2101_BITS*/ +/* CP2101_BITS */ #define BITS_DATA_MASK 0X0f00 +#define BITS_DATA_5 0X0500 #define BITS_DATA_6 0X0600 #define BITS_DATA_7 0X0700 #define BITS_DATA_8 0X0800 @@ -112,64 +127,137 @@ static struct usb_serial_device_type cp2101_device = { #define BITS_STOP_1 0x0000 #define BITS_STOP_1_5 0x0001 #define BITS_STOP_2 0x0002 + +/* CP2101_BREAK */ #define BREAK_ON 0x0000 #define BREAK_OFF 0x0001 +/* CP2101_CONTROL */ +#define CONTROL_DTR 0x0001 +#define CONTROL_RTS 0x0002 +#define CONTROL_CTS 0x0010 +#define CONTROL_DSR 0x0020 +#define CONTROL_RING 0x0040 +#define CONTROL_DCD 0x0080 +#define CONTROL_WRITE_DTR 0x0100 +#define CONTROL_WRITE_RTS 0x0200 -static int cp2101_get_config(struct usb_serial_port* port, u8 request) +/* + * cp2101_get_config + * Reads from the CP2101 configuration registers + * 'size' is specified in bytes. + * 'data' is a pointer to a pre-allocated array of integers large + * enough to hold 'size' bytes (with 4 bytes to each integer) + */ +static int cp2101_get_config(struct usb_serial_port* port, u8 request, + unsigned int *data, int size) { struct usb_serial *serial = port->serial; - unsigned char buf[4]; - unsigned int value; - int result, i; + u32 *buf; + int result, i, length; + + /* Number of integers required to contain the array */ + length = (((size - 1) | 3) + 1)/4; + + buf = kmalloc (length * sizeof(u32), GFP_KERNEL); + memset(buf, 0, length * sizeof(u32)); + + if (!buf) { + dev_err(&port->dev, "%s - out of memory.\n", __FUNCTION__); + return -ENOMEM; + } - /*For get requests, the request number must be incremented*/ + /* For get requests, the request number must be incremented */ request++; - /*Issue the request, attempting to read 4 bytes*/ + /* Issue the request, attempting to read 'size' bytes */ result = usb_control_msg (serial->dev,usb_rcvctrlpipe (serial->dev, 0), request, REQTYPE_DEVICE_TO_HOST, 0x0000, - 0, buf, 4, 300); + 0, buf, size, 300); - if (result < 0) { - dev_err(&port->dev, "%s - Unable to send config request, " - "request=0x%x result=%d\n", - __FUNCTION__, request, result); - return result; - } + /* Convert data into an array of integers */ + for (i=0; idev, "%s - Unable to send config request, " + "request=0x%x size=%d result=%d\n", + __FUNCTION__, request, size, result); + return -EPROTO; + } - return value; + return 0; } -static int cp2101_set_config(struct usb_serial_port* port, u8 request, u16 value) +/* + * cp2101_set_config + * Writes to the CP2101 configuration registers + * Values less than 16 bits wide are sent directly + * 'size' is specified in bytes. + */ +static int cp2101_set_config(struct usb_serial_port* port, u8 request, + unsigned int *data, int size) { struct usb_serial *serial = port->serial; - int result; - result = usb_control_msg (serial->dev, usb_sndctrlpipe(serial->dev, 0), - request, REQTYPE_HOST_TO_DEVICE, value, - 0, NULL, 0, 300); + u32 *buf; + int result, i, length; - if (result <0) { - dev_err(&port->dev, "%s - Unable to send config request, " - "request=0x%x value=0x%x result=%d\n", - __FUNCTION__, request, value, result); - return result; + /* Number of integers required to contain the array */ + length = (((size - 1) | 3) + 1)/4; + + buf = kmalloc(length * sizeof(u32), GFP_KERNEL); + if (!buf) { + dev_err(&port->dev, "%s - out of memory.\n", + __FUNCTION__); + return -ENOMEM; + } + + /* Array of integers into bytes */ + for (i = 0; i < length; i++) + buf[i] = cpu_to_le32(data[i]); + + if (size > 2) { + result = usb_control_msg (serial->dev, + usb_sndctrlpipe(serial->dev, 0), + request, REQTYPE_HOST_TO_DEVICE, 0x0000, + 0, buf, size, 300); + } else { + result = usb_control_msg (serial->dev, + usb_sndctrlpipe(serial->dev, 0), + request, REQTYPE_HOST_TO_DEVICE, data[0], + 0, NULL, 0, 300); } - dbg(" %s - request=0x%x value=0x%x result=%d", - __FUNCTION__, request, value, result); + kfree(buf); + + if ((size > 2 && result != size) || result < 0) { + dev_err(&port->dev, "%s - Unable to send request, " + "request=0x%x size=%d result=%d\n", + __FUNCTION__, request, size, result); + return -EPROTO; + } + /* Single data value */ + result = usb_control_msg (serial->dev, + usb_sndctrlpipe(serial->dev, 0), + request, REQTYPE_HOST_TO_DEVICE, data[0], + 0, NULL, 0, 300); return 0; } +/* + * cp2101_set_config_single + * Convenience function for calling cp2101_set_config on single data values + * without requiring an integer pointer + */ +static inline int cp2101_set_config_single(struct usb_serial_port* port, + u8 request, unsigned int data) +{ + return cp2101_set_config(port, request, &data, 2); +} + static int cp2101_open (struct usb_serial_port *port, struct file *filp) { struct usb_serial *serial = port->serial; @@ -177,7 +265,7 @@ static int cp2101_open (struct usb_serial_port *port, struct file *filp) dbg("%s - port %d", __FUNCTION__, port->number); - if (cp2101_set_config(port, CP2101_UART, UART_ENABLE)) { + if (cp2101_set_config_single(port, CP2101_UART, UART_ENABLE)) { dev_err(&port->dev, "%s - Unable to enable UART\n", __FUNCTION__); return -EPROTO; @@ -198,9 +286,12 @@ static int cp2101_open (struct usb_serial_port *port, struct file *filp) return result; } - /*Configure the termios structure*/ + /* Configure the termios structure */ cp2101_get_termios(port); + /* Set the DTR and RTS pins low */ + cp2101_tiocmset(port, NULL, TIOCM_DTR | TIOCM_RTS, 0); + return 0; } @@ -228,16 +319,18 @@ static void cp2101_close (struct usb_serial_port *port, struct file * filp) usb_kill_urb(port->write_urb); usb_kill_urb(port->read_urb); - cp2101_set_config(port, CP2101_UART, UART_DISABLE); + cp2101_set_config_single(port, CP2101_UART, UART_DISABLE); } -/* cp2101_get_termios*/ -/* Reads the baud rate, data bits, parity and stop bits from the device*/ -/* Corrects any unsupported values*/ -/* Configures the termios structure to reflect the state of the device*/ +/* + * cp2101_get_termios + * Reads the baud rate, data bits, parity, stop bits and flow control mode + * from the device, corrects any unsupported values, and configures the + * termios structure to reflect the state of the device + */ static void cp2101_get_termios (struct usb_serial_port *port) { - unsigned int cflag; + unsigned int cflag, modem_ctl[4]; int baud; int bits; @@ -249,15 +342,16 @@ static void cp2101_get_termios (struct usb_serial_port *port) } cflag = port->tty->termios->c_cflag; - baud = cp2101_get_config(port, CP2101_BAUDRATE); - /*Convert to baudrate*/ + cp2101_get_config(port, CP2101_BAUDRATE, &baud, 2); + /* Convert to baudrate */ if (baud) baud = BAUD_RATE_GEN_FREQ / baud; dbg("%s - baud rate = %d", __FUNCTION__, baud); cflag &= ~CBAUD; switch (baud) { - /* The baud rates which are commented out below + /* + * The baud rates which are commented out below * appear to be supported by the device * but are non-standard */ @@ -284,14 +378,18 @@ static void cp2101_get_termios (struct usb_serial_port *port) dbg("%s - Baud rate is not supported, " "using 9600 baud", __FUNCTION__); cflag |= B9600; - cp2101_set_config(port, CP2101_BAUDRATE, + cp2101_set_config_single(port, CP2101_BAUDRATE, (BAUD_RATE_GEN_FREQ/9600)); break; } - bits = cp2101_get_config(port, CP2101_BITS); + cp2101_get_config(port, CP2101_BITS, &bits, 2); cflag &= ~CSIZE; switch(bits & BITS_DATA_MASK) { + case BITS_DATA_5: + dbg("%s - data bits = 5", __FUNCTION__); + cflag |= CS5; + break; case BITS_DATA_6: dbg("%s - data bits = 6", __FUNCTION__); cflag |= CS6; @@ -310,7 +408,7 @@ static void cp2101_get_termios (struct usb_serial_port *port) cflag |= CS8; bits &= ~BITS_DATA_MASK; bits |= BITS_DATA_8; - cp2101_set_config(port, CP2101_BITS, bits); + cp2101_set_config(port, CP2101_BITS, &bits, 2); break; default: dbg("%s - Unknown number of data bits, " @@ -318,7 +416,7 @@ static void cp2101_get_termios (struct usb_serial_port *port) cflag |= CS8; bits &= ~BITS_DATA_MASK; bits |= BITS_DATA_8; - cp2101_set_config(port, CP2101_BITS, bits); + cp2101_set_config(port, CP2101_BITS, &bits, 2); break; } @@ -341,21 +439,21 @@ static void cp2101_get_termios (struct usb_serial_port *port) "disabling parity)", __FUNCTION__); cflag &= ~PARENB; bits &= ~BITS_PARITY_MASK; - cp2101_set_config(port, CP2101_BITS, bits); + cp2101_set_config(port, CP2101_BITS, &bits, 2); break; case BITS_PARITY_SPACE: dbg("%s - parity = SPACE (not supported, " "disabling parity)", __FUNCTION__); cflag &= ~PARENB; bits &= ~BITS_PARITY_MASK; - cp2101_set_config(port, CP2101_BITS, bits); + cp2101_set_config(port, CP2101_BITS, &bits, 2); break; default: dbg("%s - Unknown parity mode, " "disabling parity", __FUNCTION__); cflag &= ~PARENB; bits &= ~BITS_PARITY_MASK; - cp2101_set_config(port, CP2101_BITS, bits); + cp2101_set_config(port, CP2101_BITS, &bits, 2); break; } @@ -366,9 +464,9 @@ static void cp2101_get_termios (struct usb_serial_port *port) break; case BITS_STOP_1_5: dbg("%s - stop bits = 1.5 (not supported, " - "using 1 stop bit", __FUNCTION__); + "using 1 stop bit)", __FUNCTION__); bits &= ~BITS_STOP_MASK; - cp2101_set_config(port, CP2101_BITS, bits); + cp2101_set_config(port, CP2101_BITS, &bits, 2); break; case BITS_STOP_2: dbg("%s - stop bits = 2", __FUNCTION__); @@ -378,10 +476,19 @@ static void cp2101_get_termios (struct usb_serial_port *port) dbg("%s - Unknown number of stop bits, " "using 1 stop bit", __FUNCTION__); bits &= ~BITS_STOP_MASK; - cp2101_set_config(port, CP2101_BITS, bits); + cp2101_set_config(port, CP2101_BITS, &bits, 2); break; } + cp2101_get_config(port, CP2101_MODEMCTL, modem_ctl, 16); + if (modem_ctl[0] & 0x0008) { + dbg("%s - flow control = CRTSCTS", __FUNCTION__); + cflag |= CRTSCTS; + } else { + dbg("%s - flow control = NONE", __FUNCTION__); + cflag &= ~CRTSCTS; + } + port->tty->termios->c_cflag = cflag; } @@ -389,8 +496,8 @@ static void cp2101_set_termios (struct usb_serial_port *port, struct termios *old_termios) { unsigned int cflag, old_cflag=0; - int baud=0; - int bits; + int baud=0, bits; + unsigned int modem_ctl[4]; dbg("%s - port %d", __FUNCTION__, port->number); @@ -400,7 +507,7 @@ static void cp2101_set_termios (struct usb_serial_port *port, } cflag = port->tty->termios->c_cflag; - /* check that they really want us to change something */ + /* Check that they really want us to change something */ if (old_termios) { if ((cflag == old_termios->c_cflag) && (RELEVANT_IFLAG(port->tty->termios->c_iflag) @@ -415,7 +522,8 @@ static void cp2101_set_termios (struct usb_serial_port *port, /* If the baud rate is to be updated*/ if ((cflag & CBAUD) != (old_cflag & CBAUD)) { switch (cflag & CBAUD) { - /* The baud rates which are commented out below + /* + * The baud rates which are commented out below * appear to be supported by the device * but are non-standard */ @@ -448,18 +556,22 @@ static void cp2101_set_termios (struct usb_serial_port *port, if (baud) { dbg("%s - Setting baud rate to %d baud", __FUNCTION__, baud); - if (cp2101_set_config(port, CP2101_BAUDRATE, + if (cp2101_set_config_single(port, CP2101_BAUDRATE, (BAUD_RATE_GEN_FREQ / baud))) dev_err(&port->dev, "Baud rate requested not " "supported by device\n"); } } - /*If the number of data bits is to be updated*/ + /* If the number of data bits is to be updated */ if ((cflag & CSIZE) != (old_cflag & CSIZE)) { - bits = cp2101_get_config(port, CP2101_BITS); + cp2101_get_config(port, CP2101_BITS, &bits, 2); bits &= ~BITS_DATA_MASK; switch (cflag & CSIZE) { + case CS5: + bits |= BITS_DATA_5; + dbg("%s - data bits = 5", __FUNCTION__); + break; case CS6: bits |= BITS_DATA_6; dbg("%s - data bits = 6", __FUNCTION__); @@ -483,13 +595,13 @@ static void cp2101_set_termios (struct usb_serial_port *port, bits |= BITS_DATA_8; break; } - if (cp2101_set_config(port, CP2101_BITS, bits)) + if (cp2101_set_config(port, CP2101_BITS, &bits, 2)) dev_err(&port->dev, "Number of data bits requested " "not supported by device\n"); } if ((cflag & (PARENB|PARODD)) != (old_cflag & (PARENB|PARODD))) { - bits = cp2101_get_config(port, CP2101_BITS); + cp2101_get_config(port, CP2101_BITS, &bits, 2); bits &= ~BITS_PARITY_MASK; if (cflag & PARENB) { if (cflag & PARODD) { @@ -500,13 +612,13 @@ static void cp2101_set_termios (struct usb_serial_port *port, dbg("%s - parity = EVEN", __FUNCTION__); } } - if (cp2101_set_config(port, CP2101_BITS, bits)) + if (cp2101_set_config(port, CP2101_BITS, &bits, 2)) dev_err(&port->dev, "Parity mode not supported " "by device\n"); } if ((cflag & CSTOPB) != (old_cflag & CSTOPB)) { - bits = cp2101_get_config(port, CP2101_BITS); + cp2101_get_config(port, CP2101_BITS, &bits, 2); bits &= ~BITS_STOP_MASK; if (cflag & CSTOPB) { bits |= BITS_STOP_2; @@ -515,15 +627,90 @@ static void cp2101_set_termios (struct usb_serial_port *port, bits |= BITS_STOP_1; dbg("%s - stop bits = 1", __FUNCTION__); } - if (cp2101_set_config(port, CP2101_BITS, bits)) + if (cp2101_set_config(port, CP2101_BITS, &bits, 2)) dev_err(&port->dev, "Number of stop bits requested " "not supported by device\n"); } + + if ((cflag & CRTSCTS) != (old_cflag & CRTSCTS)) { + cp2101_get_config(port, CP2101_MODEMCTL, modem_ctl, 16); + dbg("%s - read modem controls = 0x%.4x 0x%.4x 0x%.4x 0x%.4x", + __FUNCTION__, modem_ctl[0], modem_ctl[1], + modem_ctl[2], modem_ctl[3]); + + if (cflag & CRTSCTS) { + modem_ctl[0] &= ~0x7B; + modem_ctl[0] |= 0x09; + modem_ctl[1] = 0x80; + dbg("%s - flow control = CRTSCTS", __FUNCTION__); + } else { + modem_ctl[0] &= ~0x7B; + modem_ctl[0] |= 0x01; + modem_ctl[1] |= 0x40; + dbg("%s - flow control = NONE", __FUNCTION__); + } + + dbg("%s - write modem controls = 0x%.4x 0x%.4x 0x%.4x 0x%.4x", + __FUNCTION__, modem_ctl[0], modem_ctl[1], + modem_ctl[2], modem_ctl[3]); + cp2101_set_config(port, CP2101_MODEMCTL, modem_ctl, 16); + } + +} + +static int cp2101_tiocmset (struct usb_serial_port *port, struct file *file, + unsigned int set, unsigned int clear) +{ + int control = 0; + + dbg("%s - port %d", __FUNCTION__, port->number); + + if (set & TIOCM_RTS) { + control |= CONTROL_RTS; + control |= CONTROL_WRITE_RTS; + } + if (set & TIOCM_DTR) { + control |= CONTROL_DTR; + control |= CONTROL_WRITE_DTR; + } + if (clear & TIOCM_RTS) { + control &= ~CONTROL_RTS; + control |= CONTROL_WRITE_RTS; + } + if (clear & TIOCM_DTR) { + control &= ~CONTROL_DTR; + control |= CONTROL_WRITE_DTR; + } + + dbg("%s - control = 0x%.4x", __FUNCTION__, control); + + return cp2101_set_config(port, CP2101_CONTROL, &control, 2); + +} + +static int cp2101_tiocmget (struct usb_serial_port *port, struct file *file) +{ + int control, result; + + dbg("%s - port %d", __FUNCTION__, port->number); + + cp2101_get_config(port, CP2101_CONTROL, &control, 1); + + result = ((control & CONTROL_DTR) ? TIOCM_DTR : 0) + |((control & CONTROL_RTS) ? TIOCM_RTS : 0) + |((control & CONTROL_CTS) ? TIOCM_CTS : 0) + |((control & CONTROL_DSR) ? TIOCM_DSR : 0) + |((control & CONTROL_RING)? TIOCM_RI : 0) + |((control & CONTROL_DCD) ? TIOCM_CD : 0); + + dbg("%s - control = 0x%.2x", __FUNCTION__, control); + + return result; } static void cp2101_break_ctl (struct usb_serial_port *port, int break_state) { - u16 state; + int state; dbg("%s - port %d", __FUNCTION__, port->number); if (break_state == 0) @@ -532,12 +719,12 @@ static void cp2101_break_ctl (struct usb_serial_port *port, int break_state) state = BREAK_ON; dbg("%s - turning break %s", __FUNCTION__, state==BREAK_OFF ? "off" : "on"); - cp2101_set_config(port, CP2101_BREAK, state); + cp2101_set_config(port, CP2101_BREAK, &state, 2); } static int cp2101_startup (struct usb_serial *serial) { - /*CP2101 buffers behave strangely unless device is reset*/ + /* CP2101 buffers behave strangely unless device is reset */ usb_reset_device(serial->dev); return 0; } @@ -548,7 +735,7 @@ static void cp2101_shutdown (struct usb_serial *serial) dbg("%s", __FUNCTION__); - /* stop reads and writes on all ports */ + /* Stop reads and writes on all ports */ for (i=0; i < serial->num_ports; ++i) { cp2101_cleanup(serial->port[i]); } @@ -560,16 +747,16 @@ static int __init cp2101_init (void) retval = usb_serial_register(&cp2101_device); if (retval) - return retval; /*Failed to register*/ + return retval; /* Failed to register */ retval = usb_register(&cp2101_driver); if (retval) { - /*Failed to register*/ + /* Failed to register */ usb_serial_deregister(&cp2101_device); return retval; } - /*Success*/ + /* Success */ info(DRIVER_DESC " " DRIVER_VERSION); return 0; } -- cgit v1.2.3-70-g09d2 From 18e144d32cd3dae6953c385e4b376ef9688b61b0 Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Fri, 27 May 2005 15:04:47 -0700 Subject: [SCSI] qla2xxx: fix bad locking during eh_abort Correct incorrect locking order in qla2xxx_eh_abort() handler which would case a hang during certain code-paths. With extra pieces to fix the irq state in the locks. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_os.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 579448222d6..3c97aa45772 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -507,6 +507,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) int ret, i; unsigned int id, lun; unsigned long serial; + unsigned long flags; if (!CMD_SP(cmd)) return FAILED; @@ -519,7 +520,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) /* Check active list for command command. */ spin_unlock_irq(ha->host->host_lock); - spin_lock(&ha->hardware_lock); + spin_lock_irqsave(&ha->hardware_lock, flags); for (i = 1; i < MAX_OUTSTANDING_COMMANDS; i++) { sp = ha->outstanding_cmds[i]; @@ -534,7 +535,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) sp->state)); DEBUG3(qla2x00_print_scsi_cmd(cmd);) - spin_unlock(&ha->hardware_lock); + spin_unlock_irqrestore(&ha->hardware_lock, flags); if (qla2x00_abort_command(ha, sp)) { DEBUG2(printk("%s(%ld): abort_command " "mbx failed.\n", __func__, ha->host_no)); @@ -543,20 +544,19 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) "mbx success.\n", __func__, ha->host_no)); ret = SUCCESS; } - spin_lock(&ha->hardware_lock); + spin_lock_irqsave(&ha->hardware_lock, flags); break; } + spin_unlock_irqrestore(&ha->hardware_lock, flags); /* Wait for the command to be returned. */ if (ret == SUCCESS) { - spin_unlock(&ha->hardware_lock); if (qla2x00_eh_wait_on_command(ha, cmd) != QLA_SUCCESS) { qla_printk(KERN_ERR, ha, "scsi(%ld:%d:%d): Abort handler timed out -- %lx " "%x.\n", ha->host_no, id, lun, serial, ret); } - spin_lock(&ha->hardware_lock); } spin_lock_irq(ha->host->host_lock); @@ -588,6 +588,7 @@ qla2x00_eh_wait_for_pending_target_commands(scsi_qla_host_t *ha, unsigned int t) int status; srb_t *sp; struct scsi_cmnd *cmd; + unsigned long flags; status = 0; @@ -596,11 +597,11 @@ qla2x00_eh_wait_for_pending_target_commands(scsi_qla_host_t *ha, unsigned int t) * array */ for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) { - spin_lock(&ha->hardware_lock); + spin_lock_irqsave(&ha->hardware_lock, flags); sp = ha->outstanding_cmds[cnt]; if (sp) { cmd = sp->cmd; - spin_unlock(&ha->hardware_lock); + spin_unlock_irqrestore(&ha->hardware_lock, flags); if (cmd->device->id == t) { if (!qla2x00_eh_wait_on_command(ha, cmd)) { status = 1; @@ -608,7 +609,7 @@ qla2x00_eh_wait_for_pending_target_commands(scsi_qla_host_t *ha, unsigned int t) } } } else { - spin_unlock(&ha->hardware_lock); + spin_unlock_irqrestore(&ha->hardware_lock, flags); } } return (status); @@ -740,6 +741,7 @@ qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *ha) int status; srb_t *sp; struct scsi_cmnd *cmd; + unsigned long flags; status = 1; @@ -748,17 +750,17 @@ qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *ha) * array */ for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) { - spin_lock(&ha->hardware_lock); + spin_lock_irqsave(&ha->hardware_lock, flags); sp = ha->outstanding_cmds[cnt]; if (sp) { cmd = sp->cmd; - spin_unlock(&ha->hardware_lock); + spin_unlock_irqrestore(&ha->hardware_lock, flags); status = qla2x00_eh_wait_on_command(ha, cmd); if (status == 0) break; } else { - spin_unlock(&ha->hardware_lock); + spin_unlock_irqrestore(&ha->hardware_lock, flags); } } return (status); -- cgit v1.2.3-70-g09d2 From c92715b3c22e94105a8fd9e4a23047d05c5077e7 Mon Sep 17 00:00:00 2001 From: Nathan Lynch Date: Thu, 2 Jun 2005 17:15:09 -0500 Subject: [SCSI] fix slab corruption during ipr probe With CONFIG_DEBUG_SLAB=y I see slab corruption messages during boot on pSeries machines with IPR adapters with any 2.6.12-rc kernel. The change which seems to have introduced the problem is "SCSI: revamp target scanning routines" and may be found at: http://marc.theaimsgroup.com/?l=bk-commits-head&m=111093946426333&w=2 In order to revert that in a 2.6.12-rc1 tree, I had to revert "target code updates to support scanned targets" first: http://marc.theaimsgroup.com/?l=bk-commits-head&m=111094132524649&w=2 With both patches reverted, the corruption messages go away. ipr: IBM Power RAID SCSI Device Driver version: 2.0.13 (February 21, 2005) ipr 0001:d0:01.0: Found IOA with IRQ: 167 ipr 0001:d0:01.0: Starting IOA initialization sequence. ipr 0001:d0:01.0: Adapter firmware version: 020A005C ipr 0001:d0:01.0: IOA initialized. scsi0 : IBM 570B Storage Adapter Vendor: IBM Model: VSBPD4E1 U4SCSI Rev: 4770 Type: Enclosure ANSI SCSI revision: 02 Vendor: IBM H0 Model: HUS103036FL3800 Rev: RPQF Type: Direct-Access ANSI SCSI revision: 04 Vendor: IBM H0 Model: HUS103036FL3800 Rev: RPQF Type: Direct-Access ANSI SCSI revision: 04 Vendor: IBM H0 Model: HUS103036FL3800 Rev: RPQF Type: Direct-Access ANSI SCSI revision: 04 Vendor: IBM H0 Model: HUS103036FL3800 Rev: RPQF Type: Direct-Access ANSI SCSI revision: 04 Vendor: IBM Model: VSBPD4E1 U4SCSI Rev: 4770 Type: Enclosure ANSI SCSI revision: 02 Slab corruption: start=c0000001e8de5268, len=512 Redzone: 0x5a2cf071/0x5a2cf071. Last user: [](.scsi_target_dev_release+0x28/0x50) 080: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6a Prev obj: start=c0000001e8de5050, len=512 Redzone: 0x5a2cf071/0x5a2cf071. Last user: [<0000000000000000>](0x0) 000: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 010: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b Next obj: start=c0000001e8de5480, len=512 Redzone: 0x170fc2a5/0x170fc2a5. Last user: [](.as_init_queue+0x5c/0x228) 000: c0 00 00 01 e8 83 26 08 00 00 00 00 00 00 00 00 010: 00 00 00 00 00 00 00 00 c0 00 00 01 e8 de 54 98 Slab corruption: start=c0000001e8de5268, len=512 Redzone: 0x5a2cf071/0x5a2cf071. Last user: [](.scsi_target_dev_release+0x28/0x50) 080: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6a Prev obj: start=c0000001e8de5050, len=512 Redzone: 0x5a2cf071/0x5a2cf071. Last user: [<0000000000000000>](0x0) 000: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 010: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b Next obj: start=c0000001e8de5480, len=512 Redzone: 0x170fc2a5/0x170fc2a5. Last user: [](.as_init_queue+0x5c/0x228) 000: c0 00 00 01 e8 83 26 08 00 00 00 00 00 00 00 00 010: 00 00 00 00 00 00 00 00 c0 00 00 01 e8 de 54 98 ... I did some digging and the problem seems to be a refcounting issue in __scsi_add_device. The target gets freed in scsi_target_reap, and then __scsi_add_device tries to do another device_put on it. Signed-off-by: Nathan Lynch Signed-off-by: James Bottomley --- drivers/scsi/scsi_scan.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index cca772624ae..8d0d302844a 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -1197,6 +1197,7 @@ struct scsi_device *__scsi_add_device(struct Scsi_Host *shost, uint channel, if (!starget) return ERR_PTR(-ENOMEM); + get_device(&starget->dev); down(&shost->scan_mutex); res = scsi_probe_and_add_lun(starget, lun, NULL, &sdev, 1, hostdata); if (res != SCSI_SCAN_LUN_PRESENT) -- cgit v1.2.3-70-g09d2 From f4d340cf869b2b63e1043eed72aa2eab6fa2cb2c Mon Sep 17 00:00:00 2001 From: David Brownell Date: Fri, 3 Jun 2005 08:01:35 -0700 Subject: [PATCH] USB: resolve Zaurus problem This "obvious" one-liner is needed to recognize Zaurus SL 6000; it just checks two GUIDs not just one. OSDL bugids #4512 and #4545 seem to be duplicates of this report. From: Gerald Skerbitz Signed-off-by: David Brownell Signed-off-by: Linus Torvalds --- drivers/usb/net/usbnet.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/net/usbnet.c b/drivers/usb/net/usbnet.c index 85476e76b24..4cbb408af72 100644 --- a/drivers/usb/net/usbnet.c +++ b/drivers/usb/net/usbnet.c @@ -2765,7 +2765,7 @@ static int blan_mdlm_bind (struct usbnet *dev, struct usb_interface *intf) } /* expect bcdVersion 1.0, ignore */ if (memcmp(&desc->bGUID, blan_guid, 16) - && memcmp(&desc->bGUID, blan_guid, 16) ) { + && memcmp(&desc->bGUID, safe_guid, 16) ) { /* hey, this one might _really_ be MDLM! */ dev_dbg (&intf->dev, "MDLM guid\n"); goto bad_desc; -- cgit v1.2.3-70-g09d2 From b05a720b374ac6af05b2fd4c70bb2c61a9f461ca Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Fri, 3 Jun 2005 11:35:20 +1000 Subject: [PATCH] m68knommu: fix scheduling and race problems in idle loop Re-work the m68knommu specific idle code according to suggestions from Nick Piggin . A couple of rules that we need to follow: 1. Preempt should now disabled over idle routines. Should only be enabled to call schedule() then disabled again. 3. When cpu_idle finds (need_resched() == 'true'), it should call schedule(). It should not call schedule() otherwise. Also fix interrupt locking around the need_resched() and cpu stop state so that there is no race condition. Signed-off-by: Greg Ungerer Signed-off-by: Linus Torvalds --- arch/m68knommu/kernel/process.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/arch/m68knommu/kernel/process.c b/arch/m68knommu/kernel/process.c index 2b6c9d32b7a..c4a33f265dc 100644 --- a/arch/m68knommu/kernel/process.c +++ b/arch/m68knommu/kernel/process.c @@ -45,11 +45,13 @@ asmlinkage void ret_from_fork(void); */ void default_idle(void) { - while(1) { - if (need_resched()) - __asm__("stop #0x2000" : : : "cc"); - schedule(); + local_irq_disable(); + while (!need_resched()) { + /* This stop will re-enable interrupts */ + __asm__("stop #0x2000" : : : "cc"); + local_irq_disable(); } + local_irq_enable(); } void (*idle)(void) = default_idle; @@ -63,7 +65,12 @@ void (*idle)(void) = default_idle; void cpu_idle(void) { /* endless idle loop with no priority at all */ - idle(); + while (1) { + idle(); + preempt_enable_no_resched(); + schedule(); + preempt_disable(); + } } void machine_restart(char * __unused) -- cgit v1.2.3-70-g09d2 From ff89bf3bc0534aa03b5375aa906544d96911bad4 Mon Sep 17 00:00:00 2001 From: Dean Nelson Date: Fri, 3 Jun 2005 05:25:00 -0700 Subject: [IA64] fix setting of sn_hub_info->shub_1_1_found Fix a bug in which shub_1_1_found is not being properly initialized or set, resulting in the improper setting of sn_hub_info->shub_1_1_found. Signed-off-by: Dean Nelson Signed-off-by: Tony Luck --- arch/ia64/sn/kernel/setup.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c index e64cb8175f7..44bfc7f318c 100644 --- a/arch/ia64/sn/kernel/setup.c +++ b/arch/ia64/sn/kernel/setup.c @@ -222,7 +222,7 @@ void __init early_sn_setup(void) extern int platform_intr_list[]; extern nasid_t master_nasid; -static int shub_1_1_found __initdata; +static int __initdata shub_1_1_found = 0; /* * sn_check_for_wars @@ -251,7 +251,7 @@ static void __init sn_check_for_wars(void) } else { for_each_online_node(cnode) { if (is_shub_1_1(cnodeid_to_nasid(cnode))) - sn_hub_info->shub_1_1_found = 1; + shub_1_1_found = 1; } } } -- cgit v1.2.3-70-g09d2 From 4ab5c01c7cc28f29d5cf5f2a591cb6f7bbece48e Mon Sep 17 00:00:00 2001 From: Deepak Saxena Date: Fri, 3 Jun 2005 20:52:25 +0100 Subject: [PATCH] ARM: 2692/1: Fix compile warnings in include/asm-arm/arch-ixp2000/io.h Patch from Deepak Saxena This patch fixes the following warnings: include/asm/arch/io.h: In function `insw': include/asm/arch/io.h:78: warning: comparison of distinct pointer types lacks acast include/asm/arch/io.h:79: warning: comparison of distinct pointer types lacks acast include/asm/arch/io.h: In function `outsw': include/asm/arch/io.h:103: warning: comparison of distinct pointer types lacks a cast include/asm/arch/io.h:104: warning: comparison of distinct pointer types lacks a cast include/asm/arch/io.h: In function `inw': include/asm/arch/io.h:127: warning: comparison of distinct pointer types lacks a cast Signed-off-by: Deepak Saxena Signed-off-by: Russell King --- include/asm-arm/arch-ixp2000/io.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/include/asm-arm/arch-ixp2000/io.h b/include/asm-arm/arch-ixp2000/io.h index a8e3c2daefd..083462668e1 100644 --- a/include/asm-arm/arch-ixp2000/io.h +++ b/include/asm-arm/arch-ixp2000/io.h @@ -75,8 +75,8 @@ static inline void insw(u32 ptr, void *buf, int length) * Is this cycle meant for the CS8900? */ if ((machine_is_ixdp2401() || machine_is_ixdp2801()) && - ((port >= IXDP2X01_CS8900_VIRT_BASE) && - (port <= IXDP2X01_CS8900_VIRT_END))) { + (((u32)port >= (u32)IXDP2X01_CS8900_VIRT_BASE) && + ((u32)port <= (u32)IXDP2X01_CS8900_VIRT_END))) { u8 *buf8 = (u8*)buf; register u32 tmp32; @@ -100,8 +100,8 @@ static inline void outsw(u32 ptr, void *buf, int length) * Is this cycle meant for the CS8900? */ if ((machine_is_ixdp2401() || machine_is_ixdp2801()) && - ((port >= IXDP2X01_CS8900_VIRT_BASE) && - (port <= IXDP2X01_CS8900_VIRT_END))) { + (((u32)port >= (u32)IXDP2X01_CS8900_VIRT_BASE) && + ((u32)port <= (u32)IXDP2X01_CS8900_VIRT_END))) { register u32 tmp32; u8 *buf8 = (u8*)buf; do { @@ -124,8 +124,8 @@ static inline u16 inw(u32 ptr) * Is this cycle meant for the CS8900? */ if ((machine_is_ixdp2401() || machine_is_ixdp2801()) && - ((port >= IXDP2X01_CS8900_VIRT_BASE) && - (port <= IXDP2X01_CS8900_VIRT_END))) { + (((u32)port >= (u32)IXDP2X01_CS8900_VIRT_BASE) && + ((u32)port <= (u32)IXDP2X01_CS8900_VIRT_END))) { return (u16)(*port); } @@ -137,8 +137,8 @@ static inline void outw(u16 value, u32 ptr) register volatile u32 *port = (volatile u32 *)ptr; if ((machine_is_ixdp2401() || machine_is_ixdp2801()) && - ((port >= IXDP2X01_CS8900_VIRT_BASE) && - (port <= IXDP2X01_CS8900_VIRT_END))) { + (((u32)port >= (u32)IXDP2X01_CS8900_VIRT_BASE) && + ((u32)port <= (u32)IXDP2X01_CS8900_VIRT_END))) { *port = value; return; } -- cgit v1.2.3-70-g09d2 From 105bb2698b54a838165947199f1c8be5c2e7d9bb Mon Sep 17 00:00:00 2001 From: Albrecht Dreß Date: Fri, 3 Jun 2005 20:52:26 +0100 Subject: [PATCH] ARM: 2694/1: [s3c2410/dma] release irq properly to fix kernel oops MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Patch from Albrecht Dreß Problem: When a module requests a DMA channel via the function s3c2410_dma_request(), this function requests the appropriate irq under the name of the client module. When the client module is unloaded, it calls s3c2410_dma_free() which does not free the irq. Consequently, when e.g. running "cat /proc/interrupts", the irq owner points to freed memory, leading to a kernel oops. File: linux/arch/arm/mach-s3c2410/dma.c Fix: trivial, below Signed-off-by: Albrecht Dreß Signed-off-by: Russell King --- arch/arm/mach-s3c2410/dma.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm/mach-s3c2410/dma.c b/arch/arm/mach-s3c2410/dma.c index bc229fab86d..c7c28890d40 100644 --- a/arch/arm/mach-s3c2410/dma.c +++ b/arch/arm/mach-s3c2410/dma.c @@ -785,6 +785,10 @@ int s3c2410_dma_free(dmach_t channel, s3c2410_dma_client_t *client) chan->client = NULL; chan->in_use = 0; + if (chan->irq_claimed) + free_irq(chan->irq, (void *)chan); + chan->irq_claimed = 0; + local_irq_restore(flags); return 0; -- cgit v1.2.3-70-g09d2 From 718a30a5cf0a9142f716a49853bd4b4a25a8da1b Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Fri, 3 Jun 2005 20:52:26 +0100 Subject: [PATCH] ARM: 2696/1: remove ';' in ELF_DATA define in asm-arm{,26}/elf.h Patch from Mike Frysinger the ELF_DATA define in both arm asm subdirs of linux/include/ contain a semicolon at the end. this of course will cause any code that tries to use ELF_DATA in assignment or comparison to fail. no other arch has a semicolon in their ELF_DATA defines. Signed-off-by: Mike Frysinger Signed-off-by: Russell King --- include/asm-arm/elf.h | 4 ++-- include/asm-arm26/elf.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/asm-arm/elf.h b/include/asm-arm/elf.h index cbceacbe5af..a1696ba238d 100644 --- a/include/asm-arm/elf.h +++ b/include/asm-arm/elf.h @@ -38,9 +38,9 @@ typedef struct user_fp elf_fpregset_t; */ #define ELF_CLASS ELFCLASS32 #ifdef __ARMEB__ -#define ELF_DATA ELFDATA2MSB; +#define ELF_DATA ELFDATA2MSB #else -#define ELF_DATA ELFDATA2LSB; +#define ELF_DATA ELFDATA2LSB #endif #define ELF_ARCH EM_ARM diff --git a/include/asm-arm26/elf.h b/include/asm-arm26/elf.h index 8b149474db2..5a47fdb3015 100644 --- a/include/asm-arm26/elf.h +++ b/include/asm-arm26/elf.h @@ -36,7 +36,7 @@ typedef struct { void *null; } elf_fpregset_t; * These are used to set parameters in the core dumps. */ #define ELF_CLASS ELFCLASS32 -#define ELF_DATA ELFDATA2LSB; +#define ELF_DATA ELFDATA2LSB #define ELF_ARCH EM_ARM #define USE_ELF_CORE_DUMP -- cgit v1.2.3-70-g09d2 From 8775420d2fbcfff866995471ea5f6130d14d121c Mon Sep 17 00:00:00 2001 From: Todd Poynor Date: Fri, 3 Jun 2005 20:52:27 +0100 Subject: [PATCH] ARM: 2691/1: PXA27x sleep fixes take 2 Patch from Todd Poynor PXA27x sleep fixes: * set additional sleep/wakeup registers for Mainstone boards. * move CKEN=0 to pxa25x-specific code; that value is harmful on pxa27x. * save/restore additional registers, including some found necessary for C5 processors and/or newer blob versions. * enable future support of additional sleep modes for PXA27x (eg, standby, deep sleep). * split off cpu-specific sleep processing between pxa27x and pxa25x into separate files (partly in preparation for additional sleep modes). Includes fixes from David Burrage. Signed-off-by: Todd Poynor Signed-off-by: Nicolas Pitre Signed-off-by: Russell King --- arch/arm/mach-pxa/mainstone.c | 9 +++++++++ arch/arm/mach-pxa/pm.c | 32 ++++++++++++++++++-------------- arch/arm/mach-pxa/pxa25x.c | 29 +++++++++++++++++++++++++++++ arch/arm/mach-pxa/pxa27x.c | 32 ++++++++++++++++++++++++++++++++ 4 files changed, 88 insertions(+), 14 deletions(-) diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c index 3f952237ae3..6823ae28ae6 100644 --- a/arch/arm/mach-pxa/mainstone.c +++ b/arch/arm/mach-pxa/mainstone.c @@ -304,6 +304,15 @@ static void __init mainstone_map_io(void) PWER = 0xC0000002; PRER = 0x00000002; PFER = 0x00000002; + /* for use I SRAM as framebuffer. */ + PSLR |= 0xF04; + PCFR = 0x66; + /* For Keypad wakeup. */ + KPC &=~KPC_ASACT; + KPC |=KPC_AS; + PKWR = 0x000FD000; + /* Need read PKWR back after set it. */ + PKWR; } MACHINE_START(MAINSTONE, "Intel HCDDBBVA0 Development Platform (aka Mainstone)") diff --git a/arch/arm/mach-pxa/pm.c b/arch/arm/mach-pxa/pm.c index 82a4bf34c25..9799fe80df2 100644 --- a/arch/arm/mach-pxa/pm.c +++ b/arch/arm/mach-pxa/pm.c @@ -29,9 +29,6 @@ */ #undef DEBUG -extern void pxa_cpu_suspend(void); -extern void pxa_cpu_resume(void); - #define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x #define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x] @@ -63,6 +60,12 @@ enum { SLEEP_SAVE_START = 0, SLEEP_SAVE_ICMR, SLEEP_SAVE_CKEN, +#ifdef CONFIG_PXA27x + SLEEP_SAVE_MDREFR, + SLEEP_SAVE_PWER, SLEEP_SAVE_PCFR, SLEEP_SAVE_PRER, + SLEEP_SAVE_PFER, SLEEP_SAVE_PKWR, +#endif + SLEEP_SAVE_CKSUM, SLEEP_SAVE_SIZE @@ -75,9 +78,7 @@ static int pxa_pm_enter(suspend_state_t state) unsigned long checksum = 0; struct timespec delta, rtc; int i; - - if (state != PM_SUSPEND_MEM) - return -EINVAL; + extern void pxa_cpu_pm_enter(suspend_state_t state); #ifdef CONFIG_IWMMXT /* force any iWMMXt context to ram **/ @@ -100,16 +101,17 @@ static int pxa_pm_enter(suspend_state_t state) SAVE(GAFR2_L); SAVE(GAFR2_U); #ifdef CONFIG_PXA27x + SAVE(MDREFR); SAVE(GPLR3); SAVE(GPDR3); SAVE(GRER3); SAVE(GFER3); SAVE(PGSR3); SAVE(GAFR3_L); SAVE(GAFR3_U); + SAVE(PWER); SAVE(PCFR); SAVE(PRER); + SAVE(PFER); SAVE(PKWR); #endif SAVE(ICMR); ICMR = 0; SAVE(CKEN); - CKEN = 0; - SAVE(PSTR); /* Note: wake up source are set up in each machine specific files */ @@ -123,16 +125,13 @@ static int pxa_pm_enter(suspend_state_t state) /* Clear sleep reset status */ RCSR = RCSR_SMR; - /* set resume return address */ - PSPR = virt_to_phys(pxa_cpu_resume); - /* before sleeping, calculate and save a checksum */ for (i = 0; i < SLEEP_SAVE_SIZE - 1; i++) checksum += sleep_save[i]; sleep_save[SLEEP_SAVE_CKSUM] = checksum; /* *** go zzz *** */ - pxa_cpu_suspend(); + pxa_cpu_pm_enter(state); /* after sleeping, validate the checksum */ checksum = 0; @@ -145,7 +144,7 @@ static int pxa_pm_enter(suspend_state_t state) LUB_HEXLED = 0xbadbadc5; #endif while (1) - pxa_cpu_suspend(); + pxa_cpu_pm_enter(state); } /* ensure not to come back here if it wasn't intended */ @@ -162,8 +161,11 @@ static int pxa_pm_enter(suspend_state_t state) RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2); #ifdef CONFIG_PXA27x + RESTORE(MDREFR); RESTORE(GAFR3_L); RESTORE(GAFR3_U); RESTORE_GPLEVEL(3); RESTORE(GPDR3); RESTORE(GRER3); RESTORE(GFER3); RESTORE(PGSR3); + RESTORE(PWER); RESTORE(PCFR); RESTORE(PRER); + RESTORE(PFER); RESTORE(PKWR); #endif PSSR = PSSR_RDH | PSSR_PH; @@ -197,7 +199,9 @@ unsigned long sleep_phys_sp(void *sp) */ static int pxa_pm_prepare(suspend_state_t state) { - return 0; + extern int pxa_cpu_pm_prepare(suspend_state_t state); + + return pxa_cpu_pm_prepare(state); } /* diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c index e887b7175ef..b6d945a6e77 100644 --- a/arch/arm/mach-pxa/pxa25x.c +++ b/arch/arm/mach-pxa/pxa25x.c @@ -102,3 +102,32 @@ unsigned int get_lcdclk_frequency_10khz(void) } EXPORT_SYMBOL(get_lcdclk_frequency_10khz); + + +int pxa_cpu_pm_prepare(suspend_state_t state) +{ + switch (state) { + case PM_SUSPEND_MEM: + break; + default: + return -EINVAL; + } + + return 0; +} + +void pxa_cpu_pm_enter(suspend_state_t state) +{ + extern void pxa_cpu_suspend(unsigned int); + extern void pxa_cpu_resume(void); + + CKEN = 0; + + switch (state) { + case PM_SUSPEND_MEM: + /* set resume return address */ + PSPR = virt_to_phys(pxa_cpu_resume); + pxa_cpu_suspend(3); + break; + } +} diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c index 7e863afefb5..aa3c3b2ab75 100644 --- a/arch/arm/mach-pxa/pxa27x.c +++ b/arch/arm/mach-pxa/pxa27x.c @@ -120,6 +120,38 @@ EXPORT_SYMBOL(get_clk_frequency_khz); EXPORT_SYMBOL(get_memclk_frequency_10khz); EXPORT_SYMBOL(get_lcdclk_frequency_10khz); +int pxa_cpu_pm_prepare(suspend_state_t state) +{ + switch (state) { + case PM_SUSPEND_MEM: + return 0; + default: + return -EINVAL; + } +} + +void pxa_cpu_pm_enter(suspend_state_t state) +{ + extern void pxa_cpu_standby(void); + extern void pxa_cpu_suspend(unsigned int); + extern void pxa_cpu_resume(void); + + CKEN = CKEN22_MEMC | CKEN9_OSTIMER; + + /* ensure voltage-change sequencer not initiated, which hangs */ + PCFR &= ~PCFR_FVC; + + /* Clear edge-detect status register. */ + PEDR = 0xDF12FE1B; + + switch (state) { + case PM_SUSPEND_MEM: + /* set resume return address */ + PSPR = virt_to_phys(pxa_cpu_resume); + pxa_cpu_suspend(3); + break; + } +} /* * device registration specific to PXA27x. -- cgit v1.2.3-70-g09d2 From 8be3de3fd8469154a2b3e18a4712032dac5b4a53 Mon Sep 17 00:00:00 2001 From: Nathan Lynch Date: Fri, 3 Jun 2005 14:25:25 -0500 Subject: [PATCH] prom_find_machine_type typo breaks pSeries lpar boot A typo in prom_find_machine_type from Ben's recent patch "ppc64: Fix result code handling in prom_init" prevents pSeries LPAR systems from booting. Tested on a pSeries 570 and OpenPower 720 (both Power5 LPAR). Signed-off-by: Nathan Lynch Signed-off-by: Linus Torvalds --- arch/ppc64/kernel/prom_init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/ppc64/kernel/prom_init.c b/arch/ppc64/kernel/prom_init.c index 1ac531ba705..b7683abfbe6 100644 --- a/arch/ppc64/kernel/prom_init.c +++ b/arch/ppc64/kernel/prom_init.c @@ -1370,7 +1370,7 @@ static int __init prom_find_machine_type(void) } /* Default to pSeries. We need to know if we are running LPAR */ rtas = call_prom("finddevice", 1, 1, ADDR("/rtas")); - if (!PHANDLE_VALID(rtas)) { + if (PHANDLE_VALID(rtas)) { int x = prom_getproplen(rtas, "ibm,hypertas-functions"); if (x != PROM_ERROR) { prom_printf("Hypertas detected, assuming LPAR !\n"); -- cgit v1.2.3-70-g09d2 From 17d82fcc6a15887b7138d35802ab8fc5f249794f Mon Sep 17 00:00:00 2001 From: Deepak Saxena Date: Fri, 3 Jun 2005 22:18:52 +0100 Subject: [PATCH] ARM: 2700/1: Disable IXP2000 IRQs at bootup Patch from Deepak Saxena The IXDP2800 bootloader does not disable IRQs before jumping into the kernel and this is causing the Grand Unified KGDB to crash the system when we do an early call to trap_init() and irq handlers have not yet been registered. This patch disables IRQs before we jump into the kernel. Signed-off-by: Deepak Saxena Signed-off-by: Russell King --- arch/arm/boot/compressed/head-xscale.S | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/arm/boot/compressed/head-xscale.S b/arch/arm/boot/compressed/head-xscale.S index 665bd2c2074..d3fe2533907 100644 --- a/arch/arm/boot/compressed/head-xscale.S +++ b/arch/arm/boot/compressed/head-xscale.S @@ -47,3 +47,10 @@ __XScale_start: orr r7, r7, #(MACH_TYPE_GTWX5715 & 0xff00) #endif +#ifdef CONFIG_ARCH_IXP2000 + mov r1, #-1 + mov r0, #0xd6000000 + str r1, [r0, #0x14] + str r1, [r0, #0x18] +#endif + -- cgit v1.2.3-70-g09d2 From 854715be73b221596c7127d4042e1120d4539e19 Mon Sep 17 00:00:00 2001 From: Qu Fuping Date: Sat, 4 Jun 2005 15:43:29 -0700 Subject: [PATCH] mpage_end_io_write() I/O error handling fix When fsync() runs wait_on_page_writeback_range() it only inspects pages which are actually under I/O (PAGECACHE_TAG_WRITEBACK). If a page completed I/O prior to wait_on_page_writeback_range() looking at it, it is supposed to have recorded its I/O error state in the address_space. But mpage_mpage_end_io_write() forgot to set the address_space error flag in this case. Signed-off-by: Qu Fuping Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/mpage.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/fs/mpage.c b/fs/mpage.c index b92c0e64aef..bb9aebe9386 100644 --- a/fs/mpage.c +++ b/fs/mpage.c @@ -79,8 +79,11 @@ static int mpage_end_io_write(struct bio *bio, unsigned int bytes_done, int err) if (--bvec >= bio->bi_io_vec) prefetchw(&bvec->bv_page->flags); - if (!uptodate) + if (!uptodate){ SetPageError(page); + if (page->mapping) + set_bit(AS_EIO, &page->mapping->flags); + } end_page_writeback(page); } while (bvec >= bio->bi_io_vec); bio_put(bio); -- cgit v1.2.3-70-g09d2 From 778959db97c7ed8eed4025916916b17a4629ce3d Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Sat, 4 Jun 2005 15:43:30 -0700 Subject: [PATCH] s390: ptrace peek and poke The special cases of peek and poke on acrs[15] and the fpc register are not handled correctly. A poke on acrs[15] will clobber the 4 bytes after the access registers in the thread_info structure. That happens to be the kernel stack pointer. A poke on the fpc with an invalid value is not caught by the validity check. On the next context switch the broken fpc value will cause a program check in the kernel. Improving the checks in peek and poke fixes this. Signed-off-by: Martin Schwidefsky Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/s390/kernel/ptrace.c | 48 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 5 deletions(-) diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c index 26889366929..329d9391c83 100644 --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c @@ -40,6 +40,7 @@ #include #include #include +#include #ifdef CONFIG_S390_SUPPORT #include "compat_ptrace.h" @@ -130,13 +131,19 @@ static int peek_user(struct task_struct *child, addr_t addr, addr_t data) { struct user *dummy = NULL; - addr_t offset, tmp; + addr_t offset, tmp, mask; /* * Stupid gdb peeks/pokes the access registers in 64 bit with * an alignment of 4. Programmers from hell... */ - if ((addr & 3) || addr > sizeof(struct user) - __ADDR_MASK) + mask = __ADDR_MASK; +#ifdef CONFIG_ARCH_S390X + if (addr >= (addr_t) &dummy->regs.acrs && + addr < (addr_t) &dummy->regs.orig_gpr2) + mask = 3; +#endif + if ((addr & mask) || addr > sizeof(struct user) - __ADDR_MASK) return -EIO; if (addr < (addr_t) &dummy->regs.acrs) { @@ -153,6 +160,16 @@ peek_user(struct task_struct *child, addr_t addr, addr_t data) * access registers are stored in the thread structure */ offset = addr - (addr_t) &dummy->regs.acrs; +#ifdef CONFIG_ARCH_S390X + /* + * Very special case: old & broken 64 bit gdb reading + * from acrs[15]. Result is a 64 bit value. Read the + * 32 bit acrs[15] value and shift it by 32. Sick... + */ + if (addr == (addr_t) &dummy->regs.acrs[15]) + tmp = ((unsigned long) child->thread.acrs[15]) << 32; + else +#endif tmp = *(addr_t *)((addr_t) &child->thread.acrs + offset); } else if (addr == (addr_t) &dummy->regs.orig_gpr2) { @@ -167,6 +184,9 @@ peek_user(struct task_struct *child, addr_t addr, addr_t data) */ offset = addr - (addr_t) &dummy->regs.fp_regs; tmp = *(addr_t *)((addr_t) &child->thread.fp_regs + offset); + if (addr == (addr_t) &dummy->regs.fp_regs.fpc) + tmp &= (unsigned long) FPC_VALID_MASK + << (BITS_PER_LONG - 32); } else if (addr < (addr_t) (&dummy->regs.per_info + 1)) { /* @@ -191,13 +211,19 @@ static int poke_user(struct task_struct *child, addr_t addr, addr_t data) { struct user *dummy = NULL; - addr_t offset; + addr_t offset, mask; /* * Stupid gdb peeks/pokes the access registers in 64 bit with * an alignment of 4. Programmers from hell indeed... */ - if ((addr & 3) || addr > sizeof(struct user) - __ADDR_MASK) + mask = __ADDR_MASK; +#ifdef CONFIG_ARCH_S390X + if (addr >= (addr_t) &dummy->regs.acrs && + addr < (addr_t) &dummy->regs.orig_gpr2) + mask = 3; +#endif + if ((addr & mask) || addr > sizeof(struct user) - __ADDR_MASK) return -EIO; if (addr < (addr_t) &dummy->regs.acrs) { @@ -224,6 +250,17 @@ poke_user(struct task_struct *child, addr_t addr, addr_t data) * access registers are stored in the thread structure */ offset = addr - (addr_t) &dummy->regs.acrs; +#ifdef CONFIG_ARCH_S390X + /* + * Very special case: old & broken 64 bit gdb writing + * to acrs[15] with a 64 bit value. Ignore the lower + * half of the value and write the upper 32 bit to + * acrs[15]. Sick... + */ + if (addr == (addr_t) &dummy->regs.acrs[15]) + child->thread.acrs[15] = (unsigned int) (data >> 32); + else +#endif *(addr_t *)((addr_t) &child->thread.acrs + offset) = data; } else if (addr == (addr_t) &dummy->regs.orig_gpr2) { @@ -237,7 +274,8 @@ poke_user(struct task_struct *child, addr_t addr, addr_t data) * floating point regs. are stored in the thread structure */ if (addr == (addr_t) &dummy->regs.fp_regs.fpc && - (data & ~FPC_VALID_MASK) != 0) + (data & ~((unsigned long) FPC_VALID_MASK + << (BITS_PER_LONG - 32))) != 0) return -EINVAL; offset = addr - (addr_t) &dummy->regs.fp_regs; *(addr_t *)((addr_t) &child->thread.fp_regs + offset) = data; -- cgit v1.2.3-70-g09d2 From c5c3a6d8fe923b8780b9cd10e72344b8cf8518b5 Mon Sep 17 00:00:00 2001 From: Bodo Stroesser Date: Sat, 4 Jun 2005 15:43:32 -0700 Subject: [PATCH] s390: uml ptrace fixes To make UML build and run on s390, I needed to do these two little changes: 1) UML includes some of the subarch's (s390) headers. I had to change one of them with the following one-liner, to make this compile. AFAICS, this change doesn't break compilation of s390 itself. 2) UML needs to intercept syscalls via ptrace to invalidate the syscall, read syscall's parameters and write the result with the result of UML's syscall processing. Also, UML needs to make sure, that the host does no syscall restart processing. On i386 for example, this can be done by writing -1 to orig_eax on the 2nd syscall interception (orig_eax is the syscall number, which after the interception is used as a "interrupt was a syscall" flag only. Unfortunately, s390 holds syscall number and syscall result in gpr2 and its "interrupt was a syscall" flag (trap) is unreachable via ptrace. So I changed the host to set trap to -1, if the syscall number is changed to an invalid value on the first syscall interception. Signed-off-by: Martin Schwidefsky Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/s390/kernel/ptrace.c | 7 +++++++ include/asm-s390/user.h | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c index 329d9391c83..06afa3103ac 100644 --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c @@ -760,6 +760,13 @@ syscall_trace(struct pt_regs *regs, int entryexit) ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) ? 0x80 : 0)); + /* + * If the debuffer has set an invalid system call number, + * we prepare to skip the system call restart handling. + */ + if (!entryexit && regs->gprs[2] >= NR_syscalls) + regs->trap = -1; + /* * this isn't the same as continuing with a signal, but it will do * for normal use. strace only continues with a signal if the diff --git a/include/asm-s390/user.h b/include/asm-s390/user.h index c64f8c181df..1dc74baf03c 100644 --- a/include/asm-s390/user.h +++ b/include/asm-s390/user.h @@ -10,7 +10,7 @@ #define _S390_USER_H #include -#include +#include /* Core file format: The core file is written in such a way that gdb can understand it and provide useful information to the user (under linux we use the 'trad-core' bfd). There are quite a number of -- cgit v1.2.3-70-g09d2 From 595bf2aacae96d0f87352a1ff5476b79e52e212f Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Sat, 4 Jun 2005 15:43:32 -0700 Subject: [PATCH] s390: in_interrupt vs. in_atomic The condition for no context in do_exception checks for hard and soft interrupts by using in_interrupt() but not for preemption. This is bad for the users of __copy_from/to_user_inatomic because the fault handler might call schedule although the preemption count is != 0. Use in_atomic() instead in_interrupt(). Signed-off-by: Martin Schwidefsky Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/s390/mm/fault.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index 80306bc8c79..75fde949d12 100644 --- a/arch/s390/mm/fault.c +++ b/arch/s390/mm/fault.c @@ -207,7 +207,7 @@ do_exception(struct pt_regs *regs, unsigned long error_code, int is_protection) * we are not in an interrupt and that there is a * user context. */ - if (user_address == 0 || in_interrupt() || !mm) + if (user_address == 0 || in_atomic() || !mm) goto no_context; /* -- cgit v1.2.3-70-g09d2 From f26d583e41aedad8159acf9533fa287d7209dfbf Mon Sep 17 00:00:00 2001 From: Gerald Schaefer Date: Sat, 4 Jun 2005 15:43:33 -0700 Subject: [PATCH] s390: deadlock in appldata The system might hang when using appldata_mem with high I/O traffic and a large number of devices. The spinlocks bdev_lock and swaplock are acquired via calls to si_meminfo() and si_swapinfo() from a tasklet, i.e. interrupt context, which can lead to a deadlock. Replace tasklet with work queue. Signed-off-by: Martin Schwidefsky Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/s390/appldata/appldata_base.c | 72 ++++++++++++++++++++--------------- arch/s390/appldata/appldata_mem.c | 2 +- arch/s390/appldata/appldata_net_sum.c | 2 +- arch/s390/appldata/appldata_os.c | 4 +- 4 files changed, 45 insertions(+), 35 deletions(-) diff --git a/arch/s390/appldata/appldata_base.c b/arch/s390/appldata/appldata_base.c index 01ae1964c93..c067435bae4 100644 --- a/arch/s390/appldata/appldata_base.c +++ b/arch/s390/appldata/appldata_base.c @@ -28,6 +28,7 @@ //#include #include #include +#include #include "appldata.h" @@ -133,9 +134,12 @@ static int appldata_interval = APPLDATA_CPU_INTERVAL; static int appldata_timer_active; /* - * Tasklet + * Work queue */ -static struct tasklet_struct appldata_tasklet_struct; +static struct workqueue_struct *appldata_wq; +static void appldata_work_fn(void *data); +static DECLARE_WORK(appldata_work, appldata_work_fn, NULL); + /* * Ops list @@ -144,11 +148,11 @@ static DEFINE_SPINLOCK(appldata_ops_lock); static LIST_HEAD(appldata_ops_list); -/************************* timer, tasklet, DIAG ******************************/ +/*************************** timer, work, DIAG *******************************/ /* * appldata_timer_function() * - * schedule tasklet and reschedule timer + * schedule work and reschedule timer */ static void appldata_timer_function(unsigned long data, struct pt_regs *regs) { @@ -157,22 +161,22 @@ static void appldata_timer_function(unsigned long data, struct pt_regs *regs) atomic_read(&appldata_expire_count)); if (atomic_dec_and_test(&appldata_expire_count)) { atomic_set(&appldata_expire_count, num_online_cpus()); - tasklet_schedule((struct tasklet_struct *) data); + queue_work(appldata_wq, (struct work_struct *) data); } } /* - * appldata_tasklet_function() + * appldata_work_fn() * * call data gathering function for each (active) module */ -static void appldata_tasklet_function(unsigned long data) +static void appldata_work_fn(void *data) { struct list_head *lh; struct appldata_ops *ops; int i; - P_DEBUG(" -= Tasklet =-\n"); + P_DEBUG(" -= Work Queue =-\n"); i = 0; spin_lock(&appldata_ops_lock); list_for_each(lh, &appldata_ops_list) { @@ -231,7 +235,7 @@ static int appldata_diag(char record_nr, u16 function, unsigned long buffer, : "=d" (ry) : "d" (&(appldata_parameter_list)) : "cc"); return (int) ry; } -/********************** timer, tasklet, DIAG ***************************/ +/************************ timer, work, DIAG ****************************/ /****************************** /proc stuff **********************************/ @@ -411,7 +415,7 @@ appldata_generic_handler(ctl_table *ctl, int write, struct file *filp, struct list_head *lh; found = 0; - spin_lock_bh(&appldata_ops_lock); + spin_lock(&appldata_ops_lock); list_for_each(lh, &appldata_ops_list) { tmp_ops = list_entry(lh, struct appldata_ops, list); if (&tmp_ops->ctl_table[2] == ctl) { @@ -419,15 +423,15 @@ appldata_generic_handler(ctl_table *ctl, int write, struct file *filp, } } if (!found) { - spin_unlock_bh(&appldata_ops_lock); + spin_unlock(&appldata_ops_lock); return -ENODEV; } ops = ctl->data; if (!try_module_get(ops->owner)) { // protect this function - spin_unlock_bh(&appldata_ops_lock); + spin_unlock(&appldata_ops_lock); return -ENODEV; } - spin_unlock_bh(&appldata_ops_lock); + spin_unlock(&appldata_ops_lock); if (!*lenp || *ppos) { *lenp = 0; @@ -451,10 +455,11 @@ appldata_generic_handler(ctl_table *ctl, int write, struct file *filp, return -EFAULT; } - spin_lock_bh(&appldata_ops_lock); + spin_lock(&appldata_ops_lock); if ((buf[0] == '1') && (ops->active == 0)) { - if (!try_module_get(ops->owner)) { // protect tasklet - spin_unlock_bh(&appldata_ops_lock); + // protect work queue callback + if (!try_module_get(ops->owner)) { + spin_unlock(&appldata_ops_lock); module_put(ops->owner); return -ENODEV; } @@ -485,7 +490,7 @@ appldata_generic_handler(ctl_table *ctl, int write, struct file *filp, } module_put(ops->owner); } - spin_unlock_bh(&appldata_ops_lock); + spin_unlock(&appldata_ops_lock); out: *lenp = len; *ppos += len; @@ -529,7 +534,7 @@ int appldata_register_ops(struct appldata_ops *ops) } memset(ops->ctl_table, 0, 4*sizeof(struct ctl_table)); - spin_lock_bh(&appldata_ops_lock); + spin_lock(&appldata_ops_lock); list_for_each(lh, &appldata_ops_list) { tmp_ops = list_entry(lh, struct appldata_ops, list); P_DEBUG("register_ops loop: %i) name = %s, ctl = %i\n", @@ -541,18 +546,18 @@ int appldata_register_ops(struct appldata_ops *ops) APPLDATA_PROC_NAME_LENGTH) == 0) { P_ERROR("Name \"%s\" already registered!\n", ops->name); kfree(ops->ctl_table); - spin_unlock_bh(&appldata_ops_lock); + spin_unlock(&appldata_ops_lock); return -EBUSY; } if (tmp_ops->ctl_nr == ops->ctl_nr) { P_ERROR("ctl_nr %i already registered!\n", ops->ctl_nr); kfree(ops->ctl_table); - spin_unlock_bh(&appldata_ops_lock); + spin_unlock(&appldata_ops_lock); return -EBUSY; } } list_add(&ops->list, &appldata_ops_list); - spin_unlock_bh(&appldata_ops_lock); + spin_unlock(&appldata_ops_lock); ops->ctl_table[0].ctl_name = CTL_APPLDATA; ops->ctl_table[0].procname = appldata_proc_name; @@ -583,12 +588,12 @@ int appldata_register_ops(struct appldata_ops *ops) */ void appldata_unregister_ops(struct appldata_ops *ops) { - spin_lock_bh(&appldata_ops_lock); + spin_lock(&appldata_ops_lock); unregister_sysctl_table(ops->sysctl_header); list_del(&ops->list); kfree(ops->ctl_table); ops->ctl_table = NULL; - spin_unlock_bh(&appldata_ops_lock); + spin_unlock(&appldata_ops_lock); P_INFO("%s-ops unregistered!\n", ops->name); } /********************** module-ops management **************************/ @@ -602,7 +607,7 @@ appldata_online_cpu(int cpu) init_virt_timer(&per_cpu(appldata_timer, cpu)); per_cpu(appldata_timer, cpu).function = appldata_timer_function; per_cpu(appldata_timer, cpu).data = (unsigned long) - &appldata_tasklet_struct; + &appldata_work; atomic_inc(&appldata_expire_count); spin_lock(&appldata_timer_lock); __appldata_vtimer_setup(APPLDATA_MOD_TIMER); @@ -615,7 +620,7 @@ appldata_offline_cpu(int cpu) del_virt_timer(&per_cpu(appldata_timer, cpu)); if (atomic_dec_and_test(&appldata_expire_count)) { atomic_set(&appldata_expire_count, num_online_cpus()); - tasklet_schedule(&appldata_tasklet_struct); + queue_work(appldata_wq, &appldata_work); } spin_lock(&appldata_timer_lock); __appldata_vtimer_setup(APPLDATA_MOD_TIMER); @@ -648,7 +653,7 @@ static struct notifier_block __devinitdata appldata_nb = { /* * appldata_init() * - * init timer and tasklet, register /proc entries + * init timer, register /proc entries */ static int __init appldata_init(void) { @@ -657,6 +662,12 @@ static int __init appldata_init(void) P_DEBUG("sizeof(parameter_list) = %lu\n", sizeof(struct appldata_parameter_list)); + appldata_wq = create_singlethread_workqueue("appldata"); + if (!appldata_wq) { + P_ERROR("Could not create work queue\n"); + return -ENOMEM; + } + for_each_online_cpu(i) appldata_online_cpu(i); @@ -670,7 +681,6 @@ static int __init appldata_init(void) appldata_table[1].de->owner = THIS_MODULE; #endif - tasklet_init(&appldata_tasklet_struct, appldata_tasklet_function, 0); P_DEBUG("Base interface initialized.\n"); return 0; } @@ -678,7 +688,7 @@ static int __init appldata_init(void) /* * appldata_exit() * - * stop timer and tasklet, unregister /proc entries + * stop timer, unregister /proc entries */ static void __exit appldata_exit(void) { @@ -690,7 +700,7 @@ static void __exit appldata_exit(void) /* * ops list should be empty, but just in case something went wrong... */ - spin_lock_bh(&appldata_ops_lock); + spin_lock(&appldata_ops_lock); list_for_each(lh, &appldata_ops_list) { ops = list_entry(lh, struct appldata_ops, list); rc = appldata_diag(ops->record_nr, APPLDATA_STOP_REC, @@ -700,7 +710,7 @@ static void __exit appldata_exit(void) "return code: %d\n", ops->name, rc); } } - spin_unlock_bh(&appldata_ops_lock); + spin_unlock(&appldata_ops_lock); for_each_online_cpu(i) appldata_offline_cpu(i); @@ -709,7 +719,7 @@ static void __exit appldata_exit(void) unregister_sysctl_table(appldata_sysctl_header); - tasklet_kill(&appldata_tasklet_struct); + destroy_workqueue(appldata_wq); P_DEBUG("... module unloaded!\n"); } /**************************** init / exit ******************************/ diff --git a/arch/s390/appldata/appldata_mem.c b/arch/s390/appldata/appldata_mem.c index 462ee9a84e7..f0e2fbed3d4 100644 --- a/arch/s390/appldata/appldata_mem.c +++ b/arch/s390/appldata/appldata_mem.c @@ -68,7 +68,7 @@ struct appldata_mem_data { u64 pgmajfault; /* page faults (major only) */ // <-- New in 2.6 -} appldata_mem_data; +} __attribute__((packed)) appldata_mem_data; static inline void appldata_debug_print(struct appldata_mem_data *mem_data) diff --git a/arch/s390/appldata/appldata_net_sum.c b/arch/s390/appldata/appldata_net_sum.c index dd61638d302..2a4c7432db4 100644 --- a/arch/s390/appldata/appldata_net_sum.c +++ b/arch/s390/appldata/appldata_net_sum.c @@ -57,7 +57,7 @@ struct appldata_net_sum_data { u64 rx_dropped; /* no space in linux buffers */ u64 tx_dropped; /* no space available in linux */ u64 collisions; /* collisions while transmitting */ -} appldata_net_sum_data; +} __attribute__((packed)) appldata_net_sum_data; static inline void appldata_print_debug(struct appldata_net_sum_data *net_data) diff --git a/arch/s390/appldata/appldata_os.c b/arch/s390/appldata/appldata_os.c index b83f0748455..e0a476bf4fd 100644 --- a/arch/s390/appldata/appldata_os.c +++ b/arch/s390/appldata/appldata_os.c @@ -49,7 +49,7 @@ struct appldata_os_per_cpu { u32 per_cpu_softirq; /* ... spent in softirqs */ u32 per_cpu_iowait; /* ... spent while waiting for I/O */ // <-- New in 2.6 -}; +} __attribute__((packed)); struct appldata_os_data { u64 timestamp; @@ -75,7 +75,7 @@ struct appldata_os_data { /* per cpu data */ struct appldata_os_per_cpu os_cpu[0]; -}; +} __attribute__((packed)); static struct appldata_os_data *appldata_os_data; -- cgit v1.2.3-70-g09d2 From eae936e21bd726f9d9555f2262d439fbcd61dccf Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Sat, 4 Jun 2005 15:43:34 -0700 Subject: [PATCH] serial: update NEC VR4100 series serial support - Changed the return value of unknown type to NULL. - Deleted the NULL check of dev_id in siu_interrupt(). - Deleted the NULL check of port->membase in siu_shutdown(). - Added the NULL check of port->membase to siu_startup(). - Removed early_uart_ops. Now using vr41xx_siu standerd one. - Changed KSEG1ADDR() in siu_console_setup() to ioremap(). - When uart_add_one_port() failed, changed to set NULL to port->dev. Signed-off-by: Yoichi Yuasa Cc: Russell King Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/serial/vr41xx_siu.c | 66 +++++++-------------------------------------- 1 file changed, 9 insertions(+), 57 deletions(-) diff --git a/drivers/serial/vr41xx_siu.c b/drivers/serial/vr41xx_siu.c index 5d2ceb623e6..1f985327b0d 100644 --- a/drivers/serial/vr41xx_siu.c +++ b/drivers/serial/vr41xx_siu.c @@ -234,7 +234,7 @@ static inline const char *siu_type_name(struct uart_port *port) return "DSIU"; } - return "unknown"; + return NULL; } static unsigned int siu_tx_empty(struct uart_port *port) @@ -482,9 +482,6 @@ static irqreturn_t siu_interrupt(int irq, void *dev_id, struct pt_regs *regs) struct uart_port *port; uint8_t iir, lsr; - if (dev_id == NULL) - return IRQ_NONE; - port = (struct uart_port *)dev_id; iir = siu_read(port, UART_IIR); @@ -507,6 +504,9 @@ static int siu_startup(struct uart_port *port) { int retval; + if (port->membase == NULL) + return -ENODEV; + siu_clear_fifo(port); (void)siu_read(port, UART_LSR); @@ -545,9 +545,6 @@ static void siu_shutdown(struct uart_port *port) unsigned long flags; uint8_t lcr; - if (port->membase == NULL) - return; - siu_write(port, UART_IER, 0); spin_lock_irqsave(&port->lock, flags); @@ -802,53 +799,6 @@ static int siu_init_ports(void) #ifdef CONFIG_SERIAL_VR41XX_CONSOLE -static void early_set_termios(struct uart_port *port, struct termios *new, - struct termios *old) -{ - tcflag_t c_cflag; - uint8_t lcr; - unsigned int baud, quot; - - c_cflag = new->c_cflag; - switch (c_cflag & CSIZE) { - case CS5: - lcr = UART_LCR_WLEN5; - break; - case CS6: - lcr = UART_LCR_WLEN6; - break; - case CS7: - lcr = UART_LCR_WLEN7; - break; - default: - lcr = UART_LCR_WLEN8; - break; - } - - if (c_cflag & CSTOPB) - lcr |= UART_LCR_STOP; - if (c_cflag & PARENB) - lcr |= UART_LCR_PARITY; - if ((c_cflag & PARODD) != PARODD) - lcr |= UART_LCR_EPAR; - if (c_cflag & CMSPAR) - lcr |= UART_LCR_SPAR; - - baud = uart_get_baud_rate(port, new, old, 0, port->uartclk/16); - quot = uart_get_divisor(port, baud); - - siu_write(port, UART_LCR, lcr | UART_LCR_DLAB); - - siu_write(port, UART_DLL, (uint8_t)quot); - siu_write(port, UART_DLM, (uint8_t)(quot >> 8)); - - siu_write(port, UART_LCR, lcr); -} - -static struct uart_ops early_uart_ops = { - .set_termios = early_set_termios, -}; - #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) static void wait_for_xmitr(struct uart_port *port) @@ -915,7 +865,7 @@ static int siu_console_setup(struct console *con, char *options) if (port->membase == NULL) { if (port->mapbase == 0) return -ENODEV; - port->membase = (unsigned char __iomem *)KSEG1ADDR(port->mapbase); + port->membase = ioremap(port->mapbase, siu_port_size(port)); } vr41xx_select_siu_interface(SIU_INTERFACE_RS232C); @@ -949,7 +899,7 @@ static int __devinit siu_console_init(void) for (i = 0; i < num; i++) { port = &siu_uart_ports[i]; - port->ops = &early_uart_ops; + port->ops = &siu_uart_ops; } register_console(&siu_console); @@ -994,8 +944,10 @@ static int siu_probe(struct device *dev) port->dev = dev; retval = uart_add_one_port(&siu_uart_driver, port); - if (retval) + if (retval < 0) { + port->dev = NULL; break; + } } if (i == 0 && retval < 0) { -- cgit v1.2.3-70-g09d2 From 7cef5677ef3a8084f2588ce0a129dc95d65161f6 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 6 Jun 2005 08:22:29 -0700 Subject: Linux 2.6.12-rc6 Getting ready for the real release.. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index c11a317ea91..9e005e18c71 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 12 -EXTRAVERSION =-rc5 +EXTRAVERSION =-rc6 NAME=Woozy Numbat # *DOCUMENTATION* -- cgit v1.2.3-70-g09d2 From a51171816826b074828fa96cb6ef60fc3b13631a Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Mon, 6 Jun 2005 13:35:54 -0700 Subject: [PATCH] broken fault_in_pages_readable call in generic_file_buffered_write() fault_in_pages_readable() is being passed an incorrect `end' address, which can result in writes accidentally faulting in pages which will not be affected by the write() call. Signed-off-by: Martin Schwidefsky Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/filemap.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/mm/filemap.c b/mm/filemap.c index 1d33fec7bac..4a2fee2cb62 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -1968,6 +1968,7 @@ generic_file_buffered_write(struct kiocb *iocb, const struct iovec *iov, do { unsigned long index; unsigned long offset; + unsigned long maxlen; size_t copied; offset = (pos & (PAGE_CACHE_SIZE -1)); /* Within page */ @@ -1982,7 +1983,10 @@ generic_file_buffered_write(struct kiocb *iocb, const struct iovec *iov, * same page as we're writing to, without it being marked * up-to-date. */ - fault_in_pages_readable(buf, bytes); + maxlen = cur_iov->iov_len - iov_base; + if (maxlen > bytes) + maxlen = bytes; + fault_in_pages_readable(buf, maxlen); page = __grab_cache_page(mapping,index,&cached_page,&lru_pvec); if (!page) { @@ -2024,6 +2028,8 @@ generic_file_buffered_write(struct kiocb *iocb, const struct iovec *iov, filemap_set_next_iovec(&cur_iov, &iov_base, status); buf = cur_iov->iov_base + iov_base; + } else { + iov_base += status; } } } -- cgit v1.2.3-70-g09d2 From 3399ba5b70eccc918ea4ab2630cac68f5c8ff845 Mon Sep 17 00:00:00 2001 From: Denis Vlasenko Date: Mon, 6 Jun 2005 13:35:55 -0700 Subject: [PATCH] moxa: do not ignore input Stop using tty internal structure in mxser_receive_chars(), use tty_insert_flip_char(tty, ch flag); instead. Without this change driver ignores any rx'ed chars. Run tested. Cc: Alan Cox Cc: Russell King Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/mxser.c | 38 +++++++++++++------------------------- 1 file changed, 13 insertions(+), 25 deletions(-) diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c index 7a245068e3e..f022f094443 100644 --- a/drivers/char/mxser.c +++ b/drivers/char/mxser.c @@ -1995,9 +1995,6 @@ static void mxser_receive_chars(struct mxser_struct *info, int *status) unsigned char ch, gdl; int ignored = 0; int cnt = 0; - unsigned char *cp; - char *fp; - int count; int recv_room; int max = 256; unsigned long flags; @@ -2011,10 +2008,6 @@ static void mxser_receive_chars(struct mxser_struct *info, int *status) //return; } - cp = tty->flip.char_buf; - fp = tty->flip.flag_buf; - count = 0; - // following add by Victor Yu. 09-02-2002 if (info->IsMoxaMustChipFlag != MOXA_OTHER_UART) { @@ -2041,12 +2034,10 @@ static void mxser_receive_chars(struct mxser_struct *info, int *status) } while (gdl--) { ch = inb(info->base + UART_RX); - count++; - *cp++ = ch; - *fp++ = 0; + tty_insert_flip_char(tty, ch, 0); cnt++; /* - if((count>=HI_WATER) && (info->stop_rx==0)){ + if((cnt>=HI_WATER) && (info->stop_rx==0)){ mxser_stoprx(tty); info->stop_rx=1; break; @@ -2061,7 +2052,7 @@ intr_old: if (max-- < 0) break; /* - if((count>=HI_WATER) && (info->stop_rx==0)){ + if((cnt>=HI_WATER) && (info->stop_rx==0)){ mxser_stoprx(tty); info->stop_rx=1; break; @@ -2078,36 +2069,33 @@ intr_old: if (++ignored > 100) break; } else { - count++; + char flag = 0; if (*status & UART_LSR_SPECIAL) { if (*status & UART_LSR_BI) { - *fp++ = TTY_BREAK; + flag = TTY_BREAK; /* added by casper 1/11/2000 */ info->icount.brk++; - /* */ if (info->flags & ASYNC_SAK) do_SAK(tty); } else if (*status & UART_LSR_PE) { - *fp++ = TTY_PARITY; + flag = TTY_PARITY; /* added by casper 1/11/2000 */ info->icount.parity++; /* */ } else if (*status & UART_LSR_FE) { - *fp++ = TTY_FRAME; + flag = TTY_FRAME; /* added by casper 1/11/2000 */ info->icount.frame++; /* */ } else if (*status & UART_LSR_OE) { - *fp++ = TTY_OVERRUN; + flag = TTY_OVERRUN; /* added by casper 1/11/2000 */ info->icount.overrun++; /* */ - } else - *fp++ = 0; - } else - *fp++ = 0; - *cp++ = ch; + } + } + tty_insert_flip_char(tty, ch, flag); cnt++; if (cnt >= recv_room) { if (!info->ldisc_stop_rx) { @@ -2132,13 +2120,13 @@ intr_old: // above add by Victor Yu. 09-02-2002 } while (*status & UART_LSR_DR); - end_intr: // add by Victor Yu. 09-02-2002 +end_intr: // add by Victor Yu. 09-02-2002 mxvar_log.rxcnt[info->port] += cnt; info->mon_data.rxcnt += cnt; info->mon_data.up_rxcnt += cnt; spin_unlock_irqrestore(&info->slock, flags); - + tty_flip_buffer_push(tty); } -- cgit v1.2.3-70-g09d2 From 8e2894e51d6407e47226a60c0d19bf384642c55a Mon Sep 17 00:00:00 2001 From: Yoshinori Sato Date: Mon, 6 Jun 2005 13:35:56 -0700 Subject: [PATCH] h8300 build error fix h8300 was missing a few definitions. Signed-off-by: Yoshinori Sato Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-h8300/kmap_types.h | 6 ++++-- include/asm-h8300/mman.h | 3 +++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/include/asm-h8300/kmap_types.h b/include/asm-h8300/kmap_types.h index 82431edeb2a..1ec8a342712 100644 --- a/include/asm-h8300/kmap_types.h +++ b/include/asm-h8300/kmap_types.h @@ -1,5 +1,5 @@ -#ifndef _ASM_KMAP_TYPES_H -#define _ASM_KMAP_TYPES_H +#ifndef _ASM_H8300_KMAP_TYPES_H +#define _ASM_H8300_KMAP_TYPES_H enum km_type { KM_BOUNCE_READ, @@ -13,6 +13,8 @@ enum km_type { KM_PTE1, KM_IRQ0, KM_IRQ1, + KM_SOFTIRQ0, + KM_SOFTIRQ1, KM_TYPE_NR }; diff --git a/include/asm-h8300/mman.h b/include/asm-h8300/mman.h index abe08856c84..63f727a5985 100644 --- a/include/asm-h8300/mman.h +++ b/include/asm-h8300/mman.h @@ -4,6 +4,7 @@ #define PROT_READ 0x1 /* page can be read */ #define PROT_WRITE 0x2 /* page can be written */ #define PROT_EXEC 0x4 /* page can be executed */ +#define PROT_SEM 0x8 /* page may be used for atomic ops */ #define PROT_NONE 0x0 /* page can not be accessed */ #define PROT_GROWSDOWN 0x01000000 /* mprotect flag: extend change to start of growsdown vma */ #define PROT_GROWSUP 0x02000000 /* mprotect flag: extend change to end of growsup vma */ @@ -19,6 +20,8 @@ #define MAP_EXECUTABLE 0x1000 /* mark it as an executable */ #define MAP_LOCKED 0x2000 /* pages are locked */ #define MAP_NORESERVE 0x4000 /* don't check for reservations */ +#define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */ +#define MAP_NONBLOCK 0x10000 /* do not block on IO */ #define MS_ASYNC 1 /* sync memory asynchronously */ #define MS_INVALIDATE 2 /* invalidate the caches */ -- cgit v1.2.3-70-g09d2 From 4481e8eea761857367162b0957277d5524fbea63 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Mon, 6 Jun 2005 13:35:57 -0700 Subject: [PATCH] ppc32: Fix incorrect CPU_FTR fixup usage for unified caches Runtime feature support for unified caches was testing a userland feature flag (PPC_FEATURE_UNIFIED_CACHE) instead of a cpu feature flag (CPU_FTR_SPLIT_ID_CACHE). Luckily the current defined bit mask for cpu features and userland features do not overlap so this only causes an issue on machines with a unified cache, which is extremely rare on PPC today. Signed-off-by: Kumar Gala Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc/kernel/misc.S | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S index e4f1615ec13..7329ef177a1 100644 --- a/arch/ppc/kernel/misc.S +++ b/arch/ppc/kernel/misc.S @@ -619,7 +619,7 @@ _GLOBAL(flush_instruction_cache) _GLOBAL(flush_icache_range) BEGIN_FTR_SECTION blr /* for 601, do nothing */ -END_FTR_SECTION_IFSET(PPC_FEATURE_UNIFIED_CACHE) +END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE) li r5,L1_CACHE_LINE_SIZE-1 andc r3,r3,r5 subf r4,r3,r4 @@ -736,7 +736,7 @@ _GLOBAL(flush_dcache_all) _GLOBAL(__flush_dcache_icache) BEGIN_FTR_SECTION blr /* for 601, do nothing */ -END_FTR_SECTION_IFSET(PPC_FEATURE_UNIFIED_CACHE) +END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE) rlwinm r3,r3,0,0,19 /* Get page base address */ li r4,4096/L1_CACHE_LINE_SIZE /* Number of lines in a page */ mtctr r4 @@ -764,7 +764,7 @@ END_FTR_SECTION_IFSET(PPC_FEATURE_UNIFIED_CACHE) _GLOBAL(__flush_dcache_icache_phys) BEGIN_FTR_SECTION blr /* for 601, do nothing */ -END_FTR_SECTION_IFSET(PPC_FEATURE_UNIFIED_CACHE) +END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE) mfmsr r10 rlwinm r0,r10,0,28,26 /* clear DR */ mtmsr r0 -- cgit v1.2.3-70-g09d2 From 90ebe5654febe3555a2516d51d3d251226d35fdb Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 6 Jun 2005 13:35:58 -0700 Subject: [PATCH] namei fixes OK, here comes a patch series that hopefully should close all too-early-mntput() races in fs/namei.c. Entire area is convoluted as hell, so I'm splitting that series into _very_ small chunks. Patches alread in the tree close only (very wide) races in following symlinks (see "busy inodes after umount" thread some time ago). Unfortunately, quite a few narrower races of the same nature were not closed. Hopefully this should take care of all of them. Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/namei.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index dd78f01b6de..abeec34e755 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -493,6 +493,11 @@ fail: return PTR_ERR(link); } +struct path { + struct vfsmount *mnt; + struct dentry *dentry; +}; + static inline int __do_follow_link(struct dentry *dentry, struct nameidata *nd) { int error; @@ -518,7 +523,7 @@ static inline int __do_follow_link(struct dentry *dentry, struct nameidata *nd) * Without that kind of total limit, nasty chains of consecutive * symlinks can cause almost arbitrarily long lookups. */ -static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd) +static inline int do_follow_link(struct path *path, struct nameidata *nd) { int err = -ELOOP; if (current->link_count >= MAX_NESTED_LINKS) @@ -527,13 +532,13 @@ static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd) goto loop; BUG_ON(nd->depth >= MAX_NESTED_LINKS); cond_resched(); - err = security_inode_follow_link(dentry, nd); + err = security_inode_follow_link(path->dentry, nd); if (err) goto loop; current->link_count++; current->total_link_count++; nd->depth++; - err = __do_follow_link(dentry, nd); + err = __do_follow_link(path->dentry, nd); current->link_count--; nd->depth--; return err; @@ -641,11 +646,6 @@ static inline void follow_dotdot(struct vfsmount **mnt, struct dentry **dentry) follow_mount(mnt, dentry); } -struct path { - struct vfsmount *mnt; - struct dentry *dentry; -}; - /* * It's more convoluted than I'd like it to be, but... it's still fairly * small and for now I'd prefer to have fast path as straight as possible. @@ -784,7 +784,7 @@ static fastcall int __link_path_walk(const char * name, struct nameidata *nd) if (inode->i_op->follow_link) { mntget(next.mnt); - err = do_follow_link(next.dentry, nd); + err = do_follow_link(&next, nd); dput(next.dentry); mntput(next.mnt); if (err) @@ -838,7 +838,7 @@ last_component: if ((lookup_flags & LOOKUP_FOLLOW) && inode && inode->i_op && inode->i_op->follow_link) { mntget(next.mnt); - err = do_follow_link(next.dentry, nd); + err = do_follow_link(&next, nd); dput(next.dentry); mntput(next.mnt); if (err) -- cgit v1.2.3-70-g09d2 From 5f92b3bcec0fa2e2d775b589850097f9dc6b2de2 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 6 Jun 2005 13:35:59 -0700 Subject: [PATCH] namei fixes (2/19) All callers of do_follow_link() do mntget() right before it and dput()+mntput() right after. These calls are moved inside do_follow_link() now. Obviously equivalent transformation. Signed-off-by: Al Viro Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/namei.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index abeec34e755..12d75ed214f 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -526,6 +526,7 @@ static inline int __do_follow_link(struct dentry *dentry, struct nameidata *nd) static inline int do_follow_link(struct path *path, struct nameidata *nd) { int err = -ELOOP; + mntget(path->mnt); if (current->link_count >= MAX_NESTED_LINKS) goto loop; if (current->total_link_count >= 40) @@ -541,9 +542,13 @@ static inline int do_follow_link(struct path *path, struct nameidata *nd) err = __do_follow_link(path->dentry, nd); current->link_count--; nd->depth--; + dput(path->dentry); + mntput(path->mnt); return err; loop: path_release(nd); + dput(path->dentry); + mntput(path->mnt); return err; } @@ -783,10 +788,7 @@ static fastcall int __link_path_walk(const char * name, struct nameidata *nd) goto out_dput; if (inode->i_op->follow_link) { - mntget(next.mnt); err = do_follow_link(&next, nd); - dput(next.dentry); - mntput(next.mnt); if (err) goto return_err; err = -ENOENT; @@ -837,10 +839,7 @@ last_component: inode = next.dentry->d_inode; if ((lookup_flags & LOOKUP_FOLLOW) && inode && inode->i_op && inode->i_op->follow_link) { - mntget(next.mnt); err = do_follow_link(&next, nd); - dput(next.dentry); - mntput(next.mnt); if (err) goto return_err; inode = nd->dentry->d_inode; -- cgit v1.2.3-70-g09d2 From 4e7506e4dd9e40c189fcbec95d5dbc92f2e5926a Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 6 Jun 2005 13:36:00 -0700 Subject: [PATCH] namei fixes (3/19) Replaced struct dentry *dentry in namei with struct path path. All uses of dentry replaced with path.dentry there. Obviously equivalent transformation. Signed-off-by: Al Viro Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/namei.c | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index 12d75ed214f..167f19b5e51 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -1397,7 +1397,7 @@ int may_open(struct nameidata *nd, int acc_mode, int flag) int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd) { int acc_mode, error = 0; - struct dentry *dentry; + struct path path; struct dentry *dir; int count = 0; @@ -1441,23 +1441,23 @@ int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd) dir = nd->dentry; nd->flags &= ~LOOKUP_PARENT; down(&dir->d_inode->i_sem); - dentry = __lookup_hash(&nd->last, nd->dentry, nd); + path.dentry = __lookup_hash(&nd->last, nd->dentry, nd); do_last: - error = PTR_ERR(dentry); - if (IS_ERR(dentry)) { + error = PTR_ERR(path.dentry); + if (IS_ERR(path.dentry)) { up(&dir->d_inode->i_sem); goto exit; } /* Negative dentry, just create the file */ - if (!dentry->d_inode) { + if (!path.dentry->d_inode) { if (!IS_POSIXACL(dir->d_inode)) mode &= ~current->fs->umask; - error = vfs_create(dir->d_inode, dentry, mode, nd); + error = vfs_create(dir->d_inode, path.dentry, mode, nd); up(&dir->d_inode->i_sem); dput(nd->dentry); - nd->dentry = dentry; + nd->dentry = path.dentry; if (error) goto exit; /* Don't check for write permission, don't truncate */ @@ -1475,22 +1475,22 @@ do_last: if (flag & O_EXCL) goto exit_dput; - if (d_mountpoint(dentry)) { + if (d_mountpoint(path.dentry)) { error = -ELOOP; if (flag & O_NOFOLLOW) goto exit_dput; - while (__follow_down(&nd->mnt,&dentry) && d_mountpoint(dentry)); + while (__follow_down(&nd->mnt,&path.dentry) && d_mountpoint(path.dentry)); } error = -ENOENT; - if (!dentry->d_inode) + if (!path.dentry->d_inode) goto exit_dput; - if (dentry->d_inode->i_op && dentry->d_inode->i_op->follow_link) + if (path.dentry->d_inode->i_op && path.dentry->d_inode->i_op->follow_link) goto do_link; dput(nd->dentry); - nd->dentry = dentry; + nd->dentry = path.dentry; error = -EISDIR; - if (dentry->d_inode && S_ISDIR(dentry->d_inode->i_mode)) + if (path.dentry->d_inode && S_ISDIR(path.dentry->d_inode->i_mode)) goto exit; ok: error = may_open(nd, acc_mode, flag); @@ -1499,7 +1499,7 @@ ok: return 0; exit_dput: - dput(dentry); + dput(path.dentry); exit: path_release(nd); return error; @@ -1519,16 +1519,16 @@ do_link: * are done. Procfs-like symlinks just set LAST_BIND. */ nd->flags |= LOOKUP_PARENT; - error = security_inode_follow_link(dentry, nd); + error = security_inode_follow_link(path.dentry, nd); if (error) goto exit_dput; - error = __do_follow_link(dentry, nd); - dput(dentry); + error = __do_follow_link(path.dentry, nd); + dput(path.dentry); if (error) return error; nd->flags &= ~LOOKUP_PARENT; if (nd->last_type == LAST_BIND) { - dentry = nd->dentry; + path.dentry = nd->dentry; goto ok; } error = -EISDIR; @@ -1545,7 +1545,7 @@ do_link: } dir = nd->dentry; down(&dir->d_inode->i_sem); - dentry = __lookup_hash(&nd->last, nd->dentry, nd); + path.dentry = __lookup_hash(&nd->last, nd->dentry, nd); putname(nd->last.name); goto do_last; } -- cgit v1.2.3-70-g09d2 From d73ffe16b8baafae6e9249acee6b50c24099c6de Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 6 Jun 2005 13:36:01 -0700 Subject: [PATCH] namei fixes (4/19) path.mnt in open_namei() set to mirror nd->mnt. nd->mnt is set in 3 places in that function - path_lookup() in the beginning, __follow_down() loop after do_last: and __do_follow_link() call after do_link:. We set path.mnt to nd->mnt after path_lookup() and __do_follow_link(). In __follow_down() loop we use &path.mnt instead of &nd->mnt and set nd->mnt to path.mnt immediately after that loop. Obviously equivalent transformation. Signed-off-by: Al Viro Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/namei.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/fs/namei.c b/fs/namei.c index 167f19b5e51..e42f7c35545 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -1442,6 +1442,7 @@ int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd) nd->flags &= ~LOOKUP_PARENT; down(&dir->d_inode->i_sem); path.dentry = __lookup_hash(&nd->last, nd->dentry, nd); + path.mnt = nd->mnt; do_last: error = PTR_ERR(path.dentry); @@ -1479,7 +1480,8 @@ do_last: error = -ELOOP; if (flag & O_NOFOLLOW) goto exit_dput; - while (__follow_down(&nd->mnt,&path.dentry) && d_mountpoint(path.dentry)); + while (__follow_down(&path.mnt,&path.dentry) && d_mountpoint(path.dentry)); + nd->mnt = path.mnt; } error = -ENOENT; if (!path.dentry->d_inode) @@ -1524,6 +1526,7 @@ do_link: goto exit_dput; error = __do_follow_link(path.dentry, nd); dput(path.dentry); + path.mnt = nd->mnt; if (error) return error; nd->flags &= ~LOOKUP_PARENT; -- cgit v1.2.3-70-g09d2 From 1be4a0900be5d2c2fd9cd012e3a153e1ea47b96a Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 6 Jun 2005 13:36:01 -0700 Subject: [PATCH] namei fixes (5/19) fix for too early mntput() in open_namei() - we pin path.mnt down for the duration of __do_follow_link(). Otherwise we could get the fs where our symlink lived unmounted while we were in __do_follow_link(). That would end up with dentry of symlink staying pinned down through the fs shutdown. Signed-off-by: Al Viro Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/namei.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/namei.c b/fs/namei.c index e42f7c35545..020fb8c8d1c 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -1524,8 +1524,10 @@ do_link: error = security_inode_follow_link(path.dentry, nd); if (error) goto exit_dput; + mntget(path.mnt); error = __do_follow_link(path.dentry, nd); dput(path.dentry); + mntput(path.mnt); path.mnt = nd->mnt; if (error) return error; -- cgit v1.2.3-70-g09d2 From 839d9f93c9f1623fb37234d464d739617879d97e Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 6 Jun 2005 13:36:02 -0700 Subject: [PATCH] namei fixes (6/19) mntget(path->mnt) in do_follow_link() moved down to right before the __do_follow_link() call and rigth after loop: resp. dput()+mntput() on non-ELOOP branch moved up to right after __do_follow_link() call. resulting loop: mntget(path->mnt); path_release(nd); dput(path->mnt); mntput(path->mnt); replaced with equivalent dput(path->mnt); path_release(nd); Equivalent transformations - the reason why we have that mntget() is that __do_follow_link() can drop a reference to nd->mnt and that's what holds path->mnt. So that call can happen at any point prior to __do_follow_link() touching nd->mnt. The rest is obvious. NOTE: current tree relies on symlinks *never* being mounted on anything. It's not hard to get rid of that assumption (actually, that will come for free later in the series). For now we are just not making the situation worse than it is. Signed-off-by: Al Viro Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/namei.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index 020fb8c8d1c..519900d83bc 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -526,7 +526,6 @@ static inline int __do_follow_link(struct dentry *dentry, struct nameidata *nd) static inline int do_follow_link(struct path *path, struct nameidata *nd) { int err = -ELOOP; - mntget(path->mnt); if (current->link_count >= MAX_NESTED_LINKS) goto loop; if (current->total_link_count >= 40) @@ -539,16 +538,16 @@ static inline int do_follow_link(struct path *path, struct nameidata *nd) current->link_count++; current->total_link_count++; nd->depth++; + mntget(path->mnt); err = __do_follow_link(path->dentry, nd); - current->link_count--; - nd->depth--; dput(path->dentry); mntput(path->mnt); + current->link_count--; + nd->depth--; return err; loop: - path_release(nd); dput(path->dentry); - mntput(path->mnt); + path_release(nd); return err; } -- cgit v1.2.3-70-g09d2 From cd4e91d3bca8d5527289f5984cf32e9fe6fb8293 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 6 Jun 2005 13:36:03 -0700 Subject: [PATCH] namei fixes (7/19) The first argument of __do_follow_link() switched to struct path * (__do_follow_link(path->dentry, ...) -> __do_follow_link(path, ...)). All callers have the same calls of mntget() right before and dput()/mntput() right after __do_follow_link(); these calls have been moved inside. Obviously equivalent transformations. Signed-off-by: Al Viro Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/namei.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index 519900d83bc..18ea0606145 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -498,12 +498,15 @@ struct path { struct dentry *dentry; }; -static inline int __do_follow_link(struct dentry *dentry, struct nameidata *nd) +static inline int __do_follow_link(struct path *path, struct nameidata *nd) { int error; + struct dentry *dentry = path->dentry; touch_atime(nd->mnt, dentry); nd_set_link(nd, NULL); + + mntget(path->mnt); error = dentry->d_inode->i_op->follow_link(dentry, nd); if (!error) { char *s = nd_get_link(nd); @@ -512,6 +515,8 @@ static inline int __do_follow_link(struct dentry *dentry, struct nameidata *nd) if (dentry->d_inode->i_op->put_link) dentry->d_inode->i_op->put_link(dentry, nd); } + dput(dentry); + mntput(path->mnt); return error; } @@ -538,10 +543,7 @@ static inline int do_follow_link(struct path *path, struct nameidata *nd) current->link_count++; current->total_link_count++; nd->depth++; - mntget(path->mnt); - err = __do_follow_link(path->dentry, nd); - dput(path->dentry); - mntput(path->mnt); + err = __do_follow_link(path, nd); current->link_count--; nd->depth--; return err; @@ -1523,10 +1525,7 @@ do_link: error = security_inode_follow_link(path.dentry, nd); if (error) goto exit_dput; - mntget(path.mnt); - error = __do_follow_link(path.dentry, nd); - dput(path.dentry); - mntput(path.mnt); + error = __do_follow_link(&path, nd); path.mnt = nd->mnt; if (error) return error; -- cgit v1.2.3-70-g09d2 From d671d5e51400aab03c713a16ce3545aa81ad7b1c Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 6 Jun 2005 13:36:04 -0700 Subject: [PATCH] namei fixes (8/19) In open_namei() we never use path.mnt or path.dentry after exit: or ok:. Assignment of path.dentry in case of LAST_BIND is dead code and only obfuscates already convoluted function; assignment of path.mnt after __do_follow_link() can be moved down to the place where we set path.dentry. Obviously equivalent transformations, just to clean the air a bit in that region. Signed-off-by: Al Viro Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/namei.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index 18ea0606145..3d08478d313 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -1526,14 +1526,11 @@ do_link: if (error) goto exit_dput; error = __do_follow_link(&path, nd); - path.mnt = nd->mnt; if (error) return error; nd->flags &= ~LOOKUP_PARENT; - if (nd->last_type == LAST_BIND) { - path.dentry = nd->dentry; + if (nd->last_type == LAST_BIND) goto ok; - } error = -EISDIR; if (nd->last_type != LAST_NORM) goto exit; @@ -1549,6 +1546,7 @@ do_link: dir = nd->dentry; down(&dir->d_inode->i_sem); path.dentry = __lookup_hash(&nd->last, nd->dentry, nd); + path.mnt = nd->mnt; putname(nd->last.name); goto do_last; } -- cgit v1.2.3-70-g09d2 From 463ffb2e9d39c2a3fd8c3c1d4a34e01f2078f972 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 6 Jun 2005 13:36:05 -0700 Subject: [PATCH] namei fixes (9/19) New helper: __follow_mount(struct path *path). Same as follow_mount(), except that we do *not* do mntput() after the first lookup_mnt(). IOW, original path->mnt stays pinned down. We also take care to do dput() before mntput() in the loop body (follow_mount() also needs that reordering, but that will be done later in the series). The following are equivalent, assuming that path.mnt == x: (1) follow_mount(&path.mnt, &path.dentry) (2) __follow_mount(&path); if (path->mnt != x) mntput(x); (3) if (__follow_mount(&path)) mntput(x); Callers of follow_mount() in __link_path_walk() converted to (2). Equivalent transformation + fix for too-late-mntput() race in __follow_mount() loop. Signed-off-by: Al Viro Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/namei.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index 3d08478d313..23a1ad46797 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -576,6 +576,23 @@ int follow_up(struct vfsmount **mnt, struct dentry **dentry) /* no need for dcache_lock, as serialization is taken care in * namespace.c */ +static int __follow_mount(struct path *path) +{ + int res = 0; + while (d_mountpoint(path->dentry)) { + struct vfsmount *mounted = lookup_mnt(path->mnt, path->dentry); + if (!mounted) + break; + dput(path->dentry); + if (res) + mntput(path->mnt); + path->mnt = mounted; + path->dentry = dget(mounted->mnt_root); + res = 1; + } + return res; +} + static int follow_mount(struct vfsmount **mnt, struct dentry **dentry) { int res = 0; @@ -778,7 +795,9 @@ static fastcall int __link_path_walk(const char * name, struct nameidata *nd) if (err) break; /* Check mountpoints.. */ - follow_mount(&next.mnt, &next.dentry); + __follow_mount(&next); + if (nd->mnt != next.mnt) + mntput(nd->mnt); err = -ENOENT; inode = next.dentry->d_inode; @@ -836,7 +855,9 @@ last_component: err = do_lookup(nd, &this, &next); if (err) break; - follow_mount(&next.mnt, &next.dentry); + __follow_mount(&next); + if (nd->mnt != next.mnt) + mntput(nd->mnt); inode = next.dentry->d_inode; if ((lookup_flags & LOOKUP_FOLLOW) && inode && inode->i_op && inode->i_op->follow_link) { -- cgit v1.2.3-70-g09d2 From e13b210f6f7bdc44dfee0a9bbd633a32db0d6333 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 6 Jun 2005 13:36:06 -0700 Subject: [PATCH] namei fixes (10/19) In open_namei(), __follow_down() loop turned into __follow_mount(). Instead of if we are on a mountpoint dentry if O_NOFOLLOW checks fail drop path.dentry drop nd return do equivalent of follow_mount(&path.mnt, &path.dentry) nd->mnt = path.mnt we do if __follow_mount(path) had, indeed, traversed mountpoint /* now both nd->mnt and path.mnt are pinned down */ if O_NOFOLLOW checks fail drop path.dentry drop path.mnt drop nd return mntput(nd->mnt) nd->mnt = path.mnt Now __follow_down() can be folded into follow_down() - no other callers left. We need to reorder dput()/mntput() there - same problem as in follow_mount(). Equivalent transformation + fix for a bug in O_NOFOLLOW handling - we used to get -ELOOP if we had the same fs mounted on /foo and /bar, had something bound on /bar/baz and tried to open /foo/baz with O_NOFOLLOW. And fix of too-early-mntput() race in follow_down() Signed-off-by: Al Viro Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/namei.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index 23a1ad46797..935b08d8dcd 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -612,26 +612,21 @@ static int follow_mount(struct vfsmount **mnt, struct dentry **dentry) /* no need for dcache_lock, as serialization is taken care in * namespace.c */ -static inline int __follow_down(struct vfsmount **mnt, struct dentry **dentry) +int follow_down(struct vfsmount **mnt, struct dentry **dentry) { struct vfsmount *mounted; mounted = lookup_mnt(*mnt, *dentry); if (mounted) { + dput(*dentry); mntput(*mnt); *mnt = mounted; - dput(*dentry); *dentry = dget(mounted->mnt_root); return 1; } return 0; } -int follow_down(struct vfsmount **mnt, struct dentry **dentry) -{ - return __follow_down(mnt,dentry); -} - static inline void follow_dotdot(struct vfsmount **mnt, struct dentry **dentry) { while(1) { @@ -1498,11 +1493,14 @@ do_last: if (flag & O_EXCL) goto exit_dput; - if (d_mountpoint(path.dentry)) { + if (__follow_mount(&path)) { error = -ELOOP; - if (flag & O_NOFOLLOW) - goto exit_dput; - while (__follow_down(&path.mnt,&path.dentry) && d_mountpoint(path.dentry)); + if (flag & O_NOFOLLOW) { + dput(path.dentry); + mntput(path.mnt); + goto exit; + } + mntput(nd->mnt); nd->mnt = path.mnt; } error = -ENOENT; -- cgit v1.2.3-70-g09d2 From 2f12dbfbb6286c725c283a169f8f05e89a86848b Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 6 Jun 2005 13:36:07 -0700 Subject: [PATCH] namei fixes (11/19) shifted conditional mntput() calls in __link_path_walk() downstream. Obviously equivalent transformation. Signed-off-by: Al Viro Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/namei.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index 935b08d8dcd..907a3f2b4c9 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -791,8 +791,6 @@ static fastcall int __link_path_walk(const char * name, struct nameidata *nd) break; /* Check mountpoints.. */ __follow_mount(&next); - if (nd->mnt != next.mnt) - mntput(nd->mnt); err = -ENOENT; inode = next.dentry->d_inode; @@ -803,6 +801,8 @@ static fastcall int __link_path_walk(const char * name, struct nameidata *nd) goto out_dput; if (inode->i_op->follow_link) { + if (nd->mnt != next.mnt) + mntput(nd->mnt); err = do_follow_link(&next, nd); if (err) goto return_err; @@ -815,6 +815,8 @@ static fastcall int __link_path_walk(const char * name, struct nameidata *nd) break; } else { dput(nd->dentry); + if (nd->mnt != next.mnt) + mntput(nd->mnt); nd->mnt = next.mnt; nd->dentry = next.dentry; } @@ -851,17 +853,19 @@ last_component: if (err) break; __follow_mount(&next); - if (nd->mnt != next.mnt) - mntput(nd->mnt); inode = next.dentry->d_inode; if ((lookup_flags & LOOKUP_FOLLOW) && inode && inode->i_op && inode->i_op->follow_link) { + if (next.mnt != nd->mnt) + mntput(nd->mnt); err = do_follow_link(&next, nd); if (err) goto return_err; inode = nd->dentry->d_inode; } else { dput(nd->dentry); + if (nd->mnt != next.mnt) + mntput(nd->mnt); nd->mnt = next.mnt; nd->dentry = next.dentry; } @@ -901,6 +905,8 @@ return_base: return 0; out_dput: dput(next.dentry); + if (nd->mnt != next.mnt) + mntput(nd->mnt); break; } path_release(nd); -- cgit v1.2.3-70-g09d2 From a15a3f6fc67d910f43098acec6e19d25a37d7cb9 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 6 Jun 2005 13:36:08 -0700 Subject: [PATCH] namei fixes (12/19) In open_namei() we take mntput(nd->mnt);nd->mnt=path.mnt; out of the if (__follow_mount(...)), making it conditional on nd->mnt != path.mnt instead. Then we shift the result downstream. Equivalent transformations. Signed-off-by: Al Viro Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/namei.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index 907a3f2b4c9..37fcf941fa3 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -1506,8 +1506,6 @@ do_last: mntput(path.mnt); goto exit; } - mntput(nd->mnt); - nd->mnt = path.mnt; } error = -ENOENT; if (!path.dentry->d_inode) @@ -1517,6 +1515,9 @@ do_last: dput(nd->dentry); nd->dentry = path.dentry; + if (nd->mnt != path.mnt) + mntput(nd->mnt); + nd->mnt = path.mnt; error = -EISDIR; if (path.dentry->d_inode && S_ISDIR(path.dentry->d_inode->i_mode)) goto exit; @@ -1528,6 +1529,9 @@ ok: exit_dput: dput(path.dentry); + if (nd->mnt != path.mnt) + mntput(nd->mnt); + nd->mnt = path.mnt; exit: path_release(nd); return error; @@ -1550,6 +1554,9 @@ do_link: error = security_inode_follow_link(path.dentry, nd); if (error) goto exit_dput; + if (nd->mnt != path.mnt) + mntput(nd->mnt); + nd->mnt = path.mnt; error = __do_follow_link(&path, nd); if (error) return error; -- cgit v1.2.3-70-g09d2 From ba7a4c1a76f56c607560f1676680ff491747bdae Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 6 Jun 2005 13:36:08 -0700 Subject: [PATCH] namei fixes (13/19) In open_namei() exit_dput: we have mntput() done in the wrong order - if nd->mnt != path.mnt we end up doing mntput(nd->mnt); nd->mnt = path.mnt; dput(nd->dentry); mntput(nd->mnt); which drops nd->dentry too late. Fixed by having path.mnt go first. That allows to switch O_NOFOLLOW under if (__follow_mount(...)) back to exit_dput, while we are at it. Fix for early-mntput() race + equivalent transformation. Signed-off-by: Al Viro Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/namei.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index 37fcf941fa3..5153f57ee6b 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -1501,11 +1501,8 @@ do_last: if (__follow_mount(&path)) { error = -ELOOP; - if (flag & O_NOFOLLOW) { - dput(path.dentry); - mntput(path.mnt); - goto exit; - } + if (flag & O_NOFOLLOW) + goto exit_dput; } error = -ENOENT; if (!path.dentry->d_inode) @@ -1530,8 +1527,7 @@ ok: exit_dput: dput(path.dentry); if (nd->mnt != path.mnt) - mntput(nd->mnt); - nd->mnt = path.mnt; + mntput(path.mnt); exit: path_release(nd); return error; -- cgit v1.2.3-70-g09d2 From 4b7b9772e4c3d87e649d4c419d2487aacf1235aa Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 6 Jun 2005 13:36:10 -0700 Subject: [PATCH] namei fixes (14/19) shifted conditional mntput() into do_follow_link() - all callers were doing the same thing. Obviously equivalent transformation. Signed-off-by: Al Viro Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/namei.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index 5153f57ee6b..411bb3243c3 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -543,11 +543,15 @@ static inline int do_follow_link(struct path *path, struct nameidata *nd) current->link_count++; current->total_link_count++; nd->depth++; + if (path->mnt != nd->mnt) + mntput(nd->mnt); err = __do_follow_link(path, nd); current->link_count--; nd->depth--; return err; loop: + if (path->mnt != nd->mnt) + mntput(nd->mnt); dput(path->dentry); path_release(nd); return err; @@ -801,8 +805,6 @@ static fastcall int __link_path_walk(const char * name, struct nameidata *nd) goto out_dput; if (inode->i_op->follow_link) { - if (nd->mnt != next.mnt) - mntput(nd->mnt); err = do_follow_link(&next, nd); if (err) goto return_err; @@ -856,8 +858,6 @@ last_component: inode = next.dentry->d_inode; if ((lookup_flags & LOOKUP_FOLLOW) && inode && inode->i_op && inode->i_op->follow_link) { - if (next.mnt != nd->mnt) - mntput(nd->mnt); err = do_follow_link(&next, nd); if (err) goto return_err; -- cgit v1.2.3-70-g09d2 From d9d29a29669f96903d9950bb881c2a393fd33849 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 6 Jun 2005 13:36:11 -0700 Subject: [PATCH] namei fixes (15/19) Getting rid of sloppy logics: a) in do_follow_link() we have the wrong vfsmount dropped if our symlink had been mounted on something. Currently it worls only because we never get such situation (modulo filesystem playing dirty tricks on us). And it obfuscates already convoluted logics... b) same goes for open_namei(). c) in __link_path_walk() we have another "it should never happen" sloppiness - out_dput: there does double-free on underlying vfsmount and leaks the covering one if we hit it just after crossing a mountpoint. Again, wrong vfsmount getting dropped. d) another too-early-mntput() race - in do_follow_mount() we need to postpone conditional mntput(path->mnt) until after dput(path->dentry). Again, this one happens only in it-currently-never-happens-unless-some-fs-plays-dirty scenario... Signed-off-by: Al Viro Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/namei.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index 411bb3243c3..6a884682b0a 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -544,15 +544,15 @@ static inline int do_follow_link(struct path *path, struct nameidata *nd) current->total_link_count++; nd->depth++; if (path->mnt != nd->mnt) - mntput(nd->mnt); + mntput(path->mnt); err = __do_follow_link(path, nd); current->link_count--; nd->depth--; return err; loop: - if (path->mnt != nd->mnt) - mntput(nd->mnt); dput(path->dentry); + if (path->mnt != nd->mnt) + mntput(path->mnt); path_release(nd); return err; } @@ -906,7 +906,7 @@ return_base: out_dput: dput(next.dentry); if (nd->mnt != next.mnt) - mntput(nd->mnt); + mntput(next.mnt); break; } path_release(nd); @@ -1551,8 +1551,7 @@ do_link: if (error) goto exit_dput; if (nd->mnt != path.mnt) - mntput(nd->mnt); - nd->mnt = path.mnt; + mntput(path.mnt); error = __do_follow_link(&path, nd); if (error) return error; -- cgit v1.2.3-70-g09d2 From 39ca6d49759346d4710c759d443eec8048b27213 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 6 Jun 2005 13:36:12 -0700 Subject: [PATCH] namei fixes (16/19) Conditional mntput() moved into __do_follow_link(). There it collapses with unconditional mntget() on the same sucker, closing another too-early-mntput() race. Signed-off-by: Al Viro Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/namei.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index 6a884682b0a..444086d441e 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -506,7 +506,8 @@ static inline int __do_follow_link(struct path *path, struct nameidata *nd) touch_atime(nd->mnt, dentry); nd_set_link(nd, NULL); - mntget(path->mnt); + if (path->mnt == nd->mnt) + mntget(path->mnt); error = dentry->d_inode->i_op->follow_link(dentry, nd); if (!error) { char *s = nd_get_link(nd); @@ -543,8 +544,6 @@ static inline int do_follow_link(struct path *path, struct nameidata *nd) current->link_count++; current->total_link_count++; nd->depth++; - if (path->mnt != nd->mnt) - mntput(path->mnt); err = __do_follow_link(path, nd); current->link_count--; nd->depth--; @@ -1550,8 +1549,6 @@ do_link: error = security_inode_follow_link(path.dentry, nd); if (error) goto exit_dput; - if (nd->mnt != path.mnt) - mntput(path.mnt); error = __do_follow_link(&path, nd); if (error) return error; -- cgit v1.2.3-70-g09d2 From 58c465eba4d7ed307c4c7cb3382ba7ee565e8858 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 6 Jun 2005 13:36:13 -0700 Subject: [PATCH] namei fixes (17/19) follow_mount() made void, reordered dput()/mntput() in it. follow_dotdot() switched from struct vfmount ** + struct dentry ** to struct nameidata *; callers updated. Equivalent transformation + fix for too-early-mntput() race. Signed-off-by: Al Viro Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/namei.c | 35 ++++++++++++++++------------------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index 444086d441e..36925ff307b 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -596,20 +596,17 @@ static int __follow_mount(struct path *path) return res; } -static int follow_mount(struct vfsmount **mnt, struct dentry **dentry) +static void follow_mount(struct vfsmount **mnt, struct dentry **dentry) { - int res = 0; while (d_mountpoint(*dentry)) { struct vfsmount *mounted = lookup_mnt(*mnt, *dentry); if (!mounted) break; + dput(*dentry); mntput(*mnt); *mnt = mounted; - dput(*dentry); *dentry = dget(mounted->mnt_root); - res = 1; } - return res; } /* no need for dcache_lock, as serialization is taken care in @@ -630,41 +627,41 @@ int follow_down(struct vfsmount **mnt, struct dentry **dentry) return 0; } -static inline void follow_dotdot(struct vfsmount **mnt, struct dentry **dentry) +static inline void follow_dotdot(struct nameidata *nd) { while(1) { struct vfsmount *parent; - struct dentry *old = *dentry; + struct dentry *old = nd->dentry; read_lock(¤t->fs->lock); - if (*dentry == current->fs->root && - *mnt == current->fs->rootmnt) { + if (nd->dentry == current->fs->root && + nd->mnt == current->fs->rootmnt) { read_unlock(¤t->fs->lock); break; } read_unlock(¤t->fs->lock); spin_lock(&dcache_lock); - if (*dentry != (*mnt)->mnt_root) { - *dentry = dget((*dentry)->d_parent); + if (nd->dentry != nd->mnt->mnt_root) { + nd->dentry = dget(nd->dentry->d_parent); spin_unlock(&dcache_lock); dput(old); break; } spin_unlock(&dcache_lock); spin_lock(&vfsmount_lock); - parent = (*mnt)->mnt_parent; - if (parent == *mnt) { + parent = nd->mnt->mnt_parent; + if (parent == nd->mnt) { spin_unlock(&vfsmount_lock); break; } mntget(parent); - *dentry = dget((*mnt)->mnt_mountpoint); + nd->dentry = dget(nd->mnt->mnt_mountpoint); spin_unlock(&vfsmount_lock); dput(old); - mntput(*mnt); - *mnt = parent; + mntput(nd->mnt); + nd->mnt = parent; } - follow_mount(mnt, dentry); + follow_mount(&nd->mnt, &nd->dentry); } /* @@ -772,7 +769,7 @@ static fastcall int __link_path_walk(const char * name, struct nameidata *nd) case 2: if (this.name[1] != '.') break; - follow_dotdot(&nd->mnt, &nd->dentry); + follow_dotdot(nd); inode = nd->dentry->d_inode; /* fallthrough */ case 1: @@ -839,7 +836,7 @@ last_component: case 2: if (this.name[1] != '.') break; - follow_dotdot(&nd->mnt, &nd->dentry); + follow_dotdot(nd); inode = nd->dentry->d_inode; /* fallthrough */ case 1: -- cgit v1.2.3-70-g09d2 From 634ee7017b31e46e28c0bd2cb488213331bfd39a Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 6 Jun 2005 13:36:13 -0700 Subject: [PATCH] namei fixes (18/19) Cosmetical cleanups - __follow_mount() calls in __link_path_walk() absorbed into do_lookup(). Obviously equivalent transformation. Signed-off-by: Al Viro Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/namei.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index 36925ff307b..5af7681e8ea 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -682,6 +682,7 @@ static int do_lookup(struct nameidata *nd, struct qstr *name, done: path->mnt = mnt; path->dentry = dentry; + __follow_mount(path); return 0; need_lookup: @@ -789,8 +790,6 @@ static fastcall int __link_path_walk(const char * name, struct nameidata *nd) err = do_lookup(nd, &this, &next); if (err) break; - /* Check mountpoints.. */ - __follow_mount(&next); err = -ENOENT; inode = next.dentry->d_inode; @@ -850,7 +849,6 @@ last_component: err = do_lookup(nd, &this, &next); if (err) break; - __follow_mount(&next); inode = next.dentry->d_inode; if ((lookup_flags & LOOKUP_FOLLOW) && inode && inode->i_op && inode->i_op->follow_link) { -- cgit v1.2.3-70-g09d2 From d671a1cbf7c7a5c5562106d39eb7f830ae5273ae Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 6 Jun 2005 13:36:14 -0700 Subject: [PATCH] namei fixes (19/19) __do_follow_link() passes potentially worng vfsmount to touch_atime(). It matters only in (currently impossible) case of symlink mounted on something, but it's trivial to fix and that actually makes more sense. Signed-off-by: Al Viro Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/namei.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/namei.c b/fs/namei.c index 5af7681e8ea..a7f7f44119b 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -503,7 +503,7 @@ static inline int __do_follow_link(struct path *path, struct nameidata *nd) int error; struct dentry *dentry = path->dentry; - touch_atime(nd->mnt, dentry); + touch_atime(path->mnt, dentry); nd_set_link(nd, NULL); if (path->mnt == nd->mnt) -- cgit v1.2.3-70-g09d2 From 8f5bb0438b86d1a5393176ceeec2836fd469edf8 Mon Sep 17 00:00:00 2001 From: Yoshinori Sato Date: Mon, 6 Jun 2005 14:46:32 -0700 Subject: [PATCH] binfmt_flat mmap flag fix Make sure that binfmt_flat passes the correct flags into do_mmap(). nommu's validate_mmap_request() will simple return -EINVAL if we try and pass it a flags value of zero. Signed-off-by: Yoshinori Sato Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/binfmt_flat.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c index f0cd67d9d31..c8998dc6688 100644 --- a/fs/binfmt_flat.c +++ b/fs/binfmt_flat.c @@ -520,7 +520,7 @@ static int load_flat_file(struct linux_binprm * bprm, DBG_FLT("BINFMT_FLAT: ROM mapping of file (we hope)\n"); down_write(¤t->mm->mmap_sem); - textpos = do_mmap(bprm->file, 0, text_len, PROT_READ|PROT_EXEC, 0, 0); + textpos = do_mmap(bprm->file, 0, text_len, PROT_READ|PROT_EXEC, MAP_SHARED, 0); up_write(¤t->mm->mmap_sem); if (!textpos || textpos >= (unsigned long) -4096) { if (!textpos) @@ -532,7 +532,7 @@ static int load_flat_file(struct linux_binprm * bprm, down_write(¤t->mm->mmap_sem); realdatastart = do_mmap(0, 0, data_len + extra + MAX_SHARED_LIBS * sizeof(unsigned long), - PROT_READ|PROT_WRITE|PROT_EXEC, 0, 0); + PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, 0); up_write(¤t->mm->mmap_sem); if (realdatastart == 0 || realdatastart >= (unsigned long)-4096) { @@ -574,7 +574,7 @@ static int load_flat_file(struct linux_binprm * bprm, down_write(¤t->mm->mmap_sem); textpos = do_mmap(0, 0, text_len + data_len + extra + MAX_SHARED_LIBS * sizeof(unsigned long), - PROT_READ | PROT_EXEC | PROT_WRITE, 0, 0); + PROT_READ | PROT_EXEC | PROT_WRITE, MAP_PRIVATE, 0); up_write(¤t->mm->mmap_sem); if (!textpos || textpos >= (unsigned long) -4096) { if (!textpos) -- cgit v1.2.3-70-g09d2 From fa04ae5c09f3dfedbc923c2954a9a26a573833f1 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 6 Jun 2005 15:07:19 -0700 Subject: [ETHTOOL]: Check correct pointer in ethtool_set_coalesce(). It was checking the "GET" function pointer instead of the "SET" one. Looks like a cut&paste error :-) Signed-off-by: David S. Miller --- net/core/ethtool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 8ec484894d6..a3eeb88e1c8 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c @@ -356,7 +356,7 @@ static int ethtool_set_coalesce(struct net_device *dev, void __user *useraddr) { struct ethtool_coalesce coalesce; - if (!dev->ethtool_ops->get_coalesce) + if (!dev->ethtool_ops->set_coalesce) return -EOPNOTSUPP; if (copy_from_user(&coalesce, useraddr, sizeof(coalesce))) -- cgit v1.2.3-70-g09d2 From 9beb1d587f690d5b2f9087f8f10c0ff9f6b66886 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Mon, 6 Jun 2005 15:14:35 -0700 Subject: [TG3]: Update pci.ids for BCM5752 Signed-off-by: John W. Linville Signed-off-by: David S. Miller --- drivers/pci/pci.ids | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pci/pci.ids b/drivers/pci/pci.ids index 93481b41b61..1d2ef1e2ffc 100644 --- a/drivers/pci/pci.ids +++ b/drivers/pci/pci.ids @@ -7173,6 +7173,7 @@ 080f Sentry5 DDR/SDR RAM Controller 0811 Sentry5 External Interface Core 0816 BCM3302 Sentry5 MIPS32 CPU + 1600 NetXtreme BCM5752 Gigabit Ethernet PCI Express 1644 NetXtreme BCM5700 Gigabit Ethernet 1014 0277 Broadcom Vigil B5700 1000Base-T 1028 00d1 Broadcom BCM5700 -- cgit v1.2.3-70-g09d2 From 49cabf49abd7676d026a61baabf5aae9337a82be Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Mon, 6 Jun 2005 15:15:17 -0700 Subject: [TG3]: Add TSO firmware license Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index fc9b5cd957a..d2050133930 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -7,7 +7,12 @@ * Copyright (C) 2005 Broadcom Corporation. * * Firmware is: - * Copyright (C) 2000-2003 Broadcom Corporation. + * Derived from proprietary unpublished source code, + * Copyright (C) 2000-2003 Broadcom Corporation. + * + * Permission is hereby granted for the distribution of this firmware + * data in hexadecimal or equivalent format, provided this copyright + * notice is accompanying it. */ #include -- cgit v1.2.3-70-g09d2 From 9ba27794197a18168b99ccecfb7b799f18b64426 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Mon, 6 Jun 2005 15:16:20 -0700 Subject: [TG3] Fix link failure in 5701 On some 5701 devices with older bootcode, the LED configuration bits in SRAM may be invalid with value zero. The fix is to check for invalid bits (0) and default to PHY 1 mode. Incorrect LED mode will lead to error in programming the PHY. Thanks to Grant Grundler for debugging the problem. >From Grant: | In May, 2004, tg3 v3.4 changed how MAC_LED_CTRL (0x40c) was getting | programmed and how to determine what to program into LED_CTRL. The new | code trusted NIC_SRAM_DATA_CFG (0x00000b58) to indicate what to write | to LED_CTRL and MII EXT_CTRL registers. On "IOX Core Lan", SRAM was | saying MODE_MAC (0x0) and that doesn't work. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index d2050133930..6315564d2dc 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -8560,6 +8560,16 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp) case NIC_SRAM_DATA_CFG_LED_MODE_MAC: tp->led_ctrl = LED_CTRL_MODE_MAC; + + /* Default to PHY_1_MODE if 0 (MAC_MODE) is + * read on some older 5700/5701 bootcode. + */ + if (GET_ASIC_REV(tp->pci_chip_rev_id) == + ASIC_REV_5700 || + GET_ASIC_REV(tp->pci_chip_rev_id) == + ASIC_REV_5701) + tp->led_ctrl = LED_CTRL_MODE_PHY_1; + break; case SHASTA_EXT_LED_SHARED: -- cgit v1.2.3-70-g09d2 From 15def7bfb6902aa2b2bc67059f26d696fb27c235 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 6 Jun 2005 15:22:56 -0700 Subject: [TG3]: Update driver version and release date. Signed-off-by: David S. Miller --- drivers/net/tg3.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 6315564d2dc..e944aac258e 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -66,8 +66,8 @@ #define DRV_MODULE_NAME "tg3" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "3.29" -#define DRV_MODULE_RELDATE "May 23, 2005" +#define DRV_MODULE_VERSION "3.30" +#define DRV_MODULE_RELDATE "June 6, 2005" #define TG3_DEF_MAC_MODE 0 #define TG3_DEF_RX_MODE 0 -- cgit v1.2.3-70-g09d2 From 74262de5d15fe0cab9e6fe75655a502d3c90acca Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Mon, 6 Jun 2005 15:50:08 -0700 Subject: [PATCH] ppc32: add to On ppc32, uses __user, but doesn't directly include . This adds that in. Without this, glibc will not compile. Signed-off-by: Tom Rini Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-ppc/sigcontext.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/asm-ppc/sigcontext.h b/include/asm-ppc/sigcontext.h index f82dcccdee1..b7a417e0a92 100644 --- a/include/asm-ppc/sigcontext.h +++ b/include/asm-ppc/sigcontext.h @@ -2,7 +2,7 @@ #define _ASM_PPC_SIGCONTEXT_H #include - +#include struct sigcontext { unsigned long _unused[4]; -- cgit v1.2.3-70-g09d2 From 3f5948fa2cbbda1261eec9a39ef3004b3caf73fb Mon Sep 17 00:00:00 2001 From: David Mosberger Date: Mon, 6 Jun 2005 15:50:09 -0700 Subject: [PATCH] Include before testing CONFIG_ACPI I'm not sure why this issue is suddenly showing, but without this patchlet, the zx1 config won't compile anymore (e.g., to see the compilation-error, look for "***" in [1]). [1] http://www.gelato.unsw.edu.au/kerncomp/results//2005-06-06-17-00/zx1_defconfig-log.html Signed-off-by: David Mosberger-Tang Cc: "Brown, Len" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/acpi.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/acpi.h b/include/linux/acpi.h index d5a55bdb9c3..b123cc08773 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -25,6 +25,8 @@ #ifndef _LINUX_ACPI_H #define _LINUX_ACPI_H +#include + #ifdef CONFIG_ACPI #ifndef _LINUX -- cgit v1.2.3-70-g09d2 From d0de98fa16169562bd74913c6c9b3857f9065c79 Mon Sep 17 00:00:00 2001 From: Alan Hourihane Date: Tue, 31 May 2005 19:50:49 +0100 Subject: [PATCH] i945G patch for agpgart Attached is a small patch for i945G support against 2.6.11.11. From: Alan Hourihane Signed-off-by: Dave Jones --- drivers/char/agp/intel-agp.c | 15 +++++++++++++-- include/linux/pci_ids.h | 2 ++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index 8c7d727432b..6a5047e0d33 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c @@ -418,7 +418,8 @@ static void intel_i830_init_gtt_entries(void) case I915_GMCH_GMS_STOLEN_48M: /* Check it's really I915G */ if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915G_HB || - agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB) + agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB || + agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB) gtt_entries = MB(48) - KB(size); else gtt_entries = 0; @@ -426,7 +427,8 @@ static void intel_i830_init_gtt_entries(void) case I915_GMCH_GMS_STOLEN_64M: /* Check it's really I915G */ if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915G_HB || - agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB) + agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB || + agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB) gtt_entries = MB(64) - KB(size); else gtt_entries = 0; @@ -1662,6 +1664,14 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev, } name = "915GM"; break; + case PCI_DEVICE_ID_INTEL_82945G_HB: + if (find_i830(PCI_DEVICE_ID_INTEL_82945G_IG)) { + bridge->driver = &intel_915_driver; + } else { + bridge->driver = &intel_845_driver; + } + name = "945G"; + break; case PCI_DEVICE_ID_INTEL_7505_0: bridge->driver = &intel_7505_driver; name = "E7505"; @@ -1801,6 +1811,7 @@ static struct pci_device_id agp_intel_pci_table[] = { ID(PCI_DEVICE_ID_INTEL_7205_0), ID(PCI_DEVICE_ID_INTEL_82915G_HB), ID(PCI_DEVICE_ID_INTEL_82915GM_HB), + ID(PCI_DEVICE_ID_INTEL_82945G_HB), { } }; diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index b0d6134e1ee..18f734ec918 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2382,6 +2382,8 @@ #define PCI_DEVICE_ID_INTEL_82915G_IG 0x2582 #define PCI_DEVICE_ID_INTEL_82915GM_HB 0x2590 #define PCI_DEVICE_ID_INTEL_82915GM_IG 0x2592 +#define PCI_DEVICE_ID_INTEL_82945G_HB 0x2770 +#define PCI_DEVICE_ID_INTEL_82945G_IG 0x2772 #define PCI_DEVICE_ID_INTEL_ICH6_0 0x2640 #define PCI_DEVICE_ID_INTEL_ICH6_1 0x2641 #define PCI_DEVICE_ID_INTEL_ICH6_2 0x2642 -- cgit v1.2.3-70-g09d2 From e29b545cb153f230fbd8ff4c19bc98ab950f9f5c Mon Sep 17 00:00:00 2001 From: Michael Werner Date: Sun, 27 Mar 2005 22:08:42 -0800 Subject: [PATCH] sgi-agp: fixes a problem with accessing GART memory in sgi_tioca_insert_memory and sgi_tioca_remove_memory This patch fixes a problem with accessing GART memory in sgi_tioca_insert_memory and sgi_tioca_remove_memory. sgi-agp.c | 12 +++++++++--- 1 files changed, 9 insertions(+), 3 deletions(-) Signed-off-by: Mike Werner Signed-off-by: Dave Jones --- drivers/char/agp/sgi-agp.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/char/agp/sgi-agp.c b/drivers/char/agp/sgi-agp.c index 4b3eda26797..d3aa159c9de 100644 --- a/drivers/char/agp/sgi-agp.c +++ b/drivers/char/agp/sgi-agp.c @@ -133,11 +133,14 @@ static int sgi_tioca_insert_memory(struct agp_memory *mem, off_t pg_start, off_t j; void *temp; struct agp_bridge_data *bridge; + u64 *table; bridge = mem->bridge; if (!bridge) return -EINVAL; + table = (u64 *)bridge->gatt_table; + temp = bridge->current_size; switch (bridge->driver->size_type) { @@ -175,7 +178,7 @@ static int sgi_tioca_insert_memory(struct agp_memory *mem, off_t pg_start, j = pg_start; while (j < (pg_start + mem->page_count)) { - if (*(bridge->gatt_table + j)) + if (table[j]) return -EBUSY; j++; } @@ -186,7 +189,7 @@ static int sgi_tioca_insert_memory(struct agp_memory *mem, off_t pg_start, } for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { - *(bridge->gatt_table + j) = + table[j] = bridge->driver->mask_memory(bridge, mem->memory[i], mem->type); } @@ -200,6 +203,7 @@ static int sgi_tioca_remove_memory(struct agp_memory *mem, off_t pg_start, { size_t i; struct agp_bridge_data *bridge; + u64 *table; bridge = mem->bridge; if (!bridge) @@ -209,8 +213,10 @@ static int sgi_tioca_remove_memory(struct agp_memory *mem, off_t pg_start, return -EINVAL; } + table = (u64 *)bridge->gatt_table; + for (i = pg_start; i < (mem->page_count + pg_start); i++) { - *(bridge->gatt_table + i) = 0; + table[i] = 0; } bridge->driver->tlb_flush(mem); -- cgit v1.2.3-70-g09d2 From 07eee78ea8ba2d0b7b20551c35a3e7dd158d50bb Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Wed, 30 Mar 2005 13:17:04 -0800 Subject: [PATCH] AGP fix for Xen VMM When Linux is running on the Xen virtual machine monitor, physical addresses are virtualised and cannot be directly referenced by the AGP GART. This patch fixes the GART driver for Xen by adding a layer of abstraction between physical addresses and 'GART addresses'. Architecture-specific functions are also defined for allocating and freeing the GATT. Xen requires this to ensure that table really is contiguous from the point of view of the GART. These extra interface functions are defined as 'no-ops' for all existing architectures that use the GART driver. Signed-off-by: Keir Fraser Signed-off-by: Andrew Morton Signed-off-by: Dave Jones --- drivers/char/agp/agp.h | 2 ++ drivers/char/agp/ali-agp.c | 4 ++-- drivers/char/agp/amd-k7-agp.c | 6 +++--- drivers/char/agp/amd64-agp.c | 4 ++-- drivers/char/agp/ati-agp.c | 6 +++--- drivers/char/agp/backend.c | 6 +++--- drivers/char/agp/efficeon-agp.c | 2 +- drivers/char/agp/generic.c | 17 ++++++++--------- drivers/char/agp/hp-agp.c | 4 ++-- drivers/char/agp/i460-agp.c | 4 ++-- drivers/char/agp/intel-agp.c | 6 +++--- drivers/char/agp/sworks-agp.c | 8 ++++---- drivers/char/agp/uninorth-agp.c | 2 +- include/asm-alpha/agp.h | 10 ++++++++++ include/asm-i386/agp.h | 10 ++++++++++ include/asm-ia64/agp.h | 10 ++++++++++ include/asm-ppc/agp.h | 10 ++++++++++ include/asm-ppc64/agp.h | 10 ++++++++++ include/asm-sparc64/agp.h | 10 ++++++++++ include/asm-x86_64/agp.h | 10 ++++++++++ 20 files changed, 106 insertions(+), 35 deletions(-) diff --git a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h index ad9c11391d8..c1fe013c64f 100644 --- a/drivers/char/agp/agp.h +++ b/drivers/char/agp/agp.h @@ -278,6 +278,8 @@ void agp3_generic_cleanup(void); #define AGP_GENERIC_SIZES_ENTRIES 11 extern struct aper_size_info_16 agp3_generic_sizes[]; +#define virt_to_gart(x) (phys_to_gart(virt_to_phys(x))) +#define gart_to_virt(x) (phys_to_virt(gart_to_phys(x))) extern int agp_off; extern int agp_try_unsupported_boot; diff --git a/drivers/char/agp/ali-agp.c b/drivers/char/agp/ali-agp.c index 0212febda65..9c9c9c2247c 100644 --- a/drivers/char/agp/ali-agp.c +++ b/drivers/char/agp/ali-agp.c @@ -150,7 +150,7 @@ static void *m1541_alloc_page(struct agp_bridge_data *bridge) pci_read_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, &temp); pci_write_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, (((temp & ALI_CACHE_FLUSH_ADDR_MASK) | - virt_to_phys(addr)) | ALI_CACHE_FLUSH_EN )); + virt_to_gart(addr)) | ALI_CACHE_FLUSH_EN )); return addr; } @@ -174,7 +174,7 @@ static void m1541_destroy_page(void * addr) pci_read_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, &temp); pci_write_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, (((temp & ALI_CACHE_FLUSH_ADDR_MASK) | - virt_to_phys(addr)) | ALI_CACHE_FLUSH_EN)); + virt_to_gart(addr)) | ALI_CACHE_FLUSH_EN)); agp_generic_destroy_page(addr); } diff --git a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c index e62a3c2c44a..3a41672e4d6 100644 --- a/drivers/char/agp/amd-k7-agp.c +++ b/drivers/char/agp/amd-k7-agp.c @@ -43,7 +43,7 @@ static int amd_create_page_map(struct amd_page_map *page_map) SetPageReserved(virt_to_page(page_map->real)); global_cache_flush(); - page_map->remapped = ioremap_nocache(virt_to_phys(page_map->real), + page_map->remapped = ioremap_nocache(virt_to_gart(page_map->real), PAGE_SIZE); if (page_map->remapped == NULL) { ClearPageReserved(virt_to_page(page_map->real)); @@ -154,7 +154,7 @@ static int amd_create_gatt_table(struct agp_bridge_data *bridge) agp_bridge->gatt_table_real = (u32 *)page_dir.real; agp_bridge->gatt_table = (u32 __iomem *)page_dir.remapped; - agp_bridge->gatt_bus_addr = virt_to_phys(page_dir.real); + agp_bridge->gatt_bus_addr = virt_to_gart(page_dir.real); /* Get the address for the gart region. * This is a bus address even on the alpha, b/c its @@ -167,7 +167,7 @@ static int amd_create_gatt_table(struct agp_bridge_data *bridge) /* Calculate the agp offset */ for (i = 0; i < value->num_entries / 1024; i++, addr += 0x00400000) { - writel(virt_to_phys(amd_irongate_private.gatt_pages[i]->real) | 1, + writel(virt_to_gart(amd_irongate_private.gatt_pages[i]->real) | 1, page_dir.remapped+GET_PAGE_DIR_OFF(addr)); readl(page_dir.remapped+GET_PAGE_DIR_OFF(addr)); /* PCI Posting. */ } diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c index 399c042f68f..1407945a589 100644 --- a/drivers/char/agp/amd64-agp.c +++ b/drivers/char/agp/amd64-agp.c @@ -219,7 +219,7 @@ static struct aper_size_info_32 amd_8151_sizes[7] = static int amd_8151_configure(void) { - unsigned long gatt_bus = virt_to_phys(agp_bridge->gatt_table_real); + unsigned long gatt_bus = virt_to_gart(agp_bridge->gatt_table_real); /* Configure AGP regs in each x86-64 host bridge. */ for_each_nb() { @@ -591,7 +591,7 @@ static void __devexit agp_amd64_remove(struct pci_dev *pdev) { struct agp_bridge_data *bridge = pci_get_drvdata(pdev); - release_mem_region(virt_to_phys(bridge->gatt_table_real), + release_mem_region(virt_to_gart(bridge->gatt_table_real), amd64_aperture_sizes[bridge->aperture_size_idx].size); agp_remove_bridge(bridge); agp_put_bridge(bridge); diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c index a65f8827c28..e572ced9100 100644 --- a/drivers/char/agp/ati-agp.c +++ b/drivers/char/agp/ati-agp.c @@ -61,7 +61,7 @@ static int ati_create_page_map(ati_page_map *page_map) SetPageReserved(virt_to_page(page_map->real)); err = map_page_into_agp(virt_to_page(page_map->real)); - page_map->remapped = ioremap_nocache(virt_to_phys(page_map->real), + page_map->remapped = ioremap_nocache(virt_to_gart(page_map->real), PAGE_SIZE); if (page_map->remapped == NULL || err) { ClearPageReserved(virt_to_page(page_map->real)); @@ -343,7 +343,7 @@ static int ati_create_gatt_table(struct agp_bridge_data *bridge) agp_bridge->gatt_table_real = (u32 *)page_dir.real; agp_bridge->gatt_table = (u32 __iomem *) page_dir.remapped; - agp_bridge->gatt_bus_addr = virt_to_bus(page_dir.real); + agp_bridge->gatt_bus_addr = virt_to_gart(page_dir.real); /* Write out the size register */ current_size = A_SIZE_LVL2(agp_bridge->current_size); @@ -373,7 +373,7 @@ static int ati_create_gatt_table(struct agp_bridge_data *bridge) /* Calculate the agp offset */ for(i = 0; i < value->num_entries / 1024; i++, addr += 0x00400000) { - writel(virt_to_bus(ati_generic_private.gatt_pages[i]->real) | 1, + writel(virt_to_gart(ati_generic_private.gatt_pages[i]->real) | 1, page_dir.remapped+GET_PAGE_DIR_OFF(addr)); readl(page_dir.remapped+GET_PAGE_DIR_OFF(addr)); /* PCI Posting. */ } diff --git a/drivers/char/agp/backend.c b/drivers/char/agp/backend.c index 2f3dfb63bdc..4d4e602fdc7 100644 --- a/drivers/char/agp/backend.c +++ b/drivers/char/agp/backend.c @@ -148,7 +148,7 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge) return -ENOMEM; } - bridge->scratch_page_real = virt_to_phys(addr); + bridge->scratch_page_real = virt_to_gart(addr); bridge->scratch_page = bridge->driver->mask_memory(bridge, bridge->scratch_page_real, 0); } @@ -189,7 +189,7 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge) err_out: if (bridge->driver->needs_scratch_page) bridge->driver->agp_destroy_page( - phys_to_virt(bridge->scratch_page_real)); + gart_to_virt(bridge->scratch_page_real)); if (got_gatt) bridge->driver->free_gatt_table(bridge); if (got_keylist) { @@ -214,7 +214,7 @@ static void agp_backend_cleanup(struct agp_bridge_data *bridge) if (bridge->driver->agp_destroy_page && bridge->driver->needs_scratch_page) bridge->driver->agp_destroy_page( - phys_to_virt(bridge->scratch_page_real)); + gart_to_virt(bridge->scratch_page_real)); } /* When we remove the global variable agp_bridge from all drivers diff --git a/drivers/char/agp/efficeon-agp.c b/drivers/char/agp/efficeon-agp.c index 1383c3165ea..ac19fdcd21c 100644 --- a/drivers/char/agp/efficeon-agp.c +++ b/drivers/char/agp/efficeon-agp.c @@ -219,7 +219,7 @@ static int efficeon_create_gatt_table(struct agp_bridge_data *bridge) efficeon_private.l1_table[index] = page; - value = __pa(page) | pati | present | index; + value = virt_to_gart(page) | pati | present | index; pci_write_config_dword(agp_bridge->dev, EFFICEON_ATTPAGE, value); diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c index c321a924e38..d62505b5d25 100644 --- a/drivers/char/agp/generic.c +++ b/drivers/char/agp/generic.c @@ -153,7 +153,7 @@ void agp_free_memory(struct agp_memory *curr) } if (curr->page_count != 0) { for (i = 0; i < curr->page_count; i++) { - curr->bridge->driver->agp_destroy_page(phys_to_virt(curr->memory[i])); + curr->bridge->driver->agp_destroy_page(gart_to_virt(curr->memory[i])); } } agp_free_key(curr->key); @@ -209,7 +209,7 @@ struct agp_memory *agp_allocate_memory(struct agp_bridge_data *bridge, agp_free_memory(new); return NULL; } - new->memory[i] = virt_to_phys(addr); + new->memory[i] = virt_to_gart(addr); new->page_count++; } new->bridge = bridge; @@ -806,8 +806,7 @@ int agp_generic_create_gatt_table(struct agp_bridge_data *bridge) break; } - table = (char *) __get_free_pages(GFP_KERNEL, - page_order); + table = alloc_gatt_pages(page_order); if (table == NULL) { i++; @@ -838,7 +837,7 @@ int agp_generic_create_gatt_table(struct agp_bridge_data *bridge) size = ((struct aper_size_info_fixed *) temp)->size; page_order = ((struct aper_size_info_fixed *) temp)->page_order; num_entries = ((struct aper_size_info_fixed *) temp)->num_entries; - table = (char *) __get_free_pages(GFP_KERNEL, page_order); + table = alloc_gatt_pages(page_order); } if (table == NULL) @@ -853,7 +852,7 @@ int agp_generic_create_gatt_table(struct agp_bridge_data *bridge) agp_gatt_table = (void *)table; bridge->driver->cache_flush(); - bridge->gatt_table = ioremap_nocache(virt_to_phys(table), + bridge->gatt_table = ioremap_nocache(virt_to_gart(table), (PAGE_SIZE * (1 << page_order))); bridge->driver->cache_flush(); @@ -861,11 +860,11 @@ int agp_generic_create_gatt_table(struct agp_bridge_data *bridge) for (page = virt_to_page(table); page <= virt_to_page(table_end); page++) ClearPageReserved(page); - free_pages((unsigned long) table, page_order); + free_gatt_pages(table, page_order); return -ENOMEM; } - bridge->gatt_bus_addr = virt_to_phys(bridge->gatt_table_real); + bridge->gatt_bus_addr = virt_to_gart(bridge->gatt_table_real); /* AK: bogus, should encode addresses > 4GB */ for (i = 0; i < num_entries; i++) { @@ -919,7 +918,7 @@ int agp_generic_free_gatt_table(struct agp_bridge_data *bridge) for (page = virt_to_page(table); page <= virt_to_page(table_end); page++) ClearPageReserved(page); - free_pages((unsigned long) bridge->gatt_table_real, page_order); + free_gatt_pages(bridge->gatt_table_real, page_order); agp_gatt_table = NULL; bridge->gatt_table = NULL; diff --git a/drivers/char/agp/hp-agp.c b/drivers/char/agp/hp-agp.c index 6052bfa04c7..99762b6c19a 100644 --- a/drivers/char/agp/hp-agp.c +++ b/drivers/char/agp/hp-agp.c @@ -110,7 +110,7 @@ static int __init hp_zx1_ioc_shared(void) hp->gart_size = HP_ZX1_GART_SIZE; hp->gatt_entries = hp->gart_size / hp->io_page_size; - hp->io_pdir = phys_to_virt(readq(hp->ioc_regs+HP_ZX1_PDIR_BASE)); + hp->io_pdir = gart_to_virt(readq(hp->ioc_regs+HP_ZX1_PDIR_BASE)); hp->gatt = &hp->io_pdir[HP_ZX1_IOVA_TO_PDIR(hp->gart_base)]; if (hp->gatt[0] != HP_ZX1_SBA_IOMMU_COOKIE) { @@ -248,7 +248,7 @@ hp_zx1_configure (void) agp_bridge->mode = readl(hp->lba_regs+hp->lba_cap_offset+PCI_AGP_STATUS); if (hp->io_pdir_owner) { - writel(virt_to_phys(hp->io_pdir), hp->ioc_regs+HP_ZX1_PDIR_BASE); + writel(virt_to_gart(hp->io_pdir), hp->ioc_regs+HP_ZX1_PDIR_BASE); readl(hp->ioc_regs+HP_ZX1_PDIR_BASE); writel(hp->io_tlb_ps, hp->ioc_regs+HP_ZX1_TCNFG); readl(hp->ioc_regs+HP_ZX1_TCNFG); diff --git a/drivers/char/agp/i460-agp.c b/drivers/char/agp/i460-agp.c index adbea896c0d..94943298c03 100644 --- a/drivers/char/agp/i460-agp.c +++ b/drivers/char/agp/i460-agp.c @@ -372,7 +372,7 @@ static int i460_alloc_large_page (struct lp_desc *lp) } memset(lp->alloced_map, 0, map_size); - lp->paddr = virt_to_phys(lpage); + lp->paddr = virt_to_gart(lpage); lp->refcount = 0; atomic_add(I460_KPAGES_PER_IOPAGE, &agp_bridge->current_memory_agp); return 0; @@ -383,7 +383,7 @@ static void i460_free_large_page (struct lp_desc *lp) kfree(lp->alloced_map); lp->alloced_map = NULL; - free_pages((unsigned long) phys_to_virt(lp->paddr), I460_IO_PAGE_SHIFT - PAGE_SHIFT); + free_pages((unsigned long) gart_to_virt(lp->paddr), I460_IO_PAGE_SHIFT - PAGE_SHIFT); atomic_sub(I460_KPAGES_PER_IOPAGE, &agp_bridge->current_memory_agp); } diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index 6a5047e0d33..51266d6b4d7 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c @@ -286,7 +286,7 @@ static struct agp_memory *alloc_agpphysmem_i8xx(size_t pg_count, int type) if (new == NULL) return NULL; - new->memory[0] = virt_to_phys(addr); + new->memory[0] = virt_to_gart(addr); if (pg_count == 4) { /* kludge to get 4 physical pages for ARGB cursor */ new->memory[1] = new->memory[0] + PAGE_SIZE; @@ -329,10 +329,10 @@ static void intel_i810_free_by_type(struct agp_memory *curr) agp_free_key(curr->key); if(curr->type == AGP_PHYS_MEMORY) { if (curr->page_count == 4) - i8xx_destroy_pages(phys_to_virt(curr->memory[0])); + i8xx_destroy_pages(gart_to_virt(curr->memory[0])); else agp_bridge->driver->agp_destroy_page( - phys_to_virt(curr->memory[0])); + gart_to_virt(curr->memory[0])); vfree(curr->memory); } kfree(curr); diff --git a/drivers/char/agp/sworks-agp.c b/drivers/char/agp/sworks-agp.c index 10c23302dd8..a9fb12c20eb 100644 --- a/drivers/char/agp/sworks-agp.c +++ b/drivers/char/agp/sworks-agp.c @@ -51,7 +51,7 @@ static int serverworks_create_page_map(struct serverworks_page_map *page_map) } SetPageReserved(virt_to_page(page_map->real)); global_cache_flush(); - page_map->remapped = ioremap_nocache(virt_to_phys(page_map->real), + page_map->remapped = ioremap_nocache(virt_to_gart(page_map->real), PAGE_SIZE); if (page_map->remapped == NULL) { ClearPageReserved(virt_to_page(page_map->real)); @@ -162,7 +162,7 @@ static int serverworks_create_gatt_table(struct agp_bridge_data *bridge) /* Create a fake scratch directory */ for(i = 0; i < 1024; i++) { writel(agp_bridge->scratch_page, serverworks_private.scratch_dir.remapped+i); - writel(virt_to_phys(serverworks_private.scratch_dir.real) | 1, page_dir.remapped+i); + writel(virt_to_gart(serverworks_private.scratch_dir.real) | 1, page_dir.remapped+i); } retval = serverworks_create_gatt_pages(value->num_entries / 1024); @@ -174,7 +174,7 @@ static int serverworks_create_gatt_table(struct agp_bridge_data *bridge) agp_bridge->gatt_table_real = (u32 *)page_dir.real; agp_bridge->gatt_table = (u32 __iomem *)page_dir.remapped; - agp_bridge->gatt_bus_addr = virt_to_phys(page_dir.real); + agp_bridge->gatt_bus_addr = virt_to_gart(page_dir.real); /* Get the address for the gart region. * This is a bus address even on the alpha, b/c its @@ -187,7 +187,7 @@ static int serverworks_create_gatt_table(struct agp_bridge_data *bridge) /* Calculate the agp offset */ for(i = 0; i < value->num_entries / 1024; i++) - writel(virt_to_phys(serverworks_private.gatt_pages[i]->real)|1, page_dir.remapped+i); + writel(virt_to_gart(serverworks_private.gatt_pages[i]->real)|1, page_dir.remapped+i); return 0; } diff --git a/drivers/char/agp/uninorth-agp.c b/drivers/char/agp/uninorth-agp.c index a673971f2a9..c8255312b8c 100644 --- a/drivers/char/agp/uninorth-agp.c +++ b/drivers/char/agp/uninorth-agp.c @@ -407,7 +407,7 @@ static int uninorth_create_gatt_table(struct agp_bridge_data *bridge) bridge->gatt_table_real = (u32 *) table; bridge->gatt_table = (u32 *)table; - bridge->gatt_bus_addr = virt_to_phys(table); + bridge->gatt_bus_addr = virt_to_gart(table); for (i = 0; i < num_entries; i++) bridge->gatt_table[i] = 0; diff --git a/include/asm-alpha/agp.h b/include/asm-alpha/agp.h index c99dbbb5bcb..ef855a3bc0f 100644 --- a/include/asm-alpha/agp.h +++ b/include/asm-alpha/agp.h @@ -10,4 +10,14 @@ #define flush_agp_mappings() #define flush_agp_cache() mb() +/* Convert a physical address to an address suitable for the GART. */ +#define phys_to_gart(x) (x) +#define gart_to_phys(x) (x) + +/* GATT allocation. Returns/accepts GATT kernel virtual address. */ +#define alloc_gatt_pages(order) \ + ((char *)__get_free_pages(GFP_KERNEL, (order))) +#define free_gatt_pages(table, order) \ + free_pages((unsigned long)(table), (order)) + #endif diff --git a/include/asm-i386/agp.h b/include/asm-i386/agp.h index a917ff50354..b82f5f3ab88 100644 --- a/include/asm-i386/agp.h +++ b/include/asm-i386/agp.h @@ -21,4 +21,14 @@ int unmap_page_from_agp(struct page *page); worth it. Would need a page for it. */ #define flush_agp_cache() asm volatile("wbinvd":::"memory") +/* Convert a physical address to an address suitable for the GART. */ +#define phys_to_gart(x) (x) +#define gart_to_phys(x) (x) + +/* GATT allocation. Returns/accepts GATT kernel virtual address. */ +#define alloc_gatt_pages(order) \ + ((char *)__get_free_pages(GFP_KERNEL, (order))) +#define free_gatt_pages(table, order) \ + free_pages((unsigned long)(table), (order)) + #endif diff --git a/include/asm-ia64/agp.h b/include/asm-ia64/agp.h index d1316f1e6ee..4e517f0e6af 100644 --- a/include/asm-ia64/agp.h +++ b/include/asm-ia64/agp.h @@ -18,4 +18,14 @@ #define flush_agp_mappings() /* nothing */ #define flush_agp_cache() mb() +/* Convert a physical address to an address suitable for the GART. */ +#define phys_to_gart(x) (x) +#define gart_to_phys(x) (x) + +/* GATT allocation. Returns/accepts GATT kernel virtual address. */ +#define alloc_gatt_pages(order) \ + ((char *)__get_free_pages(GFP_KERNEL, (order))) +#define free_gatt_pages(table, order) \ + free_pages((unsigned long)(table), (order)) + #endif /* _ASM_IA64_AGP_H */ diff --git a/include/asm-ppc/agp.h b/include/asm-ppc/agp.h index be27cfa8c5b..ca9e423307f 100644 --- a/include/asm-ppc/agp.h +++ b/include/asm-ppc/agp.h @@ -10,4 +10,14 @@ #define flush_agp_mappings() #define flush_agp_cache() mb() +/* Convert a physical address to an address suitable for the GART. */ +#define phys_to_gart(x) (x) +#define gart_to_phys(x) (x) + +/* GATT allocation. Returns/accepts GATT kernel virtual address. */ +#define alloc_gatt_pages(order) \ + ((char *)__get_free_pages(GFP_KERNEL, (order))) +#define free_gatt_pages(table, order) \ + free_pages((unsigned long)(table), (order)) + #endif diff --git a/include/asm-ppc64/agp.h b/include/asm-ppc64/agp.h index be27cfa8c5b..ca9e423307f 100644 --- a/include/asm-ppc64/agp.h +++ b/include/asm-ppc64/agp.h @@ -10,4 +10,14 @@ #define flush_agp_mappings() #define flush_agp_cache() mb() +/* Convert a physical address to an address suitable for the GART. */ +#define phys_to_gart(x) (x) +#define gart_to_phys(x) (x) + +/* GATT allocation. Returns/accepts GATT kernel virtual address. */ +#define alloc_gatt_pages(order) \ + ((char *)__get_free_pages(GFP_KERNEL, (order))) +#define free_gatt_pages(table, order) \ + free_pages((unsigned long)(table), (order)) + #endif diff --git a/include/asm-sparc64/agp.h b/include/asm-sparc64/agp.h index ba05bdf9a21..58f8cb6ae76 100644 --- a/include/asm-sparc64/agp.h +++ b/include/asm-sparc64/agp.h @@ -8,4 +8,14 @@ #define flush_agp_mappings() #define flush_agp_cache() mb() +/* Convert a physical address to an address suitable for the GART. */ +#define phys_to_gart(x) (x) +#define gart_to_phys(x) (x) + +/* GATT allocation. Returns/accepts GATT kernel virtual address. */ +#define alloc_gatt_pages(order) \ + ((char *)__get_free_pages(GFP_KERNEL, (order))) +#define free_gatt_pages(table, order) \ + free_pages((unsigned long)(table), (order)) + #endif diff --git a/include/asm-x86_64/agp.h b/include/asm-x86_64/agp.h index 0bb9019d58a..06c52ee9c06 100644 --- a/include/asm-x86_64/agp.h +++ b/include/asm-x86_64/agp.h @@ -19,4 +19,14 @@ int unmap_page_from_agp(struct page *page); worth it. Would need a page for it. */ #define flush_agp_cache() asm volatile("wbinvd":::"memory") +/* Convert a physical address to an address suitable for the GART. */ +#define phys_to_gart(x) (x) +#define gart_to_phys(x) (x) + +/* GATT allocation. Returns/accepts GATT kernel virtual address. */ +#define alloc_gatt_pages(order) \ + ((char *)__get_free_pages(GFP_KERNEL, (order))) +#define free_gatt_pages(table, order) \ + free_pages((unsigned long)(table), (order)) + #endif -- cgit v1.2.3-70-g09d2 From 66bb8bf8b235ba4d37fda14375827864977c6a3e Mon Sep 17 00:00:00 2001 From: David Mosberger Date: Mon, 4 Apr 2005 13:29:43 -0700 Subject: [PATCH] Replace check_bridge_mode() with (bridge->mode & AGSTAT_MODE_3_0). [AGPGART] Replace check_bridge_mode() with (bridge->mode & AGSTAT_MODE_3_0). As mentioned earlier, the current check_bridge_mode() code assumes that AGP bridges are PCI devices. This isn't always true. Definitely not for HP zx1 chipset and the same seems to be the case for SGI's AGP bridge. The patch below fixes the problem by picking up the AGP_MODE_3_0 bit from bridge->mode. I feel like I may be missing something, since I can't see any reason why check_bridge_mode() wasn't doing that in the first place. According to the AGP 3.0 specs, the AGP_MODE_3_0 bit is determined during the hardware reset and cannot be changed, so it seems to me it should be safe to pick it up from bridge->mode. With the patch applied, I can definitely use AGP acceleration both with AGP 2.0 and AGP 3.0 (one with an Nvidia card, the other with an ATI FireGL card). Unless someone spots a problem, please apply this patch so 3d acceleration can work on zx1 boxes again. This makes AGP work again on machines with an AGP bridge that isn't a PCI device. Signed-off-by: David Mosberger-Tang Signed-off-by: Dave Jones --- drivers/char/agp/generic.c | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c index d62505b5d25..f0079e991bd 100644 --- a/drivers/char/agp/generic.c +++ b/drivers/char/agp/generic.c @@ -295,19 +295,6 @@ int agp_num_entries(void) EXPORT_SYMBOL_GPL(agp_num_entries); -static int check_bridge_mode(struct pci_dev *dev) -{ - u32 agp3; - u8 cap_ptr; - - cap_ptr = pci_find_capability(dev, PCI_CAP_ID_AGP); - pci_read_config_dword(dev, cap_ptr+AGPSTAT, &agp3); - if (agp3 & AGPSTAT_MODE_3_0) - return 1; - return 0; -} - - /** * agp_copy_info - copy bridge state information * @@ -328,7 +315,7 @@ int agp_copy_info(struct agp_bridge_data *bridge, struct agp_kern_info *info) info->version.minor = bridge->version->minor; info->chipset = SUPPORTED; info->device = bridge->dev; - if (check_bridge_mode(bridge->dev)) + if (bridge->mode & AGPSTAT_MODE_3_0) info->mode = bridge->mode & ~AGP3_RESERVED_MASK; else info->mode = bridge->mode & ~AGP2_RESERVED_MASK; @@ -661,7 +648,7 @@ u32 agp_collect_device_status(struct agp_bridge_data *bridge, u32 requested_mode bridge_agpstat &= ~AGPSTAT_FW; /* Check to see if we are operating in 3.0 mode */ - if (check_bridge_mode(agp_bridge->dev)) + if (agp_bridge->mode & AGPSTAT_MODE_3_0) agp_v3_parse_one(&requested_mode, &bridge_agpstat, &vga_agpstat); else agp_v2_parse_one(&requested_mode, &bridge_agpstat, &vga_agpstat); @@ -732,7 +719,7 @@ void agp_generic_enable(struct agp_bridge_data *bridge, u32 requested_mode) /* Do AGP version specific frobbing. */ if (bridge->major_version >= 3) { - if (check_bridge_mode(bridge->dev)) { + if (bridge->mode & AGPSTAT_MODE_3_0) { /* If we have 3.5, we can do the isoch stuff. */ if (bridge->minor_version >= 5) agp_3_5_enable(bridge); -- cgit v1.2.3-70-g09d2 From eda9937656e0b9879ca521140fe61cbc9788c398 Mon Sep 17 00:00:00 2001 From: Matthew Dobson Date: Tue, 7 Jun 2005 13:22:05 -0700 Subject: [PATCH] send_IPI_mask_sequence() warning fix In file included from arch/i386/kernel/smp.c:235: include/asm-i386/mach-numaq/mach_ipi.h:4: warning: `send_IPI_mask_sequence' declared inline after its definition Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-i386/mach-numaq/mach_ipi.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/asm-i386/mach-numaq/mach_ipi.h b/include/asm-i386/mach-numaq/mach_ipi.h index 1b46fd3f2ae..c6044488e9e 100644 --- a/include/asm-i386/mach-numaq/mach_ipi.h +++ b/include/asm-i386/mach-numaq/mach_ipi.h @@ -1,7 +1,7 @@ #ifndef __ASM_MACH_IPI_H #define __ASM_MACH_IPI_H -inline void send_IPI_mask_sequence(cpumask_t, int vector); +void send_IPI_mask_sequence(cpumask_t, int vector); static inline void send_IPI_mask(cpumask_t mask, int vector) { -- cgit v1.2.3-70-g09d2 From ad95d6098dd1e94a09d2a1fdf39fd8281fcd8958 Mon Sep 17 00:00:00 2001 From: Eugene Surovegin Date: Tue, 7 Jun 2005 13:22:09 -0700 Subject: [PATCH] ppc32: add 405EP cpu_spec entry Add a definition for PPC 405EP which was lost somehow during 2.4 -> 2.6 transition. Recent change to arch/ppc/kernel/misc.S ("Fix incorrect CPU_FTR fixup usage for unified caches") triggered this bug and 405EP boards don't boot anymore. Signed-off-by: Eugene Surovegin Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc/kernel/cputable.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/arch/ppc/kernel/cputable.c b/arch/ppc/kernel/cputable.c index 8aa5e8c6900..d44b7dc5390 100644 --- a/arch/ppc/kernel/cputable.c +++ b/arch/ppc/kernel/cputable.c @@ -838,6 +838,17 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, }, + { /* 405EP */ + .pvr_mask = 0xffff0000, + .pvr_value = 0x51210000, + .cpu_name = "405EP", + .cpu_features = CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_USE_TB, + .cpu_user_features = PPC_FEATURE_32 | + PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, + .icache_bsize = 32, + .dcache_bsize = 32, + }, #endif /* CONFIG_40x */ #ifdef CONFIG_44x -- cgit v1.2.3-70-g09d2 From a86d1f4301fad4ff44c1f614c897000bc574ab2f Mon Sep 17 00:00:00 2001 From: Vojtech Pavlik Date: Tue, 7 Jun 2005 13:22:14 -0700 Subject: [PATCH] input: disable scroll feature on AT keyboards This patch disables the scroll feature on AT keyboards by default, because it causes the numbers of mouse devices to shift, breaking user setups. Signed-off-by: Vojtech Pavlik Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/input/keyboard/atkbd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index af0446c6de8..48fdf1e517c 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c @@ -54,7 +54,7 @@ static int atkbd_softraw = 1; module_param_named(softraw, atkbd_softraw, bool, 0); MODULE_PARM_DESC(softraw, "Use software generated rawmode"); -static int atkbd_scroll = 1; +static int atkbd_scroll = 0; module_param_named(scroll, atkbd_scroll, bool, 0); MODULE_PARM_DESC(scroll, "Enable scroll-wheel on MS Office and similar keyboards"); -- cgit v1.2.3-70-g09d2 From 93cffffa19960464a52f9c78d9a6150270d23785 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Tue, 7 Jun 2005 13:22:18 -0700 Subject: [PATCH] PCI: do VIA IRQ fixup always, not just in PIC mode At least some VIA chipsets require the fixup even in IO-APIC mode. This was found and debugged with the patient assistance of Stian Jordet on an Asus CUV266-DLS motherboard. Signed-off-by: Bjorn Helgaas Signed-off-by: Greg Kroah-Hartman Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/pci/quirks.c | 35 +++++++++++++---------------------- 1 file changed, 13 insertions(+), 22 deletions(-) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 637e9493034..2194669300b 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -459,17 +459,6 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_APIC, #endif /* CONFIG_X86_IO_APIC */ -/* - * Via 686A/B: The PCI_INTERRUPT_LINE register for the on-chip - * devices, USB0/1, AC97, MC97, and ACPI, has an unusual feature: - * when written, it makes an internal connection to the PIC. - * For these devices, this register is defined to be 4 bits wide. - * Normally this is fine. However for IO-APIC motherboards, or - * non-x86 architectures (yes Via exists on PPC among other places), - * we must mask the PCI_INTERRUPT_LINE value versus 0xf to get - * interrupts delivered properly. - */ - /* * FIXME: it is questionable that quirk_via_acpi * is needed. It shows up as an ISA bridge, and does not @@ -492,28 +481,30 @@ static void __devinit quirk_via_acpi(struct pci_dev *d) DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3, quirk_via_acpi ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_via_acpi ); -static void quirk_via_irqpic(struct pci_dev *dev) +/* + * Via 686A/B: The PCI_INTERRUPT_LINE register for the on-chip + * devices, USB0/1, AC97, MC97, and ACPI, has an unusual feature: + * when written, it makes an internal connection to the PIC. + * For these devices, this register is defined to be 4 bits wide. + * Normally this is fine. However for IO-APIC motherboards, or + * non-x86 architectures (yes Via exists on PPC among other places), + * we must mask the PCI_INTERRUPT_LINE value versus 0xf to get + * interrupts delivered properly. + */ +static void quirk_via_irq(struct pci_dev *dev) { u8 irq, new_irq; -#ifdef CONFIG_X86_IO_APIC - if (nr_ioapics && !skip_ioapic_setup) - return; -#endif -#ifdef CONFIG_ACPI - if (acpi_irq_model != ACPI_IRQ_MODEL_PIC) - return; -#endif new_irq = dev->irq & 0xf; pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq); if (new_irq != irq) { - printk(KERN_INFO "PCI: Via PIC IRQ fixup for %s, from %d to %d\n", + printk(KERN_INFO "PCI: Via IRQ fixup for %s, from %d to %d\n", pci_name(dev), irq, new_irq); udelay(15); /* unknown if delay really needed */ pci_write_config_byte(dev, PCI_INTERRUPT_LINE, new_irq); } } -DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_ANY_ID, quirk_via_irqpic); +DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_ANY_ID, quirk_via_irq); /* * PIIX3 USB: We have to disable USB interrupts that are -- cgit v1.2.3-70-g09d2 From 1d6757fbff5bc86e94e59ab0d7bdd7e71351d839 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Tue, 7 Jun 2005 18:37:01 -0400 Subject: [PATCH] NFS: Fix lookup intent handling We should never apply a lookup intent to anything other than the last path component in an open(), create() or access() call. Introduce the helper nfs_lookup_check_intent() which always returns zero if LOOKUP_CONTINUE or LOOKUP_PARENT are set, and returns the intent flags if we're on the last component of the lookup. By doing so, we fix a bug in open(O_EXCL), where we may end up optimizing away a real lookup of the parent directory. Problem noticed by Linda Dunaphant Signed-off-by: Trond Myklebust Signed-off-by: Linus Torvalds --- fs/nfs/dir.c | 49 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 14 deletions(-) diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 73f96acd5d3..ff6155f5e8d 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -528,19 +528,39 @@ static inline void nfs_renew_times(struct dentry * dentry) dentry->d_time = jiffies; } +/* + * Return the intent data that applies to this particular path component + * + * Note that the current set of intents only apply to the very last + * component of the path. + * We check for this using LOOKUP_CONTINUE and LOOKUP_PARENT. + */ +static inline unsigned int nfs_lookup_check_intent(struct nameidata *nd, unsigned int mask) +{ + if (nd->flags & (LOOKUP_CONTINUE|LOOKUP_PARENT)) + return 0; + return nd->flags & mask; +} + +/* + * Inode and filehandle revalidation for lookups. + * + * We force revalidation in the cases where the VFS sets LOOKUP_REVAL, + * or if the intent information indicates that we're about to open this + * particular file and the "nocto" mount flag is not set. + * + */ static inline int nfs_lookup_verify_inode(struct inode *inode, struct nameidata *nd) { struct nfs_server *server = NFS_SERVER(inode); if (nd != NULL) { - int ndflags = nd->flags; /* VFS wants an on-the-wire revalidation */ - if (ndflags & LOOKUP_REVAL) + if (nd->flags & LOOKUP_REVAL) goto out_force; /* This is an open(2) */ - if ((ndflags & LOOKUP_OPEN) && - !(ndflags & LOOKUP_CONTINUE) && + if (nfs_lookup_check_intent(nd, LOOKUP_OPEN) != 0 && !(server->flags & NFS_MOUNT_NOCTO)) goto out_force; } @@ -560,12 +580,8 @@ static inline int nfs_neg_need_reval(struct inode *dir, struct dentry *dentry, struct nameidata *nd) { - int ndflags = 0; - - if (nd) - ndflags = nd->flags; /* Don't revalidate a negative dentry if we're creating a new file */ - if ((ndflags & LOOKUP_CREATE) && !(ndflags & LOOKUP_CONTINUE)) + if (nd != NULL && nfs_lookup_check_intent(nd, LOOKUP_CREATE) != 0) return 0; return !nfs_check_verifier(dir, dentry); } @@ -700,12 +716,16 @@ struct dentry_operations nfs_dentry_operations = { .d_iput = nfs_dentry_iput, }; +/* + * Use intent information to check whether or not we're going to do + * an O_EXCL create using this path component. + */ static inline int nfs_is_exclusive_create(struct inode *dir, struct nameidata *nd) { if (NFS_PROTO(dir)->version == 2) return 0; - if (!nd || (nd->flags & LOOKUP_CONTINUE) || !(nd->flags & LOOKUP_CREATE)) + if (nd == NULL || nfs_lookup_check_intent(nd, LOOKUP_CREATE) == 0) return 0; return (nd->intent.open.flags & O_EXCL) != 0; } @@ -772,12 +792,13 @@ struct dentry_operations nfs4_dentry_operations = { .d_iput = nfs_dentry_iput, }; +/* + * Use intent information to determine whether we need to substitute + * the NFSv4-style stateful OPEN for the LOOKUP call + */ static int is_atomic_open(struct inode *dir, struct nameidata *nd) { - if (!nd) - return 0; - /* Check that we are indeed trying to open this file */ - if ((nd->flags & LOOKUP_CONTINUE) || !(nd->flags & LOOKUP_OPEN)) + if (nd == NULL || nfs_lookup_check_intent(nd, LOOKUP_OPEN) == 0) return 0; /* NFS does not (yet) have a stateful open for directories */ if (nd->flags & LOOKUP_DIRECTORY) -- cgit v1.2.3-70-g09d2 From f8f98a9335db4a7d6285b785180fad720bf22864 Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 8 Jun 2005 15:28:24 +0100 Subject: [PATCH] ARM: Fix Xscale copy_page implementation The ARM copypage changes in 2.6.12-rc4-git1 removed the preempt locking from the copypage functions which broke the XScale implementation. This patch fixes the locking on XScale and removes the now unneeded minicache code. Signed-off-by: Russell King Checked-by: Richard Purdie --- arch/arm/mm/Kconfig | 7 --- arch/arm/mm/Makefile | 2 - arch/arm/mm/copypage-xscale.S | 113 ------------------------------------ arch/arm/mm/copypage-xscale.c | 131 ++++++++++++++++++++++++++++++++++++++++++ arch/arm/mm/minicache.c | 73 ----------------------- 5 files changed, 131 insertions(+), 195 deletions(-) delete mode 100644 arch/arm/mm/copypage-xscale.S create mode 100644 arch/arm/mm/copypage-xscale.c diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index 48bac7da8c7..ade0e2222f5 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -228,7 +228,6 @@ config CPU_SA1100 select CPU_CACHE_V4WB select CPU_CACHE_VIVT select CPU_TLB_V4WB - select CPU_MINICACHE # XScale config CPU_XSCALE @@ -239,7 +238,6 @@ config CPU_XSCALE select CPU_ABRT_EV5T select CPU_CACHE_VIVT select CPU_TLB_V4WBI - select CPU_MINICACHE # ARMv6 config CPU_V6 @@ -345,11 +343,6 @@ config CPU_TLB_V4WBI config CPU_TLB_V6 bool -config CPU_MINICACHE - bool - help - Processor has a minicache. - comment "Processor Features" config ARM_THUMB diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile index ccf316c11e0..59f47d4c2df 100644 --- a/arch/arm/mm/Makefile +++ b/arch/arm/mm/Makefile @@ -31,8 +31,6 @@ obj-$(CONFIG_CPU_COPY_V6) += copypage-v6.o mmu.o obj-$(CONFIG_CPU_SA1100) += copypage-v4mc.o obj-$(CONFIG_CPU_XSCALE) += copypage-xscale.o -obj-$(CONFIG_CPU_MINICACHE) += minicache.o - obj-$(CONFIG_CPU_TLB_V3) += tlb-v3.o obj-$(CONFIG_CPU_TLB_V4WT) += tlb-v4.o obj-$(CONFIG_CPU_TLB_V4WB) += tlb-v4wb.o diff --git a/arch/arm/mm/copypage-xscale.S b/arch/arm/mm/copypage-xscale.S deleted file mode 100644 index bb277316ef5..00000000000 --- a/arch/arm/mm/copypage-xscale.S +++ /dev/null @@ -1,113 +0,0 @@ -/* - * linux/arch/arm/lib/copypage-xscale.S - * - * Copyright (C) 2001 Russell King - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include -#include -#include - -/* - * General note: - * We don't really want write-allocate cache behaviour for these functions - * since that will just eat through 8K of the cache. - */ - - .text - .align 5 -/* - * XScale optimised copy_user_page - * r0 = destination - * r1 = source - * r2 = virtual user address of ultimate destination page - * - * The source page may have some clean entries in the cache already, but we - * can safely ignore them - break_cow() will flush them out of the cache - * if we eventually end up using our copied page. - * - * What we could do is use the mini-cache to buffer reads from the source - * page. We rely on the mini-cache being smaller than one page, so we'll - * cycle through the complete cache anyway. - */ -ENTRY(xscale_mc_copy_user_page) - stmfd sp!, {r4, r5, lr} - mov r5, r0 - mov r0, r1 - bl map_page_minicache - mov r1, r5 - mov lr, #PAGE_SZ/64-1 - - /* - * Strangely enough, best performance is achieved - * when prefetching destination as well. (NP) - */ - pld [r0, #0] - pld [r0, #32] - pld [r1, #0] - pld [r1, #32] - -1: pld [r0, #64] - pld [r0, #96] - pld [r1, #64] - pld [r1, #96] - -2: ldrd r2, [r0], #8 - ldrd r4, [r0], #8 - mov ip, r1 - strd r2, [r1], #8 - ldrd r2, [r0], #8 - strd r4, [r1], #8 - ldrd r4, [r0], #8 - strd r2, [r1], #8 - strd r4, [r1], #8 - mcr p15, 0, ip, c7, c10, 1 @ clean D line - ldrd r2, [r0], #8 - mcr p15, 0, ip, c7, c6, 1 @ invalidate D line - ldrd r4, [r0], #8 - mov ip, r1 - strd r2, [r1], #8 - ldrd r2, [r0], #8 - strd r4, [r1], #8 - ldrd r4, [r0], #8 - strd r2, [r1], #8 - strd r4, [r1], #8 - mcr p15, 0, ip, c7, c10, 1 @ clean D line - subs lr, lr, #1 - mcr p15, 0, ip, c7, c6, 1 @ invalidate D line - bgt 1b - beq 2b - - ldmfd sp!, {r4, r5, pc} - - .align 5 -/* - * XScale optimised clear_user_page - * r0 = destination - * r1 = virtual user address of ultimate destination page - */ -ENTRY(xscale_mc_clear_user_page) - mov r1, #PAGE_SZ/32 - mov r2, #0 - mov r3, #0 -1: mov ip, r0 - strd r2, [r0], #8 - strd r2, [r0], #8 - strd r2, [r0], #8 - strd r2, [r0], #8 - mcr p15, 0, ip, c7, c10, 1 @ clean D line - subs r1, r1, #1 - mcr p15, 0, ip, c7, c6, 1 @ invalidate D line - bne 1b - mov pc, lr - - __INITDATA - - .type xscale_mc_user_fns, #object -ENTRY(xscale_mc_user_fns) - .long xscale_mc_clear_user_page - .long xscale_mc_copy_user_page - .size xscale_mc_user_fns, . - xscale_mc_user_fns diff --git a/arch/arm/mm/copypage-xscale.c b/arch/arm/mm/copypage-xscale.c new file mode 100644 index 00000000000..42a6ee255ce --- /dev/null +++ b/arch/arm/mm/copypage-xscale.c @@ -0,0 +1,131 @@ +/* + * linux/arch/arm/lib/copypage-xscale.S + * + * Copyright (C) 1995-2005 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This handles the mini data cache, as found on SA11x0 and XScale + * processors. When we copy a user page page, we map it in such a way + * that accesses to this page will not touch the main data cache, but + * will be cached in the mini data cache. This prevents us thrashing + * the main data cache on page faults. + */ +#include +#include + +#include +#include +#include + +/* + * 0xffff8000 to 0xffffffff is reserved for any ARM architecture + * specific hacks for copying pages efficiently. + */ +#define COPYPAGE_MINICACHE 0xffff8000 + +#define minicache_pgprot __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | \ + L_PTE_CACHEABLE) + +#define TOP_PTE(x) pte_offset_kernel(top_pmd, x) + +static DEFINE_SPINLOCK(minicache_lock); + +/* + * XScale mini-dcache optimised copy_user_page + * + * We flush the destination cache lines just before we write the data into the + * corresponding address. Since the Dcache is read-allocate, this removes the + * Dcache aliasing issue. The writes will be forwarded to the write buffer, + * and merged as appropriate. + */ +static void __attribute__((naked)) +mc_copy_user_page(void *from, void *to) +{ + /* + * Strangely enough, best performance is achieved + * when prefetching destination as well. (NP) + */ + asm volatile( + "stmfd sp!, {r4, r5, lr} \n\ + mov lr, %2 \n\ + pld [r0, #0] \n\ + pld [r0, #32] \n\ + pld [r1, #0] \n\ + pld [r1, #32] \n\ +1: pld [r0, #64] \n\ + pld [r0, #96] \n\ + pld [r1, #64] \n\ + pld [r1, #96] \n\ +2: ldrd r2, [r0], #8 \n\ + ldrd r4, [r0], #8 \n\ + mov ip, r1 \n\ + strd r2, [r1], #8 \n\ + ldrd r2, [r0], #8 \n\ + strd r4, [r1], #8 \n\ + ldrd r4, [r0], #8 \n\ + strd r2, [r1], #8 \n\ + strd r4, [r1], #8 \n\ + mcr p15, 0, ip, c7, c10, 1 @ clean D line\n\ + ldrd r2, [r0], #8 \n\ + mcr p15, 0, ip, c7, c6, 1 @ invalidate D line\n\ + ldrd r4, [r0], #8 \n\ + mov ip, r1 \n\ + strd r2, [r1], #8 \n\ + ldrd r2, [r0], #8 \n\ + strd r4, [r1], #8 \n\ + ldrd r4, [r0], #8 \n\ + strd r2, [r1], #8 \n\ + strd r4, [r1], #8 \n\ + mcr p15, 0, ip, c7, c10, 1 @ clean D line\n\ + subs lr, lr, #1 \n\ + mcr p15, 0, ip, c7, c6, 1 @ invalidate D line\n\ + bgt 1b \n\ + beq 2b \n\ + ldmfd sp!, {r4, r5, pc} " + : + : "r" (from), "r" (to), "I" (PAGE_SIZE / 64 - 1)); +} + +void xscale_mc_copy_user_page(void *kto, const void *kfrom, unsigned long vaddr) +{ + spin_lock(&minicache_lock); + + set_pte(TOP_PTE(COPYPAGE_MINICACHE), pfn_pte(__pa(kfrom) >> PAGE_SHIFT, minicache_pgprot)); + flush_tlb_kernel_page(COPYPAGE_MINICACHE); + + mc_copy_user_page((void *)COPYPAGE_MINICACHE, kto); + + spin_unlock(&minicache_lock); +} + +/* + * XScale optimised clear_user_page + */ +void __attribute__((naked)) +xscale_mc_clear_user_page(void *kaddr, unsigned long vaddr) +{ + asm volatile( + "mov r1, %0 \n\ + mov r2, #0 \n\ + mov r3, #0 \n\ +1: mov ip, r0 \n\ + strd r2, [r0], #8 \n\ + strd r2, [r0], #8 \n\ + strd r2, [r0], #8 \n\ + strd r2, [r0], #8 \n\ + mcr p15, 0, ip, c7, c10, 1 @ clean D line\n\ + subs r1, r1, #1 \n\ + mcr p15, 0, ip, c7, c6, 1 @ invalidate D line\n\ + bne 1b \n\ + mov pc, lr" + : + : "I" (PAGE_SIZE / 32)); +} + +struct cpu_user_fns xscale_mc_user_fns __initdata = { + .cpu_clear_user_page = xscale_mc_clear_user_page, + .cpu_copy_user_page = xscale_mc_copy_user_page, +}; diff --git a/arch/arm/mm/minicache.c b/arch/arm/mm/minicache.c index dedf2ab01b2..e69de29bb2d 100644 --- a/arch/arm/mm/minicache.c +++ b/arch/arm/mm/minicache.c @@ -1,73 +0,0 @@ -/* - * linux/arch/arm/mm/minicache.c - * - * Copyright (C) 2001 Russell King - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This handles the mini data cache, as found on SA11x0 and XScale - * processors. When we copy a user page page, we map it in such a way - * that accesses to this page will not touch the main data cache, but - * will be cached in the mini data cache. This prevents us thrashing - * the main data cache on page faults. - */ -#include -#include - -#include -#include -#include - -/* - * 0xffff8000 to 0xffffffff is reserved for any ARM architecture - * specific hacks for copying pages efficiently. - */ -#define minicache_address (0xffff8000) -#define minicache_pgprot __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | \ - L_PTE_CACHEABLE) - -static pte_t *minicache_pte; - -/* - * Note that this is intended to be called only from the copy_user_page - * asm code; anything else will require special locking to prevent the - * mini-cache space being re-used. (Note: probably preempt unsafe). - * - * We rely on the fact that the minicache is 2K, and we'll be pushing - * 4K of data through it, so we don't actually have to specifically - * flush the minicache when we change the mapping. - * - * Note also: assert(PAGE_OFFSET <= virt < high_memory). - * Unsafe: preempt, kmap. - */ -unsigned long map_page_minicache(unsigned long virt) -{ - set_pte(minicache_pte, pfn_pte(__pa(virt) >> PAGE_SHIFT, minicache_pgprot)); - flush_tlb_kernel_page(minicache_address); - - return minicache_address; -} - -static int __init minicache_init(void) -{ - pgd_t *pgd; - pmd_t *pmd; - - spin_lock(&init_mm.page_table_lock); - - pgd = pgd_offset_k(minicache_address); - pmd = pmd_alloc(&init_mm, pgd, minicache_address); - if (!pmd) - BUG(); - minicache_pte = pte_alloc_kernel(&init_mm, pmd, minicache_address); - if (!minicache_pte) - BUG(); - - spin_unlock(&init_mm.page_table_lock); - - return 0; -} - -core_initcall(minicache_init); -- cgit v1.2.3-70-g09d2 From 7840e5e95c1a8622425f11454600a49b6c718886 Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Wed, 8 Jun 2005 15:12:00 +1000 Subject: [PATCH] ppc64: print negative numbers correctly in boot wrapper if num has a value of -1, accessing the digits[] array will fail and the format string will be printed in funny way, or not at all. This happens if one prints negative numbers. Just change the code to match lib/vsprintf.c asm/div64.h cant be used because u64 maps to u32 for this build. Signed-off-by: Olaf Hering Signed-off-by: Paul Mackerras --- arch/ppc64/boot/prom.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/arch/ppc64/boot/prom.c b/arch/ppc64/boot/prom.c index 7b607d1862c..d5218b15824 100644 --- a/arch/ppc64/boot/prom.c +++ b/arch/ppc64/boot/prom.c @@ -11,6 +11,23 @@ #include #include +extern __u32 __div64_32(unsigned long long *dividend, __u32 divisor); + +/* The unnecessary pointer compare is there + * to check for type safety (n must be 64bit) + */ +# define do_div(n,base) ({ \ + __u32 __base = (base); \ + __u32 __rem; \ + (void)(((typeof((n)) *)0) == ((unsigned long long *)0)); \ + if (((n) >> 32) == 0) { \ + __rem = (__u32)(n) % __base; \ + (n) = (__u32)(n) / __base; \ + } else \ + __rem = __div64_32(&(n), __base); \ + __rem; \ + }) + int (*prom)(void *); void *chosen_handle; @@ -352,7 +369,7 @@ static int skip_atoi(const char **s) #define SPECIAL 32 /* 0x */ #define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */ -static char * number(char * str, long num, int base, int size, int precision, int type) +static char * number(char * str, unsigned long long num, int base, int size, int precision, int type) { char c,sign,tmp[66]; const char *digits="0123456789abcdefghijklmnopqrstuvwxyz"; @@ -367,9 +384,9 @@ static char * number(char * str, long num, int base, int size, int precision, in c = (type & ZEROPAD) ? '0' : ' '; sign = 0; if (type & SIGN) { - if (num < 0) { + if ((signed long long)num < 0) { sign = '-'; - num = -num; + num = - (signed long long)num; size--; } else if (type & PLUS) { sign = '+'; @@ -389,8 +406,7 @@ static char * number(char * str, long num, int base, int size, int precision, in if (num == 0) tmp[i++]='0'; else while (num != 0) { - tmp[i++] = digits[num % base]; - num /= base; + tmp[i++] = digits[do_div(num, base)]; } if (i > precision) precision = i; @@ -426,7 +442,7 @@ int sprintf(char * buf, const char *fmt, ...); int vsprintf(char *buf, const char *fmt, va_list args) { int len; - unsigned long num; + unsigned long long num; int i, base; char * str; const char *s; -- cgit v1.2.3-70-g09d2 From 358c6ac0dd4ffa5e44d59d4008a2627aa2f02b6f Mon Sep 17 00:00:00 2001 From: Ananth N Mavinakayanahalli Date: Wed, 8 Jun 2005 15:33:43 +1000 Subject: [PATCH] ppc64 kprobes: don't eat dabr/iabr exceptions Kprobes was eating the hardware instruction and data address breakpoint exceptions. This patch fixes it; kprobes doesn't use those exceptions at all and should ignore them. Signed-off-by: Ananth N Mavinakayanahalli Signed-off-by: Paul Mackerras Signed-off-by: Linus Torvalds --- arch/ppc64/kernel/kprobes.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/ppc64/kernel/kprobes.c b/arch/ppc64/kernel/kprobes.c index 103daaf7357..5a9f47b18c4 100644 --- a/arch/ppc64/kernel/kprobes.c +++ b/arch/ppc64/kernel/kprobes.c @@ -233,8 +233,6 @@ int kprobe_exceptions_notify(struct notifier_block *self, unsigned long val, */ preempt_disable(); switch (val) { - case DIE_IABR_MATCH: - case DIE_DABR_MATCH: case DIE_BPT: if (kprobe_handler(args->regs)) ret = NOTIFY_STOP; -- cgit v1.2.3-70-g09d2 From ad597bd518559f59ede8d01262cdf4467e13282e Mon Sep 17 00:00:00 2001 From: David Mosberger-Tang Date: Wed, 8 Jun 2005 10:45:00 -0700 Subject: [IA64] Fill holes in FIXADDR_USER space with zero pages. This fixes an oops reported by Jason Baron. Signed-off-by: David Mosberger-Tang Signed-off-by: Tony Luck --- arch/ia64/mm/init.c | 19 +++++++++++++++++-- include/asm-ia64/pgtable.h | 8 ++++++-- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c index 547785e3cba..4eb2f52b87a 100644 --- a/arch/ia64/mm/init.c +++ b/arch/ia64/mm/init.c @@ -305,8 +305,9 @@ setup_gate (void) struct page *page; /* - * Map the gate page twice: once read-only to export the ELF headers etc. and once - * execute-only page to enable privilege-promotion via "epc": + * Map the gate page twice: once read-only to export the ELF + * headers etc. and once execute-only page to enable + * privilege-promotion via "epc": */ page = virt_to_page(ia64_imva(__start_gate_section)); put_kernel_page(page, GATE_ADDR, PAGE_READONLY); @@ -315,6 +316,20 @@ setup_gate (void) put_kernel_page(page, GATE_ADDR + PAGE_SIZE, PAGE_GATE); #else put_kernel_page(page, GATE_ADDR + PERCPU_PAGE_SIZE, PAGE_GATE); + /* Fill in the holes (if any) with read-only zero pages: */ + { + unsigned long addr; + + for (addr = GATE_ADDR + PAGE_SIZE; + addr < GATE_ADDR + PERCPU_PAGE_SIZE; + addr += PAGE_SIZE) + { + put_kernel_page(ZERO_PAGE(0), addr, + PAGE_READONLY); + put_kernel_page(ZERO_PAGE(0), addr + PERCPU_PAGE_SIZE, + PAGE_READONLY); + } + } #endif ia64_patch_gate(); } diff --git a/include/asm-ia64/pgtable.h b/include/asm-ia64/pgtable.h index ea121a00230..fcc9c3344ab 100644 --- a/include/asm-ia64/pgtable.h +++ b/include/asm-ia64/pgtable.h @@ -8,7 +8,7 @@ * This hopefully works with any (fixed) IA-64 page-size, as defined * in . * - * Copyright (C) 1998-2004 Hewlett-Packard Co + * Copyright (C) 1998-2005 Hewlett-Packard Co * David Mosberger-Tang */ @@ -551,7 +551,11 @@ do { \ /* These tell get_user_pages() that the first gate page is accessible from user-level. */ #define FIXADDR_USER_START GATE_ADDR -#define FIXADDR_USER_END (GATE_ADDR + 2*PERCPU_PAGE_SIZE) +#ifdef HAVE_BUGGY_SEGREL +# define FIXADDR_USER_END (GATE_ADDR + 2*PAGE_SIZE) +#else +# define FIXADDR_USER_END (GATE_ADDR + 2*PERCPU_PAGE_SIZE) +#endif #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_DIRTY -- cgit v1.2.3-70-g09d2 From 57cfa5e97ff60d909a7e0a5f6e4d0a49aa3e2aec Mon Sep 17 00:00:00 2001 From: Giorgio Padrin Date: Wed, 8 Jun 2005 19:00:15 +0100 Subject: [PATCH] ARM: 2703/1: pxa-regs.h: complete I2S GPIO alternate functions for PXA27x Patch from Giorgio Padrin The patch completes I2S GPIO alternate functions for PXA27x, adding I2S_SYSCLK. File: pxa-regs.h . Signed-off-by: Giorgio Padrin Signed-off-by: Russell King --- include/asm-arm/arch-pxa/pxa-regs.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/asm-arm/arch-pxa/pxa-regs.h b/include/asm-arm/arch-pxa/pxa-regs.h index 39741d3c9a3..b5e54a9e9fa 100644 --- a/include/asm-arm/arch-pxa/pxa-regs.h +++ b/include/asm-arm/arch-pxa/pxa-regs.h @@ -1296,6 +1296,7 @@ #define GPIO111_MMCDAT3 111 /* MMC DAT3 (PXA27x) */ #define GPIO111_MMCCS1 111 /* MMC Chip Select 1 (PXA27x) */ #define GPIO112_MMCCMD 112 /* MMC CMD (PXA27x) */ +#define GPIO113_I2S_SYSCLK 113 /* I2S System Clock (PXA27x) */ #define GPIO113_AC97_RESET_N 113 /* AC97 NRESET on (PXA27x) */ /* GPIO alternate function mode & direction */ @@ -1428,6 +1429,7 @@ #define GPIO111_MMCDAT3_MD (111 | GPIO_ALT_FN_1_OUT) #define GPIO110_MMCCS1_MD (111 | GPIO_ALT_FN_1_OUT) #define GPIO112_MMCCMD_MD (112 | GPIO_ALT_FN_1_OUT) +#define GPIO113_I2S_SYSCLK_MD (113 | GPIO_ALT_FN_1_OUT) #define GPIO113_AC97_RESET_N_MD (113 | GPIO_ALT_FN_2_OUT) #define GPIO117_I2CSCL_MD (117 | GPIO_ALT_FN_1_OUT) #define GPIO118_I2CSDA_MD (118 | GPIO_ALT_FN_1_IN) -- cgit v1.2.3-70-g09d2 From aeabbbbe126f3d5e61e2db07629443cd10932bb2 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Wed, 8 Jun 2005 19:00:16 +0100 Subject: [PATCH] ARM: 2705/1: fix writesw for misaligned source pointer Patch from Nicolas Pitre Signed-off-by: Nicolas Pitre Signed-off-by: Russell King --- arch/arm/lib/io-writesw-armv4.S | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm/lib/io-writesw-armv4.S b/arch/arm/lib/io-writesw-armv4.S index 6d1d7c27806..5e240e452af 100644 --- a/arch/arm/lib/io-writesw-armv4.S +++ b/arch/arm/lib/io-writesw-armv4.S @@ -87,9 +87,9 @@ ENTRY(__raw_writesw) subs r2, r2, #2 orr ip, ip, r3, push_hbyte1 strh ip, [r0] - bpl 2b + bpl 1b -3: tst r2, #1 -2: movne ip, r3, lsr #8 + tst r2, #1 +3: movne ip, r3, lsr #8 strneh ip, [r0] mov pc, lr -- cgit v1.2.3-70-g09d2 From dcef1f634657dabe7905af3ccda12cf7f0b6fcc1 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Wed, 8 Jun 2005 19:00:47 +0100 Subject: [PATCH] ARM: 2664/2: add support for atomic ops on pre-ARMv6 SMP systems Patch from Nicolas Pitre Not that there might be many of them on the planet, but at least RMK apparently has one. Signed-off-by: Nicolas Pitre Signed-off-by: Russell King --- arch/arm/kernel/entry-armv.S | 16 ++++++++++----- arch/arm/kernel/traps.c | 49 ++++++++++++++++++++++++++++++++++++++++++++ arch/arm/mm/Kconfig | 8 ++++++++ 3 files changed, 68 insertions(+), 5 deletions(-) diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index 4eb36155dc9..e14278d5988 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S @@ -269,7 +269,7 @@ __pabt_svc: add r5, sp, #S_PC ldmia r7, {r2 - r4} @ Get USR pc, cpsr -#if __LINUX_ARM_ARCH__ < 6 +#if __LINUX_ARM_ARCH__ < 6 && !defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG) @ make sure our user space atomic helper is aborted cmp r2, #VIRT_OFFSET bichs r3, r3, #PSR_Z_BIT @@ -616,11 +616,17 @@ __kuser_helper_start: __kuser_cmpxchg: @ 0xffff0fc0 -#if __LINUX_ARM_ARCH__ < 6 +#if defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG) -#ifdef CONFIG_SMP /* sanity check */ -#error "CONFIG_SMP on a machine supporting pre-ARMv6 processors?" -#endif + /* + * Poor you. No fast solution possible... + * The kernel itself must perform the operation. + * A special ghost syscall is used for that (see traps.c). + */ + swi #0x9ffff0 + mov pc, lr + +#elif __LINUX_ARM_ARCH__ < 6 /* * Theory of operation: diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 14df16b983f..45d2a032d89 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -464,6 +464,55 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs) #endif return 0; +#ifdef CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG + /* + * Atomically store r1 in *r2 if *r2 is equal to r0 for user space. + * Return zero in r0 if *MEM was changed or non-zero if no exchange + * happened. Also set the user C flag accordingly. + * If access permissions have to be fixed up then non-zero is + * returned and the operation has to be re-attempted. + * + * *NOTE*: This is a ghost syscall private to the kernel. Only the + * __kuser_cmpxchg code in entry-armv.S should be aware of its + * existence. Don't ever use this from user code. + */ + case 0xfff0: + { + extern void do_DataAbort(unsigned long addr, unsigned int fsr, + struct pt_regs *regs); + unsigned long val; + unsigned long addr = regs->ARM_r2; + struct mm_struct *mm = current->mm; + pgd_t *pgd; pmd_t *pmd; pte_t *pte; + + regs->ARM_cpsr &= ~PSR_C_BIT; + spin_lock(&mm->page_table_lock); + pgd = pgd_offset(mm, addr); + if (!pgd_present(*pgd)) + goto bad_access; + pmd = pmd_offset(pgd, addr); + if (!pmd_present(*pmd)) + goto bad_access; + pte = pte_offset_map(pmd, addr); + if (!pte_present(*pte) || !pte_write(*pte)) + goto bad_access; + val = *(unsigned long *)addr; + val -= regs->ARM_r0; + if (val == 0) { + *(unsigned long *)addr = regs->ARM_r1; + regs->ARM_cpsr |= PSR_C_BIT; + } + spin_unlock(&mm->page_table_lock); + return val; + + bad_access: + spin_unlock(&mm->page_table_lock); + /* simulate a read access fault */ + do_DataAbort(addr, 15 + (1 << 11), regs); + return -1; + } +#endif + default: /* Calls 9f00xx..9f07ff are defined to return -ENOSYS if not implemented, rather than raising SIGILL. This diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index ade0e2222f5..3fefb43c67f 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -422,3 +422,11 @@ config HAS_TLS_REG assume directly accessing that register and always obtain the expected value only on ARMv7 and above. +config NEEDS_SYSCALL_FOR_CMPXCHG + bool + default y if SMP && (CPU_32v5 || CPU_32v4 || CPU_32v3) + help + SMP on a pre-ARMv6 processor? Well OK then. + Forget about fast user space cmpxchg support. + It is just not possible. + -- cgit v1.2.3-70-g09d2 From ff39bc772ad18d8c7f9334926053b718d7932de0 Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 8 Jun 2005 19:26:47 +0100 Subject: [PATCH] Serial: remove unused variable in sa1100 driver Signed-off-by: Russell King --- drivers/serial/sa1100.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/serial/sa1100.c b/drivers/serial/sa1100.c index 22565a67a57..98641c3f5ab 100644 --- a/drivers/serial/sa1100.c +++ b/drivers/serial/sa1100.c @@ -197,7 +197,7 @@ static void sa1100_rx_chars(struct sa1100_port *sport, struct pt_regs *regs) { struct tty_struct *tty = sport->port.info->tty; - unsigned int status, ch, flg, ignored = 0; + unsigned int status, ch, flg; status = UTSR1_TO_SM(UART_GET_UTSR1(sport)) | UTSR0_TO_SM(UART_GET_UTSR0(sport)); -- cgit v1.2.3-70-g09d2 From 866ba633a81c1e179038f7527809d9513160a6f7 Mon Sep 17 00:00:00 2001 From: Keith Owens Date: Mon, 6 Jun 2005 02:04:00 -0700 Subject: [IA64] Module gp must point to valid memory Some bits of the kernel assume that gp always points to valid memory, in particular PHYSICAL_MODE_ENTER() assumes that both gp and sp are valid virtual addresses with associated physical pages. The IA64 module loader puts gp well past the end of the module, with no physical backing. Offsets on gp are still valid, but physical mode addressing breaks for modules. Ensure that gp always falls within the module body. Also ensure that gp is 8 byte aligned. Signed-off-by: Keith Owens Signed-off-by: Tony Luck --- arch/ia64/kernel/module.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/arch/ia64/kernel/module.c b/arch/ia64/kernel/module.c index febc091c2f0..f1aca7cffd1 100644 --- a/arch/ia64/kernel/module.c +++ b/arch/ia64/kernel/module.c @@ -825,14 +825,16 @@ apply_relocate_add (Elf64_Shdr *sechdrs, const char *strtab, unsigned int symind * XXX Should have an arch-hook for running this after final section * addresses have been selected... */ - /* See if gp can cover the entire core module: */ - uint64_t gp = (uint64_t) mod->module_core + MAX_LTOFF / 2; - if (mod->core_size >= MAX_LTOFF) + uint64_t gp; + if (mod->core_size > MAX_LTOFF) /* * This takes advantage of fact that SHF_ARCH_SMALL gets allocated * at the end of the module. */ - gp = (uint64_t) mod->module_core + mod->core_size - MAX_LTOFF / 2; + gp = mod->core_size - MAX_LTOFF / 2; + else + gp = mod->core_size / 2; + gp = (uint64_t) mod->module_core + ((gp + 7) & -8); mod->arch.gp = gp; DEBUGP("%s: placing gp at 0x%lx\n", __FUNCTION__, gp); } -- cgit v1.2.3-70-g09d2 From 86ebacd360767f6a5cf9c8810977593dccf3f3da Mon Sep 17 00:00:00 2001 From: Tony Luck Date: Wed, 8 Jun 2005 12:12:48 -0700 Subject: [IA64] Update comment to describe modes set in default control register. Christian Hildner pointed out that the comment did not match what the code does in cpu_init() when we set up the default control register. Patch based on suggestions from Ken Chen. Signed-off-by: Tony Luck --- arch/ia64/kernel/setup.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index b7e6b4cb374..d14692e0920 100644 --- a/arch/ia64/kernel/setup.c +++ b/arch/ia64/kernel/setup.c @@ -720,7 +720,8 @@ cpu_init (void) ia64_set_kr(IA64_KR_PT_BASE, __pa(ia64_imva(empty_zero_page))); /* - * Initialize default control register to defer all speculative faults. The + * Initialize default control register to defer speculative faults except + * for those arising from TLB misses, which are not deferred. The * kernel MUST NOT depend on a particular setting of these bits (in other words, * the kernel must have recovery code for all speculative accesses). Turn on * dcr.lc as per recommendation by the architecture team. Most IA-32 apps -- cgit v1.2.3-70-g09d2 From 70aa488cff83c965c9e1850f48d82b000d0d6c1c Mon Sep 17 00:00:00 2001 From: Keith Owens Date: Fri, 27 May 2005 23:09:00 -0700 Subject: [IA64] Extract correct break number for break.b break.b does not store the break number in cr.iim, instead it stores 0, which makes all break.b instructions look like BUG(). Extract the break number from the instruction itself. Signed-off-by: Keith Owens Signed-off-by: Tony Luck --- arch/ia64/kernel/traps.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c index e82ad78081b..9bad6652d53 100644 --- a/arch/ia64/kernel/traps.c +++ b/arch/ia64/kernel/traps.c @@ -111,6 +111,24 @@ ia64_bad_break (unsigned long break_num, struct pt_regs *regs) siginfo_t siginfo; int sig, code; + /* break.b always sets cr.iim to 0, which causes problems for + * debuggers. Get the real break number from the original instruction, + * but only for kernel code. User space break.b is left alone, to + * preserve the existing behaviour. All break codings have the same + * format, so there is no need to check the slot type. + */ + if (break_num == 0 && !user_mode(regs)) { + struct ia64_psr *ipsr = ia64_psr(regs); + unsigned long *bundle = (unsigned long *)regs->cr_iip; + unsigned long slot; + switch (ipsr->ri) { + case 0: slot = (bundle[0] >> 5); break; + case 1: slot = (bundle[0] >> 46) | (bundle[1] << 18); break; + default: slot = (bundle[1] >> 23); break; + } + break_num = ((slot >> 36 & 1) << 20) | (slot >> 6 & 0xfffff); + } + /* SIGILL, SIGFPE, SIGSEGV, and SIGBUS want these field initialized: */ siginfo.si_addr = (void __user *) (regs->cr_iip + ia64_psr(regs)->ri); siginfo.si_imm = break_num; -- cgit v1.2.3-70-g09d2 From 6d1cfbab4de64f2d0c5b0f81177ade0d75b69288 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Wed, 8 Jun 2005 14:13:14 -0700 Subject: [TG3]: Fix 5700/5701 DMA corruption on Apple G4. Fix 5700/5701 DMA write corruption on Apple G4 by detecting the Apple UniNorth PCI 1.5 chipset and adjusting the DMA write boundary to 16. DMA test fails to detect the problem with this chipset. Thanks to Manuel Perez Ayala for reporting the problem and helping to debug it. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 18 ++++++++++++++++-- include/linux/pci_ids.h | 1 + 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index e944aac258e..77337c3b428 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -9695,10 +9695,24 @@ static int __devinit tg3_test_dma(struct tg3 *tp) } if ((tp->dma_rwctrl & DMA_RWCTRL_WRITE_BNDRY_MASK) != DMA_RWCTRL_WRITE_BNDRY_16) { + static struct pci_device_id dma_wait_state_chipsets[] = { + { PCI_DEVICE(PCI_VENDOR_ID_APPLE, + PCI_DEVICE_ID_APPLE_UNI_N_PCI15) }, + { }, + }; + /* DMA test passed without adjusting DMA boundary, - * just restore the calculated DMA boundary + * now look for chipsets that are known to expose the + * DMA bug without failing the test. */ - tp->dma_rwctrl = saved_dma_rwctrl; + if (pci_dev_present(dma_wait_state_chipsets)) { + tp->dma_rwctrl &= ~DMA_RWCTRL_WRITE_BNDRY_MASK; + tp->dma_rwctrl |= DMA_RWCTRL_WRITE_BNDRY_16; + } + else + /* Safe to use the calculated DMA boundary. */ + tp->dma_rwctrl = saved_dma_rwctrl; + tw32(TG3PCI_DMA_RW_CTRL, tp->dma_rwctrl); } diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 18f734ec918..b8b4ebf9abf 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -874,6 +874,7 @@ #define PCI_DEVICE_ID_APPLE_KL_USB_P 0x0026 #define PCI_DEVICE_ID_APPLE_UNI_N_AGP_P 0x0027 #define PCI_DEVICE_ID_APPLE_UNI_N_AGP15 0x002d +#define PCI_DEVICE_ID_APPLE_UNI_N_PCI15 0x002e #define PCI_DEVICE_ID_APPLE_UNI_N_FW2 0x0030 #define PCI_DEVICE_ID_APPLE_UNI_N_GMAC2 0x0032 #define PCI_DEVIEC_ID_APPLE_UNI_N_ATA 0x0033 -- cgit v1.2.3-70-g09d2 From ed7fce6c13bdd802817e1988d67047d432e7e30b Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 8 Jun 2005 14:15:52 -0700 Subject: [TG3]: Update driver version and release date. Signed-off-by: David S. Miller --- drivers/net/tg3.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 77337c3b428..a0b8848049c 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -66,8 +66,8 @@ #define DRV_MODULE_NAME "tg3" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "3.30" -#define DRV_MODULE_RELDATE "June 6, 2005" +#define DRV_MODULE_VERSION "3.31" +#define DRV_MODULE_RELDATE "June 8, 2005" #define TG3_DEF_MAC_MODE 0 #define TG3_DEF_RX_MODE 0 -- cgit v1.2.3-70-g09d2 From 8181b8c1f3a69fe5abcc51cb732eb512ccd1566a Mon Sep 17 00:00:00 2001 From: Gabor Fekete Date: Wed, 8 Jun 2005 14:54:38 -0700 Subject: [IPV6]: Update parm.link in ip6ip6_tnl_change() Signed-off-by: Gabor Fekete Signed-off-by: David S. Miller --- net/ipv6/ip6_tunnel.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 3b1c9fa184a..ba3b0c267f7 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -882,6 +882,7 @@ ip6ip6_tnl_change(struct ip6_tnl *t, struct ip6_tnl_parm *p) t->parms.hop_limit = p->hop_limit; t->parms.encap_limit = p->encap_limit; t->parms.flowinfo = p->flowinfo; + t->parms.link = p->link; ip6ip6_tnl_link_config(t); return 0; } -- cgit v1.2.3-70-g09d2 From 699a411451a32cc111410f44f172b265f6d679c8 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 8 Jun 2005 14:55:42 -0700 Subject: [NET]: Allow controlling NAPI device weight with sysfs Simple interface to allow changing network device scheduling weight with sysfs. Please consider this for 2.6.12, since risk/impact is small. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- net/core/net-sysfs.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index 910eb4c05a4..e2137f3e489 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c @@ -185,6 +185,22 @@ static ssize_t store_tx_queue_len(struct class_device *dev, const char *buf, siz static CLASS_DEVICE_ATTR(tx_queue_len, S_IRUGO | S_IWUSR, show_tx_queue_len, store_tx_queue_len); +NETDEVICE_SHOW(weight, fmt_dec); + +static int change_weight(struct net_device *net, unsigned long new_weight) +{ + net->weight = new_weight; + return 0; +} + +static ssize_t store_weight(struct class_device *dev, const char *buf, size_t len) +{ + return netdev_store(dev, buf, len, change_weight); +} + +static CLASS_DEVICE_ATTR(weight, S_IRUGO | S_IWUSR, show_weight, + store_weight); + static struct class_device_attribute *net_class_attributes[] = { &class_device_attr_ifindex, @@ -194,6 +210,7 @@ static struct class_device_attribute *net_class_attributes[] = { &class_device_attr_features, &class_device_attr_mtu, &class_device_attr_flags, + &class_device_attr_weight, &class_device_attr_type, &class_device_attr_address, &class_device_attr_broadcast, -- cgit v1.2.3-70-g09d2 From e3876605450979fe52a1a03e7eb78a89bf59e76a Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 8 Jun 2005 14:56:01 -0700 Subject: [NET]: Fix sysctl net.core.dev_weight Changing the sysctl net.core.dev_weight has no effect because the weight of the backlog devices is set during initialization and never changed. This patch propagates any changes to the global value affected by sysctl to the per-cpu devices. It is done every time the packet handler function is run. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- net/core/dev.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/core/dev.c b/net/core/dev.c index f15a3ffff63..ab935778ce8 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1744,6 +1744,7 @@ static int process_backlog(struct net_device *backlog_dev, int *budget) struct softnet_data *queue = &__get_cpu_var(softnet_data); unsigned long start_time = jiffies; + backlog_dev->weight = weight_p; for (;;) { struct sk_buff *skb; struct net_device *dev; -- cgit v1.2.3-70-g09d2 From b824979aeccbfd997e6e5dbe75c47d586b5a2923 Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Wed, 8 Jun 2005 15:10:22 -0700 Subject: [PKT_SCHED]: Fix typo in NET_EMATCH_STACK help text Spotted by Geert Uytterhoeven . Signed-off-by: Thomas Graf Signed-off-by: David S. Miller --- net/sched/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/sched/Kconfig b/net/sched/Kconfig index b0941186f86..b22c9beb604 100644 --- a/net/sched/Kconfig +++ b/net/sched/Kconfig @@ -405,7 +405,7 @@ config NET_EMATCH_STACK ---help--- Size of the local stack variable used while evaluating the tree of ematches. Limits the depth of the tree, i.e. the number of - encapsulated precedences. Every level requires 4 bytes of addtional + encapsulated precedences. Every level requires 4 bytes of additional stack space. config NET_EMATCH_CMP -- cgit v1.2.3-70-g09d2 From 4890062960cbc4d3cebdbd8261a68bc85efcf5d4 Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Wed, 8 Jun 2005 15:10:48 -0700 Subject: [PKT_SCHED]: Allow socket attributes to be matched on via meta ematch Adds meta collectors for all socket attributes that make sense to be filtered upon. Some of them are only useful for debugging but having them doesn't hurt. Signed-off-by: Thomas Graf Signed-off-by: David S. Miller --- include/linux/tc_ematch/tc_em_meta.h | 30 ++++ net/sched/em_meta.c | 291 ++++++++++++++++++++++++++++++++--- 2 files changed, 297 insertions(+), 24 deletions(-) diff --git a/include/linux/tc_ematch/tc_em_meta.h b/include/linux/tc_ematch/tc_em_meta.h index aa6b48bb4dc..a6b2cc530af 100644 --- a/include/linux/tc_ematch/tc_em_meta.h +++ b/include/linux/tc_ematch/tc_em_meta.h @@ -56,6 +56,36 @@ enum TCF_META_ID_TCCLASSID, TCF_META_ID_RTCLASSID, TCF_META_ID_RTIIF, + TCF_META_ID_SK_FAMILY, + TCF_META_ID_SK_STATE, + TCF_META_ID_SK_REUSE, + TCF_META_ID_SK_BOUND_IF, + TCF_META_ID_SK_REFCNT, + TCF_META_ID_SK_SHUTDOWN, + TCF_META_ID_SK_PROTO, + TCF_META_ID_SK_TYPE, + TCF_META_ID_SK_RCVBUF, + TCF_META_ID_SK_RMEM_ALLOC, + TCF_META_ID_SK_WMEM_ALLOC, + TCF_META_ID_SK_OMEM_ALLOC, + TCF_META_ID_SK_WMEM_QUEUED, + TCF_META_ID_SK_RCV_QLEN, + TCF_META_ID_SK_SND_QLEN, + TCF_META_ID_SK_ERR_QLEN, + TCF_META_ID_SK_FORWARD_ALLOCS, + TCF_META_ID_SK_SNDBUF, + TCF_META_ID_SK_ALLOCS, + TCF_META_ID_SK_ROUTE_CAPS, + TCF_META_ID_SK_HASHENT, + TCF_META_ID_SK_LINGERTIME, + TCF_META_ID_SK_ACK_BACKLOG, + TCF_META_ID_SK_MAX_ACK_BACKLOG, + TCF_META_ID_SK_PRIO, + TCF_META_ID_SK_RCVLOWAT, + TCF_META_ID_SK_RCVTIMEO, + TCF_META_ID_SK_SNDTIMEO, + TCF_META_ID_SK_SENDMSG_OFF, + TCF_META_ID_SK_WRITE_PENDING, __TCF_META_ID_MAX }; #define TCF_META_ID_MAX (__TCF_META_ID_MAX - 1) diff --git a/net/sched/em_meta.c b/net/sched/em_meta.c index f1eeaf65cee..ed2a46cbb67 100644 --- a/net/sched/em_meta.c +++ b/net/sched/em_meta.c @@ -32,7 +32,7 @@ * +-----------+ +-----------+ * | | * ---> meta_ops[INT][INDEV](...) | - * | | + * | | * ----------- | * V V * +-----------+ +-----------+ @@ -70,6 +70,7 @@ #include #include #include +#include struct meta_obj { @@ -283,6 +284,214 @@ META_COLLECTOR(int_rtiif) dst->value = ((struct rtable*) skb->dst)->fl.iif; } +/************************************************************************** + * Socket Attributes + **************************************************************************/ + +#define SKIP_NONLOCAL(skb) \ + if (unlikely(skb->sk == NULL)) { \ + *err = -1; \ + return; \ + } + +META_COLLECTOR(int_sk_family) +{ + SKIP_NONLOCAL(skb); + dst->value = skb->sk->sk_family; +} + +META_COLLECTOR(int_sk_state) +{ + SKIP_NONLOCAL(skb); + dst->value = skb->sk->sk_state; +} + +META_COLLECTOR(int_sk_reuse) +{ + SKIP_NONLOCAL(skb); + dst->value = skb->sk->sk_reuse; +} + +META_COLLECTOR(int_sk_bound_if) +{ + SKIP_NONLOCAL(skb); + /* No error if bound_dev_if is 0, legal userspace check */ + dst->value = skb->sk->sk_bound_dev_if; +} + +META_COLLECTOR(var_sk_bound_if) +{ + SKIP_NONLOCAL(skb); + + if (skb->sk->sk_bound_dev_if == 0) { + dst->value = (unsigned long) "any"; + dst->len = 3; + } else { + struct net_device *dev; + + dev = dev_get_by_index(skb->sk->sk_bound_dev_if); + *err = var_dev(dev, dst); + if (dev) + dev_put(dev); + } +} + +META_COLLECTOR(int_sk_refcnt) +{ + SKIP_NONLOCAL(skb); + dst->value = atomic_read(&skb->sk->sk_refcnt); +} + +META_COLLECTOR(int_sk_rcvbuf) +{ + SKIP_NONLOCAL(skb); + dst->value = skb->sk->sk_rcvbuf; +} + +META_COLLECTOR(int_sk_shutdown) +{ + SKIP_NONLOCAL(skb); + dst->value = skb->sk->sk_shutdown; +} + +META_COLLECTOR(int_sk_proto) +{ + SKIP_NONLOCAL(skb); + dst->value = skb->sk->sk_protocol; +} + +META_COLLECTOR(int_sk_type) +{ + SKIP_NONLOCAL(skb); + dst->value = skb->sk->sk_type; +} + +META_COLLECTOR(int_sk_rmem_alloc) +{ + SKIP_NONLOCAL(skb); + dst->value = atomic_read(&skb->sk->sk_rmem_alloc); +} + +META_COLLECTOR(int_sk_wmem_alloc) +{ + SKIP_NONLOCAL(skb); + dst->value = atomic_read(&skb->sk->sk_wmem_alloc); +} + +META_COLLECTOR(int_sk_omem_alloc) +{ + SKIP_NONLOCAL(skb); + dst->value = atomic_read(&skb->sk->sk_omem_alloc); +} + +META_COLLECTOR(int_sk_rcv_qlen) +{ + SKIP_NONLOCAL(skb); + dst->value = skb->sk->sk_receive_queue.qlen; +} + +META_COLLECTOR(int_sk_snd_qlen) +{ + SKIP_NONLOCAL(skb); + dst->value = skb->sk->sk_write_queue.qlen; +} + +META_COLLECTOR(int_sk_wmem_queued) +{ + SKIP_NONLOCAL(skb); + dst->value = skb->sk->sk_wmem_queued; +} + +META_COLLECTOR(int_sk_fwd_alloc) +{ + SKIP_NONLOCAL(skb); + dst->value = skb->sk->sk_forward_alloc; +} + +META_COLLECTOR(int_sk_sndbuf) +{ + SKIP_NONLOCAL(skb); + dst->value = skb->sk->sk_sndbuf; +} + +META_COLLECTOR(int_sk_alloc) +{ + SKIP_NONLOCAL(skb); + dst->value = skb->sk->sk_allocation; +} + +META_COLLECTOR(int_sk_route_caps) +{ + SKIP_NONLOCAL(skb); + dst->value = skb->sk->sk_route_caps; +} + +META_COLLECTOR(int_sk_hashent) +{ + SKIP_NONLOCAL(skb); + dst->value = skb->sk->sk_hashent; +} + +META_COLLECTOR(int_sk_lingertime) +{ + SKIP_NONLOCAL(skb); + dst->value = skb->sk->sk_lingertime / HZ; +} + +META_COLLECTOR(int_sk_err_qlen) +{ + SKIP_NONLOCAL(skb); + dst->value = skb->sk->sk_error_queue.qlen; +} + +META_COLLECTOR(int_sk_ack_bl) +{ + SKIP_NONLOCAL(skb); + dst->value = skb->sk->sk_ack_backlog; +} + +META_COLLECTOR(int_sk_max_ack_bl) +{ + SKIP_NONLOCAL(skb); + dst->value = skb->sk->sk_max_ack_backlog; +} + +META_COLLECTOR(int_sk_prio) +{ + SKIP_NONLOCAL(skb); + dst->value = skb->sk->sk_priority; +} + +META_COLLECTOR(int_sk_rcvlowat) +{ + SKIP_NONLOCAL(skb); + dst->value = skb->sk->sk_rcvlowat; +} + +META_COLLECTOR(int_sk_rcvtimeo) +{ + SKIP_NONLOCAL(skb); + dst->value = skb->sk->sk_rcvtimeo / HZ; +} + +META_COLLECTOR(int_sk_sndtimeo) +{ + SKIP_NONLOCAL(skb); + dst->value = skb->sk->sk_sndtimeo / HZ; +} + +META_COLLECTOR(int_sk_sendmsg_off) +{ + SKIP_NONLOCAL(skb); + dst->value = skb->sk->sk_sndmsg_off; +} + +META_COLLECTOR(int_sk_write_pend) +{ + SKIP_NONLOCAL(skb); + dst->value = skb->sk->sk_write_pending; +} + /************************************************************************** * Meta value collectors assignment table **************************************************************************/ @@ -293,41 +502,75 @@ struct meta_ops struct meta_value *, struct meta_obj *, int *); }; +#define META_ID(name) TCF_META_ID_##name +#define META_FUNC(name) { .get = meta_##name } + /* Meta value operations table listing all meta value collectors and * assigns them to a type and meta id. */ static struct meta_ops __meta_ops[TCF_META_TYPE_MAX+1][TCF_META_ID_MAX+1] = { [TCF_META_TYPE_VAR] = { - [TCF_META_ID_DEV] = { .get = meta_var_dev }, - [TCF_META_ID_INDEV] = { .get = meta_var_indev }, - [TCF_META_ID_REALDEV] = { .get = meta_var_realdev } + [META_ID(DEV)] = META_FUNC(var_dev), + [META_ID(INDEV)] = META_FUNC(var_indev), + [META_ID(REALDEV)] = META_FUNC(var_realdev), + [META_ID(SK_BOUND_IF)] = META_FUNC(var_sk_bound_if), }, [TCF_META_TYPE_INT] = { - [TCF_META_ID_RANDOM] = { .get = meta_int_random }, - [TCF_META_ID_LOADAVG_0] = { .get = meta_int_loadavg_0 }, - [TCF_META_ID_LOADAVG_1] = { .get = meta_int_loadavg_1 }, - [TCF_META_ID_LOADAVG_2] = { .get = meta_int_loadavg_2 }, - [TCF_META_ID_DEV] = { .get = meta_int_dev }, - [TCF_META_ID_INDEV] = { .get = meta_int_indev }, - [TCF_META_ID_REALDEV] = { .get = meta_int_realdev }, - [TCF_META_ID_PRIORITY] = { .get = meta_int_priority }, - [TCF_META_ID_PROTOCOL] = { .get = meta_int_protocol }, - [TCF_META_ID_SECURITY] = { .get = meta_int_security }, - [TCF_META_ID_PKTTYPE] = { .get = meta_int_pkttype }, - [TCF_META_ID_PKTLEN] = { .get = meta_int_pktlen }, - [TCF_META_ID_DATALEN] = { .get = meta_int_datalen }, - [TCF_META_ID_MACLEN] = { .get = meta_int_maclen }, + [META_ID(RANDOM)] = META_FUNC(int_random), + [META_ID(LOADAVG_0)] = META_FUNC(int_loadavg_0), + [META_ID(LOADAVG_1)] = META_FUNC(int_loadavg_1), + [META_ID(LOADAVG_2)] = META_FUNC(int_loadavg_2), + [META_ID(DEV)] = META_FUNC(int_dev), + [META_ID(INDEV)] = META_FUNC(int_indev), + [META_ID(REALDEV)] = META_FUNC(int_realdev), + [META_ID(PRIORITY)] = META_FUNC(int_priority), + [META_ID(PROTOCOL)] = META_FUNC(int_protocol), + [META_ID(SECURITY)] = META_FUNC(int_security), + [META_ID(PKTTYPE)] = META_FUNC(int_pkttype), + [META_ID(PKTLEN)] = META_FUNC(int_pktlen), + [META_ID(DATALEN)] = META_FUNC(int_datalen), + [META_ID(MACLEN)] = META_FUNC(int_maclen), #ifdef CONFIG_NETFILTER - [TCF_META_ID_NFMARK] = { .get = meta_int_nfmark }, + [META_ID(NFMARK)] = META_FUNC(int_nfmark), #endif - [TCF_META_ID_TCINDEX] = { .get = meta_int_tcindex }, + [META_ID(TCINDEX)] = META_FUNC(int_tcindex), #ifdef CONFIG_NET_CLS_ACT - [TCF_META_ID_TCVERDICT] = { .get = meta_int_tcverd }, - [TCF_META_ID_TCCLASSID] = { .get = meta_int_tcclassid }, + [META_ID(TCVERDICT)] = META_FUNC(int_tcverd), + [META_ID(TCCLASSID)] = META_FUNC(int_tcclassid), #endif #ifdef CONFIG_NET_CLS_ROUTE - [TCF_META_ID_RTCLASSID] = { .get = meta_int_rtclassid }, + [META_ID(RTCLASSID)] = META_FUNC(int_rtclassid), #endif - [TCF_META_ID_RTIIF] = { .get = meta_int_rtiif } + [META_ID(RTIIF)] = META_FUNC(int_rtiif), + [META_ID(SK_FAMILY)] = META_FUNC(int_sk_family), + [META_ID(SK_STATE)] = META_FUNC(int_sk_state), + [META_ID(SK_REUSE)] = META_FUNC(int_sk_reuse), + [META_ID(SK_BOUND_IF)] = META_FUNC(int_sk_bound_if), + [META_ID(SK_REFCNT)] = META_FUNC(int_sk_refcnt), + [META_ID(SK_RCVBUF)] = META_FUNC(int_sk_rcvbuf), + [META_ID(SK_SNDBUF)] = META_FUNC(int_sk_sndbuf), + [META_ID(SK_SHUTDOWN)] = META_FUNC(int_sk_shutdown), + [META_ID(SK_PROTO)] = META_FUNC(int_sk_proto), + [META_ID(SK_TYPE)] = META_FUNC(int_sk_type), + [META_ID(SK_RMEM_ALLOC)] = META_FUNC(int_sk_rmem_alloc), + [META_ID(SK_WMEM_ALLOC)] = META_FUNC(int_sk_wmem_alloc), + [META_ID(SK_OMEM_ALLOC)] = META_FUNC(int_sk_omem_alloc), + [META_ID(SK_WMEM_QUEUED)] = META_FUNC(int_sk_wmem_queued), + [META_ID(SK_RCV_QLEN)] = META_FUNC(int_sk_rcv_qlen), + [META_ID(SK_SND_QLEN)] = META_FUNC(int_sk_snd_qlen), + [META_ID(SK_ERR_QLEN)] = META_FUNC(int_sk_err_qlen), + [META_ID(SK_FORWARD_ALLOCS)] = META_FUNC(int_sk_fwd_alloc), + [META_ID(SK_ALLOCS)] = META_FUNC(int_sk_alloc), + [META_ID(SK_ROUTE_CAPS)] = META_FUNC(int_sk_route_caps), + [META_ID(SK_HASHENT)] = META_FUNC(int_sk_hashent), + [META_ID(SK_LINGERTIME)] = META_FUNC(int_sk_lingertime), + [META_ID(SK_ACK_BACKLOG)] = META_FUNC(int_sk_ack_bl), + [META_ID(SK_MAX_ACK_BACKLOG)] = META_FUNC(int_sk_max_ack_bl), + [META_ID(SK_PRIO)] = META_FUNC(int_sk_prio), + [META_ID(SK_RCVLOWAT)] = META_FUNC(int_sk_rcvlowat), + [META_ID(SK_RCVTIMEO)] = META_FUNC(int_sk_rcvtimeo), + [META_ID(SK_SNDTIMEO)] = META_FUNC(int_sk_sndtimeo), + [META_ID(SK_SENDMSG_OFF)] = META_FUNC(int_sk_sendmsg_off), + [META_ID(SK_WRITE_PENDING)] = META_FUNC(int_sk_write_pend), } }; -- cgit v1.2.3-70-g09d2 From e1e284a4bd827db2288af9536664b44590e419eb Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Wed, 8 Jun 2005 15:11:02 -0700 Subject: [PKT_SCHED]: Dump classification result for basic classifier Signed-off-by: Thomas Graf Signed-off-by: David S. Miller --- net/sched/cls_basic.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/sched/cls_basic.c b/net/sched/cls_basic.c index 0d2d4415f33..dfb300bb6ba 100644 --- a/net/sched/cls_basic.c +++ b/net/sched/cls_basic.c @@ -261,6 +261,9 @@ static int basic_dump(struct tcf_proto *tp, unsigned long fh, rta = (struct rtattr *) b; RTA_PUT(skb, TCA_OPTIONS, 0, NULL); + if (f->res.classid) + RTA_PUT(skb, TCA_BASIC_CLASSID, sizeof(u32), &f->res.classid); + if (tcf_exts_dump(skb, &f->exts, &basic_ext_map) < 0 || tcf_em_tree_dump(skb, &f->ematches, TCA_BASIC_EMATCHES) < 0) goto rtattr_failure; -- cgit v1.2.3-70-g09d2 From 98e56405521b74b4826f855d45ef7859f34548ff Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Wed, 8 Jun 2005 15:11:19 -0700 Subject: [PKT_SCHED]: Fix numeric comparison in meta ematch This patch is brought to you by the department of applied stupidity. Signed-off-by: Thomas Graf Signed-off-by: David S. Miller --- net/sched/em_meta.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/sched/em_meta.c b/net/sched/em_meta.c index ed2a46cbb67..48bb23c2a35 100644 --- a/net/sched/em_meta.c +++ b/net/sched/em_meta.c @@ -639,9 +639,9 @@ static int meta_int_compare(struct meta_obj *a, struct meta_obj *b) /* Let gcc optimize it, the unlikely is not really based on * some numbers but jump free code for mismatches seems * more logical. */ - if (unlikely(a == b)) + if (unlikely(a->value == b->value)) return 0; - else if (a < b) + else if (a->value < b->value) return -1; else return 1; -- cgit v1.2.3-70-g09d2 From 3df59529ad1045da61698bb5dd8ebaa547aeb46f Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Wed, 8 Jun 2005 15:47:50 -0700 Subject: [PATCH] uml: make the emulated iomem driver work on 2.6 This makes the minimal fixes needed to make the UML iomem driver work in 2.6. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/Kconfig_char | 6 ++++++ arch/um/drivers/mmapper_kern.c | 24 ++++++++++++++++++++---- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/arch/um/Kconfig_char b/arch/um/Kconfig_char index 3e50fdb6762..62d87b71179 100644 --- a/arch/um/Kconfig_char +++ b/arch/um/Kconfig_char @@ -204,5 +204,11 @@ config UML_RANDOM http://sourceforge.net/projects/gkernel/). rngd periodically reads /dev/hwrng and injects the entropy into /dev/random. +config MMAPPER + tristate "iomem emulation driver" + help + This driver allows a host file to be used as emulated IO memory inside + UML. + endmenu diff --git a/arch/um/drivers/mmapper_kern.c b/arch/um/drivers/mmapper_kern.c index a63231dffe0..a37a5ac13c2 100644 --- a/arch/um/drivers/mmapper_kern.c +++ b/arch/um/drivers/mmapper_kern.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -117,24 +118,39 @@ static struct file_operations mmapper_fops = { .release = mmapper_release, }; +static struct miscdevice mmapper_dev = { + .minor = MISC_DYNAMIC_MINOR, + .name = "mmapper", + .fops = &mmapper_fops +}; + static int __init mmapper_init(void) { + int err; + printk(KERN_INFO "Mapper v0.1\n"); v_buf = (char *) find_iomem("mmapper", &mmapper_size); if(mmapper_size == 0){ printk(KERN_ERR "mmapper_init - find_iomem failed\n"); - return(0); + goto out; } - p_buf = __pa(v_buf); + err = misc_register(&mmapper_dev); + if(err){ + printk(KERN_ERR "mmapper - misc_register failed, err = %d\n", + err); + goto out; + } - devfs_mk_cdev(MKDEV(30, 0), S_IFCHR|S_IRUGO|S_IWUGO, "mmapper"); - return(0); + p_buf = __pa(v_buf); +out: + return 0; } static void mmapper_exit(void) { + misc_deregister(&mmapper_dev); } module_init(mmapper_init); -- cgit v1.2.3-70-g09d2 From da00d9a5466558ccd9e7b7d04b13d7cb9160c876 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Wed, 8 Jun 2005 15:48:01 -0700 Subject: [PATCH] uml: compile fixes for gcc 4 This is a bunch of compile fixes provoked by building UML with gcc 4. There are a bunch of signedness mismatches, a couple of uninitialized references, and a botched C99 structure initialization which had somehow gone unnoticed. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/chan_user.c | 4 ++-- arch/um/drivers/net_user.c | 2 +- arch/um/drivers/slip.h | 4 ++-- arch/um/drivers/slip_proto.h | 3 ++- arch/um/drivers/slirp.h | 4 ++-- arch/um/drivers/stderr_console.c | 6 +++--- arch/um/include/mconsole.h | 2 +- arch/um/include/net_user.h | 2 +- arch/um/include/os.h | 2 +- arch/um/include/user_util.h | 3 --- arch/um/os-Linux/elf_aux.c | 6 +++++- arch/um/os-Linux/file.c | 2 +- 12 files changed, 21 insertions(+), 19 deletions(-) diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c index 583b8e137c3..96f3a477c95 100644 --- a/arch/um/drivers/chan_user.c +++ b/arch/um/drivers/chan_user.c @@ -168,7 +168,7 @@ static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out) printk("winch_tramp : failed to read synchronization byte\n"); printk("read failed, err = %d\n", -n); printk("fd %d will not support SIGWINCH\n", fd); - *fd_out = -1; + pid = -1; } return(pid); } @@ -186,7 +186,7 @@ void register_winch(int fd, struct tty_struct *tty) if(!CHOOSE_MODE_PROC(is_tracer_winch, is_skas_winch, pid, fd, tty) && (pid == -1)){ thread = winch_tramp(fd, tty, &thread_fd); - if(fd != -1){ + if(thread > 0){ register_winch_irq(thread_fd, fd, thread, tty); count = os_write_file(thread_fd, &c, sizeof(c)); diff --git a/arch/um/drivers/net_user.c b/arch/um/drivers/net_user.c index 47229fe4a81..3730d4f1271 100644 --- a/arch/um/drivers/net_user.c +++ b/arch/um/drivers/net_user.c @@ -32,7 +32,7 @@ int tap_open_common(void *dev, char *gate_addr) return(0); } -void tap_check_ips(char *gate_addr, char *eth_addr) +void tap_check_ips(char *gate_addr, unsigned char *eth_addr) { int tap_addr[4]; diff --git a/arch/um/drivers/slip.h b/arch/um/drivers/slip.h index 495f2f1b142..d523618cd5a 100644 --- a/arch/um/drivers/slip.h +++ b/arch/um/drivers/slip.h @@ -12,8 +12,8 @@ struct slip_data { char *addr; char *gate_addr; int slave; - char ibuf[ENC_BUF_SIZE]; - char obuf[ENC_BUF_SIZE]; + unsigned char ibuf[ENC_BUF_SIZE]; + unsigned char obuf[ENC_BUF_SIZE]; int more; /* more data: do not read fd until ibuf has been drained */ int pos; int esc; diff --git a/arch/um/drivers/slip_proto.h b/arch/um/drivers/slip_proto.h index 7206361ace4..4c4d94a3310 100644 --- a/arch/um/drivers/slip_proto.h +++ b/arch/um/drivers/slip_proto.h @@ -12,7 +12,8 @@ #define SLIP_ESC_END 0334 /* ESC ESC_END means END 'data' */ #define SLIP_ESC_ESC 0335 /* ESC ESC_ESC means ESC 'data' */ -static inline int slip_unesc(unsigned char c,char *buf,int *pos, int *esc) +static inline int slip_unesc(unsigned char c, unsigned char *buf, int *pos, + int *esc) { int ret; diff --git a/arch/um/drivers/slirp.h b/arch/um/drivers/slirp.h index 04e407d1e44..afa4e30284f 100644 --- a/arch/um/drivers/slirp.h +++ b/arch/um/drivers/slirp.h @@ -24,8 +24,8 @@ struct slirp_data { struct arg_list_dummy_wrapper argw; int pid; int slave; - char ibuf[ENC_BUF_SIZE]; - char obuf[ENC_BUF_SIZE]; + unsigned char ibuf[ENC_BUF_SIZE]; + unsigned char obuf[ENC_BUF_SIZE]; int more; /* more data: do not read fd until ibuf has been drained */ int pos; int esc; diff --git a/arch/um/drivers/stderr_console.c b/arch/um/drivers/stderr_console.c index 98565b53d17..429ae8e6c7e 100644 --- a/arch/um/drivers/stderr_console.c +++ b/arch/um/drivers/stderr_console.c @@ -22,9 +22,9 @@ static void stderr_console_write(struct console *console, const char *string, } static struct console stderr_console = { - .name "stderr", - .write stderr_console_write, - .flags CON_PRINTBUFFER, + .name = "stderr", + .write = stderr_console_write, + .flags = CON_PRINTBUFFER, }; static int __init stderr_console_init(void) diff --git a/arch/um/include/mconsole.h b/arch/um/include/mconsole.h index 9fbe3083fdd..cfa368e045a 100644 --- a/arch/um/include/mconsole.h +++ b/arch/um/include/mconsole.h @@ -56,7 +56,7 @@ struct mc_request int as_interrupt; int originating_fd; - int originlen; + unsigned int originlen; unsigned char origin[128]; /* sockaddr_un */ struct mconsole_request request; diff --git a/arch/um/include/net_user.h b/arch/um/include/net_user.h index 36807b796e9..89885a77a77 100644 --- a/arch/um/include/net_user.h +++ b/arch/um/include/net_user.h @@ -35,7 +35,7 @@ extern void *get_output_buffer(int *len_out); extern void free_output_buffer(void *buffer); extern int tap_open_common(void *dev, char *gate_addr); -extern void tap_check_ips(char *gate_addr, char *eth_addr); +extern void tap_check_ips(char *gate_addr, unsigned char *eth_addr); extern void read_output(int fd, char *output_out, int len); diff --git a/arch/um/include/os.h b/arch/um/include/os.h index d246d5a2460..881d2988d2d 100644 --- a/arch/um/include/os.h +++ b/arch/um/include/os.h @@ -136,7 +136,7 @@ extern int os_seek_file(int fd, __u64 offset); extern int os_open_file(char *file, struct openflags flags, int mode); extern int os_read_file(int fd, void *buf, int len); extern int os_write_file(int fd, const void *buf, int count); -extern int os_file_size(char *file, long long *size_out); +extern int os_file_size(char *file, unsigned long long *size_out); extern int os_file_modtime(char *file, unsigned long *modtime); extern int os_pipe(int *fd, int stream, int close_on_exec); extern int os_set_fd_async(int fd, int owner); diff --git a/arch/um/include/user_util.h b/arch/um/include/user_util.h index b8c5b8a9525..7b6a24dfd30 100644 --- a/arch/um/include/user_util.h +++ b/arch/um/include/user_util.h @@ -41,9 +41,6 @@ extern unsigned long highmem; extern char host_info[]; extern char saved_command_line[]; -extern char command_line[]; - -extern char *tempdir; extern unsigned long _stext, _etext, _sdata, _edata, __bss_start, _end; extern unsigned long _unprotected_end; diff --git a/arch/um/os-Linux/elf_aux.c b/arch/um/os-Linux/elf_aux.c index 9aee0b62ebc..f0d6060e3e5 100644 --- a/arch/um/os-Linux/elf_aux.c +++ b/arch/um/os-Linux/elf_aux.c @@ -45,7 +45,11 @@ __init void scan_elf_aux( char **envp) elf_aux_hwcap = auxv->a_un.a_val; break; case AT_PLATFORM: - elf_aux_platform = auxv->a_un.a_ptr; + /* elf.h removed the pointer elements from + * a_un, so we have to use a_val, which is + * all that's left. + */ + elf_aux_platform = (char *) auxv->a_un.a_val; break; case AT_PAGESZ: page_size = auxv->a_un.a_val; diff --git a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c index 77d4066d1af..fd45bb26090 100644 --- a/arch/um/os-Linux/file.c +++ b/arch/um/os-Linux/file.c @@ -363,7 +363,7 @@ int os_write_file(int fd, const void *buf, int len) (int (*)(int, void *, int)) write, copy_to_user_proc)); } -int os_file_size(char *file, long long *size_out) +int os_file_size(char *file, unsigned long long *size_out) { struct uml_stat buf; int err; -- cgit v1.2.3-70-g09d2 From 501cb02b431fb88c7f157c46c8b54de59d1dd463 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Wed, 8 Jun 2005 15:48:13 -0700 Subject: [PATCH] uml: fix strace -f It turns out that we need to check for pending signals when a newly forked process is run for the first time. With strace -f, strace needs to know about the forked process before it gets going. If it doesn't, then it ptraces some bogus values into its registers, and the process segfaults. So, I added calls to interrupt_end, which does that, plus checks for reschedules. There shouldn't be any of those, but x86 does the same thing, so I'm copying that behavior to be safe. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/kernel/skas/process_kern.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/arch/um/kernel/skas/process_kern.c b/arch/um/kernel/skas/process_kern.c index ab5d3271da0..fc71ef29578 100644 --- a/arch/um/kernel/skas/process_kern.c +++ b/arch/um/kernel/skas/process_kern.c @@ -68,8 +68,11 @@ void new_thread_handler(int sig) * 0 if it just exits */ n = run_kernel_thread(fn, arg, ¤t->thread.exec_buf); - if(n == 1) + if(n == 1){ + /* Handle any immediate reschedules or signals */ + interrupt_end(); userspace(¤t->thread.regs.regs); + } else do_exit(0); } @@ -96,6 +99,8 @@ void fork_handler(int sig) schedule_tail(current->thread.prev_sched); current->thread.prev_sched = NULL; + /* Handle any immediate reschedules or signals */ + interrupt_end(); userspace(¤t->thread.regs.regs); } -- cgit v1.2.3-70-g09d2 From 1f96ddb4fb40961a8ebebf7a00bbfaad55aacbd2 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Wed, 8 Jun 2005 15:48:27 -0700 Subject: [PATCH] uml: clean up error path This cleans an error path which used to leak file descriptors by returning without trying to tidy up. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/chan_user.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c index 96f3a477c95..5d3768156c9 100644 --- a/arch/um/drivers/chan_user.c +++ b/arch/um/drivers/chan_user.c @@ -143,22 +143,22 @@ static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out) { struct winch_data data; unsigned long stack; - int fds[2], pid, n, err; + int fds[2], n, err; char c; err = os_pipe(fds, 1, 1); if(err < 0){ printk("winch_tramp : os_pipe failed, err = %d\n", -err); - return(err); + goto out; } data = ((struct winch_data) { .pty_fd = fd, .pipe_fd = fds[1], .close_me = fds[0] } ); - pid = run_helper_thread(winch_thread, &data, 0, &stack, 0); - if(pid < 0){ + err = run_helper_thread(winch_thread, &data, 0, &stack, 0); + if(err < 0){ printk("fork of winch_thread failed - errno = %d\n", errno); - return(pid); + goto out_close; } os_close_file(fds[1]); @@ -168,14 +168,22 @@ static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out) printk("winch_tramp : failed to read synchronization byte\n"); printk("read failed, err = %d\n", -n); printk("fd %d will not support SIGWINCH\n", fd); - pid = -1; + err = -EINVAL; + goto out_close1; } - return(pid); + return err ; + + out_close: + os_close_file(fds[1]); + out_close1: + os_close_file(fds[0]); + out: + return err; } void register_winch(int fd, struct tty_struct *tty) { - int pid, thread, thread_fd; + int pid, thread, thread_fd = -1; int count; char c = 1; -- cgit v1.2.3-70-g09d2 From beb9e1c3f32a0f878765c7c1142f91083739c5bd Mon Sep 17 00:00:00 2001 From: Eugene Surovegin Date: Wed, 8 Jun 2005 15:48:42 -0700 Subject: [PATCH] ppc32: add 405EP cpu_spec entry Add a definition for PPC 405EP which was lost somehow during 2.4 -> 2.6 transition. Recent change to arch/ppc/kernel/misc.S ("Fix incorrect CPU_FTR fixup usage for unified caches") triggered this bug and 405EP boards don't boot anymore. Signed-off-by: Eugene Surovegin Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc/kernel/cputable.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/arch/ppc/kernel/cputable.c b/arch/ppc/kernel/cputable.c index d44b7dc5390..17abf6cd0d9 100644 --- a/arch/ppc/kernel/cputable.c +++ b/arch/ppc/kernel/cputable.c @@ -849,6 +849,17 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, }, + { /* 405EP */ + .pvr_mask = 0xffff0000, + .pvr_value = 0x51210000, + .cpu_name = "405EP", + .cpu_features = CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_USE_TB, + .cpu_user_features = PPC_FEATURE_32 | + PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, + .icache_bsize = 32, + .dcache_bsize = 32, + }, #endif /* CONFIG_40x */ #ifdef CONFIG_44x -- cgit v1.2.3-70-g09d2 From f8acd944ea511af02485b1709c07ac7aac12aa48 Mon Sep 17 00:00:00 2001 From: William Lee Irwin III Date: Wed, 8 Jun 2005 15:48:52 -0700 Subject: [PATCH] sparc32: silence access_ok() warnings The fact that access_ok() doesn't use some of its arguments trips some unused variable warnings. This patch silences them permanently. Signed-off-by: William Irwin Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-sparc/uaccess.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/include/asm-sparc/uaccess.h b/include/asm-sparc/uaccess.h index f461144067e..0a780e84a12 100644 --- a/include/asm-sparc/uaccess.h +++ b/include/asm-sparc/uaccess.h @@ -41,10 +41,11 @@ * No one can read/write anything from userland in the kernel space by setting * large size and address near to PAGE_OFFSET - a fault will break his intentions. */ -#define __user_ok(addr,size) ((addr) < STACK_TOP) +#define __user_ok(addr, size) ({ (void)(size); (addr) < STACK_TOP; }) #define __kernel_ok (segment_eq(get_fs(), KERNEL_DS)) #define __access_ok(addr,size) (__user_ok((addr) & get_fs().seg,(size))) -#define access_ok(type,addr,size) __access_ok((unsigned long)(addr),(size)) +#define access_ok(type, addr, size) \ + ({ (void)(type); __access_ok((unsigned long)(addr), size); }) /* this function will go away soon - use access_ok() instead */ static inline int __deprecated verify_area(int type, const void __user * addr, unsigned long size) -- cgit v1.2.3-70-g09d2 From 5754c9b649e414f1e3a3ea2ec15e42ed3e42eeb8 Mon Sep 17 00:00:00 2001 From: Keith Owens Date: Wed, 8 Jun 2005 15:49:07 -0700 Subject: [PATCH] Stop arch/i386/kernel/vsyscall-note.o being rebuilt every time arch/i386/kernel/vsyscall-note.o is not listed as a target so its .cmd file is neither considered as a target nor is it read on the next build. This causes vsyscall-note.o to be rebuilt every time that you run make, which causes vmlinux to be rebuilt every time. Signed-off-by: Keith Owens Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile index 0fbcfe00dd8..51ecd512603 100644 --- a/arch/i386/kernel/Makefile +++ b/arch/i386/kernel/Makefile @@ -43,7 +43,7 @@ obj-$(CONFIG_SCx200) += scx200.o # Note: kbuild does not track this dependency due to usage of .incbin $(obj)/vsyscall.o: $(obj)/vsyscall-int80.so $(obj)/vsyscall-sysenter.so targets += $(foreach F,int80 sysenter,vsyscall-$F.o vsyscall-$F.so) -targets += vsyscall.lds +targets += vsyscall-note.o vsyscall.lds # The DSO images are built using a special linker script. quiet_cmd_syscall = SYSCALL $@ -- cgit v1.2.3-70-g09d2 From 42442ed5744b03f5351a142649b8b4c97e6950ab Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 8 Jun 2005 15:49:25 -0700 Subject: [PATCH] revert x86_64-use-the-e820-hole-to-map-the-iommu-agp-aperture Martin Bligh determined that this patch is causing his test box to not boot. Revert. Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/x86_64/kernel/aperture.c | 41 +++++++++++------------------------------ 1 file changed, 11 insertions(+), 30 deletions(-) diff --git a/arch/x86_64/kernel/aperture.c b/arch/x86_64/kernel/aperture.c index a491f72cc96..504e6347499 100644 --- a/arch/x86_64/kernel/aperture.c +++ b/arch/x86_64/kernel/aperture.c @@ -33,12 +33,10 @@ int fallback_aper_force __initdata = 0; int fix_aperture __initdata = 1; -#define NB_ID_3 (PCI_VENDOR_ID_AMD | (0x1103<<16)) +/* This code runs before the PCI subsystem is initialized, so just + access the northbridge directly. */ -static struct resource aper_res = { - .name = "Aperture", - .flags = IORESOURCE_MEM, -}; +#define NB_ID_3 (PCI_VENDOR_ID_AMD | (0x1103<<16)) static u32 __init allocate_aperture(void) { @@ -55,24 +53,11 @@ static u32 __init allocate_aperture(void) aper_size = (32 * 1024 * 1024) << fallback_aper_order; /* - * Aperture has to be naturally aligned. This means an 2GB - * aperture won't have much chances to find a place in the - * lower 4GB of memory. Unfortunately we cannot move it up - * because that would make the IOMMU useless. + * Aperture has to be naturally aligned. This means an 2GB aperture won't + * have much chances to find a place in the lower 4GB of memory. + * Unfortunately we cannot move it up because that would make the + * IOMMU useless. */ - - /* First try to find some free unused space */ - if (!allocate_resource(&iomem_resource, &aper_res, - aper_size, - 0, 0xffffffff, - aper_size, - NULL, NULL)) { - printk(KERN_INFO "Putting aperture at %lx-%lx\n", - aper_res.start, aper_res.end); - return aper_res.start; - } - - /* No free space found. Go on to waste some memory... */ p = __alloc_bootmem_node(nd0, aper_size, aper_size, 0); if (!p || __pa(p)+aper_size > 0xffffffff) { printk("Cannot allocate aperture memory hole (%p,%uK)\n", @@ -81,7 +66,7 @@ static u32 __init allocate_aperture(void) free_bootmem_node(nd0, (unsigned long)p, aper_size); return 0; } - printk("Mapping aperture over %d KB of precious RAM @ %lx\n", + printk("Mapping aperture over %d KB of RAM @ %lx\n", aper_size >> 10, __pa(p)); return (u32)__pa(p); } @@ -102,16 +87,10 @@ static int __init aperture_valid(char *name, u64 aper_base, u32 aper_size) printk("Aperture from %s pointing to e820 RAM. Ignoring.\n",name); return 0; } - /* Don't check the resource here because the aperture is usually - in an e820 reserved area, and we allocated these earlier. */ return 1; } -/* - * Find a PCI capability. - * This code runs before the PCI subsystem is initialized, so just - * access the northbridge directly. - */ +/* Find a PCI capability */ static __u32 __init find_cap(int num, int slot, int func, int cap) { u8 pos; @@ -276,6 +255,8 @@ void __init iommu_hole_init(void) fallback_aper_force) { printk("Your BIOS doesn't leave a aperture memory hole\n"); printk("Please enable the IOMMU option in the BIOS setup\n"); + printk("This costs you %d MB of RAM\n", + 32 << fallback_aper_order); aper_order = fallback_aper_order; aper_alloc = allocate_aperture(); -- cgit v1.2.3-70-g09d2 From 63224d1e8b4cf87cc7420201a8cb3b44b9bf0b40 Mon Sep 17 00:00:00 2001 From: Ananth N Mavinakayanahalli Date: Wed, 8 Jun 2005 15:49:41 -0700 Subject: [PATCH] ppc64 kprobes: correct kprobe registration return values Add stricter checks during kprobe registration. Return correct error value so insmod doesn't succeed. Also printk reason for registration failure. Signed-off-by: Ananth N Mavinakayanahalli Signed-off-by: Paul Mackerras Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc64/kernel/kprobes.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/arch/ppc64/kernel/kprobes.c b/arch/ppc64/kernel/kprobes.c index 5a9f47b18c4..8f331724431 100644 --- a/arch/ppc64/kernel/kprobes.c +++ b/arch/ppc64/kernel/kprobes.c @@ -45,12 +45,17 @@ static struct pt_regs jprobe_saved_regs; int arch_prepare_kprobe(struct kprobe *p) { + int ret = 0; kprobe_opcode_t insn = *p->addr; - if (IS_MTMSRD(insn) || IS_RFID(insn)) - /* cannot put bp on RFID/MTMSRD */ - return 1; - return 0; + if ((unsigned long)p->addr & 0x03) { + printk("Attempt to register kprobe at an unaligned address\n"); + ret = -EINVAL; + } else if (IS_MTMSRD(insn) || IS_RFID(insn)) { + printk("Cannot register a kprobe on rfid or mtmsrd\n"); + ret = -EINVAL; + } + return ret; } void arch_copy_kprobe(struct kprobe *p) -- cgit v1.2.3-70-g09d2 From f829fd23c87918374bac0d90404fe12f0e788d52 Mon Sep 17 00:00:00 2001 From: Ananth N Mavinakayanahalli Date: Wed, 8 Jun 2005 15:50:00 -0700 Subject: [PATCH] ppc64 kprobes: remove spurious MSR_SE masking Remove spurious MSR_SE reset during kprobe processing. single_step_exception() already does it for us. Reset it to be safe when executing the fault_handler. Signed-off-by: Ananth N Mavinakayanahalli Signed-off-by: Paul Mackerras Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc64/kernel/kprobes.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/ppc64/kernel/kprobes.c b/arch/ppc64/kernel/kprobes.c index 8f331724431..e950a2058a1 100644 --- a/arch/ppc64/kernel/kprobes.c +++ b/arch/ppc64/kernel/kprobes.c @@ -177,8 +177,6 @@ static void resume_execution(struct kprobe *p, struct pt_regs *regs) ret = emulate_step(regs, p->ainsn.insn[0]); if (ret == 0) regs->nip = (unsigned long)p->addr + 4; - - regs->msr &= ~MSR_SE; } static inline int post_kprobe_handler(struct pt_regs *regs) @@ -215,6 +213,7 @@ static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr) if (kprobe_status & KPROBE_HIT_SS) { resume_execution(current_kprobe, regs); + regs->msr &= ~MSR_SE; regs->msr |= kprobe_saved_msr; unlock_kprobes(); -- cgit v1.2.3-70-g09d2 From 05062d96a23ec0959ee5ea969f40813170c73c0e Mon Sep 17 00:00:00 2001 From: Peter Chubb Date: Wed, 8 Jun 2005 15:50:20 -0700 Subject: [PATCH] ia64: fix floating-point preemption problem There've been reports of problems with CONFIG_PREEMPT=y and the high floating point partition. This is caused by the possibility of preemption and rescheduling on a different processor while saving or restioirng the high partition. The only places where the FPU state is touched are in ptrace, in switch_to(), and where handling a floating-point exception. In switch_to() preemption is off. So it's only in trap.c and ptrace.c that we need to prevent preemption. Here is a patch that adds commentary to make the conditions clear, and adds appropriate preempt_{en,dis}able() calls to make it so. In trap.c I use preempt_enable_no_resched(), as we're about to return to user space where the preemption flag will be checked anyway. Signed-off-by: Peter Chubb Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ia64/kernel/ptrace.c | 6 ++++++ arch/ia64/kernel/traps.c | 11 ++++++++++- include/asm-ia64/processor.h | 10 ++++++++-- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c index 08c8a5eb25a..575a8f657b3 100644 --- a/arch/ia64/kernel/ptrace.c +++ b/arch/ia64/kernel/ptrace.c @@ -635,11 +635,17 @@ ia64_flush_fph (struct task_struct *task) { struct ia64_psr *psr = ia64_psr(ia64_task_regs(task)); + /* + * Prevent migrating this task while + * we're fiddling with the FPU state + */ + preempt_disable(); if (ia64_is_local_fpu_owner(task) && psr->mfh) { psr->mfh = 0; task->thread.flags |= IA64_THREAD_FPH_VALID; ia64_save_fpu(&task->thread.fph[0]); } + preempt_enable(); } /* diff --git a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c index 9bad6652d53..1861173bd4f 100644 --- a/arch/ia64/kernel/traps.c +++ b/arch/ia64/kernel/traps.c @@ -220,13 +220,21 @@ disabled_fph_fault (struct pt_regs *regs) /* first, grant user-level access to fph partition: */ psr->dfh = 0; + + /* + * Make sure that no other task gets in on this processor + * while we're claiming the FPU + */ + preempt_disable(); #ifndef CONFIG_SMP { struct task_struct *fpu_owner = (struct task_struct *)ia64_get_kr(IA64_KR_FPU_OWNER); - if (ia64_is_local_fpu_owner(current)) + if (ia64_is_local_fpu_owner(current)) { + preempt_enable_no_resched(); return; + } if (fpu_owner) ia64_flush_fph(fpu_owner); @@ -244,6 +252,7 @@ disabled_fph_fault (struct pt_regs *regs) */ psr->mfh = 1; } + preempt_enable_no_resched(); } static inline int diff --git a/include/asm-ia64/processor.h b/include/asm-ia64/processor.h index 9e1ba8b7fb6..91bbd1f2246 100644 --- a/include/asm-ia64/processor.h +++ b/include/asm-ia64/processor.h @@ -403,7 +403,10 @@ extern void ia64_setreg_unknown_kr (void); * task_struct at this point. */ -/* Return TRUE if task T owns the fph partition of the CPU we're running on. */ +/* + * Return TRUE if task T owns the fph partition of the CPU we're running on. + * Must be called from code that has preemption disabled. + */ #define ia64_is_local_fpu_owner(t) \ ({ \ struct task_struct *__ia64_islfo_task = (t); \ @@ -411,7 +414,10 @@ extern void ia64_setreg_unknown_kr (void); && __ia64_islfo_task == (struct task_struct *) ia64_get_kr(IA64_KR_FPU_OWNER)); \ }) -/* Mark task T as owning the fph partition of the CPU we're running on. */ +/* + * Mark task T as owning the fph partition of the CPU we're running on. + * Must be called from code that has preemption disabled. + */ #define ia64_set_local_fpu_owner(t) do { \ struct task_struct *__ia64_slfo_task = (t); \ __ia64_slfo_task->thread.last_fph_cpu = smp_processor_id(); \ -- cgit v1.2.3-70-g09d2 From 4f58802fae8a51d9e79454746584175c14f84519 Mon Sep 17 00:00:00 2001 From: Lars Marowsky-Bree Date: Wed, 8 Jun 2005 15:50:31 -0700 Subject: [PATCH] dm: Handle READA requests in dm-mpath.c READA errors failing with EWOULDBLOCK/EAGAIN do not constitute a valid reason for failing the path; this lead to erratic errors on DM multipath devices. This error can be safely propagated upwards without failing the path. Acked-by: Kevin Corry Acked-by: Jens Axboe Signed-off-by: Lars Marowsky-Bree Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/dm-mpath.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c index 1e97b3c12bd..0c1b8520ef8 100644 --- a/drivers/md/dm-mpath.c +++ b/drivers/md/dm-mpath.c @@ -985,6 +985,9 @@ static int do_end_io(struct multipath *m, struct bio *bio, if (!error) return 0; /* I/O complete */ + if ((error == -EWOULDBLOCK) && bio_rw_ahead(bio)) + return error; + spin_lock(&m->lock); if (!m->nr_valid_paths) { if (!m->queue_if_no_path || m->suspended) { -- cgit v1.2.3-70-g09d2 From ce10d979053379553757c3b178a138facaddff82 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Wed, 8 Jun 2005 21:59:15 +1000 Subject: [PATCH] ppc64: Fix PER_LINUX32 behaviour This patch fixes some bugs in the ppc64 PER_LINUX32 implementation, noted by Juergen Kreileder: * uname(2) doesn't respect PER_LINUX32, it returns 'ppc64' instead of 'ppc' * Child processes of a PER_LINUX32 process don't inherit PER_LINUX32 Along the way I took the opportunity to move things around so that sys_ppc32.c only has 32-bit syscall emulation functions and to remove the obsolete "fakeppc" command line option. Signed-off-by: Paul Mackerras Signed-off-by: Linus Torvalds --- arch/ppc64/kernel/misc.S | 2 +- arch/ppc64/kernel/sys_ppc32.c | 70 ++++++++++++++++++++----------------------- arch/ppc64/kernel/syscalls.c | 33 ++++++++++++-------- include/asm-ppc64/elf.h | 4 +-- 4 files changed, 56 insertions(+), 53 deletions(-) diff --git a/arch/ppc64/kernel/misc.S b/arch/ppc64/kernel/misc.S index b944717c1db..e3c73b3425d 100644 --- a/arch/ppc64/kernel/misc.S +++ b/arch/ppc64/kernel/misc.S @@ -792,7 +792,7 @@ _GLOBAL(sys_call_table32) .llong .compat_sys_newstat .llong .compat_sys_newlstat .llong .compat_sys_newfstat - .llong .sys_uname + .llong .sys32_uname .llong .sys_ni_syscall /* 110 old iopl syscall */ .llong .sys_vhangup .llong .sys_ni_syscall /* old idle syscall */ diff --git a/arch/ppc64/kernel/sys_ppc32.c b/arch/ppc64/kernel/sys_ppc32.c index 7cf7a960002..9c8e317c598 100644 --- a/arch/ppc64/kernel/sys_ppc32.c +++ b/arch/ppc64/kernel/sys_ppc32.c @@ -791,31 +791,6 @@ asmlinkage int sys32_pciconfig_iobase(u32 which, u32 in_bus, u32 in_devfn) } -asmlinkage int ppc64_newuname(struct new_utsname __user * name) -{ - int errno = sys_newuname(name); - - if (current->personality == PER_LINUX32 && !errno) { - if(copy_to_user(name->machine, "ppc\0\0", 8)) { - errno = -EFAULT; - } - } - return errno; -} - -asmlinkage int ppc64_personality(unsigned long personality) -{ - int ret; - if (current->personality == PER_LINUX32 && personality == PER_LINUX) - personality = PER_LINUX32; - ret = sys_personality(personality); - if (ret == PER_LINUX32) - ret = PER_LINUX; - return ret; -} - - - /* Note: it is necessary to treat mode as an unsigned int, * with the corresponding cast to a signed int to insure that the * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) @@ -1158,26 +1133,47 @@ asmlinkage long sys32_sysctl(struct __sysctl_args32 __user *args) } #endif +asmlinkage int sys32_uname(struct old_utsname __user * name) +{ + int err = 0; + + down_read(&uts_sem); + if (copy_to_user(name, &system_utsname, sizeof(*name))) + err = -EFAULT; + up_read(&uts_sem); + if (!err && personality(current->personality) == PER_LINUX32) { + /* change "ppc64" to "ppc" */ + if (__put_user(0, name->machine + 3) + || __put_user(0, name->machine + 4)) + err = -EFAULT; + } + return err; +} + asmlinkage int sys32_olduname(struct oldold_utsname __user * name) { int error; - - if (!name) - return -EFAULT; + if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname))) return -EFAULT; down_read(&uts_sem); error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN); - error -= __put_user(0,name->sysname+__OLD_UTS_LEN); - error -= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN); - error -= __put_user(0,name->nodename+__OLD_UTS_LEN); - error -= __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN); - error -= __put_user(0,name->release+__OLD_UTS_LEN); - error -= __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN); - error -= __put_user(0,name->version+__OLD_UTS_LEN); - error -= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN); - error = __put_user(0,name->machine+__OLD_UTS_LEN); + error |= __put_user(0,name->sysname+__OLD_UTS_LEN); + error |= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN); + error |= __put_user(0,name->nodename+__OLD_UTS_LEN); + error |= __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN); + error |= __put_user(0,name->release+__OLD_UTS_LEN); + error |= __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN); + error |= __put_user(0,name->version+__OLD_UTS_LEN); + error |= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN); + error |= __put_user(0,name->machine+__OLD_UTS_LEN); + if (personality(current->personality) == PER_LINUX32) { + /* change "ppc64" to "ppc" */ + error |= __put_user(0, name->machine + 3); + error |= __put_user(0, name->machine + 4); + } + up_read(&uts_sem); error = error ? -EFAULT : 0; diff --git a/arch/ppc64/kernel/syscalls.c b/arch/ppc64/kernel/syscalls.c index f2865ff8d2f..a8cbb202b8c 100644 --- a/arch/ppc64/kernel/syscalls.c +++ b/arch/ppc64/kernel/syscalls.c @@ -199,24 +199,33 @@ out: return ret; } -static int __init set_fakeppc(char *str) +long ppc64_personality(unsigned long personality) { - if (*str) - return 0; - init_task.personality = PER_LINUX32; - return 1; + long ret; + + if (personality(current->personality) == PER_LINUX32 + && personality == PER_LINUX) + personality = PER_LINUX32; + ret = sys_personality(personality); + if (ret == PER_LINUX32) + ret = PER_LINUX; + return ret; } -__setup("fakeppc", set_fakeppc); -asmlinkage int sys_uname(struct old_utsname __user * name) +long ppc64_newuname(struct new_utsname __user * name) { - int err = -EFAULT; - + int err = 0; + down_read(&uts_sem); - if (name && !copy_to_user(name, &system_utsname, sizeof (*name))) - err = 0; + if (copy_to_user(name, &system_utsname, sizeof(*name))) + err = -EFAULT; up_read(&uts_sem); - + if (!err && personality(current->personality) == PER_LINUX32) { + /* change ppc64 to ppc */ + if (__put_user(0, name->machine + 3) + || __put_user(0, name->machine + 4)) + err = -EFAULT; + } return err; } diff --git a/include/asm-ppc64/elf.h b/include/asm-ppc64/elf.h index 6c42d61bedd..085eedb956f 100644 --- a/include/asm-ppc64/elf.h +++ b/include/asm-ppc64/elf.h @@ -221,9 +221,7 @@ do { \ set_thread_flag(TIF_ABI_PENDING); \ else \ clear_thread_flag(TIF_ABI_PENDING); \ - if (ibcs2) \ - set_personality(PER_SVR4); \ - else if (current->personality != PER_LINUX32) \ + if (personality(current->personality) != PER_LINUX32) \ set_personality(PER_LINUX); \ } while (0) -- cgit v1.2.3-70-g09d2 From e1dd23a0012c3929737798fda9fede0e783f4ff3 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Wed, 8 Jun 2005 13:02:25 +0200 Subject: [PATCH] sata_sil: Fix FIFO PCI Bus Arbitration kernel oops Correct this. diff --git a/drivers/scsi/sata_sil.c b/drivers/scsi/sata_sil.c --- drivers/scsi/sata_sil.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/sata_sil.c b/drivers/scsi/sata_sil.c index 238580d244e..49ed557a4b6 100644 --- a/drivers/scsi/sata_sil.c +++ b/drivers/scsi/sata_sil.c @@ -432,7 +432,13 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) writeb(cls, mmio_base + SIL_FIFO_R0); writeb(cls, mmio_base + SIL_FIFO_W0); writeb(cls, mmio_base + SIL_FIFO_R1); - writeb(cls, mmio_base + SIL_FIFO_W2); + writeb(cls, mmio_base + SIL_FIFO_W1); + if (ent->driver_data == sil_3114) { + writeb(cls, mmio_base + SIL_FIFO_R2); + writeb(cls, mmio_base + SIL_FIFO_W2); + writeb(cls, mmio_base + SIL_FIFO_R3); + writeb(cls, mmio_base + SIL_FIFO_W3); + } } else printk(KERN_WARNING DRV_NAME "(%s): cache line size not set. Driver may not function\n", pci_name(pdev)); -- cgit v1.2.3-70-g09d2 From 6952df035509717bdc46194b2a3d6ffb9349f267 Mon Sep 17 00:00:00 2001 From: Albert Lee Date: Mon, 6 Jun 2005 15:56:03 +0800 Subject: [PATCH] sg traverse fix for __atapi_pio_bytes() Problem: Incorrect md5sum when using ATAPI PIO mode to verify a distro CD. Root cause: sg traverse problem. In __atapi_pio_bytes(), if qc->cursg++ is increased and "goto next_page" is executed, then sg is not updated to the new qc->cursg and the old sg is overwritten with the new data. Changes: - Replace "goto next_page" with "goto next_sg" to make sg updated. Signed-off-by: Albert Lee --- drivers/scsi/libata-core.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index 21d194c6ace..9e58f134f68 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c @@ -2577,7 +2577,6 @@ static void __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes) next_sg: sg = &qc->sg[qc->cursg]; -next_page: page = sg->page; offset = sg->offset + qc->cursg_ofs; @@ -2585,6 +2584,7 @@ next_page: page = nth_page(page, (offset >> PAGE_SHIFT)); offset %= PAGE_SIZE; + /* don't overrun current sg */ count = min(sg->length - qc->cursg_ofs, bytes); /* don't cross page boundaries */ @@ -2609,8 +2609,6 @@ next_page: kunmap(page); if (bytes) { - if (qc->cursg_ofs < sg->length) - goto next_page; goto next_sg; } } -- cgit v1.2.3-70-g09d2 From 03e49d40ea3436cae0fe43708f11584130ee4a0c Mon Sep 17 00:00:00 2001 From: Scott Murray Date: Mon, 6 Jun 2005 15:48:04 -0400 Subject: [PATCH] PCI Hotplug: fix CPCI reference counting bug Here's a patch that fixes up the pci_dev refcounting in the CPCI code. I've done some testing against it and it seems fine here. Signed-off-by: Scott Murray Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/cpci_hotplug_core.c | 2 ++ drivers/pci/hotplug/cpci_hotplug_pci.c | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/pci/hotplug/cpci_hotplug_core.c b/drivers/pci/hotplug/cpci_hotplug_core.c index 8132d946c38..30af105271a 100644 --- a/drivers/pci/hotplug/cpci_hotplug_core.c +++ b/drivers/pci/hotplug/cpci_hotplug_core.c @@ -217,6 +217,8 @@ static void release_slot(struct hotplug_slot *hotplug_slot) kfree(slot->hotplug_slot->info); kfree(slot->hotplug_slot->name); kfree(slot->hotplug_slot); + if (slot->dev) + pci_dev_put(slot->dev); kfree(slot); } diff --git a/drivers/pci/hotplug/cpci_hotplug_pci.c b/drivers/pci/hotplug/cpci_hotplug_pci.c index c878028ad21..225b5e551dd 100644 --- a/drivers/pci/hotplug/cpci_hotplug_pci.c +++ b/drivers/pci/hotplug/cpci_hotplug_pci.c @@ -315,9 +315,12 @@ int cpci_unconfigure_slot(struct slot* slot) PCI_DEVFN(PCI_SLOT(slot->devfn), i)); if (dev) { pci_remove_bus_device(dev); - slot->dev = NULL; + pci_dev_put(dev); } } + pci_dev_put(slot->dev); + slot->dev = NULL; + dbg("%s - exit", __FUNCTION__); return 0; } -- cgit v1.2.3-70-g09d2 From 9f793d2c77ec5818679e4747c554d9333cecf476 Mon Sep 17 00:00:00 2001 From: Pete Zaitcev Date: Mon, 6 Jun 2005 13:54:59 -0700 Subject: [PATCH] USB: fix ub issues This smoothes two imperfections: - Increase number of LUNs per device from 4 to 9. The best solution would be to remove this limit altogether, but that has to wait until the time when more than 26 hosts are allowed. - Replace mdelay with msleep in a probing routine. Signed-off-by: Pete Zaitcev Signed-off-by: Greg Kroah-Hartman --- drivers/block/ub.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/block/ub.c b/drivers/block/ub.c index adc4dcc306f..19c5e59bcfa 100644 --- a/drivers/block/ub.c +++ b/drivers/block/ub.c @@ -51,7 +51,7 @@ * This many LUNs per USB device. * Every one of them takes a host, see UB_MAX_HOSTS. */ -#define UB_MAX_LUNS 4 +#define UB_MAX_LUNS 9 /* */ @@ -2100,7 +2100,7 @@ static int ub_probe(struct usb_interface *intf, nluns = rc; break; } - mdelay(100); + msleep(100); } for (i = 0; i < nluns; i++) { -- cgit v1.2.3-70-g09d2 From 76854ceac3ef3408ab9a50a2521147fb14779f58 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 2 Jun 2005 10:34:11 +0100 Subject: [PATCH] USB: ftdi_sio: avoid losing received data in tty-ldisc ftdi_sio: Avoid losing bytes at tty-ldisc. This patch was originally developed by Daniel Smertnig. I (Ian Abbott) made a few changes. It has been tested by both Daniel and I, at least for raw, non-canonical receive data processing. Here is Daniel's original description of the patch: === During a project in which I was using a FTDI 232BM to transmit data at relative high speeds (625kBit/s), I noticed a problem where data was lost even if flow control was enabled: The FTDI-Driver receives 512 Bytes of data over USB at a time, which consists of 8 64-Byte packets. Subtracting the 2 bytes of status information included in each packet this gives 496 "real" data bytes per read. This data is passed (indirectly, via the flip buffers) to the tty line discipline which takes care of throttling when there the free buffer space reaches TTY_THRESHOLD_THROTTLE (128). Because the FTDI driver processes up to 496 bytes at a time, throttling won't happen in time and the line discipline will discard the remaining bytes. To avoid this the patch passes data in 62-byte blocks to the tty layer and checks the available space in the ldisc-buffers. If there isn't enough free space, processing the rest of the data is delayed using a workqueue. Note: The original problem should be easily reproducible with a userspace program which does slow & small reads. === Signed-off-by: Ian Abbott Signed-off-by: Daniel Smertnig Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 118 ++++++++++++++++++++++++++++++++---------- 1 file changed, 91 insertions(+), 27 deletions(-) diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 051c3a77b41..3bfcc7b9f86 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -264,7 +264,7 @@ /* * Version Information */ -#define DRIVER_VERSION "v1.4.1" +#define DRIVER_VERSION "v1.4.2" #define DRIVER_AUTHOR "Greg Kroah-Hartman , Bill Ryder , Kuba Ober " #define DRIVER_DESC "USB FTDI Serial Converters Driver" @@ -687,6 +687,8 @@ struct ftdi_private { char prev_status, diff_status; /* Used for TIOCMIWAIT */ __u8 rx_flags; /* receive state flags (throttling) */ spinlock_t rx_lock; /* spinlock for receive state */ + struct work_struct rx_work; + int rx_processed; __u16 interface; /* FT2232C port interface (0 for FT232/245) */ @@ -717,7 +719,7 @@ static int ftdi_write_room (struct usb_serial_port *port); static int ftdi_chars_in_buffer (struct usb_serial_port *port); static void ftdi_write_bulk_callback (struct urb *urb, struct pt_regs *regs); static void ftdi_read_bulk_callback (struct urb *urb, struct pt_regs *regs); -static void ftdi_process_read (struct usb_serial_port *port); +static void ftdi_process_read (void *param); static void ftdi_set_termios (struct usb_serial_port *port, struct termios * old); static int ftdi_tiocmget (struct usb_serial_port *port, struct file *file); static int ftdi_tiocmset (struct usb_serial_port *port, struct file * file, unsigned int set, unsigned int clear); @@ -1387,6 +1389,8 @@ static int ftdi_common_startup (struct usb_serial *serial) port->read_urb->transfer_buffer_length = BUFSZ; } + INIT_WORK(&priv->rx_work, ftdi_process_read, port); + /* Free port's existing write urb and transfer buffer. */ if (port->write_urb) { usb_free_urb (port->write_urb); @@ -1617,6 +1621,7 @@ static int ftdi_open (struct usb_serial_port *port, struct file *filp) spin_unlock_irqrestore(&priv->rx_lock, flags); /* Start reading from the device */ + priv->rx_processed = 0; usb_fill_bulk_urb(port->read_urb, dev, usb_rcvbulkpipe(dev, port->bulk_in_endpointAddress), port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length, @@ -1667,6 +1672,10 @@ static void ftdi_close (struct usb_serial_port *port, struct file *filp) err("Error from RTS LOW urb"); } } /* Note change no line if hupcl is off */ + + /* cancel any scheduled reading */ + cancel_delayed_work(&priv->rx_work); + flush_scheduled_work(); /* shutdown our bulk read */ if (port->read_urb) @@ -1862,23 +1871,14 @@ static void ftdi_read_bulk_callback (struct urb *urb, struct pt_regs *regs) return; } - /* If throttled, delay receive processing until unthrottled. */ - spin_lock(&priv->rx_lock); - if (priv->rx_flags & THROTTLED) { - dbg("Deferring read urb processing until unthrottled"); - priv->rx_flags |= ACTUALLY_THROTTLED; - spin_unlock(&priv->rx_lock); - return; - } - spin_unlock(&priv->rx_lock); - ftdi_process_read(port); } /* ftdi_read_bulk_callback */ -static void ftdi_process_read (struct usb_serial_port *port) +static void ftdi_process_read (void *param) { /* ftdi_process_read */ + struct usb_serial_port *port = (struct usb_serial_port*)param; struct urb *urb; struct tty_struct *tty; struct ftdi_private *priv; @@ -1889,6 +1889,7 @@ static void ftdi_process_read (struct usb_serial_port *port) int result; int need_flip; int packet_offset; + unsigned long flags; dbg("%s - port %d", __FUNCTION__, port->number); @@ -1915,12 +1916,18 @@ static void ftdi_process_read (struct usb_serial_port *port) data = urb->transfer_buffer; - /* The first two bytes of every read packet are status */ - if (urb->actual_length > 2) { - usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data); + if (priv->rx_processed) { + dbg("%s - already processed: %d bytes, %d remain", __FUNCTION__, + priv->rx_processed, + urb->actual_length - priv->rx_processed); } else { - dbg("Status only: %03oo %03oo",data[0],data[1]); - } + /* The first two bytes of every read packet are status */ + if (urb->actual_length > 2) { + usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data); + } else { + dbg("Status only: %03oo %03oo",data[0],data[1]); + } + } /* TO DO -- check for hung up line and handle appropriately: */ @@ -1929,8 +1936,12 @@ static void ftdi_process_read (struct usb_serial_port *port) /* if CD is dropped and the line is not CLOCAL then we should hangup */ need_flip = 0; - for (packet_offset=0; packet_offset < urb->actual_length; packet_offset += PKTSZ) { + for (packet_offset = priv->rx_processed; packet_offset < urb->actual_length; packet_offset += PKTSZ) { + int length; + /* Compare new line status to the old one, signal if different */ + /* N.B. packet may be processed more than once, but differences + * are only processed once. */ if (priv != NULL) { char new_status = data[packet_offset+0] & FTDI_STATUS_B0_MASK; if (new_status != priv->prev_status) { @@ -1940,6 +1951,35 @@ static void ftdi_process_read (struct usb_serial_port *port) } } + length = min(PKTSZ, urb->actual_length-packet_offset)-2; + if (length < 0) { + err("%s - bad packet length: %d", __FUNCTION__, length+2); + length = 0; + } + + /* have to make sure we don't overflow the buffer + with tty_insert_flip_char's */ + if (tty->flip.count+length > TTY_FLIPBUF_SIZE) { + tty_flip_buffer_push(tty); + need_flip = 0; + + if (tty->flip.count != 0) { + /* flip didn't work, this happens when ftdi_process_read() is + * called from ftdi_unthrottle, because TTY_DONT_FLIP is set */ + dbg("%s - flip buffer push failed", __FUNCTION__); + break; + } + } + if (priv->rx_flags & THROTTLED) { + dbg("%s - throttled", __FUNCTION__); + break; + } + if (tty->ldisc.receive_room(tty)-tty->flip.count < length) { + /* break out & wait for throttling/unthrottling to happen */ + dbg("%s - receive room low", __FUNCTION__); + break; + } + /* Handle errors and break */ error_flag = TTY_NORMAL; /* Although the device uses a bitmask and hence can have multiple */ @@ -1962,13 +2002,8 @@ static void ftdi_process_read (struct usb_serial_port *port) error_flag = TTY_FRAME; dbg("FRAMING error"); } - if (urb->actual_length > packet_offset + 2) { - for (i = 2; (i < PKTSZ) && ((i+packet_offset) < urb->actual_length); ++i) { - /* have to make sure we don't overflow the buffer - with tty_insert_flip_char's */ - if(tty->flip.count >= TTY_FLIPBUF_SIZE) { - tty_flip_buffer_push(tty); - } + if (length > 0) { + for (i = 2; i < length+2; i++) { /* Note that the error flag is duplicated for every character received since we don't know which character it applied to */ @@ -2005,6 +2040,35 @@ static void ftdi_process_read (struct usb_serial_port *port) tty_flip_buffer_push(tty); } + if (packet_offset < urb->actual_length) { + /* not completely processed - record progress */ + priv->rx_processed = packet_offset; + dbg("%s - incomplete, %d bytes processed, %d remain", + __FUNCTION__, packet_offset, + urb->actual_length - packet_offset); + /* check if we were throttled while processing */ + spin_lock_irqsave(&priv->rx_lock, flags); + if (priv->rx_flags & THROTTLED) { + priv->rx_flags |= ACTUALLY_THROTTLED; + spin_unlock_irqrestore(&priv->rx_lock, flags); + dbg("%s - deferring remainder until unthrottled", + __FUNCTION__); + return; + } + spin_unlock_irqrestore(&priv->rx_lock, flags); + /* if the port is closed stop trying to read */ + if (port->open_count > 0){ + /* delay processing of remainder */ + schedule_delayed_work(&priv->rx_work, 1); + } else { + dbg("%s - port is closed", __FUNCTION__); + } + return; + } + + /* urb is completely processed */ + priv->rx_processed = 0; + /* if the port is closed stop trying to read */ if (port->open_count > 0){ /* Continue trying to always read */ @@ -2444,7 +2508,7 @@ static void ftdi_unthrottle (struct usb_serial_port *port) spin_unlock_irqrestore(&priv->rx_lock, flags); if (actually_throttled) - ftdi_process_read(port); + schedule_work(&priv->rx_work); } static int __init ftdi_init (void) -- cgit v1.2.3-70-g09d2 From 4e71e47da3367e8df5994a17fb421ddeaa5025e3 Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 9 Jun 2005 16:53:28 +0100 Subject: [PATCH] ARM: Remove zero-byte sized file Remove the remaining zero byte file left over from the Xscale fixes. Signed-off-by: Russell King --- arch/arm/mm/minicache.c | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 arch/arm/mm/minicache.c diff --git a/arch/arm/mm/minicache.c b/arch/arm/mm/minicache.c deleted file mode 100644 index e69de29bb2d..00000000000 -- cgit v1.2.3-70-g09d2 From 12035d64565ae7ecbc7fe906e7fcc8a4a71a3789 Mon Sep 17 00:00:00 2001 From: Dave Neuer Date: Thu, 9 Jun 2005 17:40:55 +0100 Subject: [PATCH] ARM: 2706/1: Fix compile on SA-based iPAQs and remove stale CREDITS info Patch from Dave Neuer This fixes the "multiple definitions of cpufreq_get" errors on StrongARM-based iPAQs. Signed-off-by: Dave Neuer Signed-off-by: Russell King --- CREDITS | 6 +----- arch/arm/Kconfig | 2 +- arch/arm/configs/h3600_defconfig | 24 +++++++++++++++--------- arch/arm/mach-sa1100/Kconfig | 2 +- 4 files changed, 18 insertions(+), 16 deletions(-) diff --git a/CREDITS b/CREDITS index 9bd099d960f..d65ffe5a4d0 100644 --- a/CREDITS +++ b/CREDITS @@ -2475,13 +2475,9 @@ S: Potsdam, New York 13676 S: USA N: Dave Neuer -E: dneuer@innovation-charter.com -E: mr_fred_smoothie@yahoo.com +E: dave.neuer@pobox.com D: Helped implement support for Compaq's H31xx series iPAQs D: Other mostly minor tweaks & bugfixes -S: 325 E. Main St., Suite 3 -S: Carnegie, PA 15105 -S: USA N: Michael Neuffer E: mike@i-Connect.Net diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index bf397a9f8ac..e787029d197 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -497,7 +497,7 @@ source "drivers/cpufreq/Kconfig" config CPU_FREQ_SA1100 bool - depends on CPU_FREQ && (SA1100_LART || SA1100_PLEB) + depends on CPU_FREQ && (SA1100_H3100 || SA1100_H3600 || SA1100_H3800 || SA1100_LART || SA1100_PLEB) default y config CPU_FREQ_SA1110 diff --git a/arch/arm/configs/h3600_defconfig b/arch/arm/configs/h3600_defconfig index b4e297dd54b..b9de07de80f 100644 --- a/arch/arm/configs/h3600_defconfig +++ b/arch/arm/configs/h3600_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.12-rc1-bk2 -# Mon Mar 28 00:02:26 2005 +# Linux kernel version: 2.6.12-rc4 +# Thu Jun 9 01:59:03 2005 # CONFIG_ARM=y CONFIG_MMU=y @@ -16,6 +16,7 @@ CONFIG_GENERIC_IOMAP=y CONFIG_EXPERIMENTAL=y CONFIG_CLEAN_COMPILE=y CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 # # General setup @@ -33,6 +34,8 @@ CONFIG_KOBJECT_UEVENT=y # CONFIG_EMBEDDED is not set CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y @@ -120,6 +123,7 @@ CONFIG_CPU_MINICACHE=y # Bus support # CONFIG_ISA=y +CONFIG_ISA_DMA_API=y # # PCCARD (PCMCIA/CardBus) support @@ -138,6 +142,7 @@ CONFIG_PCMCIA_SA1100=y # # Kernel Features # +# CONFIG_SMP is not set # CONFIG_PREEMPT is not set CONFIG_DISCONTIGMEM=y # CONFIG_LEDS is not set @@ -159,12 +164,13 @@ CONFIG_CPU_FREQ_TABLE=y # CONFIG_CPU_FREQ_DEBUG is not set CONFIG_CPU_FREQ_STAT=y # CONFIG_CPU_FREQ_STAT_DETAILS is not set -CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y -# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set -CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y +# CONFIG_CPU_FREQ_GOV_PERFORMANCE is not set # CONFIG_CPU_FREQ_GOV_POWERSAVE is not set -# CONFIG_CPU_FREQ_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_GOV_USERSPACE=y # CONFIG_CPU_FREQ_GOV_ONDEMAND is not set +CONFIG_CPU_FREQ_SA1100=y # # Floating point emulation @@ -298,7 +304,6 @@ CONFIG_MTD_SA1100=y # # Block devices # -# CONFIG_BLK_DEV_FD is not set # CONFIG_BLK_DEV_XD is not set # CONFIG_BLK_DEV_COW_COMMON is not set CONFIG_BLK_DEV_LOOP=m @@ -379,7 +384,6 @@ CONFIG_NET=y # Networking options # # CONFIG_PACKET is not set -# CONFIG_NETLINK_DEV is not set CONFIG_UNIX=y # CONFIG_NET_KEY is not set CONFIG_INET=y @@ -476,6 +480,7 @@ CONFIG_IRCOMM=m # CONFIG_SMC_IRCC_FIR is not set # CONFIG_ALI_FIR is not set CONFIG_SA1100_FIR=m +# CONFIG_VIA_FIR is not set # CONFIG_BT is not set CONFIG_NETDEVICES=y # CONFIG_DUMMY is not set @@ -647,7 +652,6 @@ CONFIG_LEGACY_PTY_COUNT=256 # # TPM devices # -# CONFIG_TCG_TPM is not set # # I2C support @@ -676,9 +680,11 @@ CONFIG_FB_CFB_FILLRECT=y CONFIG_FB_CFB_COPYAREA=y CONFIG_FB_CFB_IMAGEBLIT=y CONFIG_FB_SOFT_CURSOR=y +# CONFIG_FB_MACMODES is not set # CONFIG_FB_MODE_HELPERS is not set # CONFIG_FB_TILEBLITTING is not set CONFIG_FB_SA1100=y +# CONFIG_FB_S1D13XXX is not set # CONFIG_FB_VIRTUAL is not set # diff --git a/arch/arm/mach-sa1100/Kconfig b/arch/arm/mach-sa1100/Kconfig index 50cde576dad..6923316b3d0 100644 --- a/arch/arm/mach-sa1100/Kconfig +++ b/arch/arm/mach-sa1100/Kconfig @@ -150,7 +150,7 @@ config SA1100_SSP config H3600_SLEEVE tristate "Compaq iPAQ Handheld sleeve support" - depends on SA1100_H3600 + depends on SA1100_H3100 || SA1100_H3600 help Choose this option to enable support for extension packs (sleeves) for the Compaq iPAQ H3XXX series of handheld computers. This option -- cgit v1.2.3-70-g09d2 From a2a64769d0d3cc0380b4b6ecdcb781a2f790a69e Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Thu, 9 Jun 2005 12:29:00 -0700 Subject: [IA64] Fix race condition in the rt_sigprocmask fastcall current->blocked will be set to the value of current->thread_info->flags if the cmpxchg to update thread_info->flags fails. For performance reasons the store into current->blocked was placed in the cmpxchg loop. However, the cmpxchg overwrites the register holding the value to be stored. In the rare case of a retry the value of thread_info->flags will be written into current->blocked. The fix is to use another register so that the register containing the current->blocked value is not overwritten. Signed-off-by: Christoph Lameter Signed-off-by: Tony Luck --- arch/ia64/kernel/fsys.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/ia64/kernel/fsys.S b/arch/ia64/kernel/fsys.S index 4f3cdef7579..962b6c4e32b 100644 --- a/arch/ia64/kernel/fsys.S +++ b/arch/ia64/kernel/fsys.S @@ -460,9 +460,9 @@ EX(.fail_efault, ld8 r14=[r33]) // r14 <- *set ;; st8 [r2]=r14 // update current->blocked with new mask - cmpxchg4.acq r14=[r9],r18,ar.ccv // current->thread_info->flags <- r18 + cmpxchg4.acq r8=[r9],r18,ar.ccv // current->thread_info->flags <- r18 ;; - cmp.ne p6,p0=r17,r14 // update failed? + cmp.ne p6,p0=r17,r8 // update failed? (p6) br.cond.spnt.few 1b // yes -> retry #ifdef CONFIG_SMP -- cgit v1.2.3-70-g09d2 From 7aa0b0d5ab5eed29a49fce55868456bca073d77e Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Thu, 9 Jun 2005 21:59:21 +0100 Subject: [PATCH] ARM: 2707/2: Fix badge4 CPU Frequency build faliure Patch from Vincent Sanders This fixes the "multiple definitions of cpufreq_get" build faliure on the Badge4 SA1100 platform. Signed-off-by: Vincent Sanders Signed-off-by: Russell King --- arch/arm/Kconfig | 2 +- arch/arm/configs/badge4_defconfig | 29 ++++++++++++++++++----------- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index e787029d197..0aeb5f91d11 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -497,7 +497,7 @@ source "drivers/cpufreq/Kconfig" config CPU_FREQ_SA1100 bool - depends on CPU_FREQ && (SA1100_H3100 || SA1100_H3600 || SA1100_H3800 || SA1100_LART || SA1100_PLEB) + depends on CPU_FREQ && (SA1100_H3100 || SA1100_H3600 || SA1100_H3800 || SA1100_LART || SA1100_PLEB || SA1100_BADGE4) default y config CPU_FREQ_SA1110 diff --git a/arch/arm/configs/badge4_defconfig b/arch/arm/configs/badge4_defconfig index 2b4059d2f8e..5d92af975d8 100644 --- a/arch/arm/configs/badge4_defconfig +++ b/arch/arm/configs/badge4_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.12-rc1-bk2 -# Sat Mar 26 21:32:26 2005 +# Linux kernel version: 2.6.12-rc6-git3 +# Thu Jun 9 19:00:50 2005 # CONFIG_ARM=y CONFIG_MMU=y @@ -16,6 +16,7 @@ CONFIG_GENERIC_IOMAP=y CONFIG_EXPERIMENTAL=y CONFIG_CLEAN_COMPILE=y CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 # # General setup @@ -34,6 +35,8 @@ CONFIG_EMBEDDED=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y @@ -109,7 +112,6 @@ CONFIG_CPU_ABRT_EV4=y CONFIG_CPU_CACHE_V4WB=y CONFIG_CPU_CACHE_VIVT=y CONFIG_CPU_TLB_V4WB=y -CONFIG_CPU_MINICACHE=y # # Processor Features @@ -122,6 +124,7 @@ CONFIG_FORCE_MAX_ZONEORDER=9 # Bus support # CONFIG_ISA=y +CONFIG_ISA_DMA_API=y # # PCCARD (PCMCIA/CardBus) support @@ -131,6 +134,7 @@ CONFIG_ISA=y # # Kernel Features # +# CONFIG_SMP is not set # CONFIG_PREEMPT is not set CONFIG_DISCONTIGMEM=y # CONFIG_LEDS is not set @@ -152,12 +156,14 @@ CONFIG_CPU_FREQ_TABLE=y # CONFIG_CPU_FREQ_DEBUG is not set CONFIG_CPU_FREQ_STAT=y # CONFIG_CPU_FREQ_STAT_DETAILS is not set -CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y -# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y CONFIG_CPU_FREQ_GOV_PERFORMANCE=y # CONFIG_CPU_FREQ_GOV_POWERSAVE is not set -# CONFIG_CPU_FREQ_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_GOV_USERSPACE=y # CONFIG_CPU_FREQ_GOV_ONDEMAND is not set +# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set +CONFIG_CPU_FREQ_SA1100=y # # Floating point emulation @@ -294,7 +300,6 @@ CONFIG_PARPORT_NOT_PC=y # # Block devices # -# CONFIG_BLK_DEV_FD is not set # CONFIG_BLK_DEV_XD is not set # CONFIG_PARIDE is not set # CONFIG_BLK_DEV_COW_COMMON is not set @@ -428,7 +433,6 @@ CONFIG_NET=y # CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set -# CONFIG_NETLINK_DEV is not set CONFIG_UNIX=y # CONFIG_NET_KEY is not set CONFIG_INET=y @@ -526,6 +530,7 @@ CONFIG_IRDA_ULTRA=y # CONFIG_SMC_IRCC_FIR is not set # CONFIG_ALI_FIR is not set CONFIG_SA1100_FIR=y +# CONFIG_VIA_FIR is not set CONFIG_BT=m CONFIG_BT_L2CAP=m # CONFIG_BT_SCO is not set @@ -618,7 +623,6 @@ CONFIG_NET_WIRELESS=y # # CONFIG_SERIO is not set # CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y # # Character devices @@ -687,7 +691,6 @@ CONFIG_RTC=m # # TPM devices # -# CONFIG_TCG_TPM is not set # # I2C support @@ -736,6 +739,7 @@ CONFIG_I2C_ELEKTOR=m # CONFIG_SENSORS_LM85 is not set # CONFIG_SENSORS_LM87 is not set # CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set # CONFIG_SENSORS_MAX1619 is not set # CONFIG_SENSORS_PC87360 is not set # CONFIG_SENSORS_SMSC47B397 is not set @@ -747,6 +751,7 @@ CONFIG_I2C_ELEKTOR=m # # Other I2C Chip support # +# CONFIG_SENSORS_DS1337 is not set # CONFIG_SENSORS_EEPROM is not set # CONFIG_SENSORS_PCF8574 is not set # CONFIG_SENSORS_PCF8591 is not set @@ -871,7 +876,6 @@ CONFIG_USB_PRINTER=m # CONFIG_USB_STORAGE=y CONFIG_USB_STORAGE_DEBUG=y -# CONFIG_USB_STORAGE_RW_DETECT is not set # CONFIG_USB_STORAGE_DATAFAB is not set # CONFIG_USB_STORAGE_FREECOM is not set # CONFIG_USB_STORAGE_ISD200 is not set @@ -954,9 +958,11 @@ CONFIG_USB_USS720=m # CONFIG_USB_SERIAL=m CONFIG_USB_SERIAL_GENERIC=y +# CONFIG_USB_SERIAL_AIRPRIME is not set CONFIG_USB_SERIAL_BELKIN=m CONFIG_USB_SERIAL_WHITEHEAT=m CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +# CONFIG_USB_SERIAL_CP2101 is not set # CONFIG_USB_SERIAL_CYPRESS_M8 is not set CONFIG_USB_SERIAL_EMPEG=m CONFIG_USB_SERIAL_FTDI_SIO=m @@ -985,6 +991,7 @@ CONFIG_USB_SERIAL_KEYSPAN=m # CONFIG_USB_SERIAL_KOBIL_SCT is not set CONFIG_USB_SERIAL_MCT_U232=m CONFIG_USB_SERIAL_PL2303=m +# CONFIG_USB_SERIAL_HP4X is not set # CONFIG_USB_SERIAL_SAFE is not set # CONFIG_USB_SERIAL_TI is not set CONFIG_USB_SERIAL_CYBERJACK=m -- cgit v1.2.3-70-g09d2 From 07c6d48fd10a8eeae899e06876aa0b885a8e2a1b Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Thu, 9 Jun 2005 21:59:22 +0100 Subject: [PATCH] ARM: 2708/1: Fix hackkit CPU Frequency build faliure Patch from Vincent Sanders This fixes the "multiple definitions of cpufreq_get" build faliure on the hackkit SA1100 platform. Signed-off-by: Vincent Sanders Signed-off-by: Russell King --- arch/arm/Kconfig | 2 +- arch/arm/configs/hackkit_defconfig | 22 ++++++++++++---------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 0aeb5f91d11..5eee3bcb22b 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -497,7 +497,7 @@ source "drivers/cpufreq/Kconfig" config CPU_FREQ_SA1100 bool - depends on CPU_FREQ && (SA1100_H3100 || SA1100_H3600 || SA1100_H3800 || SA1100_LART || SA1100_PLEB || SA1100_BADGE4) + depends on CPU_FREQ && (SA1100_H3100 || SA1100_H3600 || SA1100_H3800 || SA1100_LART || SA1100_PLEB || SA1100_BADGE4 || SA1100_HACKKIT) default y config CPU_FREQ_SA1110 diff --git a/arch/arm/configs/hackkit_defconfig b/arch/arm/configs/hackkit_defconfig index 6987c8c5ddb..fb41a36a5a6 100644 --- a/arch/arm/configs/hackkit_defconfig +++ b/arch/arm/configs/hackkit_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.12-rc1-bk2 -# Mon Mar 28 00:22:34 2005 +# Linux kernel version: 2.6.12-rc6-git3 +# Thu Jun 9 20:58:58 2005 # CONFIG_ARM=y CONFIG_MMU=y @@ -16,6 +16,7 @@ CONFIG_GENERIC_IOMAP=y CONFIG_EXPERIMENTAL=y CONFIG_CLEAN_COMPILE=y CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 # # General setup @@ -34,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y @@ -109,7 +112,6 @@ CONFIG_CPU_ABRT_EV4=y CONFIG_CPU_CACHE_V4WB=y CONFIG_CPU_CACHE_VIVT=y CONFIG_CPU_TLB_V4WB=y -CONFIG_CPU_MINICACHE=y # # Processor Features @@ -119,6 +121,7 @@ CONFIG_CPU_MINICACHE=y # Bus support # CONFIG_ISA=y +CONFIG_ISA_DMA_API=y # # PCCARD (PCMCIA/CardBus) support @@ -128,6 +131,7 @@ CONFIG_ISA=y # # Kernel Features # +# CONFIG_SMP is not set # CONFIG_PREEMPT is not set CONFIG_DISCONTIGMEM=y CONFIG_LEDS=y @@ -151,12 +155,14 @@ CONFIG_CPU_FREQ_TABLE=y # CONFIG_CPU_FREQ_DEBUG is not set CONFIG_CPU_FREQ_STAT=y # CONFIG_CPU_FREQ_STAT_DETAILS is not set -CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y -# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y CONFIG_CPU_FREQ_GOV_PERFORMANCE=y # CONFIG_CPU_FREQ_GOV_POWERSAVE is not set -# CONFIG_CPU_FREQ_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_GOV_USERSPACE=y # CONFIG_CPU_FREQ_GOV_ONDEMAND is not set +# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set +CONFIG_CPU_FREQ_SA1100=y # # Floating point emulation @@ -280,7 +286,6 @@ CONFIG_MTD_CFI_UTIL=y # # Block devices # -# CONFIG_BLK_DEV_FD is not set # CONFIG_BLK_DEV_XD is not set # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set @@ -338,7 +343,6 @@ CONFIG_NET=y # CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set -# CONFIG_NETLINK_DEV is not set CONFIG_UNIX=y # CONFIG_NET_KEY is not set CONFIG_INET=y @@ -484,7 +488,6 @@ CONFIG_SERIO=y CONFIG_SERIO_SERPORT=y # CONFIG_SERIO_RAW is not set # CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y # # Character devices @@ -533,7 +536,6 @@ CONFIG_LEGACY_PTY_COUNT=256 # # TPM devices # -# CONFIG_TCG_TPM is not set # # I2C support -- cgit v1.2.3-70-g09d2 From 3079ca621e9e09f4593c20a9a2f24237c355f683 Mon Sep 17 00:00:00 2001 From: Steve French Date: Thu, 9 Jun 2005 14:44:07 -0700 Subject: [CIFS] Fix cifs update of page cache. Write at correct offset when out of memory and add_to_page_cache fails. Thanks to Shaggy for pointing out the fix. Signed-off-by: Steve French (sfrench@us.ibm.com) Signed-off-by: Shaggy (shaggy@us.ibm.com) --- fs/cifs/CHANGES | 3 ++- fs/cifs/file.c | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES index 95483baab70..dab4774ee7b 100644 --- a/fs/cifs/CHANGES +++ b/fs/cifs/CHANGES @@ -6,7 +6,8 @@ kills the cifsd thread (NB: killing the cifs kernel threads is not recommended, unmount and rmmod cifs will kill them when they are no longer needed). Fix readdir to ASCII servers (ie older servers which do not support Unicode) and also require asterik. - +Fix out of memory case in which data could be written one page +off in the page cache. Version 1.33 ------------ diff --git a/fs/cifs/file.c b/fs/cifs/file.c index dde2d251fc3..30ab70ce554 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -1352,6 +1352,8 @@ static void cifs_copy_cache_pages(struct address_space *mapping, GFP_KERNEL)) { page_cache_release(page); cFYI(1, ("Add page cache failed")); + data += PAGE_CACHE_SIZE; + bytes_read -= PAGE_CACHE_SIZE; continue; } -- cgit v1.2.3-70-g09d2 From 1e06276704c101bd1ae7b62879faaffcd7496a3e Mon Sep 17 00:00:00 2001 From: Narendra Sankar Date: Fri, 6 May 2005 12:00:05 -0700 Subject: [PATCH] PCI: MSI functionality broken on Serverworks GC chipset MSI functionality is broken on the GC_LE x86 chipset that Serverworks developed and that is being used in various platforms today. Broadcom is going to push out to the kernel MSI enabled Gigabit drivers (in the very near future), and we would like to make sure that MSI does not get enabled on any platforms using the GC_LE chipset (device id 0x17). Following the AMD 8131 example, I am including a patch to disable MSI functionality when a GCNB_LE is detected. Please let me know if there are any issues with this. This is a permanent fix for this chipset, as the hardware will not be updated. Signed-off-by: Narendra Sankar Signed-off-by: Greg Kroah-Hartman --- drivers/pci/quirks.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 2194669300b..968033fd29f 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -456,6 +456,12 @@ static void __init quirk_amd_8131_ioapic(struct pci_dev *dev) } DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_APIC, quirk_amd_8131_ioapic ); +static void __init quirk_svw_msi(struct pci_dev *dev) +{ + pci_msi_quirk = 1; + printk(KERN_WARNING "PCI: MSI quirk detected. pci_msi_quirk set.\n"); +} +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_GCNB_LE, quirk_svw_msi ); #endif /* CONFIG_X86_IO_APIC */ -- cgit v1.2.3-70-g09d2 From 7fbdf1a23be1837b8bc5bcec096015ca99e00aa7 Mon Sep 17 00:00:00 2001 From: Eugene Surovegin Date: Thu, 9 Jun 2005 12:36:29 -0700 Subject: [PATCH] ppc32: add 405EP cpu_spec entry Add a definition for PPC 405EP which was lost somehow during 2.4 -> 2.6 transition. Recent change to arch/ppc/kernel/misc.S ("Fix incorrect CPU_FTR fixup usage for unified caches") triggered this bug and 405EP boards don't boot anymore. Signed-off-by: Eugene Surovegin Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc/kernel/cputable.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/arch/ppc/kernel/cputable.c b/arch/ppc/kernel/cputable.c index 17abf6cd0d9..ce2618ac8ac 100644 --- a/arch/ppc/kernel/cputable.c +++ b/arch/ppc/kernel/cputable.c @@ -860,6 +860,17 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, }, + { /* 405EP */ + .pvr_mask = 0xffff0000, + .pvr_value = 0x51210000, + .cpu_name = "405EP", + .cpu_features = CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_USE_TB, + .cpu_user_features = PPC_FEATURE_32 | + PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, + .icache_bsize = 32, + .dcache_bsize = 32, + }, #endif /* CONFIG_40x */ #ifdef CONFIG_44x -- cgit v1.2.3-70-g09d2 From 243cd55e021baf28babdd88112ac03ae5cd4bb9c Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 9 Jun 2005 12:36:33 -0700 Subject: [PATCH] iseries_veth: Supress spurious WARN_ON() at module unload My patch from a few weeks back (now in mainline), called "Cleanup skbs to prevent unregister_netdevice() hanging", can cause our TX timeout code to fire on machines with lots of VLANs (because it takes > 2 seconds between when we stop the queues and when we're finished stopping the connections). When that happens the TX timeout code freaks out and does a WARN_ON() because as far as it's concerned there shouldn't be a TX timeout happening, which is fair enough. I have a "proper" fix for this, which is to a) do refcounting on connections and b) implement a proper ack timer so we don't keep unacked skbs lying around for ever. But for 2.6.12 I propose just supressing the WARN_ON(). Users will still see the "NETDEV WATCHDOG" warning, but that's not nearly as bad as a WARN_ON() which users interpret as an Oops. Signed-off-by: Michael Ellerman Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/net/iseries_veth.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c index 13ed8dc1e91..55af32e9bf0 100644 --- a/drivers/net/iseries_veth.c +++ b/drivers/net/iseries_veth.c @@ -802,13 +802,14 @@ static void veth_tx_timeout(struct net_device *dev) spin_lock_irqsave(&port->pending_gate, flags); + if (!port->pending_lpmask) { + spin_unlock_irqrestore(&port->pending_gate, flags); + return; + } + printk(KERN_WARNING "%s: Tx timeout! Resetting lp connections: %08x\n", dev->name, port->pending_lpmask); - /* If we've timed out the queue must be stopped, which should - * only ever happen when there is a pending packet. */ - WARN_ON(! port->pending_lpmask); - for (i = 0; i < HVMAXARCHITECTEDLPS; i++) { struct veth_lpar_connection *cnx = veth_cnx[i]; -- cgit v1.2.3-70-g09d2 From 0086b5ec7834b78358dea3f713275a9ae2b229ec Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Fri, 10 Jun 2005 14:19:02 +1000 Subject: [PATCH] ppc32: Fix nasty sleep/wakeup problem Despite all the care lately in making the powermac sleep/wakeup as robust as possible, there is still a nasty related to the use of cpufreq on PMU based machines. Unfortunately, it affects paulus old powerbook so I have to fix it :) We didn't manage to understand what is precisely going on, it leads to memory corruption and might have to do with RAM not beeing properly refreshed when a cpufreq transition is done right before the sleep. The best workaround (and less intrusive at this point) we could come up with is included in this patch. We basically do _not_ force a switch to high speed on suspend anymore (that is what is causing the problem) on those machines. We still force a speed switch on wakeup (since we don't know what speed we are coming back from sleep at, and that seems to work fine). Since, during this short interval, the actual CPU speed might be incorrect, we also hack around by multiplying loops_per_jiffy by 2 (max speed factor on those machines) during early wakeup stage to make sure udelay's during that time aren't too short. For after 2.6.12, we'll change udelay implementation to use the CPU timebase (which is always constant) instead like we do on ppc64 and thus get rid of all those problems. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Linus Torvalds --- arch/ppc/platforms/pmac_cpufreq.c | 7 +++++-- drivers/macintosh/via-pmu.c | 6 ++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/arch/ppc/platforms/pmac_cpufreq.c b/arch/ppc/platforms/pmac_cpufreq.c index 937f46df711..5fdd4f607a4 100644 --- a/arch/ppc/platforms/pmac_cpufreq.c +++ b/arch/ppc/platforms/pmac_cpufreq.c @@ -83,7 +83,7 @@ static u32 frequency_gpio; static u32 slew_done_gpio; static int no_schedule; static int has_cpu_l2lve; - +static int is_pmu_based; /* There are only two frequency states for each processor. Values * are in kHz for the time being. @@ -463,7 +463,7 @@ static int __pmac pmac_cpufreq_suspend(struct cpufreq_policy *policy, u32 state) */ no_schedule = 1; sleep_freq = cur_freq; - if (cur_freq == low_freq) + if (cur_freq == low_freq && !is_pmu_based) do_set_cpu_speed(CPUFREQ_HIGH, 0); return 0; } @@ -588,6 +588,7 @@ static int __pmac pmac_cpufreq_init_MacRISC3(struct device_node *cpunode) return 1; hi_freq = (*value) / 1000; set_speed_proc = pmu_set_cpu_speed; + is_pmu_based = 1; return 0; } @@ -692,6 +693,7 @@ static int __init pmac_cpufreq_setup(void) hi_freq = cur_freq; low_freq = 400000; set_speed_proc = pmu_set_cpu_speed; + is_pmu_based = 1; } /* Else check for TiPb 400 & 500 */ else if (machine_is_compatible("PowerBook3,2")) { @@ -703,6 +705,7 @@ static int __init pmac_cpufreq_setup(void) hi_freq = cur_freq; low_freq = 300000; set_speed_proc = pmu_set_cpu_speed; + is_pmu_based = 1; } /* Else check for 750FX */ else if (PVR_VER(mfspr(SPRN_PVR)) == 0x7000) diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c index bb9f4044c74..b941ee22099 100644 --- a/drivers/macintosh/via-pmu.c +++ b/drivers/macintosh/via-pmu.c @@ -2593,6 +2593,9 @@ powerbook_sleep_Core99(void) /* Restore VIA */ restore_via_state(); + /* tweak LPJ before cpufreq is there */ + loops_per_jiffy *= 2; + /* Restore video */ pmac_call_early_video_resume(); @@ -2613,6 +2616,9 @@ powerbook_sleep_Core99(void) pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, pmu_intr_mask); pmu_wait_complete(&req); + /* Restore LPJ, cpufreq will adjust the cpu frequency */ + loops_per_jiffy /= 2; + pmac_wakeup_devices(); return 0; -- cgit v1.2.3-70-g09d2 From e98ded32f37a538b906d98059b3db71be36405a7 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 10 Jun 2005 18:47:38 +1000 Subject: [PATCH] drm add i945G pci id Add pci identifier for i945G chipset Signed-off-by: Dave Airlie --- drivers/char/drm/drm_pciids.h | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/char/drm/drm_pciids.h b/drivers/char/drm/drm_pciids.h index 54a2914e3a3..11c6950158b 100644 --- a/drivers/char/drm/drm_pciids.h +++ b/drivers/char/drm/drm_pciids.h @@ -220,5 +220,6 @@ {0x8086, 0x2572, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x8086, 0x2582, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x8086, 0x2592, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ + {0x8086, 0x2772, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0, 0, 0} -- cgit v1.2.3-70-g09d2 From 74e8ebc55d85ca1acb3e73610965bea63cc39054 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 10 Jun 2005 19:27:51 +1000 Subject: [PATCH] remove bogus hack from radeon IRQ handler This removes a bogus hack from the radeon IRQ handler. There is a better fix from myself and benh in DRM CVS but I'll wait until 2.6.13-rc so it gets more testing. Signed-off-by: Dave Airlie --- drivers/char/drm/radeon_irq.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/char/drm/radeon_irq.c b/drivers/char/drm/radeon_irq.c index 5b18bee6492..cd25f28e26a 100644 --- a/drivers/char/drm/radeon_irq.c +++ b/drivers/char/drm/radeon_irq.c @@ -123,11 +123,6 @@ static int radeon_wait_irq(drm_device_t *dev, int swi_nr) dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; - /* This is a hack to work around mysterious freezes on certain - * systems: - */ - radeon_acknowledge_irqs( dev_priv ); - DRM_WAIT_ON( ret, dev_priv->swi_queue, 3 * DRM_HZ, RADEON_READ( RADEON_LAST_SWI_REG ) >= swi_nr ); -- cgit v1.2.3-70-g09d2 From 90abb7b5f3bd9271a455cd640a70c285b4fd0c89 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 10 Jun 2005 09:37:21 -0700 Subject: ppc: remove two extraneous descriptors for the 405EP CPU The patch to add them keeps on getting applied, over and over again ;) Hopefully no more. --- arch/ppc/kernel/cputable.c | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/arch/ppc/kernel/cputable.c b/arch/ppc/kernel/cputable.c index ce2618ac8ac..d44b7dc5390 100644 --- a/arch/ppc/kernel/cputable.c +++ b/arch/ppc/kernel/cputable.c @@ -849,28 +849,6 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, }, - { /* 405EP */ - .pvr_mask = 0xffff0000, - .pvr_value = 0x51210000, - .cpu_name = "405EP", - .cpu_features = CPU_FTR_SPLIT_ID_CACHE | - CPU_FTR_USE_TB, - .cpu_user_features = PPC_FEATURE_32 | - PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, - .icache_bsize = 32, - .dcache_bsize = 32, - }, - { /* 405EP */ - .pvr_mask = 0xffff0000, - .pvr_value = 0x51210000, - .cpu_name = "405EP", - .cpu_features = CPU_FTR_SPLIT_ID_CACHE | - CPU_FTR_USE_TB, - .cpu_user_features = PPC_FEATURE_32 | - PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, - .icache_bsize = 32, - .dcache_bsize = 32, - }, #endif /* CONFIG_40x */ #ifdef CONFIG_44x -- cgit v1.2.3-70-g09d2 From bb011b8e8eded247cb71cb6d10e47517aacbd542 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Sun, 12 Jun 2005 23:26:05 +0100 Subject: [PATCH] ARM: 2709/1: Systems with PCMCIA should also see IDE options (for CompactFlash memories) Patch from David Brownell The ARM generic Kconfig filters out IDE options ... except for an error prone ARMload of special cases. This adds one general case to the systems that will offer IDE options: kernels with PCMCIA support, which probably want to use IDE to access CompactFlash cards. This might allow many (most?) of the other cases to disappear, for systems that only see IDE hardware through CF cards. Right now this one patch is used to gate access to CF cards, including MicroDrives, for both omap_cf and at91_cf drivers. Signed-off-by: David Brownell Signed-off-by: Russell King --- arch/arm/Kconfig | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 5eee3bcb22b..475950c8a83 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -689,7 +689,9 @@ source "drivers/block/Kconfig" source "drivers/acorn/block/Kconfig" -if ARCH_CLPS7500 || ARCH_IOP3XX || ARCH_IXP4XX || ARCH_L7200 || ARCH_LH7A40X || ARCH_PXA || ARCH_RPC || ARCH_S3C2410 || ARCH_SA1100 || ARCH_SHARK || FOOTBRIDGE +if PCMCIA || ARCH_CLPS7500 || ARCH_IOP3XX || ARCH_IXP4XX \ + || ARCH_L7200 || ARCH_LH7A40X || ARCH_PXA || ARCH_RPC \ + || ARCH_S3C2410 || ARCH_SA1100 || ARCH_SHARK || FOOTBRIDGE source "drivers/ide/Kconfig" endif -- cgit v1.2.3-70-g09d2 From 392a8b7efe069564bf7ed057103b1a3f41e55734 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sun, 12 Jun 2005 10:57:40 +0200 Subject: [PATCH] IrDA: IrDA: Fix CONFIG_VIA_FIR typo (double `those') Signed-off-by: Geert Uytterhoeven Signed-off-by: Linus Torvalds --- drivers/net/irda/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/irda/Kconfig b/drivers/net/irda/Kconfig index 1c553d7efdd..ca5914091d3 100644 --- a/drivers/net/irda/Kconfig +++ b/drivers/net/irda/Kconfig @@ -389,7 +389,7 @@ config VIA_FIR help Say Y here if you want to build support for the VIA VT8231 and VIA VT1211 IrDA controllers, found on the motherboards using - those those VIA chipsets. To use this controller, you will need + those VIA chipsets. To use this controller, you will need to plug a specific 5 pins FIR IrDA dongle in the specific motherboard connector. The driver provides support for SIR, MIR and FIR (4Mbps) speeds. -- cgit v1.2.3-70-g09d2 From a58e76f25432dc5e3e84d04c27bec03347ca365b Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sun, 12 Jun 2005 10:56:26 +0200 Subject: [PATCH] Remove obsolete HAVE_ARCH_GET_SIGNAL_TO_DELIVER? Now m68k no longer sets HAVE_ARCH_GET_SIGNAL_TO_DELIVER, can it be removed completely? Or may ARM26 still need it? Note that its usage was removed from kernel/signal.c about 2 months ago. Signed-off-by: Geert Uytterhoeven Signed-off-by: Linus Torvalds --- include/asm-arm26/signal.h | 3 --- include/linux/signal.h | 2 -- 2 files changed, 5 deletions(-) diff --git a/include/asm-arm26/signal.h b/include/asm-arm26/signal.h index dedb2928030..37ad2535559 100644 --- a/include/asm-arm26/signal.h +++ b/include/asm-arm26/signal.h @@ -166,9 +166,6 @@ typedef struct sigaltstack { #include #define sigmask(sig) (1UL << ((sig) - 1)) -//FIXME!!! -//#define HAVE_ARCH_GET_SIGNAL_TO_DELIVER - #endif diff --git a/include/linux/signal.h b/include/linux/signal.h index 0a98f5ec5ca..7be18b5e2fb 100644 --- a/include/linux/signal.h +++ b/include/linux/signal.h @@ -231,10 +231,8 @@ extern int __group_send_sig_info(int, struct siginfo *, struct task_struct *); extern long do_sigpending(void __user *, unsigned long); extern int sigprocmask(int, sigset_t *, sigset_t *); -#ifndef HAVE_ARCH_GET_SIGNAL_TO_DELIVER struct pt_regs; extern int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka, struct pt_regs *regs, void *cookie); -#endif #endif /* __KERNEL__ */ -- cgit v1.2.3-70-g09d2 From 707f919c643937e43a04e31d0502ecbf5a10445a Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sun, 12 Jun 2005 11:25:43 +0200 Subject: [PATCH] M68k: Update defconfigs Signed-off-by: Geert Uytterhoeven Signed-off-by: Linus Torvalds --- arch/m68k/configs/amiga_defconfig | 15 ++++----------- arch/m68k/configs/apollo_defconfig | 7 ++++--- arch/m68k/configs/atari_defconfig | 7 ++++--- arch/m68k/configs/bvme6000_defconfig | 7 ++++--- arch/m68k/configs/hp300_defconfig | 7 ++++--- arch/m68k/configs/mac_defconfig | 7 ++++--- arch/m68k/configs/mvme147_defconfig | 7 ++++--- arch/m68k/configs/mvme16x_defconfig | 7 ++++--- arch/m68k/configs/q40_defconfig | 15 ++++----------- arch/m68k/configs/sun3_defconfig | 7 ++++--- arch/m68k/configs/sun3x_defconfig | 7 ++++--- arch/m68k/defconfig | 7 ++++--- 12 files changed, 48 insertions(+), 52 deletions(-) diff --git a/arch/m68k/configs/amiga_defconfig b/arch/m68k/configs/amiga_defconfig index 7dbf997ff20..5649fbae430 100644 --- a/arch/m68k/configs/amiga_defconfig +++ b/arch/m68k/configs/amiga_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.12-rc2-m68k -# Tue Apr 5 14:05:59 2005 +# Linux kernel version: 2.6.12-rc6-m68k +# Tue Jun 7 20:34:23 2005 # CONFIG_M68K=y CONFIG_MMU=y @@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y @@ -135,7 +137,6 @@ CONFIG_PARPORT_1284=y # CONFIG_AMIGA_FLOPPY=y CONFIG_AMIGA_Z2RAM=y -# CONFIG_BLK_DEV_XD is not set # CONFIG_PARIDE is not set # CONFIG_BLK_DEV_COW_COMMON is not set CONFIG_BLK_DEV_LOOP=y @@ -223,17 +224,12 @@ CONFIG_SCSI_CONSTANTS=y # # SCSI low-level drivers # -# CONFIG_SCSI_7000FASST is not set # CONFIG_SCSI_AHA152X is not set -# CONFIG_SCSI_AHA1542 is not set # CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_IN2000 is not set # CONFIG_SCSI_SATA is not set -# CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_DTC3280 is not set -# CONFIG_SCSI_EATA is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_GDTH is not set # CONFIG_SCSI_GENERIC_NCR5380 is not set # CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set # CONFIG_SCSI_PPA is not set @@ -244,7 +240,6 @@ CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_QLOGIC_FAS is not set # CONFIG_SCSI_SYM53C416 is not set # CONFIG_SCSI_T128 is not set -# CONFIG_SCSI_U14_34F is not set # CONFIG_SCSI_DEBUG is not set CONFIG_A3000_SCSI=y CONFIG_A2091_SCSI=y @@ -492,7 +487,6 @@ CONFIG_HYDRA=m CONFIG_ZORRO8390=m CONFIG_APNE=m # CONFIG_NET_VENDOR_3COM is not set -# CONFIG_LANCE is not set # CONFIG_NET_VENDOR_SMC is not set # CONFIG_NET_VENDOR_RACAL is not set # CONFIG_AT1700 is not set @@ -620,7 +614,6 @@ CONFIG_SERIO_SERPORT=m # CONFIG_SERIO_PARKBD is not set # CONFIG_SERIO_RAW is not set # CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y # # Character devices diff --git a/arch/m68k/configs/apollo_defconfig b/arch/m68k/configs/apollo_defconfig index 505a2968e60..63024b0b7ac 100644 --- a/arch/m68k/configs/apollo_defconfig +++ b/arch/m68k/configs/apollo_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.12-rc2-m68k -# Tue Apr 5 14:06:00 2005 +# Linux kernel version: 2.6.12-rc6-m68k +# Tue Jun 7 20:34:27 2005 # CONFIG_M68K=y CONFIG_MMU=y @@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y @@ -497,7 +499,6 @@ CONFIG_SERIO_SERPORT=m CONFIG_SERIO_LIBPS2=m # CONFIG_SERIO_RAW is not set # CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y # # Character devices diff --git a/arch/m68k/configs/atari_defconfig b/arch/m68k/configs/atari_defconfig index 617aa73c325..6433da2d2ce 100644 --- a/arch/m68k/configs/atari_defconfig +++ b/arch/m68k/configs/atari_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.12-rc2-m68k -# Tue Apr 5 14:06:18 2005 +# Linux kernel version: 2.6.12-rc6-m68k +# Tue Jun 7 20:34:32 2005 # CONFIG_M68K=y CONFIG_MMU=y @@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y @@ -531,7 +533,6 @@ CONFIG_SERIO_SERPORT=y CONFIG_SERIO_LIBPS2=y # CONFIG_SERIO_RAW is not set # CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y # # Character devices diff --git a/arch/m68k/configs/bvme6000_defconfig b/arch/m68k/configs/bvme6000_defconfig index b501db51d9e..da2a23a2146 100644 --- a/arch/m68k/configs/bvme6000_defconfig +++ b/arch/m68k/configs/bvme6000_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.12-rc2-m68k -# Tue Apr 5 14:06:19 2005 +# Linux kernel version: 2.6.12-rc6-m68k +# Tue Jun 7 20:34:37 2005 # CONFIG_M68K=y CONFIG_MMU=y @@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y @@ -496,7 +498,6 @@ CONFIG_SERIO_SERPORT=m CONFIG_SERIO_LIBPS2=m # CONFIG_SERIO_RAW is not set # CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y # # Character devices diff --git a/arch/m68k/configs/hp300_defconfig b/arch/m68k/configs/hp300_defconfig index 2bf6cef4f2b..51251883adf 100644 --- a/arch/m68k/configs/hp300_defconfig +++ b/arch/m68k/configs/hp300_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.12-rc2-m68k -# Tue Apr 5 14:06:21 2005 +# Linux kernel version: 2.6.12-rc6-m68k +# Tue Jun 7 20:34:41 2005 # CONFIG_M68K=y CONFIG_MMU=y @@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y @@ -498,7 +500,6 @@ CONFIG_SERIO_SERPORT=m CONFIG_SERIO_LIBPS2=m # CONFIG_SERIO_RAW is not set # CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y # # Character devices diff --git a/arch/m68k/configs/mac_defconfig b/arch/m68k/configs/mac_defconfig index 7074f856820..15b80abfe94 100644 --- a/arch/m68k/configs/mac_defconfig +++ b/arch/m68k/configs/mac_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.12-rc2-m68k -# Tue Apr 5 14:06:24 2005 +# Linux kernel version: 2.6.12-rc6-m68k +# Tue Jun 7 20:34:45 2005 # CONFIG_M68K=y CONFIG_MMU=y @@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y @@ -540,7 +542,6 @@ CONFIG_SERIO_SERPORT=m CONFIG_SERIO_LIBPS2=m # CONFIG_SERIO_RAW is not set # CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y # # Character devices diff --git a/arch/m68k/configs/mvme147_defconfig b/arch/m68k/configs/mvme147_defconfig index 61f09bc4846..f0d5534f683 100644 --- a/arch/m68k/configs/mvme147_defconfig +++ b/arch/m68k/configs/mvme147_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.12-rc2-m68k -# Tue Apr 5 14:06:28 2005 +# Linux kernel version: 2.6.12-rc6-m68k +# Tue Jun 7 20:34:50 2005 # CONFIG_M68K=y CONFIG_MMU=y @@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y @@ -498,7 +500,6 @@ CONFIG_SERIO_SERPORT=m CONFIG_SERIO_LIBPS2=m # CONFIG_SERIO_RAW is not set # CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y # # Character devices diff --git a/arch/m68k/configs/mvme16x_defconfig b/arch/m68k/configs/mvme16x_defconfig index 69c01004ec4..1d5c46ff3c8 100644 --- a/arch/m68k/configs/mvme16x_defconfig +++ b/arch/m68k/configs/mvme16x_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.12-rc2-m68k -# Tue Apr 5 14:06:31 2005 +# Linux kernel version: 2.6.12-rc6-m68k +# Tue Jun 7 20:34:53 2005 # CONFIG_M68K=y CONFIG_MMU=y @@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y @@ -497,7 +499,6 @@ CONFIG_SERIO_SERPORT=m CONFIG_SERIO_LIBPS2=m # CONFIG_SERIO_RAW is not set # CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y # # Character devices diff --git a/arch/m68k/configs/q40_defconfig b/arch/m68k/configs/q40_defconfig index 550ec26006c..856238634d4 100644 --- a/arch/m68k/configs/q40_defconfig +++ b/arch/m68k/configs/q40_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.12-rc2-m68k -# Tue Apr 5 14:06:34 2005 +# Linux kernel version: 2.6.12-rc6-m68k +# Tue Jun 7 20:34:58 2005 # CONFIG_M68K=y CONFIG_MMU=y @@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y @@ -125,7 +127,6 @@ CONFIG_FW_LOADER=m # Block devices # # CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_DEV_XD is not set # CONFIG_BLK_DEV_COW_COMMON is not set CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_CRYPTOLOOP=m @@ -210,17 +211,12 @@ CONFIG_SCSI_CONSTANTS=y # # SCSI low-level drivers # -# CONFIG_SCSI_7000FASST is not set # CONFIG_SCSI_AHA152X is not set -# CONFIG_SCSI_AHA1542 is not set # CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_IN2000 is not set # CONFIG_SCSI_SATA is not set -# CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_DTC3280 is not set -# CONFIG_SCSI_EATA is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_GDTH is not set # CONFIG_SCSI_GENERIC_NCR5380 is not set # CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set # CONFIG_SCSI_NCR53C406A is not set @@ -229,7 +225,6 @@ CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_QLOGIC_FAS is not set # CONFIG_SCSI_SYM53C416 is not set # CONFIG_SCSI_T128 is not set -# CONFIG_SCSI_U14_34F is not set # CONFIG_SCSI_DEBUG is not set # @@ -466,7 +461,6 @@ CONFIG_EQUALIZER=m CONFIG_NET_ETHERNET=y CONFIG_MII=m # CONFIG_NET_VENDOR_3COM is not set -# CONFIG_LANCE is not set # CONFIG_NET_VENDOR_SMC is not set # CONFIG_NET_VENDOR_RACAL is not set # CONFIG_AT1700 is not set @@ -570,7 +564,6 @@ CONFIG_SERIO_Q40KBD=m CONFIG_SERIO_LIBPS2=m # CONFIG_SERIO_RAW is not set # CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y # # Character devices diff --git a/arch/m68k/configs/sun3_defconfig b/arch/m68k/configs/sun3_defconfig index 5b5a619645a..b96b4584735 100644 --- a/arch/m68k/configs/sun3_defconfig +++ b/arch/m68k/configs/sun3_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.12-rc2-m68k -# Tue Apr 5 14:06:37 2005 +# Linux kernel version: 2.6.12-rc6-m68k +# Tue Jun 7 20:35:02 2005 # CONFIG_M68K=y CONFIG_MMU=y @@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y @@ -487,7 +489,6 @@ CONFIG_SERIO_SERPORT=m CONFIG_SERIO_LIBPS2=m # CONFIG_SERIO_RAW is not set # CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y # # Character devices diff --git a/arch/m68k/configs/sun3x_defconfig b/arch/m68k/configs/sun3x_defconfig index 704e42344cb..997143b7928 100644 --- a/arch/m68k/configs/sun3x_defconfig +++ b/arch/m68k/configs/sun3x_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.12-rc2-m68k -# Tue Apr 5 14:06:40 2005 +# Linux kernel version: 2.6.12-rc6-m68k +# Tue Jun 7 20:35:06 2005 # CONFIG_M68K=y CONFIG_MMU=y @@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y @@ -497,7 +499,6 @@ CONFIG_SERIO_SERPORT=m CONFIG_SERIO_LIBPS2=m # CONFIG_SERIO_RAW is not set # CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y # # Character devices diff --git a/arch/m68k/defconfig b/arch/m68k/defconfig index 5b2296ecba8..7d935e48a9a 100644 --- a/arch/m68k/defconfig +++ b/arch/m68k/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.12-rc2-m68k -# Tue Apr 5 14:05:31 2005 +# Linux kernel version: 2.6.12-rc6-m68k +# Tue Jun 7 20:34:17 2005 # CONFIG_M68K=y CONFIG_MMU=y @@ -33,6 +33,8 @@ CONFIG_KOBJECT_UEVENT=y # CONFIG_EMBEDDED is not set CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y @@ -355,7 +357,6 @@ CONFIG_SERIO_SERPORT=y CONFIG_SERIO_LIBPS2=y # CONFIG_SERIO_RAW is not set # CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y # # Character devices -- cgit v1.2.3-70-g09d2 From c3315ede1bdf7bc706b59870df41b9cdb6e3995a Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sun, 12 Jun 2005 11:25:42 +0200 Subject: [PATCH] M68k: Mark Sun-3 NCR5380 SCSI broken M68k: Mark Sun-3 NCR5380 SCSI broken until NCR5380_abort() and NCR5380_bus_reset() are replaced with real new-style EH routines (the old EH SCSI constants were removed in 2.6.12-rc3). Signed-off-by: Geert Uytterhoeven Signed-off-by: Linus Torvalds --- arch/m68k/configs/sun3_defconfig | 1 - drivers/scsi/Kconfig | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/m68k/configs/sun3_defconfig b/arch/m68k/configs/sun3_defconfig index b96b4584735..af903b5c570 100644 --- a/arch/m68k/configs/sun3_defconfig +++ b/arch/m68k/configs/sun3_defconfig @@ -173,7 +173,6 @@ CONFIG_SCSI_CONSTANTS=y # # CONFIG_SCSI_SATA is not set # CONFIG_SCSI_DEBUG is not set -CONFIG_SUN3_SCSI=y # # Multi-device support (RAID and LVM) diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index 1811cb24031..27fec8a5eb5 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -1752,7 +1752,7 @@ config SCSI_NCR53C7xx_FAST config SUN3_SCSI tristate "Sun3 NCR5380 SCSI" - depends on SUN3 && SCSI + depends on SUN3 && SCSI && BROKEN help This option will enable support for the OBIO (onboard io) NCR5380 SCSI controller found in the Sun 3/50 and 3/60, as well as for -- cgit v1.2.3-70-g09d2 From 8d5f7b4353dae4c7ee342c61303372fd996ca161 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Sat, 11 Jun 2005 09:45:30 +1000 Subject: [PATCH] radeonfb: don't blow up VGA console on load The current radeonfb memset's the framebuffer to 0 when loaded. This removes occasional artifacts but has the nasty side effect that if you load radeonfb without framebuffer console, you destroy the VGA text buffer, font, etc... radeon must not touch the framebuffer content when it doesn't "own" it. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Linus Torvalds --- drivers/video/aty/radeon_base.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c index ee25b9e8db6..47a6b12bc96 100644 --- a/drivers/video/aty/radeon_base.c +++ b/drivers/video/aty/radeon_base.c @@ -2374,10 +2374,9 @@ static int radeonfb_pci_register (struct pci_dev *pdev, } while ( rinfo->fb_base == 0 && ((rinfo->mapped_vram /=2) >= MIN_MAPPED_VRAM) ); - if (rinfo->fb_base) - memset_io(rinfo->fb_base, 0, rinfo->mapped_vram); - else { - printk (KERN_ERR "radeonfb (%s): cannot map FB\n", pci_name(rinfo->pdev)); + if (rinfo->fb_base == NULL) { + printk (KERN_ERR "radeonfb (%s): cannot map FB\n", + pci_name(rinfo->pdev)); ret = -EIO; goto err_unmap_rom; } -- cgit v1.2.3-70-g09d2 From c0105338eb4e61e537ca34ae06921177cb6efcf0 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Sat, 11 Jun 2005 18:00:52 +0100 Subject: [PATCH] pwc bug fix The pwc chainsaw session left some setups not working. There is a sanity check on compression buffers that simply isn't right any more as we never allocate one. This doesn't address the email and other changes. I'll do those tomorrow if I get time, but it is the minimal fix for the code and basic feature set. Signed-off-by: Alan Cox Signed-off-by: Linus Torvalds --- drivers/usb/media/pwc/pwc-if.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/usb/media/pwc/pwc-if.c b/drivers/usb/media/pwc/pwc-if.c index 5429ff3b975..b77e65c0365 100644 --- a/drivers/usb/media/pwc/pwc-if.c +++ b/drivers/usb/media/pwc/pwc-if.c @@ -332,10 +332,6 @@ static int pwc_allocate_buffers(struct pwc_device *pdev) #endif ; } - if (kbuf == NULL) { - Err("Failed to allocate decompress table.\n"); - return -ENOMEM; - } pdev->decompress_data = kbuf; /* Allocate image buffer; double buffer for mmap() */ -- cgit v1.2.3-70-g09d2 From c22fa3acbc2ef79ea57217643f6cd6d226963069 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Mon, 13 Jun 2005 07:15:28 -0700 Subject: [PATCH] spin longer for ehci port reset completion This makes the EHCI driver spin a bit longer before concluding that the port reset failed. "Obviously safe." It allows some devices to enumerate that previously didn't. We've seen a bunch of these problem reports recently, this will make some go away. As reported by Michael Zapf , some EHCI controllers seem to take forever to finish port resets and produce "port N reset error -110" type errors. Spinning a bit longer helps. Signed-off-by: David Brownell Signed-off-by: Linus Torvalds --- drivers/usb/host/ehci-hub.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index 429330bc38d..d7b4f7939de 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c @@ -439,9 +439,12 @@ static int ehci_hub_control ( /* force reset to complete */ writel (temp & ~PORT_RESET, &ehci->regs->port_status [wIndex]); + /* REVISIT: some hardware needs 550+ usec to clear + * this bit; seems too long to spin routinely... + */ retval = handshake ( &ehci->regs->port_status [wIndex], - PORT_RESET, 0, 500); + PORT_RESET, 0, 750); if (retval != 0) { ehci_err (ehci, "port %d reset error %d\n", wIndex + 1, retval); -- cgit v1.2.3-70-g09d2 From 980802e311088fda56c16650589faa4597c695fb Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Mon, 13 Jun 2005 11:14:01 -0400 Subject: [PATCH] NFS: Ensure that we revalidate the cached file length for llseek(SEEK_END) This fixes a data corruption error for mail delivery applications that expect to be able to do posix locking and then append writes on NFS. Signed-off-by: Trond Myklebust Signed-off-by: Linus Torvalds --- fs/nfs/file.c | 42 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/fs/nfs/file.c b/fs/nfs/file.c index f06eee6dcff..55c90759249 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c @@ -37,6 +37,7 @@ static int nfs_file_open(struct inode *, struct file *); static int nfs_file_release(struct inode *, struct file *); +static loff_t nfs_file_llseek(struct file *file, loff_t offset, int origin); static int nfs_file_mmap(struct file *, struct vm_area_struct *); static ssize_t nfs_file_sendfile(struct file *, loff_t *, size_t, read_actor_t, void *); static ssize_t nfs_file_read(struct kiocb *, char __user *, size_t, loff_t); @@ -48,7 +49,7 @@ static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl); static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl); struct file_operations nfs_file_operations = { - .llseek = remote_llseek, + .llseek = nfs_file_llseek, .read = do_sync_read, .write = do_sync_write, .aio_read = nfs_file_read, @@ -114,6 +115,45 @@ nfs_file_release(struct inode *inode, struct file *filp) return NFS_PROTO(inode)->file_release(inode, filp); } +/** + * nfs_revalidate_size - Revalidate the file size + * @inode - pointer to inode struct + * @file - pointer to struct file + * + * Revalidates the file length. This is basically a wrapper around + * nfs_revalidate_inode() that takes into account the fact that we may + * have cached writes (in which case we don't care about the server's + * idea of what the file length is), or O_DIRECT (in which case we + * shouldn't trust the cache). + */ +static int nfs_revalidate_file_size(struct inode *inode, struct file *filp) +{ + struct nfs_server *server = NFS_SERVER(inode); + struct nfs_inode *nfsi = NFS_I(inode); + + if (server->flags & NFS_MOUNT_NOAC) + goto force_reval; + if (filp->f_flags & O_DIRECT) + goto force_reval; + if (nfsi->npages != 0) + return 0; + return nfs_revalidate_inode(server, inode); +force_reval: + return __nfs_revalidate_inode(server, inode); +} + +static loff_t nfs_file_llseek(struct file *filp, loff_t offset, int origin) +{ + /* origin == SEEK_END => we must revalidate the cached file length */ + if (origin == 2) { + struct inode *inode = filp->f_mapping->host; + int retval = nfs_revalidate_file_size(inode, filp); + if (retval < 0) + return (loff_t)retval; + } + return remote_llseek(filp, offset, origin); +} + /* * Flush all dirty pages, and check for write errors. * -- cgit v1.2.3-70-g09d2 From 03722adce90a248d0bea77d390decbd05991e2d2 Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Mon, 13 Jun 2005 13:57:10 -0700 Subject: [NET]: linux/if_tr.h needs asm/byteorder.h uses __be16, but does not directly include . Add this in, so that dhcp/net-tools token ring code can compile again. Signed-off-by: Tom Rini Signed-off-by: David S. Miller --- include/linux/if_tr.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/if_tr.h b/include/linux/if_tr.h index 6688b414c52..3fba9e2f542 100644 --- a/include/linux/if_tr.h +++ b/include/linux/if_tr.h @@ -19,6 +19,8 @@ #ifndef _LINUX_IF_TR_H #define _LINUX_IF_TR_H +#include /* For __be16 */ + /* IEEE 802.5 Token-Ring magic constants. The frame sizes omit the preamble and FCS/CRC (frame check sequence). */ #define TR_ALEN 6 /* Octets in one token-ring addr */ -- cgit v1.2.3-70-g09d2 From e7626486c3c4ce456b11a7944edf164ef76fc599 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Mon, 13 Jun 2005 14:24:52 -0700 Subject: [TCP]: Adjust TCP mem order check to new alloc_large_system_hash Signed-off-by: Andi Kleen Signed-off-by: David S. Miller --- net/ipv4/tcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index a037bafcba3..0d9a4fd5f1a 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -2338,7 +2338,7 @@ void __init tcp_init(void) (tcp_bhash_size * sizeof(struct tcp_bind_hashbucket)); order++) ; - if (order > 4) { + if (order >= 4) { sysctl_local_port_range[0] = 32768; sysctl_local_port_range[1] = 61000; sysctl_tcp_max_tw_buckets = 180000; -- cgit v1.2.3-70-g09d2 From 6efd8455cff1979dd081daaa1ce3d3f1764863dc Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 13 Jun 2005 14:29:06 -0700 Subject: [IPV4]: Multipath modules need a license to prevent kernel tainting. Signed-off-by: Randy Dunlap Signed-off-by: David S. Miller --- net/ipv4/multipath_drr.c | 2 ++ net/ipv4/multipath_random.c | 2 ++ net/ipv4/multipath_rr.c | 2 ++ net/ipv4/multipath_wrandom.c | 2 ++ 4 files changed, 8 insertions(+) diff --git a/net/ipv4/multipath_drr.c b/net/ipv4/multipath_drr.c index cf2e6bcf797..c9cf8726051 100644 --- a/net/ipv4/multipath_drr.c +++ b/net/ipv4/multipath_drr.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -247,3 +248,4 @@ static void __exit drr_exit(void) module_init(drr_init); module_exit(drr_exit); +MODULE_LICENSE("GPL"); diff --git a/net/ipv4/multipath_random.c b/net/ipv4/multipath_random.c index 805a16e47de..5249dbe7c55 100644 --- a/net/ipv4/multipath_random.c +++ b/net/ipv4/multipath_random.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -126,3 +127,4 @@ static void __exit random_exit(void) module_init(random_init); module_exit(random_exit); +MODULE_LICENSE("GPL"); diff --git a/net/ipv4/multipath_rr.c b/net/ipv4/multipath_rr.c index 061b6b25398..b6cd2870478 100644 --- a/net/ipv4/multipath_rr.c +++ b/net/ipv4/multipath_rr.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -93,3 +94,4 @@ static void __exit rr_exit(void) module_init(rr_init); module_exit(rr_exit); +MODULE_LICENSE("GPL"); diff --git a/net/ipv4/multipath_wrandom.c b/net/ipv4/multipath_wrandom.c index c3d2ca1a678..bd7d75b6abe 100644 --- a/net/ipv4/multipath_wrandom.c +++ b/net/ipv4/multipath_wrandom.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -342,3 +343,4 @@ static void __exit wrandom_exit(void) module_init(wrandom_init); module_exit(wrandom_exit); +MODULE_LICENSE("GPL"); -- cgit v1.2.3-70-g09d2 From 979b6c135fc4d466a39d8e3ec05583e5ee30261a Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Mon, 13 Jun 2005 14:30:40 -0700 Subject: [NET]: Move the netdev list to vger.kernel.org. From: Ralf Baechle There are archives of the old list at http://oss.sgi.com/archives/netdev Signed-off-by: Andrew Morton Signed-off-by: David S. Miller --- Documentation/networking/vortex.txt | 2 +- MAINTAINERS | 48 ++++++++++++++++++------------------- drivers/net/r8169.c | 2 +- net/sched/act_api.c | 2 +- 4 files changed, 27 insertions(+), 27 deletions(-) diff --git a/Documentation/networking/vortex.txt b/Documentation/networking/vortex.txt index fa12a9e4abd..80e1cb19609 100644 --- a/Documentation/networking/vortex.txt +++ b/Documentation/networking/vortex.txt @@ -12,7 +12,7 @@ Don is no longer the prime maintainer of this version of the driver. Please report problems to one or more of: Andrew Morton - Netdev mailing list + Netdev mailing list Linux kernel mailing list Please note the 'Reporting and Diagnosing Problems' section at the end diff --git a/MAINTAINERS b/MAINTAINERS index 65ad8251e4b..86ba94f16e8 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -73,7 +73,7 @@ S: Status, one of the following: 3C359 NETWORK DRIVER P: Mike Phillips M: mikep@linuxtr.net -L: netdev@oss.sgi.com +L: netdev@vger.kernel.org L: linux-tr@linuxtr.net W: http://www.linuxtr.net S: Maintained @@ -81,13 +81,13 @@ S: Maintained 3C505 NETWORK DRIVER P: Philip Blundell M: philb@gnu.org -L: netdev@oss.sgi.com +L: netdev@vger.kernel.org S: Maintained 3CR990 NETWORK DRIVER P: David Dillow M: dave@thedillows.org -L: netdev@oss.sgi.com +L: netdev@vger.kernel.org S: Maintained 3W-XXXX ATA-RAID CONTROLLER DRIVER @@ -130,7 +130,7 @@ S: Maintained 8169 10/100/1000 GIGABIT ETHERNET DRIVER P: Francois Romieu M: romieu@fr.zoreil.com -L: netdev@oss.sgi.com +L: netdev@vger.kernel.org S: Maintained 8250/16?50 (AND CLONE UARTS) SERIAL DRIVER @@ -143,7 +143,7 @@ S: Maintained 8390 NETWORK DRIVERS [WD80x3/SMC-ELITE, SMC-ULTRA, NE2000, 3C503, etc.] P: Paul Gortmaker M: p_gortmaker@yahoo.com -L: netdev@oss.sgi.com +L: netdev@vger.kernel.org S: Maintained A2232 SERIAL BOARD DRIVER @@ -332,7 +332,7 @@ S: Maintained ARPD SUPPORT P: Jonathan Layes -L: netdev@oss.sgi.com +L: netdev@vger.kernel.org S: Maintained ASUS ACPI EXTRAS DRIVER @@ -706,7 +706,7 @@ S: Orphaned DIGI RIGHTSWITCH NETWORK DRIVER P: Rick Richardson -L: netdev@oss.sgi.com +L: netdev@vger.kernel.org W: http://www.digi.com S: Orphaned @@ -812,7 +812,7 @@ S: Maintained ETHEREXPRESS-16 NETWORK DRIVER P: Philip Blundell M: philb@gnu.org -L: netdev@oss.sgi.com +L: netdev@vger.kernel.org S: Maintained ETHERNET BRIDGE @@ -875,7 +875,7 @@ S: Maintained FRAME RELAY DLCI/FRAD (Sangoma drivers too) P: Mike McLagan M: mike.mclagan@linux.org -L: netdev@oss.sgi.com +L: netdev@vger.kernel.org S: Maintained FREEVXFS FILESYSTEM @@ -1215,7 +1215,7 @@ S: Maintained IPX NETWORK LAYER P: Arnaldo Carvalho de Melo M: acme@conectiva.com.br -L: netdev@oss.sgi.com +L: netdev@vger.kernel.org S: Maintained IRDA SUBSYSTEM @@ -1482,7 +1482,7 @@ MARVELL MV64340 ETHERNET DRIVER P: Manish Lachwani M: Manish_Lachwani@pmc-sierra.com L: linux-mips@linux-mips.org -L: netdev@oss.sgi.com +L: netdev@vger.kernel.org S: Supported MATROX FRAMEBUFFER DRIVER @@ -1592,13 +1592,13 @@ P: Andrew Morton M: akpm@osdl.org P: Jeff Garzik M: jgarzik@pobox.com -L: netdev@oss.sgi.com +L: netdev@vger.kernel.org S: Maintained NETWORKING [GENERAL] P: Networking Team -M: netdev@oss.sgi.com -L: netdev@oss.sgi.com +M: netdev@vger.kernel.org +L: netdev@vger.kernel.org S: Maintained NETWORKING [IPv4/IPv6] @@ -1614,7 +1614,7 @@ P: Hideaki YOSHIFUJI M: yoshfuji@linux-ipv6.org P: Patrick McHardy M: kaber@coreworks.de -L: netdev@oss.sgi.com +L: netdev@vger.kernel.org S: Maintained IPVS @@ -1634,7 +1634,7 @@ NI5010 NETWORK DRIVER P: Jan-Pascal van Best and Andreas Mohr M: Jan-Pascal van Best M: Andreas Mohr <100.30936@germany.net> -L: netdev@oss.sgi.com +L: netdev@vger.kernel.org S: Maintained NINJA SCSI-3 / NINJA SCSI-32Bi (16bit/CardBus) PCMCIA SCSI HOST ADAPTER DRIVER @@ -1676,7 +1676,7 @@ P: Peter De Shrijver M: p2@ace.ulyssis.student.kuleuven.ac.be P: Mike Phillips M: mikep@linuxtr.net -L: netdev@oss.sgi.com +L: netdev@vger.kernel.org L: linux-tr@linuxtr.net W: http://www.linuxtr.net S: Maintained @@ -1783,7 +1783,7 @@ S: Unmaintained PCNET32 NETWORK DRIVER P: Thomas Bogendörfer M: tsbogend@alpha.franken.de -L: netdev@oss.sgi.com +L: netdev@vger.kernel.org S: Maintained PHRAM MTD DRIVER @@ -1795,7 +1795,7 @@ S: Maintained POSIX CLOCKS and TIMERS P: George Anzinger M: george@mvista.com -L: netdev@oss.sgi.com +L: netdev@vger.kernel.org S: Supported PNP SUPPORT @@ -1830,7 +1830,7 @@ S: Supported PRISM54 WIRELESS DRIVER P: Prism54 Development Team M: prism54-private@prism54.org -L: netdev@oss.sgi.com +L: netdev@vger.kernel.org W: http://prism54.org S: Maintained @@ -2047,7 +2047,7 @@ SIS 900/7016 FAST ETHERNET DRIVER P: Daniele Venzano M: venza@brownhat.org W: http://www.brownhat.org/sis900.html -L: netdev@oss.sgi.com +L: netdev@vger.kernel.org S: Maintained SIS FRAMEBUFFER DRIVER @@ -2106,7 +2106,7 @@ S: Maintained SONIC NETWORK DRIVER P: Thomas Bogendoerfer M: tsbogend@alpha.franken.de -L: netdev@oss.sgi.com +L: netdev@vger.kernel.org S: Maintained SONY VAIO CONTROL DEVICE DRIVER @@ -2163,7 +2163,7 @@ S: Supported SPX NETWORK LAYER P: Jay Schulist M: jschlst@samba.org -L: netdev@oss.sgi.com +L: netdev@vger.kernel.org S: Supported SRM (Alpha) environment access @@ -2242,7 +2242,7 @@ S: Maintained TOKEN-RING NETWORK DRIVER P: Mike Phillips M: mikep@linuxtr.net -L: netdev@oss.sgi.com +L: netdev@vger.kernel.org L: linux-tr@linuxtr.net W: http://www.linuxtr.net S: Maintained diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index b3768d84474..d6d0e43dab6 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -415,7 +415,7 @@ struct rtl8169_private { struct work_struct task; }; -MODULE_AUTHOR("Realtek and the Linux r8169 crew "); +MODULE_AUTHOR("Realtek and the Linux r8169 crew "); MODULE_DESCRIPTION("RealTek RTL-8169 Gigabit Ethernet driver"); module_param_array(media, int, &num_media, 0); module_param(rx_copybreak, int, 0); diff --git a/net/sched/act_api.c b/net/sched/act_api.c index cafcb084098..914c85ff8fe 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c @@ -881,7 +881,7 @@ static int __init tc_action_init(void) link_p[RTM_GETACTION-RTM_BASE].dumpit = tc_dump_action; } - printk("TC classifier action (bugs to netdev@oss.sgi.com cc " + printk("TC classifier action (bugs to netdev@vger.kernel.org cc " "hadi@cyberus.ca)\n"); return 0; } -- cgit v1.2.3-70-g09d2 From a8fa3f0c59f8a1e1d89542cff0be5b057b684653 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Mon, 13 Jun 2005 22:35:41 +0100 Subject: [PATCH] ARM: 2711/1: fix compilation on PXA targets with CONFIG_PM=n Patch from Nicolas Pitre Signed-off-by: Nicolas Pitre Signed-off-by: Russell King --- arch/arm/mach-pxa/pxa25x.c | 4 ++++ arch/arm/mach-pxa/pxa27x.c | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c index b6d945a6e77..7869c3b4e62 100644 --- a/arch/arm/mach-pxa/pxa25x.c +++ b/arch/arm/mach-pxa/pxa25x.c @@ -16,6 +16,7 @@ * initialization stuff for PXA machines which can be overridden later if * need be. */ +#include #include #include #include @@ -103,6 +104,7 @@ unsigned int get_lcdclk_frequency_10khz(void) EXPORT_SYMBOL(get_lcdclk_frequency_10khz); +#ifdef CONFIG_PM int pxa_cpu_pm_prepare(suspend_state_t state) { @@ -131,3 +133,5 @@ void pxa_cpu_pm_enter(suspend_state_t state) break; } } + +#endif diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c index aa3c3b2ab75..893964fb965 100644 --- a/arch/arm/mach-pxa/pxa27x.c +++ b/arch/arm/mach-pxa/pxa27x.c @@ -120,6 +120,8 @@ EXPORT_SYMBOL(get_clk_frequency_khz); EXPORT_SYMBOL(get_memclk_frequency_10khz); EXPORT_SYMBOL(get_lcdclk_frequency_10khz); +#ifdef CONFIG_PM + int pxa_cpu_pm_prepare(suspend_state_t state) { switch (state) { @@ -153,6 +155,8 @@ void pxa_cpu_pm_enter(suspend_state_t state) } } +#endif + /* * device registration specific to PXA27x. */ -- cgit v1.2.3-70-g09d2 From 84427d533076a08137779b3182a71c37bf000b27 Mon Sep 17 00:00:00 2001 From: YOSHIFUJI Hideaki Date: Mon, 13 Jun 2005 14:59:44 -0700 Subject: [IPV6]: Ensure to use icmpv6_socket in non-preemptive context. We saw following trace several times: |BUG: using smp_processor_id() in preemptible [00000001] code: httpd/30137 |caller is icmpv6_send+0x23/0x540 | [] smp_processor_id+0x9b/0xb8 | [] icmpv6_send+0x23/0x540 This is because of icmpv6_socket, which is the only one user of smp_processor_id() in icmpv6_send(), AFAIK. Since it should be used in non-preemptive context, let's defer the dereference after disabling preemption (by icmpv6_xmit_lock()). Signed-off-by: YOSHIFUJI Hideaki Signed-off-by: David S. Miller --- net/ipv6/icmp.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index 8e0f569b883..ff3ec9822e3 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c @@ -277,8 +277,8 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info, { struct inet6_dev *idev = NULL; struct ipv6hdr *hdr = skb->nh.ipv6h; - struct sock *sk = icmpv6_socket->sk; - struct ipv6_pinfo *np = inet6_sk(sk); + struct sock *sk; + struct ipv6_pinfo *np; struct in6_addr *saddr = NULL; struct dst_entry *dst; struct icmp6hdr tmp_hdr; @@ -358,6 +358,9 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info, if (icmpv6_xmit_lock()) return; + sk = icmpv6_socket->sk; + np = inet6_sk(sk); + if (!icmpv6_xrlim_allow(sk, type, &fl)) goto out; @@ -423,9 +426,9 @@ out: static void icmpv6_echo_reply(struct sk_buff *skb) { - struct sock *sk = icmpv6_socket->sk; + struct sock *sk; struct inet6_dev *idev; - struct ipv6_pinfo *np = inet6_sk(sk); + struct ipv6_pinfo *np; struct in6_addr *saddr = NULL; struct icmp6hdr *icmph = (struct icmp6hdr *) skb->h.raw; struct icmp6hdr tmp_hdr; @@ -454,6 +457,9 @@ static void icmpv6_echo_reply(struct sk_buff *skb) if (icmpv6_xmit_lock()) return; + sk = icmpv6_socket->sk; + np = inet6_sk(sk); + if (!fl.oif && ipv6_addr_is_multicast(&fl.fl6_dst)) fl.oif = np->mcast_oif; -- cgit v1.2.3-70-g09d2 From 77bd91967a97e5b94ae36113efe1d9e4f68a716e Mon Sep 17 00:00:00 2001 From: Rémi Denis-Courmont Date: Mon, 13 Jun 2005 15:01:34 -0700 Subject: [IPv6] Don't generate temporary for TUN devices MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Userland layer-2 tunneling devices allocated through the TUNTAP driver (drivers/net/tun.c) have a type of ARPHRD_NONE, and have no link-layer address. The kernel complains at regular interval when IPv6 Privacy extension are enabled because it can't find an hardware address : Dec 29 11:02:04 auguste kernel: __ipv6_regen_rndid(idev=cb3e0c00): cannot get EUI64 identifier; use random bytes. IPv6 Privacy extensions should probably be disabled on that sort of device. They won't work anyway. If userland wants a more usual Ethernet-ish interface with usual IPv6 autoconfiguration, it will use a TAP device with an emulated link-layer and a random hardware address rather than a TUN device. As far as I could fine, TUN virtual device from TUNTAP is the very only sort of device using ARPHRD_NONE as kernel device type. Signed-off-by: Rémi Denis-Courmont Acked-by: YOSHIFUJI Hideaki Signed-off-by: David S. Miller --- net/ipv6/addrconf.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 7744a259269..2720899d516 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -372,6 +372,7 @@ static struct inet6_dev * ipv6_add_dev(struct net_device *dev) ndev->regen_timer.data = (unsigned long) ndev; if ((dev->flags&IFF_LOOPBACK) || dev->type == ARPHRD_TUNNEL || + dev->type == ARPHRD_NONE || dev->type == ARPHRD_SIT) { printk(KERN_INFO "Disabled Privacy Extensions on device %p(%s)\n", -- cgit v1.2.3-70-g09d2 From 4243cac1e76228f7ba916d5df9e75a219352160a Mon Sep 17 00:00:00 2001 From: Vladislav Yasevich Date: Mon, 13 Jun 2005 15:10:49 -0700 Subject: [SCTP]: Fix bug in restart of peeled-off associations. Signed-off-by: Vladislav Yasevich Signed-off-by: Sridhar Samudrala Signed-off-by: David S. Miller --- net/sctp/socket.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 0b338eca6dc..2a3c0e08a09 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -4686,6 +4686,7 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk, struct sctp_endpoint *newep = newsp->ep; struct sk_buff *skb, *tmp; struct sctp_ulpevent *event; + int flags = 0; /* Migrate socket buffer sizes and all the socket level options to the * new socket. @@ -4707,6 +4708,17 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk, sctp_sk(newsk)->bind_hash = pp; inet_sk(newsk)->num = inet_sk(oldsk)->num; + /* Copy the bind_addr list from the original endpoint to the new + * endpoint so that we can handle restarts properly + */ + if (assoc->peer.ipv4_address) + flags |= SCTP_ADDR4_PEERSUPP; + if (assoc->peer.ipv6_address) + flags |= SCTP_ADDR6_PEERSUPP; + sctp_bind_addr_copy(&newsp->ep->base.bind_addr, + &oldsp->ep->base.bind_addr, + SCTP_SCOPE_GLOBAL, GFP_KERNEL, flags); + /* Move any messages in the old socket's receive queue that are for the * peeled off association to the new socket's receive queue. */ -- cgit v1.2.3-70-g09d2 From 0fd9a65a76e883b7d16e72dde3f8bf20ebc1e82a Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Mon, 13 Jun 2005 15:11:24 -0700 Subject: [SCTP] Support SO_BINDTODEVICE socket option on incoming packets. Signed-off-by: Neil Horman Signed-off-by: Sridhar Samudrala --- net/sctp/input.c | 49 ++++++++++++++++++++++++++++++++++--------------- 1 file changed, 34 insertions(+), 15 deletions(-) diff --git a/net/sctp/input.c b/net/sctp/input.c index b719a77d66b..fffc880a646 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c @@ -178,6 +178,37 @@ int sctp_rcv(struct sk_buff *skb) asoc = __sctp_rcv_lookup(skb, &src, &dest, &transport); + if (!asoc) + ep = __sctp_rcv_lookup_endpoint(&dest); + + /* Retrieve the common input handling substructure. */ + rcvr = asoc ? &asoc->base : &ep->base; + sk = rcvr->sk; + + /* + * If a frame arrives on an interface and the receiving socket is + * bound to another interface, via SO_BINDTODEVICE, treat it as OOTB + */ + if (sk->sk_bound_dev_if && (sk->sk_bound_dev_if != af->skb_iif(skb))) + { + sock_put(sk); + if (asoc) { + sctp_association_put(asoc); + asoc = NULL; + } else { + sctp_endpoint_put(ep); + ep = NULL; + } + sk = sctp_get_ctl_sock(); + ep = sctp_sk(sk)->ep; + sctp_endpoint_hold(ep); + sock_hold(sk); + rcvr = &ep->base; + } + + if (atomic_read(&sk->sk_rmem_alloc) >= sk->sk_rcvbuf) + goto discard_release; + /* * RFC 2960, 8.4 - Handle "Out of the blue" Packets. * An SCTP packet is called an "out of the blue" (OOTB) @@ -187,22 +218,12 @@ int sctp_rcv(struct sk_buff *skb) * packet belongs. */ if (!asoc) { - ep = __sctp_rcv_lookup_endpoint(&dest); if (sctp_rcv_ootb(skb)) { SCTP_INC_STATS_BH(SCTP_MIB_OUTOFBLUES); goto discard_release; } } - /* Retrieve the common input handling substructure. */ - rcvr = asoc ? &asoc->base : &ep->base; - sk = rcvr->sk; - - if ((sk) && (atomic_read(&sk->sk_rmem_alloc) >= sk->sk_rcvbuf)) { - goto discard_release; - } - - /* SCTP seems to always need a timestamp right now (FIXME) */ if (skb->stamp.tv_sec == 0) { do_gettimeofday(&skb->stamp); @@ -265,13 +286,11 @@ discard_it: discard_release: /* Release any structures we may be holding. */ - if (asoc) { - sock_put(asoc->base.sk); + sock_put(sk); + if (asoc) sctp_association_put(asoc); - } else { - sock_put(ep->base.sk); + else sctp_endpoint_put(ep); - } goto discard_it; } -- cgit v1.2.3-70-g09d2 From bca735bd0d5969497704a125b05344b92155172f Mon Sep 17 00:00:00 2001 From: Vladislav Yasevich Date: Mon, 13 Jun 2005 15:11:57 -0700 Subject: [SCTP] Extend the info exported via /proc/net/sctp to support netstat for SCTP. Signed-off-by: Vladislav Yasevich Signed-off-by: Sridhar Samudrala Signed-off-by: David S. Miller --- net/sctp/proc.c | 194 +++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 151 insertions(+), 43 deletions(-) diff --git a/net/sctp/proc.c b/net/sctp/proc.c index e42fd8c2916..98d49ec9b74 100644 --- a/net/sctp/proc.c +++ b/net/sctp/proc.c @@ -132,14 +132,25 @@ void sctp_snmp_proc_exit(void) static void sctp_seq_dump_local_addrs(struct seq_file *seq, struct sctp_ep_common *epb) { struct list_head *pos; + struct sctp_association *asoc; struct sctp_sockaddr_entry *laddr; - union sctp_addr *addr; + struct sctp_transport *peer; + union sctp_addr *addr, *primary = NULL; struct sctp_af *af; + if (epb->type == SCTP_EP_TYPE_ASSOCIATION) { + asoc = sctp_assoc(epb); + peer = asoc->peer.primary_path; + primary = &peer->saddr; + } + list_for_each(pos, &epb->bind_addr.address_list) { laddr = list_entry(pos, struct sctp_sockaddr_entry, list); addr = (union sctp_addr *)&laddr->a; af = sctp_get_af_specific(addr->sa.sa_family); + if (primary && af->cmp_addr(addr, primary)) { + seq_printf(seq, "*"); + } af->seq_dump_addr(seq, addr); } } @@ -149,17 +160,54 @@ static void sctp_seq_dump_remote_addrs(struct seq_file *seq, struct sctp_associa { struct list_head *pos; struct sctp_transport *transport; - union sctp_addr *addr; + union sctp_addr *addr, *primary; struct sctp_af *af; + primary = &(assoc->peer.primary_addr); list_for_each(pos, &assoc->peer.transport_addr_list) { transport = list_entry(pos, struct sctp_transport, transports); addr = (union sctp_addr *)&transport->ipaddr; af = sctp_get_af_specific(addr->sa.sa_family); + if (af->cmp_addr(addr, primary)) { + seq_printf(seq, "*"); + } af->seq_dump_addr(seq, addr); } } +static void * sctp_eps_seq_start(struct seq_file *seq, loff_t *pos) +{ + if (*pos > sctp_ep_hashsize) + return NULL; + + if (*pos < 0) + *pos = 0; + + if (*pos == 0) + seq_printf(seq, " ENDPT SOCK STY SST HBKT LPORT UID INODE LADDRS\n"); + + ++*pos; + + return (void *)pos; +} + +static void sctp_eps_seq_stop(struct seq_file *seq, void *v) +{ + return; +} + + +static void * sctp_eps_seq_next(struct seq_file *seq, void *v, loff_t *pos) +{ + if (*pos > sctp_ep_hashsize) + return NULL; + + ++*pos; + + return pos; +} + + /* Display sctp endpoints (/proc/net/sctp/eps). */ static int sctp_eps_seq_show(struct seq_file *seq, void *v) { @@ -167,38 +215,50 @@ static int sctp_eps_seq_show(struct seq_file *seq, void *v) struct sctp_ep_common *epb; struct sctp_endpoint *ep; struct sock *sk; - int hash; - - seq_printf(seq, " ENDPT SOCK STY SST HBKT LPORT LADDRS\n"); - for (hash = 0; hash < sctp_ep_hashsize; hash++) { - head = &sctp_ep_hashtable[hash]; - read_lock(&head->lock); - for (epb = head->chain; epb; epb = epb->next) { - ep = sctp_ep(epb); - sk = epb->sk; - seq_printf(seq, "%8p %8p %-3d %-3d %-4d %-5d ", ep, sk, - sctp_sk(sk)->type, sk->sk_state, hash, - epb->bind_addr.port); - sctp_seq_dump_local_addrs(seq, epb); - seq_printf(seq, "\n"); - } - read_unlock(&head->lock); + int hash = *(int *)v; + + if (hash > sctp_ep_hashsize) + return -ENOMEM; + + head = &sctp_ep_hashtable[hash-1]; + sctp_local_bh_disable(); + read_lock(&head->lock); + for (epb = head->chain; epb; epb = epb->next) { + ep = sctp_ep(epb); + sk = epb->sk; + seq_printf(seq, "%8p %8p %-3d %-3d %-4d %-5d %5d %5lu ", ep, sk, + sctp_sk(sk)->type, sk->sk_state, hash-1, + epb->bind_addr.port, + sock_i_uid(sk), sock_i_ino(sk)); + + sctp_seq_dump_local_addrs(seq, epb); + seq_printf(seq, "\n"); } + read_unlock(&head->lock); + sctp_local_bh_enable(); return 0; } +static struct seq_operations sctp_eps_ops = { + .start = sctp_eps_seq_start, + .next = sctp_eps_seq_next, + .stop = sctp_eps_seq_stop, + .show = sctp_eps_seq_show, +}; + + /* Initialize the seq file operations for 'eps' object. */ static int sctp_eps_seq_open(struct inode *inode, struct file *file) { - return single_open(file, sctp_eps_seq_show, NULL); + return seq_open(file, &sctp_eps_ops); } static struct file_operations sctp_eps_seq_fops = { .open = sctp_eps_seq_open, .read = seq_read, .llseek = seq_lseek, - .release = single_release, + .release = seq_release, }; /* Set up the proc fs entry for 'eps' object. */ @@ -221,6 +281,40 @@ void sctp_eps_proc_exit(void) remove_proc_entry("eps", proc_net_sctp); } + +static void * sctp_assocs_seq_start(struct seq_file *seq, loff_t *pos) +{ + if (*pos > sctp_assoc_hashsize) + return NULL; + + if (*pos < 0) + *pos = 0; + + if (*pos == 0) + seq_printf(seq, " ASSOC SOCK STY SST ST HBKT ASSOC-ID TX_QUEUE RX_QUEUE UID INODE LPORT " + "RPORT LADDRS <-> RADDRS\n"); + + ++*pos; + + return (void *)pos; +} + +static void sctp_assocs_seq_stop(struct seq_file *seq, void *v) +{ + return; +} + + +static void * sctp_assocs_seq_next(struct seq_file *seq, void *v, loff_t *pos) +{ + if (*pos > sctp_assoc_hashsize) + return NULL; + + ++*pos; + + return pos; +} + /* Display sctp associations (/proc/net/sctp/assocs). */ static int sctp_assocs_seq_show(struct seq_file *seq, void *v) { @@ -228,43 +322,57 @@ static int sctp_assocs_seq_show(struct seq_file *seq, void *v) struct sctp_ep_common *epb; struct sctp_association *assoc; struct sock *sk; - int hash; - - seq_printf(seq, " ASSOC SOCK STY SST ST HBKT LPORT RPORT " - "LADDRS <-> RADDRS\n"); - for (hash = 0; hash < sctp_assoc_hashsize; hash++) { - head = &sctp_assoc_hashtable[hash]; - read_lock(&head->lock); - for (epb = head->chain; epb; epb = epb->next) { - assoc = sctp_assoc(epb); - sk = epb->sk; - seq_printf(seq, - "%8p %8p %-3d %-3d %-2d %-4d %-5d %-5d ", - assoc, sk, sctp_sk(sk)->type, sk->sk_state, - assoc->state, hash, epb->bind_addr.port, - assoc->peer.port); - sctp_seq_dump_local_addrs(seq, epb); - seq_printf(seq, "<-> "); - sctp_seq_dump_remote_addrs(seq, assoc); - seq_printf(seq, "\n"); - } - read_unlock(&head->lock); + int hash = *(int *)v; + + if (hash > sctp_assoc_hashsize) + return -ENOMEM; + + head = &sctp_assoc_hashtable[hash-1]; + sctp_local_bh_disable(); + read_lock(&head->lock); + for (epb = head->chain; epb; epb = epb->next) { + assoc = sctp_assoc(epb); + sk = epb->sk; + seq_printf(seq, + "%8p %8p %-3d %-3d %-2d %-4d %4d %8d %8d %7d %5lu %-5d %5d ", + assoc, sk, sctp_sk(sk)->type, sk->sk_state, + assoc->state, hash-1, assoc->assoc_id, + (sk->sk_rcvbuf - assoc->rwnd), + assoc->sndbuf_used, + sock_i_uid(sk), sock_i_ino(sk), + epb->bind_addr.port, + assoc->peer.port); + + seq_printf(seq, " "); + sctp_seq_dump_local_addrs(seq, epb); + seq_printf(seq, "<-> "); + sctp_seq_dump_remote_addrs(seq, assoc); + seq_printf(seq, "\n"); } + read_unlock(&head->lock); + sctp_local_bh_enable(); return 0; } +static struct seq_operations sctp_assoc_ops = { + .start = sctp_assocs_seq_start, + .next = sctp_assocs_seq_next, + .stop = sctp_assocs_seq_stop, + .show = sctp_assocs_seq_show, +}; + /* Initialize the seq file operations for 'assocs' object. */ static int sctp_assocs_seq_open(struct inode *inode, struct file *file) { - return single_open(file, sctp_assocs_seq_show, NULL); + return seq_open(file, &sctp_assoc_ops); } static struct file_operations sctp_assocs_seq_fops = { .open = sctp_assocs_seq_open, .read = seq_read, .llseek = seq_lseek, - .release = single_release, + .release = seq_release, }; /* Set up the proc fs entry for 'assocs' object. */ -- cgit v1.2.3-70-g09d2 From cdac4e07748934e37e415437055ed591aed9eb21 Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Mon, 13 Jun 2005 15:12:33 -0700 Subject: [SCTP] Add support for ip_nonlocal_bind sysctl & IP_FREEBIND socket option Signed-off-by: Neil Horman Signed-off-by: Sridhar Samudrala Signed-off-by: David S. Miller --- include/net/ip.h | 1 + net/ipv4/af_inet.c | 1 + net/sctp/protocol.c | 7 +++++-- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/include/net/ip.h b/include/net/ip.h index 3f63992eb71..32360bbe143 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -163,6 +163,7 @@ DECLARE_SNMP_STAT(struct linux_mib, net_statistics); extern int sysctl_local_port_range[2]; extern int sysctl_ip_default_ttl; +extern int sysctl_ip_nonlocal_bind; #ifdef CONFIG_INET /* The function in 2.2 was invalid, producing wrong result for diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index b3cb49ce5fa..03942f13394 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -1181,6 +1181,7 @@ EXPORT_SYMBOL(inet_stream_connect); EXPORT_SYMBOL(inet_stream_ops); EXPORT_SYMBOL(inet_unregister_protosw); EXPORT_SYMBOL(net_statistics); +EXPORT_SYMBOL(sysctl_ip_nonlocal_bind); #ifdef INET_REFCNT_DEBUG EXPORT_SYMBOL(inet_sock_nr); diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index 2e1f9c3556f..5135e1a25d2 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c @@ -378,10 +378,13 @@ static int sctp_v4_available(union sctp_addr *addr, struct sctp_sock *sp) { int ret = inet_addr_type(addr->v4.sin_addr.s_addr); - /* FIXME: ip_nonlocal_bind sysctl support. */ - if (addr->v4.sin_addr.s_addr != INADDR_ANY && ret != RTN_LOCAL) + if (addr->v4.sin_addr.s_addr != INADDR_ANY && + ret != RTN_LOCAL && + !sp->inet.freebind && + !sysctl_ip_nonlocal_bind) return 0; + return 1; } -- cgit v1.2.3-70-g09d2 From 6a6ddb2a9c11fcc3e8d7517841d28c9ea206ddef Mon Sep 17 00:00:00 2001 From: Sridhar Samudrala Date: Mon, 13 Jun 2005 15:13:05 -0700 Subject: [SCTP] Fix incorrect setting of sk_bound_dev_if when binding/sending to a ipv6 link local address. Signed-off-by: Sridhar Samudrala Signed-off-by: David S. Miller --- net/sctp/ipv6.c | 36 +++++++++++++++--------------------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c index c9d9ea06473..c7e42d125b9 100644 --- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c @@ -812,26 +812,23 @@ static int sctp_inet6_bind_verify(struct sctp_sock *opt, union sctp_addr *addr) if (addr->sa.sa_family != AF_INET6) af = sctp_get_af_specific(addr->sa.sa_family); else { - struct sock *sk; int type = ipv6_addr_type(&addr->v6.sin6_addr); - sk = sctp_opt2sk(opt); + struct net_device *dev; + if (type & IPV6_ADDR_LINKLOCAL) { - /* Note: Behavior similar to af_inet6.c: - * 1) Overrides previous bound_dev_if - * 2) Destructive even if bind isn't successful. - */ - - if (addr->v6.sin6_scope_id) - sk->sk_bound_dev_if = addr->v6.sin6_scope_id; - if (!sk->sk_bound_dev_if) + if (!addr->v6.sin6_scope_id) + return 0; + dev = dev_get_by_index(addr->v6.sin6_scope_id); + if (!dev) return 0; + dev_put(dev); } af = opt->pf->af; } return af->available(addr, opt); } -/* Verify that the provided sockaddr looks bindable. Common verification, +/* Verify that the provided sockaddr looks sendable. Common verification, * has already been taken care of. */ static int sctp_inet6_send_verify(struct sctp_sock *opt, union sctp_addr *addr) @@ -842,19 +839,16 @@ static int sctp_inet6_send_verify(struct sctp_sock *opt, union sctp_addr *addr) if (addr->sa.sa_family != AF_INET6) af = sctp_get_af_specific(addr->sa.sa_family); else { - struct sock *sk; int type = ipv6_addr_type(&addr->v6.sin6_addr); - sk = sctp_opt2sk(opt); + struct net_device *dev; + if (type & IPV6_ADDR_LINKLOCAL) { - /* Note: Behavior similar to af_inet6.c: - * 1) Overrides previous bound_dev_if - * 2) Destructive even if bind isn't successful. - */ - - if (addr->v6.sin6_scope_id) - sk->sk_bound_dev_if = addr->v6.sin6_scope_id; - if (!sk->sk_bound_dev_if) + if (!addr->v6.sin6_scope_id) + return 0; + dev = dev_get_by_index(addr->v6.sin6_scope_id); + if (!dev) return 0; + dev_put(dev); } af = opt->pf->af; } -- cgit v1.2.3-70-g09d2 From 1c2fb7f93cb20621772bf304f3dba0849942e5db Mon Sep 17 00:00:00 2001 From: "J. Simonetti" Date: Mon, 13 Jun 2005 15:19:03 -0700 Subject: [IPV4]: Sysctl configurable icmp error source address. This patch alows you to change the source address of icmp error messages. It applies cleanly to 2.6.11.11 and retains the default behaviour. In the old (default) behaviour icmp error messages are sent with the ip of the exiting interface. The new behaviour (when the sysctl variable is toggled on), it will send the message with the ip of the interface that received the packet that caused the icmp error. This is the behaviour network administrators will expect from a router. It makes debugging complicated network layouts much easier. Also, all 'vendor routers' I know of have the later behaviour. Signed-off-by: David S. Miller --- include/linux/sysctl.h | 1 + net/ipv4/icmp.c | 9 +++++++-- net/ipv4/sysctl_net_ipv4.c | 9 +++++++++ 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index 23032d9d607..a17745c80a9 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -346,6 +346,7 @@ enum NET_TCP_MODERATE_RCVBUF=106, NET_TCP_TSO_WIN_DIVISOR=107, NET_TCP_BIC_BETA=108, + NET_IPV4_ICMP_ERRORS_USE_INBOUND_IFADDR=109, }; enum { diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 85bf0d3e294..cb759484979 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -207,6 +207,7 @@ int sysctl_icmp_ignore_bogus_error_responses; int sysctl_icmp_ratelimit = 1 * HZ; int sysctl_icmp_ratemask = 0x1818; +int sysctl_icmp_errors_use_inbound_ifaddr; /* * ICMP control array. This specifies what to do with each ICMP. @@ -511,8 +512,12 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, u32 info) */ saddr = iph->daddr; - if (!(rt->rt_flags & RTCF_LOCAL)) - saddr = 0; + if (!(rt->rt_flags & RTCF_LOCAL)) { + if (sysctl_icmp_errors_use_inbound_ifaddr) + saddr = inet_select_addr(skb_in->dev, 0, RT_SCOPE_LINK); + else + saddr = 0; + } tos = icmp_pointers[type].error ? ((iph->tos & IPTOS_TOS_MASK) | IPTOS_PREC_INTERNETCONTROL) : diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c index 3aafb298c1c..23068bddbf0 100644 --- a/net/ipv4/sysctl_net_ipv4.c +++ b/net/ipv4/sysctl_net_ipv4.c @@ -23,6 +23,7 @@ extern int sysctl_ip_nonlocal_bind; extern int sysctl_icmp_echo_ignore_all; extern int sysctl_icmp_echo_ignore_broadcasts; extern int sysctl_icmp_ignore_bogus_error_responses; +extern int sysctl_icmp_errors_use_inbound_ifaddr; /* From ip_fragment.c */ extern int sysctl_ipfrag_low_thresh; @@ -395,6 +396,14 @@ ctl_table ipv4_table[] = { .mode = 0644, .proc_handler = &proc_dointvec }, + { + .ctl_name = NET_IPV4_ICMP_ERRORS_USE_INBOUND_IFADDR, + .procname = "icmp_errors_use_inbound_ifaddr", + .data = &sysctl_icmp_errors_use_inbound_ifaddr, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, { .ctl_name = NET_IPV4_ROUTE, .procname = "route", -- cgit v1.2.3-70-g09d2 From cbd83da82b15292337ff2b71e619c9a3a95f6d80 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 13 Jun 2005 17:51:55 -0700 Subject: Update DCO ("signoff") rules to 1.1 This adds a clause that notes explicitly that the person doing the sign-off knows that the project (and his sign-off) is public and will possibly get archived and re-distributed. --- Documentation/SubmittingPatches | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches index 9838d32b2fe..4d35562b1cf 100644 --- a/Documentation/SubmittingPatches +++ b/Documentation/SubmittingPatches @@ -271,7 +271,7 @@ patch, which certifies that you wrote it or otherwise have the right to pass it on as a open-source patch. The rules are pretty simple: if you can certify the below: - Developer's Certificate of Origin 1.0 + Developer's Certificate of Origin 1.1 By making a contribution to this project, I certify that: @@ -291,6 +291,12 @@ can certify the below: person who certified (a), (b) or (c) and I have not modified it. + (d) I understand and agree that this project and the contribution + are public and that a record of the contribution (including all + personal information I submit with it, including my sign-off) is + maintained indefinitely and may be redistributed consistent with + this project or the open source license(s) involved. + then you just add a line saying Signed-off-by: Random J Developer -- cgit v1.2.3-70-g09d2 From a96aca88ac71f75e566981b554da44bfd0d111e8 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Mon, 13 Jun 2005 18:27:13 -0700 Subject: [NETFILTER]: Advance seq-file position in exp_next_seq() Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/ipv4/netfilter/ip_conntrack_standalone.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/ipv4/netfilter/ip_conntrack_standalone.c b/net/ipv4/netfilter/ip_conntrack_standalone.c index 46ca45f74d8..bc59f7b3980 100644 --- a/net/ipv4/netfilter/ip_conntrack_standalone.c +++ b/net/ipv4/netfilter/ip_conntrack_standalone.c @@ -256,6 +256,7 @@ static void *exp_seq_next(struct seq_file *s, void *v, loff_t *pos) { struct list_head *e = v; + ++*pos; e = e->next; if (e == &ip_conntrack_expect_list) -- cgit v1.2.3-70-g09d2 From 8447f3f4659d91c2f11a1476522369c9d6ae6ada Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Mon, 13 Jun 2005 15:52:04 -0700 Subject: [PATCH] uml: remove duplicate includes A few files include the same header twice. Signed-off-by: Jeff Dike Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/kernel/main.c | 2 -- arch/um/kernel/process.c | 1 - arch/um/kernel/um_arch.c | 1 - 3 files changed, 4 deletions(-) diff --git a/arch/um/kernel/main.c b/arch/um/kernel/main.c index e42e6364ca1..e59f5815267 100644 --- a/arch/um/kernel/main.c +++ b/arch/um/kernel/main.c @@ -24,8 +24,6 @@ #include "mode.h" #include "choose-mode.h" #include "uml-config.h" -#include "irq_user.h" -#include "time_user.h" #include "os.h" /* Set in set_stklim, which is called from main and __wrap_malloc. diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c index 51f8e5a8ac6..793c77c6ef9 100644 --- a/arch/um/kernel/process.c +++ b/arch/um/kernel/process.c @@ -30,7 +30,6 @@ #include "init.h" #include "os.h" #include "uml-config.h" -#include "ptrace_user.h" #include "choose-mode.h" #include "mode.h" #ifdef UML_CONFIG_MODE_SKAS diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c index 418427107b2..8736d098f0e 100644 --- a/arch/um/kernel/um_arch.c +++ b/arch/um/kernel/um_arch.c @@ -26,7 +26,6 @@ #include "asm/setup.h" #include "ubd_user.h" #include "asm/current.h" -#include "asm/setup.h" #include "user_util.h" #include "kern_util.h" #include "kern.h" -- cgit v1.2.3-70-g09d2 From 36ca1195ad7f760a6af3814cb002bd3a3d4b4db1 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Mon, 13 Jun 2005 15:52:10 -0700 Subject: [PATCH] uml: build cleanups Fix a build failure when CONFIG_MODE_SKAS is disabled and make a Makefile comment fit in 80 columns. Signed-off-by: Jeff Dike Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/include/sysdep-i386/ptrace.h | 5 ++--- arch/um/scripts/Makefile.rules | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/arch/um/include/sysdep-i386/ptrace.h b/arch/um/include/sysdep-i386/ptrace.h index 6eaeb991998..c8ee9559f3a 100644 --- a/arch/um/include/sysdep-i386/ptrace.h +++ b/arch/um/include/sysdep-i386/ptrace.h @@ -8,6 +8,8 @@ #include "uml-config.h" #include "user_constants.h" +#include "sysdep/faultinfo.h" +#include "choose-mode.h" #define MAX_REG_NR (UM_FRAME_SIZE / sizeof(unsigned long)) #define MAX_REG_OFFSET (UM_FRAME_SIZE) @@ -58,9 +60,6 @@ extern int sysemu_supported; #define PTRACE_SYSEMU_SINGLESTEP 32 #endif -#include "sysdep/faultinfo.h" -#include "choose-mode.h" - union uml_pt_regs { #ifdef UML_CONFIG_MODE_TT struct tt_regs { diff --git a/arch/um/scripts/Makefile.rules b/arch/um/scripts/Makefile.rules index 0b2491883d9..98346c71149 100644 --- a/arch/um/scripts/Makefile.rules +++ b/arch/um/scripts/Makefile.rules @@ -14,7 +14,7 @@ quiet_cmd_make_link = SYMLINK $@ cmd_make_link = ln -sf $(srctree)/arch/$(SUBARCH)/$($(notdir $@)-dir)/$(notdir $@) $@ # this needs to be before the foreach, because targets does not accept -# complete paths like $(obj)/$(f). To make sure this works, use a := assignment, +# complete paths like $(obj)/$(f). To make sure this works, use a := assignment # or we will get $(obj)/$(f) in the "targets" value. # Also, this forces you to use the := syntax when assigning to targets. # Otherwise the line below will cause an infinite loop (if you don't know why, -- cgit v1.2.3-70-g09d2 From 98fdffccea6cc3fe9dba32c0fcc310bcb5d71529 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Mon, 13 Jun 2005 15:52:14 -0700 Subject: [PATCH] uml: use fork instead of clone Convert the boot-time host ptrace testing from clone to fork. They were essentially doing fork anyway. This cleans up the code a bit, and makes valgrind a bit happier about grinding it. Signed-off-by: Jeff Dike Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/kernel/process.c | 48 +++++++++++++++++++----------------------------- 1 file changed, 19 insertions(+), 29 deletions(-) diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c index 793c77c6ef9..1b5ef3e96c7 100644 --- a/arch/um/kernel/process.c +++ b/arch/um/kernel/process.c @@ -130,7 +130,7 @@ int start_fork_tramp(void *thread_arg, unsigned long temp_stack, return(arg.pid); } -static int ptrace_child(void *arg) +static int ptrace_child(void) { int ret; int pid = os_getpid(), ppid = getppid(); @@ -159,20 +159,16 @@ static int ptrace_child(void *arg) _exit(ret); } -static int start_ptraced_child(void **stack_out) +static int start_ptraced_child(void) { - void *stack; - unsigned long sp; int pid, n, status; - stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - if(stack == MAP_FAILED) - panic("check_ptrace : mmap failed, errno = %d", errno); - sp = (unsigned long) stack + PAGE_SIZE - sizeof(void *); - pid = clone(ptrace_child, (void *) sp, SIGCHLD, NULL); + pid = fork(); + if(pid == 0) + ptrace_child(); + if(pid < 0) - panic("check_ptrace : clone failed, errno = %d", errno); + panic("check_ptrace : fork failed, errno = %d", errno); CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); if(n < 0) panic("check_ptrace : wait failed, errno = %d", errno); @@ -180,7 +176,6 @@ static int start_ptraced_child(void **stack_out) panic("check_ptrace : expected SIGSTOP, got status = %d", status); - *stack_out = stack; return(pid); } @@ -188,12 +183,12 @@ static int start_ptraced_child(void **stack_out) * just avoid using sysemu, not panic, but only if SYSEMU features are broken. * So only for SYSEMU features we test mustpanic, while normal host features * must work anyway!*/ -static int stop_ptraced_child(int pid, void *stack, int exitcode, int mustpanic) +static int stop_ptraced_child(int pid, int exitcode, int mustexit) { int status, n, ret = 0; if(ptrace(PTRACE_CONT, pid, 0, 0) < 0) - panic("check_ptrace : ptrace failed, errno = %d", errno); + panic("stop_ptraced_child : ptrace failed, errno = %d", errno); CATCH_EINTR(n = waitpid(pid, &status, 0)); if(!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode)) { int exit_with = WEXITSTATUS(status); @@ -204,15 +199,13 @@ static int stop_ptraced_child(int pid, void *stack, int exitcode, int mustpanic) printk("check_ptrace : child exited with exitcode %d, while " "expecting %d; status 0x%x", exit_with, exitcode, status); - if (mustpanic) + if (mustexit) panic("\n"); else printk("\n"); ret = -1; } - if(munmap(stack, PAGE_SIZE) < 0) - panic("check_ptrace : munmap failed, errno = %d", errno); return ret; } @@ -234,12 +227,11 @@ __uml_setup("nosysemu", nosysemu_cmd_param, static void __init check_sysemu(void) { - void *stack; int pid, syscall, n, status, count=0; printk("Checking syscall emulation patch for ptrace..."); sysemu_supported = 0; - pid = start_ptraced_child(&stack); + pid = start_ptraced_child(); if(ptrace(PTRACE_SYSEMU, pid, 0, 0) < 0) goto fail; @@ -257,7 +249,7 @@ static void __init check_sysemu(void) panic("check_sysemu : failed to modify system " "call return, errno = %d", errno); - if (stop_ptraced_child(pid, stack, 0, 0) < 0) + if (stop_ptraced_child(pid, 0, 0) < 0) goto fail_stopped; sysemu_supported = 1; @@ -265,7 +257,7 @@ static void __init check_sysemu(void) set_using_sysemu(!force_sysemu_disabled); printk("Checking advanced syscall emulation patch for ptrace..."); - pid = start_ptraced_child(&stack); + pid = start_ptraced_child(); while(1){ count++; if(ptrace(PTRACE_SYSEMU_SINGLESTEP, pid, 0, 0) < 0) @@ -290,7 +282,7 @@ static void __init check_sysemu(void) break; } } - if (stop_ptraced_child(pid, stack, 0, 0) < 0) + if (stop_ptraced_child(pid, 0, 0) < 0) goto fail_stopped; sysemu_supported = 2; @@ -301,18 +293,17 @@ static void __init check_sysemu(void) return; fail: - stop_ptraced_child(pid, stack, 1, 0); + stop_ptraced_child(pid, 1, 0); fail_stopped: printk("missing\n"); } void __init check_ptrace(void) { - void *stack; int pid, syscall, n, status; printk("Checking that ptrace can change system call numbers..."); - pid = start_ptraced_child(&stack); + pid = start_ptraced_child(); if (ptrace(PTRACE_OLDSETOPTIONS, pid, 0, (void *)PTRACE_O_TRACESYSGOOD) < 0) panic("check_ptrace: PTRACE_SETOPTIONS failed, errno = %d", errno); @@ -339,7 +330,7 @@ void __init check_ptrace(void) break; } } - stop_ptraced_child(pid, stack, 0, 1); + stop_ptraced_child(pid, 0, 1); printk("OK\n"); check_sysemu(); } @@ -371,11 +362,10 @@ void forward_pending_sigio(int target) static inline int check_skas3_ptrace_support(void) { struct ptrace_faultinfo fi; - void *stack; int pid, n, ret = 1; printf("Checking for the skas3 patch in the host..."); - pid = start_ptraced_child(&stack); + pid = start_ptraced_child(); n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi); if (n < 0) { @@ -390,7 +380,7 @@ static inline int check_skas3_ptrace_support(void) } init_registers(pid); - stop_ptraced_child(pid, stack, 1, 1); + stop_ptraced_child(pid, 1, 1); return(ret); } -- cgit v1.2.3-70-g09d2 From a3c77c67a443e631febf708bb0c376caede31657 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Mon, 13 Jun 2005 15:52:18 -0700 Subject: [PATCH] uml: slirp and slip driver cleanups and fixes This patch merges a lot of duplicated code in the slip and slirp drivers, abstracts out the slip protocol, and makes the slip driver work in 2.6. Signed-off-by: Jeff Dike Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/Makefile | 6 +- arch/um/drivers/slip.h | 23 +------ arch/um/drivers/slip_common.c | 54 +++++++++++++++ arch/um/drivers/slip_common.h | 104 +++++++++++++++++++++++++++++ arch/um/drivers/slip_kern.c | 12 ++-- arch/um/drivers/slip_proto.h | 94 -------------------------- arch/um/drivers/slip_user.c | 152 +++++++++++++++++------------------------- arch/um/drivers/slirp.h | 26 ++------ arch/um/drivers/slirp_kern.c | 5 +- arch/um/drivers/slirp_user.c | 104 ++++++----------------------- 10 files changed, 258 insertions(+), 322 deletions(-) create mode 100644 arch/um/drivers/slip_common.c create mode 100644 arch/um/drivers/slip_common.h delete mode 100644 arch/um/drivers/slip_proto.h diff --git a/arch/um/drivers/Makefile b/arch/um/drivers/Makefile index 323f72c64cd..b2de9916c32 100644 --- a/arch/um/drivers/Makefile +++ b/arch/um/drivers/Makefile @@ -22,8 +22,8 @@ obj-y := stdio_console.o fd.o chan_kern.o chan_user.o line.o obj-$(CONFIG_SSL) += ssl.o obj-$(CONFIG_STDERR_CONSOLE) += stderr_console.o -obj-$(CONFIG_UML_NET_SLIP) += slip.o -obj-$(CONFIG_UML_NET_SLIRP) += slirp.o +obj-$(CONFIG_UML_NET_SLIP) += slip.o slip_common.o +obj-$(CONFIG_UML_NET_SLIRP) += slirp.o slip_common.o obj-$(CONFIG_UML_NET_DAEMON) += daemon.o obj-$(CONFIG_UML_NET_MCAST) += mcast.o #obj-$(CONFIG_UML_NET_PCAP) += pcap.o $(PCAP) @@ -41,6 +41,6 @@ obj-$(CONFIG_UML_WATCHDOG) += harddog.o obj-$(CONFIG_BLK_DEV_COW_COMMON) += cow_user.o obj-$(CONFIG_UML_RANDOM) += random.o -USER_OBJS := fd.o null.o pty.o tty.o xterm.o +USER_OBJS := fd.o null.o pty.o tty.o xterm.o slip_common.o include arch/um/scripts/Makefile.rules diff --git a/arch/um/drivers/slip.h b/arch/um/drivers/slip.h index d523618cd5a..bb0dab41c2e 100644 --- a/arch/um/drivers/slip.h +++ b/arch/um/drivers/slip.h @@ -1,10 +1,7 @@ #ifndef __UM_SLIP_H #define __UM_SLIP_H -#define BUF_SIZE 1500 - /* two bytes each for a (pathological) max packet of escaped chars + * - * terminating END char + initial END char */ -#define ENC_BUF_SIZE (2 * BUF_SIZE + 2) +#include "slip_common.h" struct slip_data { void *dev; @@ -12,28 +9,12 @@ struct slip_data { char *addr; char *gate_addr; int slave; - unsigned char ibuf[ENC_BUF_SIZE]; - unsigned char obuf[ENC_BUF_SIZE]; - int more; /* more data: do not read fd until ibuf has been drained */ - int pos; - int esc; + struct slip_proto slip; }; extern struct net_user_info slip_user_info; -extern int set_umn_addr(int fd, char *addr, char *ptp_addr); extern int slip_user_read(int fd, void *buf, int len, struct slip_data *pri); extern int slip_user_write(int fd, void *buf, int len, struct slip_data *pri); #endif - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff --git a/arch/um/drivers/slip_common.c b/arch/um/drivers/slip_common.c new file mode 100644 index 00000000000..e89cfc68fc3 --- /dev/null +++ b/arch/um/drivers/slip_common.c @@ -0,0 +1,54 @@ +#include +#include "slip_common.h" +#include "net_user.h" + +int slip_proto_read(int fd, void *buf, int len, struct slip_proto *slip) +{ + int i, n, size, start; + + if(slip->more > 0){ + i = 0; + while(i < slip->more){ + size = slip_unesc(slip->ibuf[i++], slip->ibuf, + &slip->pos, &slip->esc); + if(size){ + memcpy(buf, slip->ibuf, size); + memmove(slip->ibuf, &slip->ibuf[i], + slip->more - i); + slip->more = slip->more - i; + return size; + } + } + slip->more = 0; + } + + n = net_read(fd, &slip->ibuf[slip->pos], + sizeof(slip->ibuf) - slip->pos); + if(n <= 0) + return n; + + start = slip->pos; + for(i = 0; i < n; i++){ + size = slip_unesc(slip->ibuf[start + i], slip->ibuf,&slip->pos, + &slip->esc); + if(size){ + memcpy(buf, slip->ibuf, size); + memmove(slip->ibuf, &slip->ibuf[start+i+1], + n - (i + 1)); + slip->more = n - (i + 1); + return size; + } + } + return 0; +} + +int slip_proto_write(int fd, void *buf, int len, struct slip_proto *slip) +{ + int actual, n; + + actual = slip_esc(buf, slip->obuf, len); + n = net_write(fd, slip->obuf, actual); + if(n < 0) + return n; + else return len; +} diff --git a/arch/um/drivers/slip_common.h b/arch/um/drivers/slip_common.h new file mode 100644 index 00000000000..2ae76d8f1be --- /dev/null +++ b/arch/um/drivers/slip_common.h @@ -0,0 +1,104 @@ +#ifndef __UM_SLIP_COMMON_H +#define __UM_SLIP_COMMON_H + +#define BUF_SIZE 1500 + /* two bytes each for a (pathological) max packet of escaped chars + * + * terminating END char + initial END char */ +#define ENC_BUF_SIZE (2 * BUF_SIZE + 2) + +/* SLIP protocol characters. */ +#define SLIP_END 0300 /* indicates end of frame */ +#define SLIP_ESC 0333 /* indicates byte stuffing */ +#define SLIP_ESC_END 0334 /* ESC ESC_END means END 'data' */ +#define SLIP_ESC_ESC 0335 /* ESC ESC_ESC means ESC 'data' */ + +static inline int slip_unesc(unsigned char c, unsigned char *buf, int *pos, + int *esc) +{ + int ret; + + switch(c){ + case SLIP_END: + *esc = 0; + ret=*pos; + *pos=0; + return(ret); + case SLIP_ESC: + *esc = 1; + return(0); + case SLIP_ESC_ESC: + if(*esc){ + *esc = 0; + c = SLIP_ESC; + } + break; + case SLIP_ESC_END: + if(*esc){ + *esc = 0; + c = SLIP_END; + } + break; + } + buf[(*pos)++] = c; + return(0); +} + +static inline int slip_esc(unsigned char *s, unsigned char *d, int len) +{ + unsigned char *ptr = d; + unsigned char c; + + /* + * Send an initial END character to flush out any + * data that may have accumulated in the receiver + * due to line noise. + */ + + *ptr++ = SLIP_END; + + /* + * For each byte in the packet, send the appropriate + * character sequence, according to the SLIP protocol. + */ + + while (len-- > 0) { + switch(c = *s++) { + case SLIP_END: + *ptr++ = SLIP_ESC; + *ptr++ = SLIP_ESC_END; + break; + case SLIP_ESC: + *ptr++ = SLIP_ESC; + *ptr++ = SLIP_ESC_ESC; + break; + default: + *ptr++ = c; + break; + } + } + *ptr++ = SLIP_END; + return (ptr - d); +} + +struct slip_proto { + unsigned char ibuf[ENC_BUF_SIZE]; + unsigned char obuf[ENC_BUF_SIZE]; + int more; /* more data: do not read fd until ibuf has been drained */ + int pos; + int esc; +}; + +#define SLIP_PROTO_INIT { \ + .ibuf = { '\0' }, \ + .obuf = { '\0' }, \ + .more = 0, \ + .pos = 0, \ + .esc = 0 \ +} + +extern int slip_proto_read(int fd, void *buf, int len, + struct slip_proto *slip); +extern int slip_proto_write(int fd, void *buf, int len, + struct slip_proto *slip); + +#endif diff --git a/arch/um/drivers/slip_kern.c b/arch/um/drivers/slip_kern.c index 0886eedba21..9a6f5c85f90 100644 --- a/arch/um/drivers/slip_kern.c +++ b/arch/um/drivers/slip_kern.c @@ -26,16 +26,16 @@ void slip_init(struct net_device *dev, void *data) .addr = NULL, .gate_addr = init->gate_addr, .slave = -1, - .ibuf = { '\0' }, - .obuf = { '\0' }, - .pos = 0, - .esc = 0, + .slip = SLIP_PROTO_INIT, .dev = dev }); dev->init = NULL; + dev->header_cache_update = NULL; + dev->hard_header_cache = NULL; + dev->hard_header = NULL; dev->hard_header_len = 0; - dev->addr_len = 4; - dev->type = ARPHRD_ETHER; + dev->addr_len = 0; + dev->type = ARPHRD_SLIP; dev->tx_queue_len = 256; dev->flags = IFF_NOARP; printk("SLIP backend - SLIP IP = %s\n", spri->gate_addr); diff --git a/arch/um/drivers/slip_proto.h b/arch/um/drivers/slip_proto.h deleted file mode 100644 index 4c4d94a3310..00000000000 --- a/arch/um/drivers/slip_proto.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#ifndef __UM_SLIP_PROTO_H__ -#define __UM_SLIP_PROTO_H__ - -/* SLIP protocol characters. */ -#define SLIP_END 0300 /* indicates end of frame */ -#define SLIP_ESC 0333 /* indicates byte stuffing */ -#define SLIP_ESC_END 0334 /* ESC ESC_END means END 'data' */ -#define SLIP_ESC_ESC 0335 /* ESC ESC_ESC means ESC 'data' */ - -static inline int slip_unesc(unsigned char c, unsigned char *buf, int *pos, - int *esc) -{ - int ret; - - switch(c){ - case SLIP_END: - *esc = 0; - ret=*pos; - *pos=0; - return(ret); - case SLIP_ESC: - *esc = 1; - return(0); - case SLIP_ESC_ESC: - if(*esc){ - *esc = 0; - c = SLIP_ESC; - } - break; - case SLIP_ESC_END: - if(*esc){ - *esc = 0; - c = SLIP_END; - } - break; - } - buf[(*pos)++] = c; - return(0); -} - -static inline int slip_esc(unsigned char *s, unsigned char *d, int len) -{ - unsigned char *ptr = d; - unsigned char c; - - /* - * Send an initial END character to flush out any - * data that may have accumulated in the receiver - * due to line noise. - */ - - *ptr++ = SLIP_END; - - /* - * For each byte in the packet, send the appropriate - * character sequence, according to the SLIP protocol. - */ - - while (len-- > 0) { - switch(c = *s++) { - case SLIP_END: - *ptr++ = SLIP_ESC; - *ptr++ = SLIP_ESC_END; - break; - case SLIP_ESC: - *ptr++ = SLIP_ESC; - *ptr++ = SLIP_ESC_ESC; - break; - default: - *ptr++ = c; - break; - } - } - *ptr++ = SLIP_END; - return (ptr - d); -} - -#endif - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff --git a/arch/um/drivers/slip_user.c b/arch/um/drivers/slip_user.c index d94846b1b4c..71af444e591 100644 --- a/arch/um/drivers/slip_user.c +++ b/arch/um/drivers/slip_user.c @@ -13,7 +13,7 @@ #include "user.h" #include "net_user.h" #include "slip.h" -#include "slip_proto.h" +#include "slip_common.h" #include "helper.h" #include "os.h" @@ -77,41 +77,51 @@ static int slip_tramp(char **argv, int fd) err = os_pipe(fds, 1, 0); if(err < 0){ printk("slip_tramp : pipe failed, err = %d\n", -err); - return(err); + goto out; } err = 0; pe_data.stdin = fd; pe_data.stdout = fds[1]; pe_data.close_me = fds[0]; - pid = run_helper(slip_pre_exec, &pe_data, argv, NULL); + err = run_helper(slip_pre_exec, &pe_data, argv, NULL); + if(err < 0) + goto out_close; + pid = err; + + output_len = page_size(); + output = um_kmalloc(output_len); + if(output == NULL){ + printk("slip_tramp : failed to allocate output buffer\n"); + os_kill_process(pid, 1); + err = -ENOMEM; + goto out_free; + } - if(pid < 0) err = pid; - else { - output_len = page_size(); - output = um_kmalloc(output_len); - if(output == NULL) - printk("slip_tramp : failed to allocate output " - "buffer\n"); - - os_close_file(fds[1]); - read_output(fds[0], output, output_len); - if(output != NULL){ - printk("%s", output); - kfree(output); - } - CATCH_EINTR(err = waitpid(pid, &status, 0)); - if(err < 0) - err = errno; - else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0)){ - printk("'%s' didn't exit with status 0\n", argv[0]); - err = -EINVAL; - } + os_close_file(fds[1]); + read_output(fds[0], output, output_len); + printk("%s", output); + + CATCH_EINTR(err = waitpid(pid, &status, 0)); + if(err < 0) + err = errno; + else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0)){ + printk("'%s' didn't exit with status 0\n", argv[0]); + err = -EINVAL; } + else err = 0; os_close_file(fds[0]); - return(err); +out_free: + kfree(output); + return err; + +out_close: + os_close_file(fds[0]); + os_close_file(fds[1]); +out: + return err; } static int slip_open(void *data) @@ -123,21 +133,26 @@ static int slip_open(void *data) NULL }; int sfd, mfd, err; - mfd = get_pty(); - if(mfd < 0){ - printk("umn : Failed to open pty, err = %d\n", -mfd); - return(mfd); + err = get_pty(); + if(err < 0){ + printk("slip-open : Failed to open pty, err = %d\n", -err); + goto out; } - sfd = os_open_file(ptsname(mfd), of_rdwr(OPENFLAGS()), 0); - if(sfd < 0){ - printk("Couldn't open tty for slip line, err = %d\n", -sfd); - os_close_file(mfd); - return(sfd); + mfd = err; + + err = os_open_file(ptsname(mfd), of_rdwr(OPENFLAGS()), 0); + if(err < 0){ + printk("Couldn't open tty for slip line, err = %d\n", -err); + goto out_close; } - if(set_up_tty(sfd)) return(-1); + sfd = err; + + if(set_up_tty(sfd)) + goto out_close2; + pri->slave = sfd; - pri->pos = 0; - pri->esc = 0; + pri->slip.pos = 0; + pri->slip.esc = 0; if(pri->gate_addr != NULL){ sprintf(version_buf, "%d", UML_NET_VERSION); strcpy(gate_buf, pri->gate_addr); @@ -146,12 +161,12 @@ static int slip_open(void *data) if(err < 0){ printk("slip_tramp failed - err = %d\n", -err); - return(err); + goto out_close2; } err = os_get_ifname(pri->slave, pri->name); if(err < 0){ printk("get_ifname failed, err = %d\n", -err); - return(err); + goto out_close2; } iter_addresses(pri->dev, open_addr, pri->name); } @@ -160,10 +175,16 @@ static int slip_open(void *data) if(err < 0){ printk("Failed to set slip discipline encapsulation - " "err = %d\n", -err); - return(err); + goto out_close2; } } return(mfd); +out_close2: + os_close_file(sfd); +out_close: + os_close_file(mfd); +out: + return err; } static void slip_close(int fd, void *data) @@ -190,48 +211,12 @@ static void slip_close(int fd, void *data) int slip_user_read(int fd, void *buf, int len, struct slip_data *pri) { - int i, n, size, start; - - if(pri->more>0) { - i = 0; - while(i < pri->more) { - size = slip_unesc(pri->ibuf[i++], - pri->ibuf, &pri->pos, &pri->esc); - if(size){ - memcpy(buf, pri->ibuf, size); - memmove(pri->ibuf, &pri->ibuf[i], pri->more-i); - pri->more=pri->more-i; - return(size); - } - } - pri->more=0; - } - - n = net_read(fd, &pri->ibuf[pri->pos], sizeof(pri->ibuf) - pri->pos); - if(n <= 0) return(n); - - start = pri->pos; - for(i = 0; i < n; i++){ - size = slip_unesc(pri->ibuf[start + i], - pri->ibuf, &pri->pos, &pri->esc); - if(size){ - memcpy(buf, pri->ibuf, size); - memmove(pri->ibuf, &pri->ibuf[start+i+1], n-(i+1)); - pri->more=n-(i+1); - return(size); - } - } - return(0); + return slip_proto_read(fd, buf, len, &pri->slip); } int slip_user_write(int fd, void *buf, int len, struct slip_data *pri) { - int actual, n; - - actual = slip_esc(buf, pri->obuf, len); - n = net_write(fd, pri->obuf, actual); - if(n < 0) return(n); - else return(len); + return slip_proto_write(fd, buf, len, &pri->slip); } static int slip_set_mtu(int mtu, void *data) @@ -267,14 +252,3 @@ struct net_user_info slip_user_info = { .delete_address = slip_del_addr, .max_packet = BUF_SIZE }; - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff --git a/arch/um/drivers/slirp.h b/arch/um/drivers/slirp.h index afa4e30284f..6cf88ab580c 100644 --- a/arch/um/drivers/slirp.h +++ b/arch/um/drivers/slirp.h @@ -1,10 +1,7 @@ #ifndef __UM_SLIRP_H #define __UM_SLIRP_H -#define BUF_SIZE 1500 - /* two bytes each for a (pathological) max packet of escaped chars + * - * terminating END char + initial END char */ -#define ENC_BUF_SIZE (2 * BUF_SIZE + 2) +#include "slip_common.h" #define SLIRP_MAX_ARGS 100 /* @@ -24,28 +21,13 @@ struct slirp_data { struct arg_list_dummy_wrapper argw; int pid; int slave; - unsigned char ibuf[ENC_BUF_SIZE]; - unsigned char obuf[ENC_BUF_SIZE]; - int more; /* more data: do not read fd until ibuf has been drained */ - int pos; - int esc; + struct slip_proto slip; }; extern struct net_user_info slirp_user_info; -extern int set_umn_addr(int fd, char *addr, char *ptp_addr); extern int slirp_user_read(int fd, void *buf, int len, struct slirp_data *pri); -extern int slirp_user_write(int fd, void *buf, int len, struct slirp_data *pri); +extern int slirp_user_write(int fd, void *buf, int len, + struct slirp_data *pri); #endif - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff --git a/arch/um/drivers/slirp_kern.c b/arch/um/drivers/slirp_kern.c index c9d6b52a831..9864d27afdb 100644 --- a/arch/um/drivers/slirp_kern.c +++ b/arch/um/drivers/slirp_kern.c @@ -25,10 +25,7 @@ void slirp_init(struct net_device *dev, void *data) { .argw = init->argw, .pid = -1, .slave = -1, - .ibuf = { '\0' }, - .obuf = { '\0' }, - .pos = 0, - .esc = 0, + .slip = SLIP_PROTO_INIT, .dev = dev }); dev->init = NULL; diff --git a/arch/um/drivers/slirp_user.c b/arch/um/drivers/slirp_user.c index c322515c71c..8d91f663d82 100644 --- a/arch/um/drivers/slirp_user.c +++ b/arch/um/drivers/slirp_user.c @@ -12,7 +12,7 @@ #include "user.h" #include "net_user.h" #include "slirp.h" -#include "slip_proto.h" +#include "slip_common.h" #include "helper.h" #include "os.h" @@ -48,47 +48,32 @@ static int slirp_tramp(char **argv, int fd) return(pid); } -/* XXX This is just a trivial wrapper around os_pipe */ -static int slirp_datachan(int *mfd, int *sfd) -{ - int fds[2], err; - - err = os_pipe(fds, 1, 1); - if(err < 0){ - printk("slirp_datachan: Failed to open pipe, err = %d\n", -err); - return(err); - } - - *mfd = fds[0]; - *sfd = fds[1]; - return(0); -} - static int slirp_open(void *data) { struct slirp_data *pri = data; - int sfd, mfd, pid, err; + int fds[2], pid, err; - err = slirp_datachan(&mfd, &sfd); + err = os_pipe(fds, 1, 1); if(err) return(err); - pid = slirp_tramp(pri->argw.argv, sfd); - - if(pid < 0){ - printk("slirp_tramp failed - errno = %d\n", -pid); - os_close_file(sfd); - os_close_file(mfd); - return(pid); + err = slirp_tramp(pri->argw.argv, fds[1]); + if(err < 0){ + printk("slirp_tramp failed - errno = %d\n", -err); + goto out; } - - pri->slave = sfd; - pri->pos = 0; - pri->esc = 0; - - pri->pid = pid; - - return(mfd); + pid = err; + + pri->slave = fds[1]; + pri->slip.pos = 0; + pri->slip.esc = 0; + pri->pid = err; + + return(fds[0]); +out: + os_close_file(fds[0]); + os_close_file(fds[1]); + return err; } static void slirp_close(int fd, void *data) @@ -129,48 +114,12 @@ static void slirp_close(int fd, void *data) int slirp_user_read(int fd, void *buf, int len, struct slirp_data *pri) { - int i, n, size, start; - - if(pri->more>0) { - i = 0; - while(i < pri->more) { - size = slip_unesc(pri->ibuf[i++], - pri->ibuf,&pri->pos,&pri->esc); - if(size){ - memcpy(buf, pri->ibuf, size); - memmove(pri->ibuf, &pri->ibuf[i], pri->more-i); - pri->more=pri->more-i; - return(size); - } - } - pri->more=0; - } - - n = net_read(fd, &pri->ibuf[pri->pos], sizeof(pri->ibuf) - pri->pos); - if(n <= 0) return(n); - - start = pri->pos; - for(i = 0; i < n; i++){ - size = slip_unesc(pri->ibuf[start + i], - pri->ibuf,&pri->pos,&pri->esc); - if(size){ - memcpy(buf, pri->ibuf, size); - memmove(pri->ibuf, &pri->ibuf[start+i+1], n-(i+1)); - pri->more=n-(i+1); - return(size); - } - } - return(0); + return slip_proto_read(fd, buf, len, &pri->slip); } int slirp_user_write(int fd, void *buf, int len, struct slirp_data *pri) { - int actual, n; - - actual = slip_esc(buf, pri->obuf, len); - n = net_write(fd, pri->obuf, actual); - if(n < 0) return(n); - else return(len); + return slip_proto_write(fd, buf, len, &pri->slip); } static int slirp_set_mtu(int mtu, void *data) @@ -188,14 +137,3 @@ struct net_user_info slirp_user_info = { .delete_address = NULL, .max_packet = BUF_SIZE }; - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ -- cgit v1.2.3-70-g09d2 From f797f9cc5485b50c35c106b462e1bc432ec37f90 Mon Sep 17 00:00:00 2001 From: Olof Johansson Date: Mon, 13 Jun 2005 15:52:27 -0700 Subject: [PATCH] Fix PCI BAR size interpretation on 64-bit arches On 64-bit machines, PCI_BASE_ADDRESS_MEM_MASK and other mask constants passed to pci_size() are 64-bit (for example ~0x0fUL). However, pci_size does comparisons between the u32 arguments and the mask, which will fail even though any result from pci_size is still just 32-bit. Changing the mask argument to u32 seems the obvious thing to do, since all arithmetic in the function is 32-bit and having a larger mask makes no sense. This triggered on a PPC64 system here where an adapter (VGA, as it happened) had a memory region base of 0xfe000000 and a sz of the same, matching the if (max == maxbase ...) test at the bottom of pci_size but failing the mask comparison. Quite a corner case which I guess explains why we haven't seen it until now. Signed-off-by: Olof Johansson Acked-by: Greg KH Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/pci/probe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index b7ae87823c6..fd48b201eb5 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -125,7 +125,7 @@ static inline unsigned int pci_calc_resource_flags(unsigned int flags) /* * Find the extent of a PCI decode.. */ -static u32 pci_size(u32 base, u32 maxbase, unsigned long mask) +static u32 pci_size(u32 base, u32 maxbase, u32 mask) { u32 size = mask & maxbase; /* Find the significant bits */ if (!size) -- cgit v1.2.3-70-g09d2 From 6df3cecbb95345981718b38d357c50bc3425420a Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Mon, 13 Jun 2005 15:52:32 -0700 Subject: [PATCH] cond_resched_lock() fix On one path, cond_resched_lock() fails to return true if it dropped the lock. We think this might be causing the crashes in JBD's log_do_checkpoint(). Cc: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- kernel/sched.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/kernel/sched.c b/kernel/sched.c index 66b2ed78482..f12a0c8a7d9 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -3755,19 +3755,22 @@ EXPORT_SYMBOL(cond_resched); */ int cond_resched_lock(spinlock_t * lock) { + int ret = 0; + if (need_lockbreak(lock)) { spin_unlock(lock); cpu_relax(); + ret = 1; spin_lock(lock); } if (need_resched()) { _raw_spin_unlock(lock); preempt_enable_no_resched(); __cond_resched(); + ret = 1; spin_lock(lock); - return 1; } - return 0; + return ret; } EXPORT_SYMBOL(cond_resched_lock); -- cgit v1.2.3-70-g09d2 From e2c16499515aa044676a14b97a1b8a35f879152a Mon Sep 17 00:00:00 2001 From: Jon Smirl Date: Mon, 13 Jun 2005 15:52:36 -0700 Subject: [PATCH] Typo in fbdev sysfs support, virtual_size It prints out x,x instead of x,y. Signed-off-by: Jon Smirl Cc: "Antonino A. Daplas" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/fbsysfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbsysfs.c index c78a2c5961d..277d733c6d0 100644 --- a/drivers/video/fbsysfs.c +++ b/drivers/video/fbsysfs.c @@ -241,7 +241,7 @@ static ssize_t show_virtual(struct class_device *class_device, char *buf) struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device); return snprintf(buf, PAGE_SIZE, "%d,%d\n", fb_info->var.xres_virtual, - fb_info->var.xres_virtual); + fb_info->var.yres_virtual); } static ssize_t store_cmap(struct class_device *class_device, const char * buf, -- cgit v1.2.3-70-g09d2 From 223230e78900e5f0be984f7697cb9bf172d71a35 Mon Sep 17 00:00:00 2001 From: Markus Lidel Date: Mon, 13 Jun 2005 22:58:00 -0700 Subject: [PATCH] i2o: Fix free of event memory in i2o_block_event() Fixed freeing of event memory in i2o_block_event() Signed-off-by: Markus Lidel Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/message/i2o/i2o_block.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c index 7b74c87b569..4830b775906 100644 --- a/drivers/message/i2o/i2o_block.c +++ b/drivers/message/i2o/i2o_block.c @@ -573,6 +573,7 @@ static int i2o_block_reply(struct i2o_controller *c, u32 m, static void i2o_block_event(struct i2o_event *evt) { osm_info("block-osm: event received\n"); + kfree(evt); }; /* -- cgit v1.2.3-70-g09d2 From 92c6dc59b7c1ca514021502c7eef53b9f2c738fd Mon Sep 17 00:00:00 2001 From: Thomas Hood Date: Mon, 13 Jun 2005 22:58:04 -0700 Subject: [PATCH] apm.c: ignore_normal_resume is set a bit too late This patch causes the ignore_normal_resume flag to be set slightly earlier, before there is a chance that the apm driver will receive the normal resume event from the BIOS. (Addresses Debian bug #310865) Signed-off-by: Thomas Hood Acked-by: Stephen Rothwell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/apm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c index 45641a87255..0ff65abcd56 100644 --- a/arch/i386/kernel/apm.c +++ b/arch/i386/kernel/apm.c @@ -1222,6 +1222,7 @@ static int suspend(int vetoable) save_processor_state(); err = set_system_power_state(APM_STATE_SUSPEND); + ignore_normal_resume = 1; restore_processor_state(); local_irq_disable(); @@ -1229,7 +1230,6 @@ static int suspend(int vetoable) spin_lock(&i8253_lock); reinit_timer(); set_time(); - ignore_normal_resume = 1; spin_unlock(&i8253_lock); write_sequnlock(&xtime_lock); -- cgit v1.2.3-70-g09d2 From 9a47696970bc8233818d370011e2fddae5cfce9f Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 13 Jun 2005 22:58:09 -0700 Subject: [PATCH] macmodes: needs a license Module needs a license to prevent kernel tainting. Signed-off-by: Randy Dunlap Acked-by: Geert Uytterhoeven Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/macmodes.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/video/macmodes.c b/drivers/video/macmodes.c index de5a0f38360..2fc71081f7e 100644 --- a/drivers/video/macmodes.c +++ b/drivers/video/macmodes.c @@ -387,3 +387,4 @@ int __init mac_find_mode(struct fb_var_screeninfo *var, struct fb_info *info, } EXPORT_SYMBOL(mac_find_mode); +MODULE_LICENSE("GPL"); -- cgit v1.2.3-70-g09d2 From efa93dbedd0e2eacf49ea6fff1fe4397d520cf61 Mon Sep 17 00:00:00 2001 From: Karsten Wiese Date: Tue, 14 Jun 2005 09:54:55 -0700 Subject: [PATCH] usbaudio: prevent oops & dead keyboard on usb unplugging while the device is being used Without this patch, some usb kobjects, which are parents to the usx2y's kobjects can be freed before the usx2y's. This led to an oops in get_kobj_path_length() and a dead keyboard, when the usx2y's kobjects were freed. The patch ensures the correct sequence. Tested ok on kernel 2.6.12-rc2. Present in ALSA cvs Signed-off-by: Karsten Wiese Signed-off-by: Greg Kroah-Hartman Signed-off-by: Chris Wright Signed-off-by: Linus Torvalds --- sound/usb/usbaudio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c index 84b0bbddbd2..aae66144d41 100644 --- a/sound/usb/usbaudio.c +++ b/sound/usb/usbaudio.c @@ -3289,7 +3289,7 @@ static void snd_usb_audio_disconnect(struct usb_device *dev, void *ptr) } usb_chip[chip->index] = NULL; up(®ister_mutex); - snd_card_free_in_thread(card); + snd_card_free(card); } else { up(®ister_mutex); } -- cgit v1.2.3-70-g09d2 From dcf78d80a6c2de829ec08c8e663a3370e982d616 Mon Sep 17 00:00:00 2001 From: Karsten Wiese Date: Tue, 14 Jun 2005 09:56:20 -0700 Subject: [PATCH] usbusx2y: prevent oops & dead keyboard on usb unplugging while the device is being used Without this patch, some usb kobjects, which are parents to the usx2y's kobjects can be freed before the usx2y's. This led to an oops in get_kobj_path_length() and a dead keyboard, when the usx2y's kobjects were freed. The patch ensures the correct sequence. Tested ok on kernel 2.6.12-rc2. Present in ALSA cvs Signed-off-by: Karsten Wiese Signed-off-by: Greg Kroah-Hartman Signed-off-by: Chris Wright Signed-off-by: Linus Torvalds --- sound/usb/usx2y/usbusx2y.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/sound/usb/usx2y/usbusx2y.c b/sound/usb/usx2y/usbusx2y.c index b06a267e5da..89ee8b73201 100644 --- a/sound/usb/usx2y/usbusx2y.c +++ b/sound/usb/usx2y/usbusx2y.c @@ -1,6 +1,11 @@ /* * usbusy2y.c - ALSA USB US-428 Driver * +2005-04-14 Karsten Wiese + Version 0.8.7.2: + Call snd_card_free() instead of snd_card_free_in_thread() to prevent oops with dead keyboard symptom. + Tested ok with kernel 2.6.12-rc2. + 2004-12-14 Karsten Wiese Version 0.8.7.1: snd_pcm_open for rawusb pcm-devices now returns -EBUSY if called without rawusb's hwdep device being open. @@ -143,7 +148,7 @@ MODULE_AUTHOR("Karsten Wiese "); -MODULE_DESCRIPTION("TASCAM "NAME_ALLCAPS" Version 0.8.7.1"); +MODULE_DESCRIPTION("TASCAM "NAME_ALLCAPS" Version 0.8.7.2"); MODULE_LICENSE("GPL"); MODULE_SUPPORTED_DEVICE("{{TASCAM(0x1604), "NAME_ALLCAPS"(0x8001)(0x8005)(0x8007) }}"); @@ -430,8 +435,6 @@ static void usX2Y_usb_disconnect(struct usb_device* device, void* ptr) if (ptr) { usX2Ydev_t* usX2Y = usX2Y((snd_card_t*)ptr); struct list_head* p; - if (usX2Y->chip_status == USX2Y_STAT_CHIP_HUP) // on 2.6.1 kernel snd_usbmidi_disconnect() - return; // calls us back. better leave :-) . usX2Y->chip.shutdown = 1; usX2Y->chip_status = USX2Y_STAT_CHIP_HUP; usX2Y_unlinkSeq(&usX2Y->AS04); @@ -443,7 +446,7 @@ static void usX2Y_usb_disconnect(struct usb_device* device, void* ptr) } if (usX2Y->us428ctls_sharedmem) wake_up(&usX2Y->us428ctls_wait_queue_head); - snd_card_free_in_thread((snd_card_t*)ptr); + snd_card_free((snd_card_t*)ptr); } } -- cgit v1.2.3-70-g09d2 From 4845f3333765b732aa2d7ea6d72fd03cfec4fbf3 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Tue, 14 Jun 2005 22:19:24 +1000 Subject: [PATCH] ppc64: update example configs Here is a patch to update the example configs in arch/ppc64/configs. Signed-off-by: Paul Mackerras Signed-off-by: Linus Torvalds --- arch/ppc64/configs/g5_defconfig | 76 +++++++++++++++----------- arch/ppc64/configs/iSeries_defconfig | 62 ++++++++++++--------- arch/ppc64/configs/maple_defconfig | 70 ++++++++++++++++-------- arch/ppc64/configs/pSeries_defconfig | 102 ++++++++++++++++++++++------------- 4 files changed, 196 insertions(+), 114 deletions(-) diff --git a/arch/ppc64/configs/g5_defconfig b/arch/ppc64/configs/g5_defconfig index 0f90df0b3f9..1eb33398648 100644 --- a/arch/ppc64/configs/g5_defconfig +++ b/arch/ppc64/configs/g5_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.11 -# Thu Mar 10 16:47:04 2005 +# Linux kernel version: 2.6.12-rc6 +# Tue Jun 14 16:59:20 2005 # CONFIG_64BIT=y CONFIG_MMU=y @@ -11,7 +11,7 @@ CONFIG_GENERIC_ISA_DMA=y CONFIG_HAVE_DEC_LOCK=y CONFIG_EARLY_PRINTK=y CONFIG_COMPAT=y -CONFIG_FRAME_POINTER=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y CONFIG_FORCE_MAX_ZONEORDER=13 # @@ -20,6 +20,7 @@ CONFIG_FORCE_MAX_ZONEORDER=13 CONFIG_EXPERIMENTAL=y CONFIG_CLEAN_COMPILE=y CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 # # General setup @@ -31,19 +32,20 @@ CONFIG_POSIX_MQUEUE=y # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y # CONFIG_AUDIT is not set -CONFIG_LOG_BUF_SHIFT=17 CONFIG_HOTPLUG=y CONFIG_KOBJECT_UEVENT=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y +# CONFIG_CPUSETS is not set # CONFIG_EMBEDDED is not set CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SHMEM=y CONFIG_CC_ALIGN_FUNCTIONS=0 CONFIG_CC_ALIGN_LABELS=0 @@ -87,6 +89,8 @@ CONFIG_NR_CPUS=2 # CONFIG_SCHED_SMT is not set # CONFIG_PREEMPT is not set CONFIG_GENERIC_HARDIRQS=y +CONFIG_SECCOMP=y +CONFIG_ISA_DMA_API=y # # General setup @@ -97,6 +101,7 @@ CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y +# CONFIG_PCI_DEBUG is not set # CONFIG_HOTPLUG_CPU is not set # @@ -104,10 +109,6 @@ CONFIG_PCI_NAMES=y # # CONFIG_PCCARD is not set -# -# PC-card bridges -# - # # PCI Hotplug Support # @@ -293,7 +294,6 @@ CONFIG_SCSI_SATA_SVW=y # CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_EATA is not set -# CONFIG_SCSI_EATA_PIO is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set # CONFIG_SCSI_GDTH is not set # CONFIG_SCSI_IPS is not set @@ -301,7 +301,6 @@ CONFIG_SCSI_SATA_SVW=y # CONFIG_SCSI_INIA100 is not set # CONFIG_SCSI_SYM53C8XX_2 is not set # CONFIG_SCSI_IPR is not set -# CONFIG_SCSI_QLOGIC_ISP is not set # CONFIG_SCSI_QLOGIC_FC is not set # CONFIG_SCSI_QLOGIC_1280 is not set CONFIG_SCSI_QLA2XXX=y @@ -310,6 +309,7 @@ CONFIG_SCSI_QLA2XXX=y # CONFIG_SCSI_QLA2300 is not set # CONFIG_SCSI_QLA2322 is not set # CONFIG_SCSI_QLA6312 is not set +# CONFIG_SCSI_LPFC is not set # CONFIG_SCSI_DC395x is not set # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_DEBUG is not set @@ -332,6 +332,7 @@ CONFIG_DM_CRYPT=m CONFIG_DM_SNAPSHOT=m CONFIG_DM_MIRROR=m CONFIG_DM_ZERO=m +# CONFIG_DM_MULTIPATH is not set # # Fusion MPT device support @@ -394,7 +395,6 @@ CONFIG_NET=y # CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set -# CONFIG_NETLINK_DEV is not set CONFIG_UNIX=y CONFIG_NET_KEY=m CONFIG_INET=y @@ -564,6 +564,8 @@ CONFIG_E1000=y # CONFIG_R8169 is not set # CONFIG_SK98LIN is not set CONFIG_TIGON3=m +# CONFIG_BNX2 is not set +# CONFIG_MV643XX_ETH is not set # # Ethernet (10000 Mbit) @@ -630,18 +632,6 @@ CONFIG_INPUT_JOYDEV=m CONFIG_INPUT_EVDEV=y # CONFIG_INPUT_EVBUG is not set -# -# Input I/O drivers -# -# CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y -CONFIG_SERIO=y -# CONFIG_SERIO_I8042 is not set -# CONFIG_SERIO_SERPORT is not set -# CONFIG_SERIO_CT82C710 is not set -# CONFIG_SERIO_PCIPS2 is not set -# CONFIG_SERIO_RAW is not set - # # Input Device Drivers # @@ -659,6 +649,16 @@ CONFIG_INPUT_MOUSE=y # CONFIG_INPUT_TOUCHSCREEN is not set # CONFIG_INPUT_MISC is not set +# +# Hardware I/O ports +# +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +# CONFIG_SERIO_SERPORT is not set +# CONFIG_SERIO_PCIPS2 is not set +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + # # Character devices # @@ -676,6 +676,7 @@ CONFIG_HW_CONSOLE=y # Non-8250 serial port support # # CONFIG_SERIAL_PMACZILOG is not set +# CONFIG_SERIAL_JSM is not set CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 @@ -698,9 +699,12 @@ CONFIG_LEGACY_PTY_COUNT=256 # # Ftape, the floppy tape device driver # +CONFIG_AGP=m +CONFIG_AGP_UNINORTH=m # CONFIG_DRM is not set CONFIG_RAW_DRIVER=y CONFIG_MAX_RAW_DEVS=256 +# CONFIG_HANGCHECK_TIMER is not set # # TPM devices @@ -730,12 +734,11 @@ CONFIG_I2C_ALGOBIT=y # CONFIG_I2C_AMD8111 is not set # CONFIG_I2C_I801 is not set # CONFIG_I2C_I810 is not set +# CONFIG_I2C_PIIX4 is not set # CONFIG_I2C_ISA is not set CONFIG_I2C_KEYWEST=y -# CONFIG_I2C_MPC is not set # CONFIG_I2C_NFORCE2 is not set # CONFIG_I2C_PARPORT_LIGHT is not set -# CONFIG_I2C_PIIX4 is not set # CONFIG_I2C_PROSAVAGE is not set # CONFIG_I2C_SAVAGE4 is not set # CONFIG_SCx200_ACB is not set @@ -772,6 +775,7 @@ CONFIG_I2C_KEYWEST=y # CONFIG_SENSORS_LM85 is not set # CONFIG_SENSORS_LM87 is not set # CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set # CONFIG_SENSORS_MAX1619 is not set # CONFIG_SENSORS_PC87360 is not set # CONFIG_SENSORS_SMSC47B397 is not set @@ -785,6 +789,7 @@ CONFIG_I2C_KEYWEST=y # # Other I2C Chip support # +# CONFIG_SENSORS_DS1337 is not set # CONFIG_SENSORS_EEPROM is not set # CONFIG_SENSORS_PCF8574 is not set # CONFIG_SENSORS_PCF8591 is not set @@ -817,6 +822,11 @@ CONFIG_I2C_KEYWEST=y # Graphics support # CONFIG_FB=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +CONFIG_FB_SOFT_CURSOR=y +CONFIG_FB_MACMODES=y CONFIG_FB_MODE_HELPERS=y CONFIG_FB_TILEBLITTING=y # CONFIG_FB_CIRRUS is not set @@ -830,6 +840,7 @@ CONFIG_FB_OF=y # CONFIG_FB_ASILIANT is not set # CONFIG_FB_IMSTT is not set # CONFIG_FB_VGA16 is not set +# CONFIG_FB_NVIDIA is not set CONFIG_FB_RIVA=y # CONFIG_FB_RIVA_I2C is not set # CONFIG_FB_RIVA_DEBUG is not set @@ -847,6 +858,7 @@ CONFIG_FB_RADEON_I2C=y # CONFIG_FB_3DFX is not set # CONFIG_FB_VOODOO1 is not set # CONFIG_FB_TRIDENT is not set +# CONFIG_FB_S1D13XXX is not set # CONFIG_FB_VIRTUAL is not set # @@ -880,6 +892,8 @@ CONFIG_LCD_DEVICE=y # # USB support # +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y CONFIG_USB=y # CONFIG_USB_DEBUG is not set @@ -890,8 +904,6 @@ CONFIG_USB_DEVICEFS=y # CONFIG_USB_BANDWIDTH is not set # CONFIG_USB_DYNAMIC_MINORS is not set # CONFIG_USB_OTG is not set -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y # # USB Host Controller Drivers @@ -917,7 +929,6 @@ CONFIG_USB_PRINTER=y # CONFIG_USB_STORAGE=y # CONFIG_USB_STORAGE_DEBUG is not set -CONFIG_USB_STORAGE_RW_DETECT=y CONFIG_USB_STORAGE_DATAFAB=y CONFIG_USB_STORAGE_FREECOM=y CONFIG_USB_STORAGE_ISD200=y @@ -1004,8 +1015,10 @@ CONFIG_USB_MON=y # CONFIG_USB_SERIAL=m CONFIG_USB_SERIAL_GENERIC=y +# CONFIG_USB_SERIAL_AIRPRIME is not set CONFIG_USB_SERIAL_BELKIN=m CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +# CONFIG_USB_SERIAL_CP2101 is not set CONFIG_USB_SERIAL_CYPRESS_M8=m CONFIG_USB_SERIAL_EMPEG=m CONFIG_USB_SERIAL_FTDI_SIO=m @@ -1034,6 +1047,7 @@ CONFIG_USB_SERIAL_KLSI=m CONFIG_USB_SERIAL_KOBIL_SCT=m CONFIG_USB_SERIAL_MCT_U232=m CONFIG_USB_SERIAL_PL2303=m +# CONFIG_USB_SERIAL_HP4X is not set CONFIG_USB_SERIAL_SAFE=m CONFIG_USB_SERIAL_SAFE_PADDED=y CONFIG_USB_SERIAL_TI=m @@ -1270,11 +1284,13 @@ CONFIG_OPROFILE=y # # Kernel hacking # +# CONFIG_PRINTK_TIME is not set CONFIG_DEBUG_KERNEL=y CONFIG_MAGIC_SYSRQ=y -# CONFIG_PRINTK_TIME is not set +CONFIG_LOG_BUF_SHIFT=17 # CONFIG_SCHEDSTATS is not set # CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_KOBJECT is not set # CONFIG_DEBUG_INFO is not set diff --git a/arch/ppc64/configs/iSeries_defconfig b/arch/ppc64/configs/iSeries_defconfig index a39e9d2e25d..f6a2b99afd6 100644 --- a/arch/ppc64/configs/iSeries_defconfig +++ b/arch/ppc64/configs/iSeries_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.11-rc3-bk6 -# Wed Feb 9 23:34:52 2005 +# Linux kernel version: 2.6.12-rc6 +# Tue Jun 14 17:01:28 2005 # CONFIG_64BIT=y CONFIG_MMU=y @@ -11,7 +11,7 @@ CONFIG_GENERIC_ISA_DMA=y CONFIG_HAVE_DEC_LOCK=y CONFIG_EARLY_PRINTK=y CONFIG_COMPAT=y -CONFIG_FRAME_POINTER=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y CONFIG_FORCE_MAX_ZONEORDER=13 # @@ -20,6 +20,7 @@ CONFIG_FORCE_MAX_ZONEORDER=13 CONFIG_EXPERIMENTAL=y CONFIG_CLEAN_COMPILE=y CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 # # General setup @@ -30,24 +31,29 @@ CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y -CONFIG_LOG_BUF_SHIFT=17 +CONFIG_AUDIT=y +CONFIG_AUDITSYSCALL=y CONFIG_HOTPLUG=y CONFIG_KOBJECT_UEVENT=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y +# CONFIG_CPUSETS is not set # CONFIG_EMBEDDED is not set CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SHMEM=y CONFIG_CC_ALIGN_FUNCTIONS=0 CONFIG_CC_ALIGN_LABELS=0 CONFIG_CC_ALIGN_LOOPS=0 CONFIG_CC_ALIGN_JUMPS=0 # CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 # # Loadable module support @@ -79,6 +85,8 @@ CONFIG_NR_CPUS=32 CONFIG_GENERIC_HARDIRQS=y CONFIG_MSCHUNKS=y CONFIG_LPARCFG=y +CONFIG_SECCOMP=y +CONFIG_ISA_DMA_API=y # # General setup @@ -89,16 +97,13 @@ CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y +# CONFIG_PCI_DEBUG is not set # # PCCARD (PCMCIA/CardBus) support # # CONFIG_PCCARD is not set -# -# PC-card bridges -# - # # PCI Hotplug Support # @@ -210,7 +215,6 @@ CONFIG_SCSI_FC_ATTRS=y # CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_EATA is not set -# CONFIG_SCSI_EATA_PIO is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set # CONFIG_SCSI_GDTH is not set # CONFIG_SCSI_IPS is not set @@ -219,7 +223,6 @@ CONFIG_SCSI_IBMVSCSI=m # CONFIG_SCSI_INIA100 is not set # CONFIG_SCSI_SYM53C8XX_2 is not set # CONFIG_SCSI_IPR is not set -# CONFIG_SCSI_QLOGIC_ISP is not set # CONFIG_SCSI_QLOGIC_FC is not set # CONFIG_SCSI_QLOGIC_1280 is not set CONFIG_SCSI_QLA2XXX=y @@ -228,6 +231,7 @@ CONFIG_SCSI_QLA2XXX=y # CONFIG_SCSI_QLA2300 is not set # CONFIG_SCSI_QLA2322 is not set # CONFIG_SCSI_QLA6312 is not set +# CONFIG_SCSI_LPFC is not set # CONFIG_SCSI_DC395x is not set # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_DEBUG is not set @@ -250,6 +254,7 @@ CONFIG_DM_CRYPT=m CONFIG_DM_SNAPSHOT=m CONFIG_DM_MIRROR=m CONFIG_DM_ZERO=m +# CONFIG_DM_MULTIPATH is not set # # Fusion MPT device support @@ -280,7 +285,6 @@ CONFIG_NET=y # CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set -# CONFIG_NETLINK_DEV is not set CONFIG_UNIX=y CONFIG_NET_KEY=m CONFIG_INET=y @@ -445,7 +449,6 @@ CONFIG_PCNET32=y # CONFIG_DGRS is not set # CONFIG_EEPRO100 is not set CONFIG_E100=y -# CONFIG_E100_NAPI is not set # CONFIG_FEALNX is not set # CONFIG_NATSEMI is not set # CONFIG_NE2K_PCI is not set @@ -471,6 +474,7 @@ CONFIG_E1000=m # CONFIG_SK98LIN is not set # CONFIG_VIA_VELOCITY is not set # CONFIG_TIGON3 is not set +# CONFIG_BNX2 is not set # # Ethernet (10000 Mbit) @@ -538,14 +542,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 # CONFIG_INPUT_EVDEV is not set # CONFIG_INPUT_EVBUG is not set -# -# Input I/O drivers -# -# CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y -# CONFIG_SERIO is not set -# CONFIG_SERIO_I8042 is not set - # # Input Device Drivers # @@ -555,6 +551,12 @@ CONFIG_SOUND_GAMEPORT=y # CONFIG_INPUT_TOUCHSCREEN is not set # CONFIG_INPUT_MISC is not set +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + # # Character devices # @@ -570,6 +572,7 @@ CONFIG_SOUND_GAMEPORT=y # CONFIG_SERIAL_CORE=m CONFIG_SERIAL_ICOM=m +# CONFIG_SERIAL_JSM is not set CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 @@ -592,9 +595,16 @@ CONFIG_LEGACY_PTY_COUNT=256 # # Ftape, the floppy tape device driver # +# CONFIG_AGP is not set # CONFIG_DRM is not set CONFIG_RAW_DRIVER=y CONFIG_MAX_RAW_DEVS=256 +# CONFIG_HANGCHECK_TIMER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set # # I2C support @@ -633,13 +643,9 @@ CONFIG_MAX_RAW_DEVS=256 # # USB support # -# CONFIG_USB is not set CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_OHCI=y - -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information -# +# CONFIG_USB is not set # # USB Gadget Support @@ -848,10 +854,13 @@ CONFIG_OPROFILE=y # # Kernel hacking # +# CONFIG_PRINTK_TIME is not set CONFIG_DEBUG_KERNEL=y CONFIG_MAGIC_SYSRQ=y +CONFIG_LOG_BUF_SHIFT=17 # CONFIG_SCHEDSTATS is not set # CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_KOBJECT is not set # CONFIG_DEBUG_INFO is not set @@ -881,6 +890,7 @@ CONFIG_CRYPTO_SHA1=m CONFIG_CRYPTO_SHA256=m CONFIG_CRYPTO_SHA512=m CONFIG_CRYPTO_WP512=m +CONFIG_CRYPTO_TGR192=m CONFIG_CRYPTO_DES=y CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_TWOFISH=m diff --git a/arch/ppc64/configs/maple_defconfig b/arch/ppc64/configs/maple_defconfig index cf527501915..8051b0f47b6 100644 --- a/arch/ppc64/configs/maple_defconfig +++ b/arch/ppc64/configs/maple_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.11-rc3-bk6 -# Wed Feb 9 23:34:53 2005 +# Linux kernel version: 2.6.12-rc6 +# Tue Jun 14 17:12:48 2005 # CONFIG_64BIT=y CONFIG_MMU=y @@ -11,7 +11,7 @@ CONFIG_GENERIC_ISA_DMA=y CONFIG_HAVE_DEC_LOCK=y CONFIG_EARLY_PRINTK=y CONFIG_COMPAT=y -CONFIG_FRAME_POINTER=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y CONFIG_FORCE_MAX_ZONEORDER=13 # @@ -20,6 +20,7 @@ CONFIG_FORCE_MAX_ZONEORDER=13 CONFIG_EXPERIMENTAL=y CONFIG_CLEAN_COMPILE=y CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 # # General setup @@ -30,24 +31,28 @@ CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y -CONFIG_LOG_BUF_SHIFT=17 +# CONFIG_AUDIT is not set # CONFIG_HOTPLUG is not set CONFIG_KOBJECT_UEVENT=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y +# CONFIG_CPUSETS is not set # CONFIG_EMBEDDED is not set CONFIG_KALLSYMS=y CONFIG_KALLSYMS_ALL=y # CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SHMEM=y CONFIG_CC_ALIGN_FUNCTIONS=0 CONFIG_CC_ALIGN_LABELS=0 CONFIG_CC_ALIGN_LOOPS=0 CONFIG_CC_ALIGN_JUMPS=0 # CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 # # Loadable module support @@ -84,6 +89,8 @@ CONFIG_NR_CPUS=2 # CONFIG_SCHED_SMT is not set # CONFIG_PREEMPT is not set CONFIG_GENERIC_HARDIRQS=y +CONFIG_SECCOMP=y +CONFIG_ISA_DMA_API=y # # General setup @@ -94,16 +101,13 @@ CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y +# CONFIG_PCI_DEBUG is not set # # PCCARD (PCMCIA/CardBus) support # # CONFIG_PCCARD is not set -# -# PC-card bridges -# - # # PCI Hotplug Support # @@ -261,7 +265,6 @@ CONFIG_NET=y # CONFIG_PACKET=y CONFIG_PACKET_MMAP=y -# CONFIG_NETLINK_DEV is not set CONFIG_UNIX=y # CONFIG_NET_KEY is not set CONFIG_INET=y @@ -376,6 +379,8 @@ CONFIG_E1000=y # CONFIG_SK98LIN is not set # CONFIG_VIA_VELOCITY is not set # CONFIG_TIGON3 is not set +# CONFIG_BNX2 is not set +# CONFIG_MV643XX_ETH is not set # # Ethernet (10000 Mbit) @@ -431,14 +436,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=1200 # CONFIG_INPUT_EVDEV is not set # CONFIG_INPUT_EVBUG is not set -# -# Input I/O drivers -# -# CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y -# CONFIG_SERIO is not set -# CONFIG_SERIO_I8042 is not set - # # Input Device Drivers # @@ -448,6 +445,12 @@ CONFIG_SOUND_GAMEPORT=y # CONFIG_INPUT_TOUCHSCREEN is not set # CONFIG_INPUT_MISC is not set +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + # # Character devices # @@ -469,7 +472,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4 # CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y -# CONFIG_SERIAL_PMACZILOG is not set +# CONFIG_SERIAL_JSM is not set CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 @@ -492,8 +495,15 @@ CONFIG_LEGACY_PTY_COUNT=256 # # Ftape, the floppy tape device driver # +# CONFIG_AGP is not set # CONFIG_DRM is not set # CONFIG_RAW_DRIVER is not set +# CONFIG_HANGCHECK_TIMER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set # # I2C support @@ -518,8 +528,8 @@ CONFIG_I2C_ALGOBIT=y CONFIG_I2C_AMD8111=y # CONFIG_I2C_I801 is not set # CONFIG_I2C_I810 is not set +# CONFIG_I2C_PIIX4 is not set # CONFIG_I2C_ISA is not set -# CONFIG_I2C_MPC is not set # CONFIG_I2C_NFORCE2 is not set # CONFIG_I2C_PARPORT_LIGHT is not set # CONFIG_I2C_PROSAVAGE is not set @@ -545,7 +555,9 @@ CONFIG_I2C_AMD8111=y # CONFIG_SENSORS_ASB100 is not set # CONFIG_SENSORS_DS1621 is not set # CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set # CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set # CONFIG_SENSORS_IT87 is not set # CONFIG_SENSORS_LM63 is not set # CONFIG_SENSORS_LM75 is not set @@ -556,9 +568,11 @@ CONFIG_I2C_AMD8111=y # CONFIG_SENSORS_LM85 is not set # CONFIG_SENSORS_LM87 is not set # CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set # CONFIG_SENSORS_MAX1619 is not set # CONFIG_SENSORS_PC87360 is not set # CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_SIS5595 is not set # CONFIG_SENSORS_SMSC47M1 is not set # CONFIG_SENSORS_VIA686A is not set # CONFIG_SENSORS_W83781D is not set @@ -568,6 +582,7 @@ CONFIG_I2C_AMD8111=y # # Other I2C Chip support # +# CONFIG_SENSORS_DS1337 is not set # CONFIG_SENSORS_EEPROM is not set # CONFIG_SENSORS_PCF8574 is not set # CONFIG_SENSORS_PCF8591 is not set @@ -615,6 +630,8 @@ CONFIG_DUMMY_CONSOLE=y # # USB support # +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y CONFIG_USB=y # CONFIG_USB_DEBUG is not set @@ -625,8 +642,6 @@ CONFIG_USB_DEVICEFS=y # CONFIG_USB_BANDWIDTH is not set # CONFIG_USB_DYNAMIC_MINORS is not set # CONFIG_USB_OTG is not set -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y # # USB Host Controller Drivers @@ -635,6 +650,8 @@ CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_SPLIT_ISO=y CONFIG_USB_EHCI_ROOT_HUB_TT=y CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_BIG_ENDIAN is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y CONFIG_USB_UHCI_HCD=y # CONFIG_USB_SL811_HCD is not set @@ -688,6 +705,7 @@ CONFIG_USB_HIDINPUT=y CONFIG_USB_PEGASUS=y # CONFIG_USB_RTL8150 is not set # CONFIG_USB_USBNET is not set +CONFIG_USB_MON=y # # USB port drivers @@ -699,8 +717,10 @@ CONFIG_USB_PEGASUS=y CONFIG_USB_SERIAL=y # CONFIG_USB_SERIAL_CONSOLE is not set CONFIG_USB_SERIAL_GENERIC=y +# CONFIG_USB_SERIAL_AIRPRIME is not set # CONFIG_USB_SERIAL_BELKIN is not set # CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +# CONFIG_USB_SERIAL_CP2101 is not set CONFIG_USB_SERIAL_CYPRESS_M8=m # CONFIG_USB_SERIAL_EMPEG is not set # CONFIG_USB_SERIAL_FTDI_SIO is not set @@ -729,6 +749,7 @@ CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y # CONFIG_USB_SERIAL_KOBIL_SCT is not set # CONFIG_USB_SERIAL_MCT_U232 is not set # CONFIG_USB_SERIAL_PL2303 is not set +# CONFIG_USB_SERIAL_HP4X is not set # CONFIG_USB_SERIAL_SAFE is not set CONFIG_USB_SERIAL_TI=m # CONFIG_USB_SERIAL_CYBERJACK is not set @@ -750,6 +771,7 @@ CONFIG_USB_EZUSB=y # CONFIG_USB_PHIDGETKIT is not set # CONFIG_USB_PHIDGETSERVO is not set # CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_SISUSBVGA is not set # CONFIG_USB_TEST is not set # @@ -936,10 +958,13 @@ CONFIG_NLS_UTF8=y # # Kernel hacking # +# CONFIG_PRINTK_TIME is not set CONFIG_DEBUG_KERNEL=y CONFIG_MAGIC_SYSRQ=y +CONFIG_LOG_BUF_SHIFT=17 # CONFIG_SCHEDSTATS is not set CONFIG_DEBUG_SLAB=y +# CONFIG_DEBUG_SPINLOCK is not set CONFIG_DEBUG_SPINLOCK_SLEEP=y # CONFIG_DEBUG_KOBJECT is not set # CONFIG_DEBUG_INFO is not set @@ -971,6 +996,7 @@ CONFIG_CRYPTO_MD5=y # CONFIG_CRYPTO_SHA256 is not set # CONFIG_CRYPTO_SHA512 is not set # CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_TGR192 is not set CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_BLOWFISH is not set # CONFIG_CRYPTO_TWOFISH is not set diff --git a/arch/ppc64/configs/pSeries_defconfig b/arch/ppc64/configs/pSeries_defconfig index 4fecf237d5c..3eb5ef25d3a 100644 --- a/arch/ppc64/configs/pSeries_defconfig +++ b/arch/ppc64/configs/pSeries_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.11-rc3-bk6 -# Wed Feb 9 23:34:54 2005 +# Linux kernel version: 2.6.12-rc6 +# Tue Jun 14 17:13:47 2005 # CONFIG_64BIT=y CONFIG_MMU=y @@ -11,7 +11,7 @@ CONFIG_GENERIC_ISA_DMA=y CONFIG_HAVE_DEC_LOCK=y CONFIG_EARLY_PRINTK=y CONFIG_COMPAT=y -CONFIG_FRAME_POINTER=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y CONFIG_FORCE_MAX_ZONEORDER=13 # @@ -20,6 +20,7 @@ CONFIG_FORCE_MAX_ZONEORDER=13 CONFIG_EXPERIMENTAL=y CONFIG_CLEAN_COMPILE=y CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 # # General setup @@ -30,24 +31,29 @@ CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y -CONFIG_LOG_BUF_SHIFT=17 +CONFIG_AUDIT=y +CONFIG_AUDITSYSCALL=y CONFIG_HOTPLUG=y CONFIG_KOBJECT_UEVENT=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y +CONFIG_CPUSETS=y # CONFIG_EMBEDDED is not set CONFIG_KALLSYMS=y CONFIG_KALLSYMS_ALL=y # CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SHMEM=y CONFIG_CC_ALIGN_FUNCTIONS=0 CONFIG_CC_ALIGN_LABELS=0 CONFIG_CC_ALIGN_LOOPS=0 CONFIG_CC_ALIGN_JUMPS=0 # CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 # # Loadable module support @@ -89,9 +95,12 @@ CONFIG_SCHED_SMT=y CONFIG_EEH=y CONFIG_GENERIC_HARDIRQS=y CONFIG_PPC_RTAS=y +CONFIG_RTAS_PROC=y CONFIG_RTAS_FLASH=m CONFIG_SCANLOG=m CONFIG_LPARCFG=y +CONFIG_SECCOMP=y +CONFIG_ISA_DMA_API=y # # General setup @@ -102,6 +111,7 @@ CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y +# CONFIG_PCI_DEBUG is not set CONFIG_HOTPLUG_CPU=y # @@ -109,10 +119,6 @@ CONFIG_HOTPLUG_CPU=y # # CONFIG_PCCARD is not set -# -# PC-card bridges -# - # # PCI Hotplug Support # @@ -147,11 +153,10 @@ CONFIG_FW_LOADER=y # CONFIG_PARPORT=m CONFIG_PARPORT_PC=m -CONFIG_PARPORT_PC_CML1=m # CONFIG_PARPORT_SERIAL is not set # CONFIG_PARPORT_PC_FIFO is not set # CONFIG_PARPORT_PC_SUPERIO is not set -# CONFIG_PARPORT_OTHER is not set +# CONFIG_PARPORT_GSC is not set # CONFIG_PARPORT_1284 is not set # @@ -293,7 +298,6 @@ CONFIG_SCSI_ISCSI_ATTRS=m # CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_EATA is not set -# CONFIG_SCSI_EATA_PIO is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set # CONFIG_SCSI_GDTH is not set # CONFIG_SCSI_IPS is not set @@ -310,7 +314,6 @@ CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 CONFIG_SCSI_IPR=y CONFIG_SCSI_IPR_TRACE=y CONFIG_SCSI_IPR_DUMP=y -# CONFIG_SCSI_QLOGIC_ISP is not set # CONFIG_SCSI_QLOGIC_FC is not set # CONFIG_SCSI_QLOGIC_1280 is not set CONFIG_SCSI_QLA2XXX=y @@ -319,6 +322,7 @@ CONFIG_SCSI_QLA22XX=m CONFIG_SCSI_QLA2300=m CONFIG_SCSI_QLA2322=m CONFIG_SCSI_QLA6312=m +CONFIG_SCSI_LPFC=m # CONFIG_SCSI_DC395x is not set # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_DEBUG is not set @@ -341,6 +345,8 @@ CONFIG_DM_CRYPT=m CONFIG_DM_SNAPSHOT=m CONFIG_DM_MIRROR=m CONFIG_DM_ZERO=m +CONFIG_DM_MULTIPATH=m +CONFIG_DM_MULTIPATH_EMC=m # # Fusion MPT device support @@ -371,7 +377,6 @@ CONFIG_NET=y # CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set -# CONFIG_NETLINK_DEV is not set CONFIG_UNIX=y CONFIG_NET_KEY=m CONFIG_INET=y @@ -539,7 +544,6 @@ CONFIG_PCNET32=y # CONFIG_DGRS is not set # CONFIG_EEPRO100 is not set CONFIG_E100=y -# CONFIG_E100_NAPI is not set # CONFIG_FEALNX is not set # CONFIG_NATSEMI is not set # CONFIG_NE2K_PCI is not set @@ -565,6 +569,8 @@ CONFIG_E1000=y # CONFIG_SK98LIN is not set # CONFIG_VIA_VELOCITY is not set CONFIG_TIGON3=y +# CONFIG_BNX2 is not set +# CONFIG_MV643XX_ETH is not set # # Ethernet (10000 Mbit) @@ -635,20 +641,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 # CONFIG_INPUT_EVDEV is not set # CONFIG_INPUT_EVBUG is not set -# -# Input I/O drivers -# -# CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y -CONFIG_SERIO=y -CONFIG_SERIO_I8042=y -# CONFIG_SERIO_SERPORT is not set -# CONFIG_SERIO_CT82C710 is not set -# CONFIG_SERIO_PARKBD is not set -# CONFIG_SERIO_PCIPS2 is not set -CONFIG_SERIO_LIBPS2=y -# CONFIG_SERIO_RAW is not set - # # Input Device Drivers # @@ -668,6 +660,18 @@ CONFIG_INPUT_MISC=y CONFIG_INPUT_PCSPKR=m # CONFIG_INPUT_UINPUT is not set +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_I8042=y +# CONFIG_SERIO_SERPORT is not set +# CONFIG_SERIO_PARKBD is not set +# CONFIG_SERIO_PCIPS2 is not set +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + # # Character devices # @@ -689,8 +693,8 @@ CONFIG_SERIAL_8250_NR_UARTS=4 # CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y -# CONFIG_SERIAL_PMACZILOG is not set CONFIG_SERIAL_ICOM=m +# CONFIG_SERIAL_JSM is not set CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 @@ -718,9 +722,16 @@ CONFIG_HVCS=m # # Ftape, the floppy tape device driver # +# CONFIG_AGP is not set # CONFIG_DRM is not set CONFIG_RAW_DRIVER=y CONFIG_MAX_RAW_DEVS=1024 +# CONFIG_HANGCHECK_TIMER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set # # I2C support @@ -745,8 +756,8 @@ CONFIG_I2C_ALGOBIT=y # CONFIG_I2C_AMD8111 is not set # CONFIG_I2C_I801 is not set # CONFIG_I2C_I810 is not set +# CONFIG_I2C_PIIX4 is not set # CONFIG_I2C_ISA is not set -# CONFIG_I2C_MPC is not set # CONFIG_I2C_NFORCE2 is not set # CONFIG_I2C_PARPORT is not set # CONFIG_I2C_PARPORT_LIGHT is not set @@ -773,7 +784,9 @@ CONFIG_I2C_ALGOBIT=y # CONFIG_SENSORS_ASB100 is not set # CONFIG_SENSORS_DS1621 is not set # CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set # CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set # CONFIG_SENSORS_IT87 is not set # CONFIG_SENSORS_LM63 is not set # CONFIG_SENSORS_LM75 is not set @@ -784,9 +797,11 @@ CONFIG_I2C_ALGOBIT=y # CONFIG_SENSORS_LM85 is not set # CONFIG_SENSORS_LM87 is not set # CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set # CONFIG_SENSORS_MAX1619 is not set # CONFIG_SENSORS_PC87360 is not set # CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_SIS5595 is not set # CONFIG_SENSORS_SMSC47M1 is not set # CONFIG_SENSORS_VIA686A is not set # CONFIG_SENSORS_W83781D is not set @@ -796,6 +811,7 @@ CONFIG_I2C_ALGOBIT=y # # Other I2C Chip support # +# CONFIG_SENSORS_DS1337 is not set # CONFIG_SENSORS_EEPROM is not set # CONFIG_SENSORS_PCF8574 is not set # CONFIG_SENSORS_PCF8591 is not set @@ -828,8 +844,13 @@ CONFIG_I2C_ALGOBIT=y # Graphics support # CONFIG_FB=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +CONFIG_FB_SOFT_CURSOR=y +CONFIG_FB_MACMODES=y CONFIG_FB_MODE_HELPERS=y -# CONFIG_FB_TILEBLITTING is not set +CONFIG_FB_TILEBLITTING=y # CONFIG_FB_CIRRUS is not set # CONFIG_FB_PM2 is not set # CONFIG_FB_CYBER2000 is not set @@ -838,6 +859,7 @@ CONFIG_FB_OF=y # CONFIG_FB_ASILIANT is not set # CONFIG_FB_IMSTT is not set # CONFIG_FB_VGA16 is not set +# CONFIG_FB_NVIDIA is not set # CONFIG_FB_RIVA is not set CONFIG_FB_MATROX=y CONFIG_FB_MATROX_MILLENIUM=y @@ -858,6 +880,7 @@ CONFIG_FB_RADEON_I2C=y # CONFIG_FB_3DFX is not set # CONFIG_FB_VOODOO1 is not set # CONFIG_FB_TRIDENT is not set +# CONFIG_FB_S1D13XXX is not set # CONFIG_FB_VIRTUAL is not set # @@ -891,6 +914,8 @@ CONFIG_LCD_DEVICE=y # # USB support # +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y CONFIG_USB=y # CONFIG_USB_DEBUG is not set @@ -901,8 +926,6 @@ CONFIG_USB_DEVICEFS=y # CONFIG_USB_BANDWIDTH is not set # CONFIG_USB_DYNAMIC_MINORS is not set # CONFIG_USB_OTG is not set -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y # # USB Host Controller Drivers @@ -911,6 +934,8 @@ CONFIG_USB_EHCI_HCD=y # CONFIG_USB_EHCI_SPLIT_ISO is not set # CONFIG_USB_EHCI_ROOT_HUB_TT is not set CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_BIG_ENDIAN is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y # CONFIG_USB_UHCI_HCD is not set # CONFIG_USB_SL811_HCD is not set @@ -926,12 +951,11 @@ CONFIG_USB_OHCI_HCD=y # CONFIG_USB_STORAGE=y # CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_RW_DETECT is not set # CONFIG_USB_STORAGE_DATAFAB is not set # CONFIG_USB_STORAGE_FREECOM is not set # CONFIG_USB_STORAGE_ISD200 is not set # CONFIG_USB_STORAGE_DPCM is not set -# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_USBAT is not set # CONFIG_USB_STORAGE_SDDR09 is not set # CONFIG_USB_STORAGE_SDDR55 is not set # CONFIG_USB_STORAGE_JUMPSHOT is not set @@ -975,6 +999,7 @@ CONFIG_USB_HIDDEV=y # CONFIG_USB_PEGASUS is not set # CONFIG_USB_RTL8150 is not set # CONFIG_USB_USBNET is not set +CONFIG_USB_MON=y # # USB port drivers @@ -1000,6 +1025,7 @@ CONFIG_USB_HIDDEV=y # CONFIG_USB_PHIDGETKIT is not set # CONFIG_USB_PHIDGETSERVO is not set # CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_SISUSBVGA is not set # CONFIG_USB_TEST is not set # @@ -1208,10 +1234,13 @@ CONFIG_OPROFILE=y # # Kernel hacking # +# CONFIG_PRINTK_TIME is not set CONFIG_DEBUG_KERNEL=y CONFIG_MAGIC_SYSRQ=y +CONFIG_LOG_BUF_SHIFT=17 # CONFIG_SCHEDSTATS is not set # CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_KOBJECT is not set # CONFIG_DEBUG_INFO is not set @@ -1243,6 +1272,7 @@ CONFIG_CRYPTO_SHA1=m CONFIG_CRYPTO_SHA256=m CONFIG_CRYPTO_SHA512=m CONFIG_CRYPTO_WP512=m +CONFIG_CRYPTO_TGR192=m CONFIG_CRYPTO_DES=y CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_TWOFISH=m -- cgit v1.2.3-70-g09d2 From 1016888fb69662936b32ab767c7419a3be9a69d3 Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Tue, 14 Jun 2005 13:52:19 -0700 Subject: [PATCH] update ppc64 defconfig enable cpusets enable new lpfc and jsm drivers enable new dm-multipath leave new agp disabled disable rivafb, it does not handle the cards in G5 models (FX5200 as example) the new nvidiafb doesnt work on bigendian, yet Signed-off-by: Olaf Hering Acked-by: Paul Mackerras Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc64/defconfig | 104 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 67 insertions(+), 37 deletions(-) diff --git a/arch/ppc64/defconfig b/arch/ppc64/defconfig index 537b1cc82ea..2f31bf3046f 100644 --- a/arch/ppc64/defconfig +++ b/arch/ppc64/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.11-rc3-bk6 -# Wed Feb 9 23:34:51 2005 +# Linux kernel version: 2.6.12-rc5-git9 +# Sun Jun 5 09:26:47 2005 # CONFIG_64BIT=y CONFIG_MMU=y @@ -11,7 +11,7 @@ CONFIG_GENERIC_ISA_DMA=y CONFIG_HAVE_DEC_LOCK=y CONFIG_EARLY_PRINTK=y CONFIG_COMPAT=y -CONFIG_FRAME_POINTER=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y CONFIG_FORCE_MAX_ZONEORDER=13 # @@ -20,6 +20,7 @@ CONFIG_FORCE_MAX_ZONEORDER=13 CONFIG_EXPERIMENTAL=y CONFIG_CLEAN_COMPILE=y CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 # # General setup @@ -30,24 +31,28 @@ CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y -CONFIG_LOG_BUF_SHIFT=17 +# CONFIG_AUDIT is not set CONFIG_HOTPLUG=y CONFIG_KOBJECT_UEVENT=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y +CONFIG_CPUSETS=y # CONFIG_EMBEDDED is not set CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SHMEM=y CONFIG_CC_ALIGN_FUNCTIONS=0 CONFIG_CC_ALIGN_LABELS=0 CONFIG_CC_ALIGN_LOOPS=0 CONFIG_CC_ALIGN_JUMPS=0 # CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 # # Loadable module support @@ -91,9 +96,12 @@ CONFIG_DISCONTIGMEM=y CONFIG_EEH=y CONFIG_GENERIC_HARDIRQS=y CONFIG_PPC_RTAS=y +CONFIG_RTAS_PROC=y CONFIG_RTAS_FLASH=m CONFIG_SCANLOG=m CONFIG_LPARCFG=y +CONFIG_SECCOMP=y +CONFIG_ISA_DMA_API=y # # General setup @@ -104,6 +112,7 @@ CONFIG_BINFMT_ELF=y CONFIG_BINFMT_MISC=m # CONFIG_PCI_LEGACY_PROC is not set # CONFIG_PCI_NAMES is not set +# CONFIG_PCI_DEBUG is not set CONFIG_HOTPLUG_CPU=y # @@ -111,10 +120,6 @@ CONFIG_HOTPLUG_CPU=y # # CONFIG_PCCARD is not set -# -# PC-card bridges -# - # # PCI Hotplug Support # @@ -149,11 +154,10 @@ CONFIG_FW_LOADER=y # CONFIG_PARPORT=m CONFIG_PARPORT_PC=m -CONFIG_PARPORT_PC_CML1=m # CONFIG_PARPORT_SERIAL is not set # CONFIG_PARPORT_PC_FIFO is not set # CONFIG_PARPORT_PC_SUPERIO is not set -# CONFIG_PARPORT_OTHER is not set +# CONFIG_PARPORT_GSC is not set # CONFIG_PARPORT_1284 is not set # @@ -301,6 +305,7 @@ CONFIG_SCSI_SATA_SVW=y # CONFIG_SCSI_ATA_PIIX is not set # CONFIG_SCSI_SATA_NV is not set # CONFIG_SCSI_SATA_PROMISE is not set +# CONFIG_SCSI_SATA_QSTOR is not set # CONFIG_SCSI_SATA_SX4 is not set # CONFIG_SCSI_SATA_SIL is not set # CONFIG_SCSI_SATA_SIS is not set @@ -310,7 +315,6 @@ CONFIG_SCSI_SATA_SVW=y # CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_EATA is not set -# CONFIG_SCSI_EATA_PIO is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set # CONFIG_SCSI_GDTH is not set # CONFIG_SCSI_IPS is not set @@ -327,7 +331,6 @@ CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 CONFIG_SCSI_IPR=y CONFIG_SCSI_IPR_TRACE=y CONFIG_SCSI_IPR_DUMP=y -# CONFIG_SCSI_QLOGIC_ISP is not set # CONFIG_SCSI_QLOGIC_FC is not set # CONFIG_SCSI_QLOGIC_1280 is not set CONFIG_SCSI_QLA2XXX=y @@ -336,6 +339,7 @@ CONFIG_SCSI_QLA22XX=m CONFIG_SCSI_QLA2300=m CONFIG_SCSI_QLA2322=m CONFIG_SCSI_QLA6312=m +CONFIG_SCSI_LPFC=m # CONFIG_SCSI_DC395x is not set # CONFIG_SCSI_DC390T is not set CONFIG_SCSI_DEBUG=m @@ -358,6 +362,8 @@ CONFIG_DM_CRYPT=m CONFIG_DM_SNAPSHOT=m CONFIG_DM_MIRROR=m CONFIG_DM_ZERO=m +CONFIG_DM_MULTIPATH=m +CONFIG_DM_MULTIPATH_EMC=m # # Fusion MPT device support @@ -405,6 +411,7 @@ CONFIG_IEEE1394_AMDTP=m # CONFIG_ADB=y CONFIG_ADB_PMU=y +CONFIG_PMAC_SMU=y # CONFIG_PMAC_PBOOK is not set # CONFIG_PMAC_BACKLIGHT is not set # CONFIG_INPUT_ADBHID is not set @@ -420,7 +427,6 @@ CONFIG_NET=y # CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set -# CONFIG_NETLINK_DEV is not set CONFIG_UNIX=y CONFIG_NET_KEY=m CONFIG_INET=y @@ -588,7 +594,6 @@ CONFIG_PCNET32=y # CONFIG_DGRS is not set # CONFIG_EEPRO100 is not set CONFIG_E100=y -# CONFIG_E100_NAPI is not set # CONFIG_FEALNX is not set # CONFIG_NATSEMI is not set # CONFIG_NE2K_PCI is not set @@ -614,6 +619,8 @@ CONFIG_E1000=y # CONFIG_SK98LIN is not set # CONFIG_VIA_VELOCITY is not set CONFIG_TIGON3=y +# CONFIG_BNX2 is not set +# CONFIG_MV643XX_ETH is not set # # Ethernet (10000 Mbit) @@ -682,20 +689,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 CONFIG_INPUT_EVDEV=m # CONFIG_INPUT_EVBUG is not set -# -# Input I/O drivers -# -# CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y -CONFIG_SERIO=y -CONFIG_SERIO_I8042=y -# CONFIG_SERIO_SERPORT is not set -# CONFIG_SERIO_CT82C710 is not set -# CONFIG_SERIO_PARKBD is not set -# CONFIG_SERIO_PCIPS2 is not set -CONFIG_SERIO_LIBPS2=y -# CONFIG_SERIO_RAW is not set - # # Input Device Drivers # @@ -715,6 +708,18 @@ CONFIG_INPUT_MISC=y CONFIG_INPUT_PCSPKR=m # CONFIG_INPUT_UINPUT is not set +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_I8042=y +# CONFIG_SERIO_SERPORT is not set +# CONFIG_SERIO_PARKBD is not set +# CONFIG_SERIO_PCIPS2 is not set +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + # # Character devices # @@ -738,6 +743,7 @@ CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_PMACZILOG is not set CONFIG_SERIAL_ICOM=m +CONFIG_SERIAL_JSM=m CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 @@ -766,9 +772,16 @@ CONFIG_HVCS=m # # Ftape, the floppy tape device driver # +# CONFIG_AGP is not set # CONFIG_DRM is not set CONFIG_RAW_DRIVER=y CONFIG_MAX_RAW_DEVS=256 +# CONFIG_HANGCHECK_TIMER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set # # I2C support @@ -793,9 +806,9 @@ CONFIG_I2C_ALGOBIT=y CONFIG_I2C_AMD8111=y # CONFIG_I2C_I801 is not set # CONFIG_I2C_I810 is not set +# CONFIG_I2C_PIIX4 is not set # CONFIG_I2C_ISA is not set CONFIG_I2C_KEYWEST=y -# CONFIG_I2C_MPC is not set # CONFIG_I2C_NFORCE2 is not set # CONFIG_I2C_PARPORT is not set # CONFIG_I2C_PARPORT_LIGHT is not set @@ -822,7 +835,9 @@ CONFIG_I2C_KEYWEST=y # CONFIG_SENSORS_ASB100 is not set # CONFIG_SENSORS_DS1621 is not set # CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set # CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set # CONFIG_SENSORS_IT87 is not set # CONFIG_SENSORS_LM63 is not set # CONFIG_SENSORS_LM75 is not set @@ -833,9 +848,11 @@ CONFIG_I2C_KEYWEST=y # CONFIG_SENSORS_LM85 is not set # CONFIG_SENSORS_LM87 is not set # CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set # CONFIG_SENSORS_MAX1619 is not set # CONFIG_SENSORS_PC87360 is not set # CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_SIS5595 is not set # CONFIG_SENSORS_SMSC47M1 is not set # CONFIG_SENSORS_VIA686A is not set # CONFIG_SENSORS_W83781D is not set @@ -845,6 +862,7 @@ CONFIG_I2C_KEYWEST=y # # Other I2C Chip support # +# CONFIG_SENSORS_DS1337 is not set # CONFIG_SENSORS_EEPROM is not set # CONFIG_SENSORS_PCF8574 is not set # CONFIG_SENSORS_PCF8591 is not set @@ -877,6 +895,11 @@ CONFIG_I2C_KEYWEST=y # Graphics support # CONFIG_FB=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +CONFIG_FB_SOFT_CURSOR=y +CONFIG_FB_MACMODES=y CONFIG_FB_MODE_HELPERS=y CONFIG_FB_TILEBLITTING=y # CONFIG_FB_CIRRUS is not set @@ -890,9 +913,8 @@ CONFIG_FB_OF=y # CONFIG_FB_ASILIANT is not set # CONFIG_FB_IMSTT is not set # CONFIG_FB_VGA16 is not set -CONFIG_FB_RIVA=y -CONFIG_FB_RIVA_I2C=y -# CONFIG_FB_RIVA_DEBUG is not set +# CONFIG_FB_NVIDIA is not set +# CONFIG_FB_RIVA is not set CONFIG_FB_MATROX=y CONFIG_FB_MATROX_MILLENIUM=y CONFIG_FB_MATROX_MYSTIQUE=y @@ -913,6 +935,7 @@ CONFIG_FB_RADEON_I2C=y # CONFIG_FB_3DFX is not set # CONFIG_FB_VOODOO1 is not set # CONFIG_FB_TRIDENT is not set +# CONFIG_FB_S1D13XXX is not set # CONFIG_FB_VIRTUAL is not set # @@ -946,6 +969,8 @@ CONFIG_LCD_DEVICE=y # # USB support # +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y CONFIG_USB=y # CONFIG_USB_DEBUG is not set @@ -956,8 +981,6 @@ CONFIG_USB_DEVICEFS=y # CONFIG_USB_BANDWIDTH is not set # CONFIG_USB_DYNAMIC_MINORS is not set # CONFIG_USB_OTG is not set -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y # # USB Host Controller Drivers @@ -966,6 +989,8 @@ CONFIG_USB_EHCI_HCD=y # CONFIG_USB_EHCI_SPLIT_ISO is not set # CONFIG_USB_EHCI_ROOT_HUB_TT is not set CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_BIG_ENDIAN is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y # CONFIG_USB_UHCI_HCD is not set # CONFIG_USB_SL811_HCD is not set @@ -981,12 +1006,11 @@ CONFIG_USB_OHCI_HCD=y # CONFIG_USB_STORAGE=m # CONFIG_USB_STORAGE_DEBUG is not set -CONFIG_USB_STORAGE_RW_DETECT=y # CONFIG_USB_STORAGE_DATAFAB is not set # CONFIG_USB_STORAGE_FREECOM is not set # CONFIG_USB_STORAGE_ISD200 is not set # CONFIG_USB_STORAGE_DPCM is not set -# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_USBAT is not set # CONFIG_USB_STORAGE_SDDR09 is not set # CONFIG_USB_STORAGE_SDDR55 is not set # CONFIG_USB_STORAGE_JUMPSHOT is not set @@ -1030,6 +1054,7 @@ CONFIG_USB_HIDDEV=y CONFIG_USB_PEGASUS=y # CONFIG_USB_RTL8150 is not set # CONFIG_USB_USBNET is not set +# CONFIG_USB_MON is not set # # USB port drivers @@ -1055,6 +1080,7 @@ CONFIG_USB_PEGASUS=y # CONFIG_USB_PHIDGETKIT is not set # CONFIG_USB_PHIDGETSERVO is not set # CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_SISUSBVGA is not set # CONFIG_USB_TEST is not set # @@ -1276,10 +1302,13 @@ CONFIG_OPROFILE=y # # Kernel hacking # +# CONFIG_PRINTK_TIME is not set CONFIG_DEBUG_KERNEL=y CONFIG_MAGIC_SYSRQ=y +CONFIG_LOG_BUF_SHIFT=17 # CONFIG_SCHEDSTATS is not set # CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_KOBJECT is not set # CONFIG_DEBUG_INFO is not set @@ -1311,6 +1340,7 @@ CONFIG_CRYPTO_SHA1=m CONFIG_CRYPTO_SHA256=m CONFIG_CRYPTO_SHA512=m CONFIG_CRYPTO_WP512=m +CONFIG_CRYPTO_TGR192=m CONFIG_CRYPTO_DES=y CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_TWOFISH=m -- cgit v1.2.3-70-g09d2 From bcfff0b471a60df350338bcd727fc9b8a6aa54b2 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 15 Jun 2005 20:51:14 -0700 Subject: [NETFILTER]: ipt_recent: last_pkts is an array of "unsigned long" not "u_int32_t" This fixes various crashes on 64-bit when using this module. Based upon a patch by Juergen Kreileder . Signed-off-by: David S. Miller ACKed-by: Patrick McHardy --- net/ipv4/netfilter/ipt_recent.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/net/ipv4/netfilter/ipt_recent.c b/net/ipv4/netfilter/ipt_recent.c index 25ab9fabdcb..2d44b07688a 100644 --- a/net/ipv4/netfilter/ipt_recent.c +++ b/net/ipv4/netfilter/ipt_recent.c @@ -223,7 +223,7 @@ static int ip_recent_ctrl(struct file *file, const char __user *input, unsigned curr_table->table[count].last_seen = 0; curr_table->table[count].addr = 0; curr_table->table[count].ttl = 0; - memset(curr_table->table[count].last_pkts,0,ip_pkt_list_tot*sizeof(u_int32_t)); + memset(curr_table->table[count].last_pkts,0,ip_pkt_list_tot*sizeof(unsigned long)); curr_table->table[count].oldest_pkt = 0; curr_table->table[count].time_pos = 0; curr_table->time_info[count].position = count; @@ -502,7 +502,7 @@ match(const struct sk_buff *skb, location = time_info[curr_table->time_pos].position; hash_table[r_list[location].hash_entry] = -1; hash_table[hash_result] = location; - memset(r_list[location].last_pkts,0,ip_pkt_list_tot*sizeof(u_int32_t)); + memset(r_list[location].last_pkts,0,ip_pkt_list_tot*sizeof(unsigned long)); r_list[location].time_pos = curr_table->time_pos; r_list[location].addr = addr; r_list[location].ttl = ttl; @@ -631,7 +631,7 @@ match(const struct sk_buff *skb, r_list[location].last_seen = 0; r_list[location].addr = 0; r_list[location].ttl = 0; - memset(r_list[location].last_pkts,0,ip_pkt_list_tot*sizeof(u_int32_t)); + memset(r_list[location].last_pkts,0,ip_pkt_list_tot*sizeof(unsigned long)); r_list[location].oldest_pkt = 0; ans = !info->invert; } @@ -734,10 +734,10 @@ checkentry(const char *tablename, memset(curr_table->table,0,sizeof(struct recent_ip_list)*ip_list_tot); #ifdef DEBUG if(debug) printk(KERN_INFO RECENT_NAME ": checkentry: Allocating %d for pkt_list.\n", - sizeof(u_int32_t)*ip_pkt_list_tot*ip_list_tot); + sizeof(unsigned long)*ip_pkt_list_tot*ip_list_tot); #endif - hold = vmalloc(sizeof(u_int32_t)*ip_pkt_list_tot*ip_list_tot); + hold = vmalloc(sizeof(unsigned long)*ip_pkt_list_tot*ip_list_tot); #ifdef DEBUG if(debug) printk(KERN_INFO RECENT_NAME ": checkentry: After pkt_list allocation.\n"); #endif -- cgit v1.2.3-70-g09d2 From 9c56187d3c345cc0e7a2f162b8c32543175d7bf7 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 16 Jun 2005 12:56:15 +0200 Subject: This patch kills elevator_global_init() in elevator.c which does nothing. Signed-off-by: Jens Axboe Signed-off-by: Tejun Heo --- drivers/block/elevator.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/block/elevator.c b/drivers/block/elevator.c index 6b79b431462..98fcabbafe1 100644 --- a/drivers/block/elevator.c +++ b/drivers/block/elevator.c @@ -220,11 +220,6 @@ void elevator_exit(elevator_t *e) kfree(e); } -static int elevator_global_init(void) -{ - return 0; -} - int elv_merge(request_queue_t *q, struct request **req, struct bio *bio) { elevator_t *e = q->elevator; @@ -692,8 +687,6 @@ ssize_t elv_iosched_show(request_queue_t *q, char *name) return len; } -module_init(elevator_global_init); - EXPORT_SYMBOL(elv_add_request); EXPORT_SYMBOL(__elv_add_request); EXPORT_SYMBOL(elv_requeue_request); -- cgit v1.2.3-70-g09d2 From c374f127e4ff17a318b9ae95a5bf65f370c2d0b1 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 16 Jun 2005 12:57:31 +0200 Subject: This patch fixes q->unplug_thresh condition check in __elv_add_request(). rq.count[READ] + rq.count[WRITE] can increase more than one if another thread has allocated a request after the current request is allocated or in_flight could have changed resulting in larger-than-one change of nrq, thus breaking the threshold mechanism. Signed-off-by: Jens Axboe Signed-off-by: Tejun Heo --- drivers/block/elevator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/block/elevator.c b/drivers/block/elevator.c index 98fcabbafe1..89982925f9e 100644 --- a/drivers/block/elevator.c +++ b/drivers/block/elevator.c @@ -317,7 +317,7 @@ void __elv_add_request(request_queue_t *q, struct request *rq, int where, int nrq = q->rq.count[READ] + q->rq.count[WRITE] - q->in_flight; - if (nrq == q->unplug_thresh) + if (nrq >= q->unplug_thresh) __generic_unplug_device(q); } } else -- cgit v1.2.3-70-g09d2 From a2ef79e1840ebbd0b5907e53c755efd5662112a1 Mon Sep 17 00:00:00 2001 From: Alexandre Oliva Date: Wed, 15 Jun 2005 22:26:31 -0700 Subject: [PATCH] sbp2 slab corruption fix This fixed a problem that showed up in the Fedora development tree a few weeks before the Fedora Core 4 release, initially as slab corruption, later as hard crashes on boot up, when slab debugging was disabled for the release. More details on the history at https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=158424 The problem is caused by sbp2's use of scsi_host->hostdata[0] to hold a scsi_id, without explicitly requesting space for it. Since hostdata is declared as a zero-sized array, we don't get any such space by default, so it must be explicitly requested. The patch below implements just that. Signed-off-by: Alexandre Oliva Cc: Jody McIntyre Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/ieee1394/sbp2.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c index 00c7b958361..ab82d6addd7 100644 --- a/drivers/ieee1394/sbp2.c +++ b/drivers/ieee1394/sbp2.c @@ -745,7 +745,8 @@ static struct scsi_id_instance_data *sbp2_alloc_device(struct unit_directory *ud list_add_tail(&scsi_id->scsi_list, &hi->scsi_ids); /* Register our host with the SCSI stack. */ - scsi_host = scsi_host_alloc(&scsi_driver_template, 0); + scsi_host = scsi_host_alloc(&scsi_driver_template, + sizeof (unsigned long)); if (!scsi_host) { SBP2_ERR("failed to register scsi host"); goto failed_alloc; -- cgit v1.2.3-70-g09d2 From 5db92850d3ab72b830a0fe6e30eaec8462801408 Mon Sep 17 00:00:00 2001 From: Daniel Jacobowitz Date: Wed, 15 Jun 2005 22:26:34 -0700 Subject: [PATCH] Fix large core dumps with a 32-bit off_t The ELF core dump code has one use of off_t when writing out segments. Some of the segments may be passed the 2GB limit of an off_t, even on a 32-bit system, so it's important to use loff_t instead. This fixes a corrupted core dump in the bigcore test in GDB's testsuite. Signed-off-by: Daniel Jacobowitz Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/binfmt_elf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index c374be51b04..f8f6b6b7617 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -1125,7 +1125,7 @@ static int dump_write(struct file *file, const void *addr, int nr) return file->f_op->write(file, addr, nr, &file->f_pos) == nr; } -static int dump_seek(struct file *file, off_t off) +static int dump_seek(struct file *file, loff_t off) { if (file->f_op->llseek) { if (file->f_op->llseek(file, off, 0) != off) -- cgit v1.2.3-70-g09d2 From e41fb09b2fa15db095d3ee981299f488d7b48dfe Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 15 Jun 2005 22:26:36 -0700 Subject: [PATCH] ALPS: fix enabling hardware tapping It looks like logic for enabling hardware tapping in ALPS driver was inverted and we enable it only if it was already enabled by BIOS or firmware. I have a confirmation from one user that the patch below fixes the problem for him and it might be beneficial if we could get it into 2.6.12. Signed-off-by: Dmitry Torokhov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/input/mouse/alps.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index 42a9f7f6f8c..7bf4be733e9 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c @@ -352,7 +352,7 @@ static int alps_reconnect(struct psmouse *psmouse) if (alps_get_status(psmouse, param)) return -1; - if (param[0] & 0x04) + if (!(param[0] & 0x04)) alps_tap_mode(psmouse, 1); if (alps_absolute_mode(psmouse)) { -- cgit v1.2.3-70-g09d2 From 58125f95c62a44f12bb71c58ef70f0068d20c7a2 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Wed, 15 Jun 2005 22:26:38 -0700 Subject: [PATCH] fix for kaweth broken by changes in the networking layer Cc: Greg KH Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/usb/net/kaweth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/net/kaweth.c b/drivers/usb/net/kaweth.c index a9a7cf4a38e..fd6ff4cb2c6 100644 --- a/drivers/usb/net/kaweth.c +++ b/drivers/usb/net/kaweth.c @@ -520,7 +520,7 @@ static void int_callback(struct urb *u, struct pt_regs *regs) /* we check the link state to report changes */ if (kaweth->linkstate != (act_state = ( kaweth->intbuffer[STATE_OFFSET] | STATE_MASK) >> STATE_SHIFT)) { - if (!act_state) + if (act_state) netif_carrier_on(kaweth->net); else netif_carrier_off(kaweth->net); -- cgit v1.2.3-70-g09d2 From 90ef713b6368dcfe7a74bcc0026b998b4c44d5bc Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Thu, 16 Jun 2005 18:01:11 +0100 Subject: [PATCH] ARM: 2712/1: Fix the RGB order for the Versatile CLCD Patch from Catalin Marinas The current red and blue colours on the Versatile CLCD are reversed when the 5:6:5 mode is used. The patch sets the proper bit in the SYS_CLCD register value. Signed-off-by: Catalin Marinas Signed-off-by: Russell King --- arch/arm/mach-versatile/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index 554e1bd30d6..302c2a7b9b6 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c @@ -543,7 +543,7 @@ static void versatile_clcd_enable(struct clcd_fb *fb) val |= SYS_CLCD_MODE_5551; break; case 6: - val |= SYS_CLCD_MODE_565_BLSB; + val |= SYS_CLCD_MODE_565_RLSB; break; case 8: val |= SYS_CLCD_MODE_888; -- cgit v1.2.3-70-g09d2 From fea7722fd7b45c6957caed84251d95269319fe16 Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Thu, 16 Jun 2005 18:01:11 +0100 Subject: [PATCH] ARM: 2713/1: Fix the GPIO base for Integrator/CP Patch from Catalin Marinas The GPIO base for Integrator/CP is different from the Integrator/AP. This patch sets the correct value for INTEGRATOR_GPIO_BASE. Signed-off-by: Catalin Marinas Signed-off-by: Russell King --- arch/arm/mach-integrator/integrator_cp.c | 1 - include/asm-arm/arch-integrator/platform.h | 4 ++++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c index 3b948e8c275..e0a01eef099 100644 --- a/arch/arm/mach-integrator/integrator_cp.c +++ b/arch/arm/mach-integrator/integrator_cp.c @@ -83,7 +83,6 @@ static struct map_desc intcp_io_desc[] __initdata = { { IO_ADDRESS(INTEGRATOR_UART1_BASE), INTEGRATOR_UART1_BASE, SZ_4K, MT_DEVICE }, { IO_ADDRESS(INTEGRATOR_DBG_BASE), INTEGRATOR_DBG_BASE, SZ_4K, MT_DEVICE }, { IO_ADDRESS(INTEGRATOR_GPIO_BASE), INTEGRATOR_GPIO_BASE, SZ_4K, MT_DEVICE }, - { 0xfc900000, 0xc9000000, SZ_4K, MT_DEVICE }, { 0xfca00000, 0xca000000, SZ_4K, MT_DEVICE }, { 0xfcb00000, 0xcb000000, SZ_4K, MT_DEVICE }, }; diff --git a/include/asm-arm/arch-integrator/platform.h b/include/asm-arm/arch-integrator/platform.h index bd364f5a99b..96ad3d2a66d 100644 --- a/include/asm-arm/arch-integrator/platform.h +++ b/include/asm-arm/arch-integrator/platform.h @@ -293,7 +293,11 @@ #define INTEGRATOR_DBG_SWITCH (INTEGRATOR_DBG_BASE + INTEGRATOR_DBG_SWITCH_OFFSET) +#if defined(CONFIG_ARCH_INTEGRATOR_AP) #define INTEGRATOR_GPIO_BASE 0x1B000000 /* GPIO */ +#elif defined(CONFIG_ARCH_INTEGRATOR_CP) +#define INTEGRATOR_GPIO_BASE 0xC9000000 /* GPIO */ +#endif /* ------------------------------------------------------------------------ * KMI keyboard/mouse definitions -- cgit v1.2.3-70-g09d2 From 95220a2ea334b5ff2168cc9bf31c0e08b29bae21 Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Thu, 16 Jun 2005 18:01:12 +0100 Subject: [PATCH] ARM: 2714/1: Fix the IB2 definitions for the Versatile platform Patch from Catalin Marinas The initial IB2 addresses did not depend on the IB2 base. This patch defines them as (VERSATILE_IB2_BASE + offset). Signed-off-by: Catalin Marinas Signed-off-by: Russell King --- include/asm-arm/arch-versatile/platform.h | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/include/asm-arm/arch-versatile/platform.h b/include/asm-arm/arch-versatile/platform.h index 2598d1f0854..a71093e44c5 100644 --- a/include/asm-arm/arch-versatile/platform.h +++ b/include/asm-arm/arch-versatile/platform.h @@ -498,11 +498,17 @@ /* * IB2 Versatile/AB expansion board definitions */ -#define VERSATILE_IB2_CAMERA_BANK 0x24000000 -#define VERSATILE_IB2_KBD_DATAREG 0x25000000 -#define VERSATILE_IB2_IER 0x26000000 /* for VICINTSOURCE27 */ -#define VERSATILE_IB2_CTRL 0x27000000 -#define VERSATILE_IB2_STAT 0x27000004 +#define VERSATILE_IB2_CAMERA_BANK VERSATILE_IB2_BASE +#define VERSATILE_IB2_KBD_DATAREG (VERSATILE_IB2_BASE + 0x01000000) + +/* VICINTSOURCE27 */ +#define VERSATILE_IB2_INT_BASE (VERSATILE_IB2_BASE + 0x02000000) +#define VERSATILE_IB2_IER (VERSATILE_IB2_INT_BASE + 0) +#define VERSATILE_IB2_ISR (VERSATILE_IB2_INT_BASE + 4) + +#define VERSATILE_IB2_CTL_BASE (VERSATILE_IB2_BASE + 0x03000000) +#define VERSATILE_IB2_CTRL (VERSATILE_IB2_CTL_BASE + 0) +#define VERSATILE_IB2_STAT (VERSATILE_IB2_CTL_BASE + 4) #endif #endif -- cgit v1.2.3-70-g09d2 From 22f11c4e662ef0bdd87f09370a76c83ed738d5fd Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Thu, 16 Jun 2005 21:23:56 +0100 Subject: [PATCH] ARM: 2715/1: restore CPLD interrupts upon resume for Lubbock and Mainstone Patch from Nicolas Pitre Without this some devices fail to work again after a suspend event. Signed-off-by: Nicolas Pitre Signed-off-by: Russell King --- arch/arm/mach-pxa/lubbock.c | 30 ++++++++++++++++++++++++++++++ arch/arm/mach-pxa/mainstone.c | 31 ++++++++++++++++++++++++++++++- 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c index dd012d6e2f5..f2c9e0d2b24 100644 --- a/arch/arm/mach-pxa/lubbock.c +++ b/arch/arm/mach-pxa/lubbock.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -106,6 +107,35 @@ static void __init lubbock_init_irq(void) set_irq_type(IRQ_GPIO(0), IRQT_FALLING); } +#ifdef CONFIG_PM + +static int lubbock_irq_resume(struct sys_device *dev) +{ + LUB_IRQ_MASK_EN = lubbock_irq_enabled; + return 0; +} + +static struct sysdev_class lubbock_irq_sysclass = { + set_kset_name("cpld_irq"), + .resume = lubbock_irq_resume, +}; + +static struct sys_device lubbock_irq_device = { + .cls = &lubbock_irq_sysclass, +}; + +static int __init lubbock_irq_device_init(void) +{ + int ret = sysdev_class_register(&lubbock_irq_sysclass); + if (ret == 0) + ret = sysdev_register(&lubbock_irq_device); + return ret; +} + +device_initcall(lubbock_irq_device_init); + +#endif + static int lubbock_udc_is_connected(void) { return (LUB_MISC_RD & (1 << 9)) == 0; diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c index 6823ae28ae6..9896afca751 100644 --- a/arch/arm/mach-pxa/mainstone.c +++ b/arch/arm/mach-pxa/mainstone.c @@ -15,6 +15,7 @@ #include #include +#include #include #include #include @@ -62,7 +63,6 @@ static struct irqchip mainstone_irq_chip = { .unmask = mainstone_unmask_irq, }; - static void mainstone_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) { @@ -100,6 +100,35 @@ static void __init mainstone_init_irq(void) set_irq_type(IRQ_GPIO(0), IRQT_FALLING); } +#ifdef CONFIG_PM + +static int mainstone_irq_resume(struct sys_device *dev) +{ + MST_INTMSKENA = mainstone_irq_enabled; + return 0; +} + +static struct sysdev_class mainstone_irq_sysclass = { + set_kset_name("cpld_irq"), + .resume = mainstone_irq_resume, +}; + +static struct sys_device mainstone_irq_device = { + .cls = &mainstone_irq_sysclass, +}; + +static int __init mainstone_irq_device_init(void) +{ + int ret = sysdev_class_register(&mainstone_irq_sysclass); + if (ret == 0) + ret = sysdev_register(&mainstone_irq_device); + return ret; +} + +device_initcall(mainstone_irq_device_init); + +#endif + static struct resource smc91x_resources[] = { [0] = { -- cgit v1.2.3-70-g09d2 From db3b5848ea6440968fcdd29b80514d0de044bb7c Mon Sep 17 00:00:00 2001 From: Kiyoshi Ueda Date: Fri, 17 Jun 2005 16:15:10 +0200 Subject: When cfq I/O scheduler is selected, get_request() in __make_request() calls __cfq_get_queue(). __cfq_get_queue() finds an existing queue (struct cfq_queue) of the current process for the device and returns it. If it's not found, __cfq_get_queue() creates and returns a new one if __cfq_get_queue() is called with __GFP_WAIT flag, or __cfq_get_queue() returns NULL (this means that get_request() fails) if no __GFP_WAIT flag. On the other hand, in __make_request(), get_request() is called without __GFP_WAIT flag at the first time. Thus, the get_request() fails when there is no existing queue, typically when it's called for the first I/O request of the process to the device. Though it will be followed by get_request_wait() for general case, __make_request() will just end the I/O with an error (EWOULDBLOCK) when the request was for read-ahead. Signed-off-by: Jens Axboe Signed-off-by: Kiyoshi Ueda Signed-off-by: Jun'ichi Nomura --- drivers/block/cfq-iosched.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/block/cfq-iosched.c b/drivers/block/cfq-iosched.c index 0ef7a0065ec..2210bacad56 100644 --- a/drivers/block/cfq-iosched.c +++ b/drivers/block/cfq-iosched.c @@ -1202,13 +1202,16 @@ retry: if (new_cfqq) { cfqq = new_cfqq; new_cfqq = NULL; - } else if (gfp_mask & __GFP_WAIT) { + } else { spin_unlock_irq(cfqd->queue->queue_lock); new_cfqq = kmem_cache_alloc(cfq_pool, gfp_mask); spin_lock_irq(cfqd->queue->queue_lock); + + if (!new_cfqq && !(gfp_mask & __GFP_WAIT)) + goto out; + goto retry; - } else - goto out; + } memset(cfqq, 0, sizeof(*cfqq)); -- cgit v1.2.3-70-g09d2 From caf2857ac6e0ba2651e722f05d5f7d3ec8ef2615 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Fri, 17 Jun 2005 11:36:36 +0200 Subject: [PATCH] timer exit cleanup Do all timer zapping in exit_itimers. Signed-off-by: Ingo Molnar Signed-off-by: Linus Torvalds --- kernel/exit.c | 4 +--- kernel/posix-timers.c | 1 + 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/kernel/exit.c b/kernel/exit.c index edaa50b5bbf..2ef2ad54020 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -811,10 +811,8 @@ fastcall NORET_TYPE void do_exit(long code) acct_update_integrals(tsk); update_mem_hiwater(tsk); group_dead = atomic_dec_and_test(&tsk->signal->live); - if (group_dead) { - del_timer_sync(&tsk->signal->real_timer); + if (group_dead) acct_process(code); - } exit_mm(tsk); exit_sem(tsk); diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c index fd316c27226..cabb63fc9e1 100644 --- a/kernel/posix-timers.c +++ b/kernel/posix-timers.c @@ -1197,6 +1197,7 @@ void exit_itimers(struct signal_struct *sig) tmr = list_entry(sig->posix_timers.next, struct k_itimer, list); itimer_delete(tmr); } + del_timer_sync(&sig->real_timer); } /* -- cgit v1.2.3-70-g09d2 From 794f5bfa77955c4455f6d72d8b0e2bee25f1ff0c Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 17 Jun 2005 12:25:25 -0700 Subject: [PATCH] PCI: don't override drv->shutdown unconditionally There are many drivers that have been setting the generic driver model level shutdown callback, and pci thus must not override it. Without this patch we can have really bad data loss on various raid controllers. Signed-off-by: Greg Kroah-Hartman Signed-off-by: Linus Torvalds --- drivers/pci/pci-driver.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index fe98553c978..f315df2005b 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -393,7 +393,10 @@ int pci_register_driver(struct pci_driver *drv) drv->driver.bus = &pci_bus_type; drv->driver.probe = pci_device_probe; drv->driver.remove = pci_device_remove; - drv->driver.shutdown = pci_device_shutdown, + /* FIXME, once all of the existing PCI drivers have been fixed to set + * the pci shutdown function, this test can go away. */ + if (!drv->driver.shutdown) + drv->driver.shutdown = pci_device_shutdown, drv->driver.owner = drv->owner; drv->driver.kobj.ktype = &pci_driver_kobj_type; pci_init_dynids(&drv->dynids); -- cgit v1.2.3-70-g09d2 From 9ee1c939d1cb936b1f98e8d81aeffab57bae46ab Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 17 Jun 2005 12:48:29 -0700 Subject: Linux 2.6.12 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 9e005e18c71..0d1e74d5006 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 12 -EXTRAVERSION =-rc6 +EXTRAVERSION = NAME=Woozy Numbat # *DOCUMENTATION* -- cgit v1.2.3-70-g09d2