This is an automated email from the git hooks/post-receive script. sthibault pushed a commit to branch master in repository hurd.
commit 070646a0b5597a10582de2d6cffb6a0f203c83ef Author: Samuel Thibault <[email protected]> Date: Tue Sep 22 18:47:30 2015 +0000 New upstream snapshot --- Makeconf | 2 +- console/display.c | 12 + console/pager.c | 3 +- daemons/runsystem.sh | 3 - exec/elfcore.c | 2 + exec/exec.c | 50 ++- ext2fs/ext2fs.c | 12 +- ext2fs/ext2fs.h | 13 +- ext2fs/pager.c | 33 +- fatfs/fatfs.h | 2 + fatfs/pager.c | 33 +- init/init.c | 2 +- libbpf/Makefile | 2 +- .../contrib/drivers/base/attribute_container.c | 2 +- libdde-linux26/contrib/drivers/base/platform.c | 2 +- libdde-linux26/contrib/drivers/base/sys.c | 2 +- libdde-linux26/contrib/include/linux/etherdevice.h | 27 ++ libdde-linux26/contrib/include/linux/ethtool.h | 36 +- libdde-linux26/contrib/include/linux/inotify.h | 4 +- libdde-linux26/contrib/include/linux/kernel.h | 2 + libdde-linux26/contrib/include/linux/netdevice.h | 90 ++++- libdde-linux26/contrib/include/linux/pci.h | 1 + libdde-linux26/contrib/include/linux/pci_ids.h | 177 +++++++--- libdde-linux26/contrib/include/linux/phy.h | 19 +- libdde-linux26/contrib/include/linux/skbuff.h | 20 +- libdde-linux26/contrib/include/linux/tty_driver.h | 2 +- libdde-linux26/contrib/include/linux/workqueue.h | 23 +- libdde-linux26/contrib/kernel/rcupdate.c | 1 + libdde-linux26/contrib/lib/kobject.c | 2 +- libdde-linux26/contrib/net/core/net-sysfs.c | 2 +- libdde-linux26/contrib/net/core/skb_dma_map.c | 12 +- libdde-linux26/include/linux/kernel.h | 2 + libdde-linux26/lib/src/Makefile | 3 + libdde-linux26/lib/src/drivers/base/core.c | 2 +- libdde-linux26/lib/src/net/core/dev.c | 389 +++++++++++++++++++-- libdde-linux26/lib/src/net/sched/sch_generic.c | 40 ++- libdiskfs/dir-lookup.c | 104 +++--- libdiskfs/disk-pager.c | 3 +- libdiskfs/diskfs-pager.h | 1 + libdiskfs/diskfs.h | 10 +- libdiskfs/file-getcontrol.c | 14 +- libdiskfs/file-syncfs.c | 6 +- libdiskfs/name-cache.c | 2 +- libpager/demuxer.c | 119 ++++++- libpager/pager.h | 28 +- libpager/queue.h | 8 + libpipe/pipe.c | 17 +- libports/Makefile | 2 +- libports/manage-multithread.c | 5 + libports/manage-one-thread.c | 5 + libshouldbeinlibc/maptime.h | 2 + libthreads/lockfile.c | 3 + libtrivfs/Makefile | 3 - pflocal/io.c | 13 +- pflocal/mig-decls.h | 2 +- pflocal/sock.c | 10 +- pflocal/sock.h | 31 +- pflocal/socket.c | 8 +- procfs/main.c | 6 + startup/startup.c | 1 - storeio/pager.c | 3 +- sutils/fstab.c | 2 +- trans/fakeroot.c | 8 +- trans/fifo.c | 2 +- utils/umount.c | 2 + 65 files changed, 1185 insertions(+), 264 deletions(-) diff --git a/Makeconf b/Makeconf index ed2f6d0..b42e4c7 100644 --- a/Makeconf +++ b/Makeconf @@ -77,7 +77,7 @@ INCLUDES += -I.. $(top_srcdirinc) endif INCLUDES += -I$(..)include -I$(top_srcdir)/include CPPFLAGS += $(INCLUDES) \ - -D_GNU_SOURCE -D_IO_MTSAFE_IO -D_FILE_OFFSET_BITS=64 \ + -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 \ $($*-CPPFLAGS) CFLAGS += -std=gnu99 $(gnu89-inline-CFLAGS) -Wall -g -O3 \ $($*-CFLAGS) diff --git a/console/display.c b/console/display.c index eb420fd..98c70f5 100644 --- a/console/display.c +++ b/console/display.c @@ -1210,6 +1210,18 @@ handle_esc_bracket (display_t display, char op) user->cursor.col -= (parse->params[0] ?: 1); limit_cursor (display); break; + case 's': /* ANSI.SYS: Save cursor and attributes. */ + /* Save cursor position: <scp>. */ + display->cursor.saved_x = user->cursor.col; + display->cursor.saved_y = user->cursor.row; + break; + case 'u': /* ANSI.SYS: Restore cursor and attributes. */ + /* Restore cursor position: <rcp>. */ + user->cursor.col = display->cursor.saved_x; + user->cursor.row = display->cursor.saved_y; + /* In case the screen was larger before: */ + limit_cursor (display); + break; case 'l': /* Reset mode. */ for (i = 0; i < parse->nparams; i++) diff --git a/console/pager.c b/console/pager.c index 5e13ba4..818e49d 100644 --- a/console/pager.c +++ b/console/pager.c @@ -42,6 +42,7 @@ struct user_pager_info /* We need a separate bucket for the pager ports. */ static struct port_bucket *pager_bucket; +static struct pager_requests *pager_requests; /* Implement the pager_clear_user_data callback from the pager library. */ @@ -133,7 +134,7 @@ user_pager_init (void) error (5, errno, "Cannot create pager bucket"); /* Start libpagers worker threads. */ - err = pager_start_workers (pager_bucket); + err = pager_start_workers (pager_bucket, &pager_requests); if (err) error (5, err, "Cannot start pager worker threads"); } diff --git a/daemons/runsystem.sh b/daemons/runsystem.sh index ae25a7d..5d0ad01 100644 --- a/daemons/runsystem.sh +++ b/daemons/runsystem.sh @@ -118,9 +118,6 @@ esac /hurd/mach-defpager # This is necessary to make stat / return the correct device ids. -# Work around a race condition (probably in the root translator). -for i in `seq 1 100000` ; do : ; done # XXX - fsysopts / --update --readonly # Finally, start the actual init. diff --git a/exec/elfcore.c b/exec/elfcore.c index 449263b..3e4551e 100644 --- a/exec/elfcore.c +++ b/exec/elfcore.c @@ -121,10 +121,12 @@ fetch_thread_fpregset (thread_t thread, prfpregset_t *fpregs) #endif +#ifndef TIME_VALUE_TO_TIMESPEC #define TIME_VALUE_TO_TIMESPEC(tv, ts) { \ (ts)->tv_sec = (tv)->seconds; \ (ts)->tv_nsec = (tv)->microseconds * 1000; \ } +#endif #define PAGES_TO_KB(x) ((x) * (vm_page_size / 1024)) #define ENCODE_PCT(f) ((uint16_t) ((f) * 32768.0)) diff --git a/exec/exec.c b/exec/exec.c index ee500d7..3b63b7f 100644 --- a/exec/exec.c +++ b/exec/exec.c @@ -686,6 +686,36 @@ finish (struct execdata *e, int dealloc_file) } } +/* Set the name of the new task so that the kernel can use it in error + messages. If PID is not zero, it will be included the name. */ +static void +set_name (task_t task, const char *exec_name, pid_t pid) +{ + char *name; + int size; + + if (pid) + size = asprintf (&name, "%s(%d)", exec_name, pid); + else + size = asprintf (&name, "%s", exec_name); + + if (size == 0) + return; + + /* This is an internal implementational detail of the GNU Mach kernel. */ +#define TASK_NAME_SIZE 32 + if (size < TASK_NAME_SIZE) + task_set_name (task, name); + else + { + char *abbr = name + size - TASK_NAME_SIZE + 1; + abbr[0] = abbr[1] = abbr[2] = '.'; + task_set_name (task, abbr); + } +#undef TASK_NAME_SIZE + + free (name); +} /* Load the file. */ static void @@ -1173,24 +1203,10 @@ do_exec (file_t file, if (e.error) goto out; - char *name; - int size = asprintf (&name, "%s(%d)", argv, pid); - if (size > 0) - { -/* This is an internal implementational detail of the gnumach kernel. */ -#define TASK_NAME_SIZE 32 - if (size < TASK_NAME_SIZE) - task_set_name (newtask, name); - else - { - char *abbr = name + size - TASK_NAME_SIZE + 1; - abbr[0] = abbr[1] = abbr[2] = '.'; - task_set_name (newtask, abbr); - } -#undef TASK_NAME_SIZE - free (name); - } + set_name (newtask, argv, pid); } + else + set_name (newtask, argv, 0); /* Create the initial thread. */ e.error = thread_create (newtask, &thread); diff --git a/ext2fs/ext2fs.c b/ext2fs/ext2fs.c index d0fdfe7..03c9eed 100644 --- a/ext2fs/ext2fs.c +++ b/ext2fs/ext2fs.c @@ -207,10 +207,20 @@ main (int argc, char **argv) error_t diskfs_reload_global_state () { + error_t err; + pokel_flush (&global_pokel); pager_flush (diskfs_disk_pager, 1); - sblock = NULL; + + /* libdiskfs is not responsible for inhibiting paging. */ + err = inhibit_ext2_pager (); + if (err) + return err; + get_hypermetadata (); map_hypermetadata (); + + resume_ext2_pager (); + return 0; } diff --git a/ext2fs/ext2fs.h b/ext2fs/ext2fs.h index 96d8e9d..42717c5 100644 --- a/ext2fs/ext2fs.h +++ b/ext2fs/ext2fs.h @@ -50,9 +50,12 @@ typedef int8_t __s8; #undef ext2_debug #ifdef EXT2FS_DEBUG +#include <stdio.h> extern int ext2_debug_flag; +#define ext2_debug_(f, a...) \ + fprintf (stderr, "ext2fs: (debug) %s: " f "\n", __FUNCTION__ , ## a) #define ext2_debug(f, a...) \ - do { if (ext2_debug_flag) printf ("ext2fs: (debug) %s: " f "\n", __FUNCTION__ , ## a); } while (0) + do { if (ext2_debug_flag) ext2_debug_(f, ## a); } while (0) #else #define ext2_debug(f, a...) (void)0 #endif @@ -65,8 +68,6 @@ extern int ext2_debug_flag; #undef DONT_CACHE_MEMORY_OBJECTS -int printf (const char *fmt, ...); - /* A block number. */ typedef __u32 block_t; @@ -201,6 +202,12 @@ struct user_pager_info /* Set up the disk pager. */ void create_disk_pager (void); +/* Inhibit the disk pager. */ +error_t inhibit_ext2_pager (void); + +/* Resume the disk pager. */ +void resume_ext2_pager (void); + /* Call this when we should turn off caching so that unused memory object ports get freed. */ void drop_pager_softrefs (struct node *node); diff --git a/ext2fs/pager.c b/ext2fs/pager.c index b56c923..3e080f8 100644 --- a/ext2fs/pager.c +++ b/ext2fs/pager.c @@ -34,6 +34,10 @@ struct port_bucket *disk_pager_bucket; /* A ports bucket to hold file pager ports. */ struct port_bucket *file_pager_bucket; +/* Stores a reference to the requests instance used by the file pager so its + worker threads can be inhibited and resumed. */ +struct pager_requests *file_pager_requests; + pthread_spinlock_t node_to_page_lock = PTHREAD_SPINLOCK_INITIALIZER; @@ -1217,11 +1221,38 @@ create_disk_pager (void) file_pager_bucket = ports_create_bucket (); /* Start libpagers worker threads. */ - err = pager_start_workers (file_pager_bucket); + err = pager_start_workers (file_pager_bucket, &file_pager_requests); if (err) ext2_panic ("can't create libpager worker threads: %s", strerror (err)); } +error_t +inhibit_ext2_pager (void) +{ + error_t err; + + /* The file pager can rely on the disk pager, so inhibit the file + pager first. */ + + err = pager_inhibit_workers (file_pager_requests); + if (err) + return err; + + err = pager_inhibit_workers (diskfs_disk_pager_requests); + /* We don't want only one pager disabled. */ + if (err) + pager_resume_workers (file_pager_requests); + + return err; +} + +void +resume_ext2_pager (void) +{ + pager_resume_workers (diskfs_disk_pager_requests); + pager_resume_workers (file_pager_requests); +} + /* Call this to create a FILE_DATA pager and return a send right. NODE must be locked. */ mach_port_t diff --git a/fatfs/fatfs.h b/fatfs/fatfs.h index 3c3d836..54c3426 100644 --- a/fatfs/fatfs.h +++ b/fatfs/fatfs.h @@ -121,6 +121,8 @@ extern struct dirrect dr_root_node; void drop_pager_softrefs (struct node *); void allow_pager_softrefs (struct node *); void create_fat_pager (void); +error_t inhibit_fat_pager (void); +void resume_fat_pager (void); void flush_node_pager (struct node *node); diff --git a/fatfs/pager.c b/fatfs/pager.c index 10d1fc9..d255f29 100644 --- a/fatfs/pager.c +++ b/fatfs/pager.c @@ -29,6 +29,10 @@ struct port_bucket *disk_pager_bucket; /* A ports bucket to hold file pager ports. */ struct port_bucket *file_pager_bucket; +/* Stores a reference to the requests instance used by the file pager so its + worker threads can be inhibited and resumed. */ +struct pager_requests *file_pager_requests; + /* Mapped image of the FAT. */ void *fat_image; @@ -776,11 +780,38 @@ create_fat_pager (void) file_pager_bucket = ports_create_bucket (); /* Start libpagers worker threads. */ - err = pager_start_workers (file_pager_bucket); + err = pager_start_workers (file_pager_bucket, &file_pager_requests); if (err) error (2, err, "can't create libpager worker threads"); } +error_t +inhibit_fat_pager (void) +{ + error_t err; + + /* The file pager can rely on the disk pager, so inhibit the file + pager first. */ + + err = pager_inhibit_workers (file_pager_requests); + if (err) + return err; + + err = pager_inhibit_workers (diskfs_disk_pager_requests); + /* We don't want only one pager disabled. */ + if (err) + pager_resume_workers (file_pager_requests); + + return err; +} + +void +resume_fat_pager (void) +{ + pager_resume_workers (diskfs_disk_pager_requests); + pager_resume_workers (file_pager_requests); +} + /* Call this to create a FILE_DATA pager and return a send right. NODE must be locked. */ mach_port_t diff --git a/init/init.c b/init/init.c index b3d3301..fe230da 100644 --- a/init/init.c +++ b/init/init.c @@ -146,7 +146,7 @@ main (int argc, char **argv) error (1, errno, "failed to fork"); case 0: execv (args[0], args); - error (2, errno, "failed to execv child"); + error (2, errno, "failed to execv child %s", args[0]); } select (0, NULL, NULL, NULL, NULL); diff --git a/libbpf/Makefile b/libbpf/Makefile index ec0723c..d6ebdc3 100644 --- a/libbpf/Makefile +++ b/libbpf/Makefile @@ -21,7 +21,7 @@ makemode := library libname = libbpf SRCS= bpf_impl.c queue.c LCLHDRS = bpf_impl.h queue.h -installhdrs = bpf_impl.h +installhdrs = bpf_impl.h queue.h MIGSTUBS = OBJS = $(sort $(SRCS:.c=.o) $(MIGSTUBS)) diff --git a/libdde-linux26/contrib/drivers/base/attribute_container.c b/libdde-linux26/contrib/drivers/base/attribute_container.c index b9cda05..e0f7859 100644 --- a/libdde-linux26/contrib/drivers/base/attribute_container.c +++ b/libdde-linux26/contrib/drivers/base/attribute_container.c @@ -167,7 +167,7 @@ attribute_container_add_device(struct device *dev, ic->classdev.parent = get_device(dev); ic->classdev.class = cont->class; cont->class->dev_release = attribute_container_release; - dev_set_name(&ic->classdev, dev_name(dev)); + dev_set_name(&ic->classdev, "%s", dev_name(dev)); if (fn) fn(cont, dev, &ic->classdev); else diff --git a/libdde-linux26/contrib/drivers/base/platform.c b/libdde-linux26/contrib/drivers/base/platform.c index 349a101..030d638 100644 --- a/libdde-linux26/contrib/drivers/base/platform.c +++ b/libdde-linux26/contrib/drivers/base/platform.c @@ -244,7 +244,7 @@ int platform_device_add(struct platform_device *pdev) if (pdev->id != -1) dev_set_name(&pdev->dev, "%s.%d", pdev->name, pdev->id); else - dev_set_name(&pdev->dev, pdev->name); + dev_set_name(&pdev->dev, "%s", pdev->name); for (i = 0; i < pdev->num_resources; i++) { struct resource *p, *r = &pdev->resource[i]; diff --git a/libdde-linux26/contrib/drivers/base/sys.c b/libdde-linux26/contrib/drivers/base/sys.c index b428c8c..38e725c 100644 --- a/libdde-linux26/contrib/drivers/base/sys.c +++ b/libdde-linux26/contrib/drivers/base/sys.c @@ -137,7 +137,7 @@ int sysdev_class_register(struct sysdev_class * cls) cls->kset.kobj.parent = &system_kset->kobj; cls->kset.kobj.ktype = &ktype_sysdev_class; cls->kset.kobj.kset = system_kset; - kobject_set_name(&cls->kset.kobj, cls->name); + kobject_set_name(&cls->kset.kobj, "%s", cls->name); return kset_register(&cls->kset); } diff --git a/libdde-linux26/contrib/include/linux/etherdevice.h b/libdde-linux26/contrib/include/linux/etherdevice.h index 1cb0f0b..fbb3836 100644 --- a/libdde-linux26/contrib/include/linux/etherdevice.h +++ b/libdde-linux26/contrib/include/linux/etherdevice.h @@ -182,6 +182,33 @@ static inline unsigned compare_ether_addr_64bits(const u8 addr1[6+2], return compare_ether_addr(addr1, addr2); #endif } + +/** + * is_etherdev_addr - Tell if given Ethernet address belongs to the device. + * @dev: Pointer to a device structure + * @addr: Pointer to a six-byte array containing the Ethernet address + * + * Compare passed address with all addresses of the device. Return true if the + * address if one of the device addresses. + * + * Note that this function calls compare_ether_addr_64bits() so take care of + * the right padding. + */ +static inline bool is_etherdev_addr(const struct net_device *dev, + const u8 addr[6 + 2]) +{ + struct netdev_hw_addr *ha; + int res = 1; + + rcu_read_lock(); + for_each_dev_addr(dev, ha) { + res = compare_ether_addr_64bits(addr, ha->addr); + if (!res) + break; + } + rcu_read_unlock(); + return !res; +} #endif /* __KERNEL__ */ #endif /* _LINUX_ETHERDEVICE_H */ diff --git a/libdde-linux26/contrib/include/linux/ethtool.h b/libdde-linux26/contrib/include/linux/ethtool.h index 27c67a5..45f34dc 100644 --- a/libdde-linux26/contrib/include/linux/ethtool.h +++ b/libdde-linux26/contrib/include/linux/ethtool.h @@ -25,11 +25,14 @@ struct ethtool_cmd { __u8 phy_address; __u8 transceiver; /* Which transceiver to use */ __u8 autoneg; /* Enable or disable autonegotiation */ + __u8 mdio_support; __u32 maxtxpkt; /* Tx pkts before generating tx int */ __u32 maxrxpkt; /* Rx pkts before generating rx int */ __u16 speed_hi; - __u16 reserved2; - __u32 reserved[3]; + __u8 eth_tp_mdix; + __u8 reserved2; + __u32 lp_advertising; /* Features the link partner advertises */ + __u32 reserved[2]; }; static inline void ethtool_cmd_speed_set(struct ethtool_cmd *ep, @@ -469,6 +472,13 @@ struct ethtool_ops { #define ETHTOOL_SRXFH 0x0000002a /* Set RX flow hash configuration */ #define ETHTOOL_GGRO 0x0000002b /* Get GRO enable (ethtool_value) */ #define ETHTOOL_SGRO 0x0000002c /* Set GRO enable (ethtool_value) */ +#define ETHTOOL_GRXRINGS 0x0000002d /* Get RX rings available for LB */ +#define ETHTOOL_GRXCLSRLCNT 0x0000002e /* Get RX class rule count */ +#define ETHTOOL_GRXCLSRULE 0x0000002f /* Get RX classification rule */ +#define ETHTOOL_GRXCLSRLALL 0x00000030 /* Get all RX classification rule */ +#define ETHTOOL_SRXCLSRLDEL 0x00000031 /* Delete RX classification rule */ +#define ETHTOOL_SRXCLSRLINS 0x00000032 /* Insert RX classification rule */ +#define ETHTOOL_FLASHDEV 0x00000033 /* Flash firmware to device */ /* compatibility with older code */ #define SPARC_ETH_GSET ETHTOOL_GSET @@ -491,6 +501,11 @@ struct ethtool_ops { #define SUPPORTED_Pause (1 << 13) #define SUPPORTED_Asym_Pause (1 << 14) #define SUPPORTED_2500baseX_Full (1 << 15) +#define SUPPORTED_Backplane (1 << 16) +#define SUPPORTED_1000baseKX_Full (1 << 17) +#define SUPPORTED_10000baseKX4_Full (1 << 18) +#define SUPPORTED_10000baseKR_Full (1 << 19) +#define SUPPORTED_10000baseR_FEC (1 << 20) /* Indicates what features are advertised by the interface. */ #define ADVERTISED_10baseT_Half (1 << 0) @@ -509,6 +524,11 @@ struct ethtool_ops { #define ADVERTISED_Pause (1 << 13) #define ADVERTISED_Asym_Pause (1 << 14) #define ADVERTISED_2500baseX_Full (1 << 15) +#define ADVERTISED_Backplane (1 << 16) +#define ADVERTISED_1000baseKX_Full (1 << 17) +#define ADVERTISED_10000baseKX4_Full (1 << 18) +#define ADVERTISED_10000baseKR_Full (1 << 19) +#define ADVERTISED_10000baseR_FEC (1 << 20) /* The following are all involved in forcing a particular link * mode for the device for setting things. When getting the @@ -533,6 +553,7 @@ struct ethtool_ops { #define PORT_MII 0x02 #define PORT_FIBRE 0x03 #define PORT_BNC 0x04 +#define PORT_OTHER 0xff /* Which transceiver to use. */ #define XCVR_INTERNAL 0x00 @@ -547,6 +568,11 @@ struct ethtool_ops { #define AUTONEG_DISABLE 0x00 #define AUTONEG_ENABLE 0x01 +/* Mode MDI or MDI-X */ +#define ETH_TP_MDI_INVALID 0x00 +#define ETH_TP_MDI 0x01 +#define ETH_TP_MDI_X 0x02 + /* Wake-On-Lan options. */ #define WAKE_PHY (1 << 0) #define WAKE_UCAST (1 << 1) @@ -565,6 +591,11 @@ struct ethtool_ops { #define UDP_V6_FLOW 0x06 #define SCTP_V6_FLOW 0x07 #define AH_ESP_V6_FLOW 0x08 +#define AH_V4_FLOW 0x09 +#define ESP_V4_FLOW 0x0a +#define AH_V6_FLOW 0x0b +#define ESP_V6_FLOW 0x0c +#define IP_USER_FLOW 0x0d /* L3-L4 network traffic flow hash options */ #define RXH_DEV_PORT (1 << 0) @@ -577,5 +608,6 @@ struct ethtool_ops { #define RXH_L4_B_2_3 (1 << 7) /* dst port in case of TCP/UDP/SCTP */ #define RXH_DISCARD (1 << 31) +#define RX_CLS_FLOW_DISC 0xffffffffffffffffULL #endif /* _LINUX_ETHTOOL_H */ diff --git a/libdde-linux26/contrib/include/linux/inotify.h b/libdde-linux26/contrib/include/linux/inotify.h index 37ea289..782fd29 100644 --- a/libdde-linux26/contrib/include/linux/inotify.h +++ b/libdde-linux26/contrib/include/linux/inotify.h @@ -230,12 +230,12 @@ static inline void put_inotify_watch(struct inotify_watch *watch) { } -extern inline int pin_inotify_watch(struct inotify_watch *watch) +static inline int pin_inotify_watch(struct inotify_watch *watch) { return 0; } -extern inline void unpin_inotify_watch(struct inotify_watch *watch) +static inline void unpin_inotify_watch(struct inotify_watch *watch) { } diff --git a/libdde-linux26/contrib/include/linux/kernel.h b/libdde-linux26/contrib/include/linux/kernel.h index 7fa3718..0bded10 100644 --- a/libdde-linux26/contrib/include/linux/kernel.h +++ b/libdde-linux26/contrib/include/linux/kernel.h @@ -353,6 +353,8 @@ static inline char *pack_hex_byte(char *buf, u8 byte) printk(KERN_NOTICE pr_fmt(fmt), ##__VA_ARGS__) #define pr_info(fmt, ...) \ printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__) +#define pr_cont(fmt, ...) \ + printk(KERN_CONT fmt, ##__VA_ARGS__) /* If you are writing a driver, please use dev_dbg instead */ #if defined(DEBUG) diff --git a/libdde-linux26/contrib/include/linux/netdevice.h b/libdde-linux26/contrib/include/linux/netdevice.h index 6593667..4414989 100644 --- a/libdde-linux26/contrib/include/linux/netdevice.h +++ b/libdde-linux26/contrib/include/linux/netdevice.h @@ -37,6 +37,7 @@ #include <asm/byteorder.h> #include <linux/device.h> +#include <linux/rculist.h> #include <linux/percpu.h> #include <linux/dmaengine.h> #include <linux/workqueue.h> @@ -81,17 +82,19 @@ struct wireless_dev; #define net_xmit_eval(e) ((e) == NET_XMIT_CN? 0 : (e)) #define net_xmit_errno(e) ((e) != NET_XMIT_CN ? -ENOBUFS : 0) +/* Driver transmit return codes */ +enum netdev_tx { + NETDEV_TX_OK = 0, /* driver took care of packet */ + NETDEV_TX_BUSY, /* driver tx path was busy*/ + NETDEV_TX_LOCKED = -1, /* driver tx lock was already taken */ +}; +typedef enum netdev_tx netdev_tx_t; + #endif #define MAX_ADDR_LEN 32 /* Largest hardware address length */ -/* Driver transmit return codes */ -#define NETDEV_TX_OK 0 /* driver took care of packet */ -#define NETDEV_TX_BUSY 1 /* driver tx path was busy*/ -#define NETDEV_TX_LOCKED -1 /* driver tx lock was already taken */ - #ifdef __KERNEL__ - /* * Compute the worst case header length according to the protocols * used. @@ -209,6 +212,24 @@ struct dev_addr_list #define dmi_users da_users #define dmi_gusers da_gusers +struct netdev_hw_addr { + struct list_head list; + unsigned char addr[MAX_ADDR_LEN]; + unsigned char type; +#define NETDEV_HW_ADDR_T_LAN 1 +#define NETDEV_HW_ADDR_T_SAN 2 +#define NETDEV_HW_ADDR_T_SLAVE 3 +#define NETDEV_HW_ADDR_T_UNICAST 4 + int refcount; + bool synced; + struct rcu_head rcu_head; +}; + +struct netdev_hw_addr_list { + struct list_head list; + int count; +}; + struct hh_cache { struct hh_cache *hh_next; /* Next entry */ @@ -441,6 +462,10 @@ struct netdev_queue { spinlock_t _xmit_lock; int xmit_lock_owner; struct Qdisc *qdisc_sleeping; + /* + * please use this field instead of dev->trans_start + */ + unsigned long trans_start; } ____cacheline_aligned_in_smp; @@ -467,9 +492,11 @@ struct netdev_queue { * This function is called when network device transistions to the down * state. * - * int (*ndo_start_xmit)(struct sk_buff *skb, struct net_device *dev); + * netdev_tx_t (*ndo_start_xmit)(struct sk_buff *skb, + * struct net_device *dev); * Called when a packet needs to be transmitted. - * Must return NETDEV_TX_OK , NETDEV_TX_BUSY, or NETDEV_TX_LOCKED, + * Must return NETDEV_TX_OK , NETDEV_TX_BUSY. + * (can also return NETDEV_TX_LOCKED iff NETIF_F_LLTX) * Required can not be NULL. * * u16 (*ndo_select_queue)(struct net_device *dev, struct sk_buff *skb); @@ -540,7 +567,7 @@ struct net_device_ops { void (*ndo_uninit)(struct net_device *dev); int (*ndo_open)(struct net_device *dev); int (*ndo_stop)(struct net_device *dev); - int (*ndo_start_xmit) (struct sk_buff *skb, + netdev_tx_t (*ndo_start_xmit) (struct sk_buff *skb, struct net_device *dev); u16 (*ndo_select_queue)(struct net_device *dev, struct sk_buff *skb); @@ -724,10 +751,10 @@ struct net_device unsigned char addr_len; /* hardware address length */ unsigned short dev_id; /* for shared network cards */ - spinlock_t addr_list_lock; - struct dev_addr_list *uc_list; /* Secondary unicast mac addresses */ - int uc_count; /* Number of installed ucasts */ + struct netdev_hw_addr_list uc; /* Secondary unicast + mac addresses */ int uc_promisc; + spinlock_t addr_list_lock; struct dev_addr_list *mc_list; /* Multicast mac addresses */ int mc_count; /* Number of installed mcasts */ unsigned int promiscuity; @@ -753,8 +780,12 @@ struct net_device */ unsigned long last_rx; /* Time of last Rx */ /* Interface address info used in eth_type_trans() */ - unsigned char dev_addr[MAX_ADDR_LEN]; /* hw address, (before bcast - because most packets are unicast) */ + unsigned char *dev_addr; /* hw address, (before bcast + because most packets are + unicast) */ + + struct netdev_hw_addr_list dev_addrs; /* list of device + hw addresses */ unsigned char broadcast[MAX_ADDR_LEN]; /* hw bcast add */ @@ -774,6 +805,11 @@ struct net_device * One part is mostly used on xmit path (device) */ /* These may be needed for future network-power-down code. */ + + /* + * trans_start here is expensive for high speed devices on SMP, + * please use netdev_queue->trans_start instead. + */ unsigned long trans_start; /* Time (in jiffies) of last Tx */ int watchdog_timeo; /* used by dev_watchdog() */ @@ -1450,6 +1486,8 @@ static inline int netif_carrier_ok(const struct net_device *dev) return !test_bit(__LINK_STATE_NOCARRIER, &dev->state); } +extern unsigned long dev_trans_start(struct net_device *dev); + extern void __netdev_watchdog_up(struct net_device *dev); extern void netif_carrier_on(struct net_device *dev); @@ -1764,6 +1802,13 @@ static inline void netif_addr_unlock_bh(struct net_device *dev) spin_unlock_bh(&dev->addr_list_lock); } +/* + * dev_addrs walker. Should be used only for read access. Call with + * rcu_read_lock held. + */ +#define for_each_dev_addr(dev, ha) \ + list_for_each_entry_rcu(ha, &dev->dev_addrs.list, list) + /* These functions live elsewhere (drivers/net/net_init.c, but related) */ extern void ether_setup(struct net_device *dev); @@ -1776,11 +1821,24 @@ extern struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name, alloc_netdev_mq(sizeof_priv, name, setup, 1) extern int register_netdev(struct net_device *dev); extern void unregister_netdev(struct net_device *dev); + +/* Functions used for device addresses handling */ +extern int dev_addr_add(struct net_device *dev, unsigned char *addr, + unsigned char addr_type); +extern int dev_addr_del(struct net_device *dev, unsigned char *addr, + unsigned char addr_type); +extern int dev_addr_add_multiple(struct net_device *to_dev, + struct net_device *from_dev, + unsigned char addr_type); +extern int dev_addr_del_multiple(struct net_device *to_dev, + struct net_device *from_dev, + unsigned char addr_type); + /* Functions used for secondary unicast and multicast support */ extern void dev_set_rx_mode(struct net_device *dev); extern void __dev_set_rx_mode(struct net_device *dev); -extern int dev_unicast_delete(struct net_device *dev, void *addr, int alen); -extern int dev_unicast_add(struct net_device *dev, void *addr, int alen); +extern int dev_unicast_delete(struct net_device *dev, void *addr); +extern int dev_unicast_add(struct net_device *dev, void *addr); extern int dev_unicast_sync(struct net_device *to, struct net_device *from); extern void dev_unicast_unsync(struct net_device *to, struct net_device *from); extern int dev_mc_delete(struct net_device *dev, void *addr, int alen, int all); diff --git a/libdde-linux26/contrib/include/linux/pci.h b/libdde-linux26/contrib/include/linux/pci.h index 7bd624b..c7fb660 100644 --- a/libdde-linux26/contrib/include/linux/pci.h +++ b/libdde-linux26/contrib/include/linux/pci.h @@ -256,6 +256,7 @@ struct pci_dev { unsigned int ari_enabled:1; /* ARI forwarding */ unsigned int is_managed:1; unsigned int is_pcie:1; + unsigned int needs_freset:1; /* Dev requires fundamental reset */ unsigned int state_saved:1; pci_dev_flags_t dev_flags; atomic_t enable_cnt; /* pci_enable_device has been called */ diff --git a/libdde-linux26/contrib/include/linux/pci_ids.h b/libdde-linux26/contrib/include/linux/pci_ids.h index aca8c45..a339386 100644 --- a/libdde-linux26/contrib/include/linux/pci_ids.h +++ b/libdde-linux26/contrib/include/linux/pci_ids.h @@ -2,6 +2,9 @@ * PCI Class, Vendor and Device IDs * * Please keep sorted. + * + * Do not add new entries to this file unless the definitions + * are shared between multiple drivers. */ /* Device classes and subclasses */ @@ -104,6 +107,7 @@ #define PCI_CLASS_SERIAL_USB_UHCI 0x0c0300 #define PCI_CLASS_SERIAL_USB_OHCI 0x0c0310 #define PCI_CLASS_SERIAL_USB_EHCI 0x0c0320 +#define PCI_CLASS_SERIAL_USB_XHCI 0x0c0330 #define PCI_CLASS_SERIAL_FIBER 0x0c04 #define PCI_CLASS_SERIAL_SMBUS 0x0c05 @@ -389,6 +393,9 @@ #define PCI_DEVICE_ID_VLSI_82C147 0x0105 #define PCI_DEVICE_ID_VLSI_VAS96011 0x0702 +/* AMD RD890 Chipset */ +#define PCI_DEVICE_ID_RD890_IOMMU 0x5a23 + #define PCI_VENDOR_ID_ADL 0x1005 #define PCI_DEVICE_ID_ADL_2301 0x2301 @@ -478,6 +485,9 @@ #define PCI_DEVICE_ID_IBM_ICOM_V2_ONE_PORT_RVX_ONE_PORT_MDM_PCIE 0x0361 #define PCI_DEVICE_ID_IBM_ICOM_FOUR_PORT_MODEL 0x252 +#define PCI_SUBVENDOR_ID_IBM 0x1014 +#define PCI_SUBDEVICE_ID_IBM_SATURN_SERIAL_ONE_PORT 0x03d4 + #define PCI_VENDOR_ID_UNISYS 0x1018 #define PCI_DEVICE_ID_UNISYS_DMA_DIRECTOR 0x001C @@ -526,6 +536,7 @@ #define PCI_DEVICE_ID_AMD_OPUS_7443 0x7443 #define PCI_DEVICE_ID_AMD_VIPER_7443 0x7443 #define PCI_DEVICE_ID_AMD_OPUS_7445 0x7445 +#define PCI_DEVICE_ID_AMD_8111_PCI 0x7460 #define PCI_DEVICE_ID_AMD_8111_LPC 0x7468 #define PCI_DEVICE_ID_AMD_8111_IDE 0x7469 #define PCI_DEVICE_ID_AMD_8111_SMBUS2 0x746a @@ -535,6 +546,8 @@ #define PCI_DEVICE_ID_AMD_8131_BRIDGE 0x7450 #define PCI_DEVICE_ID_AMD_8131_APIC 0x7451 #define PCI_DEVICE_ID_AMD_8132_BRIDGE 0x7458 +#define PCI_DEVICE_ID_AMD_HUDSON2_SMBUS 0x780b +#define PCI_DEVICE_ID_AMD_CS5535_IDE 0x208F #define PCI_DEVICE_ID_AMD_CS5536_ISA 0x2090 #define PCI_DEVICE_ID_AMD_CS5536_FLASH 0x2091 #define PCI_DEVICE_ID_AMD_CS5536_AUDIO 0x2093 @@ -543,9 +556,10 @@ #define PCI_DEVICE_ID_AMD_CS5536_UDC 0x2096 #define PCI_DEVICE_ID_AMD_CS5536_UOC 0x2097 #define PCI_DEVICE_ID_AMD_CS5536_IDE 0x209A - #define PCI_DEVICE_ID_AMD_LX_VIDEO 0x2081 #define PCI_DEVICE_ID_AMD_LX_AES 0x2082 +#define PCI_DEVICE_ID_AMD_HUDSON2_IDE 0x780c +#define PCI_DEVICE_ID_AMD_HUDSON2_SATA_IDE 0x7800 #define PCI_VENDOR_ID_TRIDENT 0x1023 #define PCI_DEVICE_ID_TRIDENT_4DWAVE_DX 0x2000 @@ -591,6 +605,8 @@ #define PCI_DEVICE_ID_MATROX_G550 0x2527 #define PCI_DEVICE_ID_MATROX_VIA 0x4536 +#define PCI_VENDOR_ID_MOBILITY_ELECTRONICS 0x14f2 + #define PCI_VENDOR_ID_CT 0x102c #define PCI_DEVICE_ID_CT_69000 0x00c0 #define PCI_DEVICE_ID_CT_65545 0x00d8 @@ -766,6 +782,7 @@ #define PCI_DEVICE_ID_TI_X515 0x8036 #define PCI_DEVICE_ID_TI_XX12 0x8039 #define PCI_DEVICE_ID_TI_XX12_FM 0x803b +#define PCI_DEVICE_ID_TI_XIO2000A 0x8231 #define PCI_DEVICE_ID_TI_1130 0xac12 #define PCI_DEVICE_ID_TI_1031 0xac13 #define PCI_DEVICE_ID_TI_1131 0xac15 @@ -834,6 +851,8 @@ #define PCI_DEVICE_ID_PROMISE_20276 0x5275 #define PCI_DEVICE_ID_PROMISE_20277 0x7275 +#define PCI_VENDOR_ID_FOXCONN 0x105b + #define PCI_VENDOR_ID_UMC 0x1060 #define PCI_DEVICE_ID_UMC_UM8673F 0x0101 #define PCI_DEVICE_ID_UMC_UM8886BF 0x673a @@ -873,6 +892,7 @@ #define PCI_DEVICE_ID_APPLE_SH_SUNGEM 0x0051 #define PCI_DEVICE_ID_APPLE_U3L_AGP 0x0058 #define PCI_DEVICE_ID_APPLE_U3H_AGP 0x0059 +#define PCI_DEVICE_ID_APPLE_U4_PCIE 0x005b #define PCI_DEVICE_ID_APPLE_IPID2_AGP 0x0066 #define PCI_DEVICE_ID_APPLE_IPID2_ATA 0x0069 #define PCI_DEVICE_ID_APPLE_IPID2_FW 0x006a @@ -941,6 +961,32 @@ #define PCI_DEVICE_ID_SUN_TOMATILLO 0xa801 #define PCI_DEVICE_ID_SUN_CASSINI 0xabba +#define PCI_VENDOR_ID_NI 0x1093 +#define PCI_DEVICE_ID_NI_PCI2322 0xd130 +#define PCI_DEVICE_ID_NI_PCI2324 0xd140 +#define PCI_DEVICE_ID_NI_PCI2328 0xd150 +#define PCI_DEVICE_ID_NI_PXI8422_2322 0xd190 +#define PCI_DEVICE_ID_NI_PXI8422_2324 0xd1a0 +#define PCI_DEVICE_ID_NI_PXI8420_2322 0xd1d0 +#define PCI_DEVICE_ID_NI_PXI8420_2324 0xd1e0 +#define PCI_DEVICE_ID_NI_PXI8420_2328 0xd1f0 +#define PCI_DEVICE_ID_NI_PXI8420_23216 0xd1f1 +#define PCI_DEVICE_ID_NI_PCI2322I 0xd250 +#define PCI_DEVICE_ID_NI_PCI2324I 0xd270 +#define PCI_DEVICE_ID_NI_PCI23216 0xd2b0 +#define PCI_DEVICE_ID_NI_PXI8430_2322 0x7080 +#define PCI_DEVICE_ID_NI_PCI8430_2322 0x70db +#define PCI_DEVICE_ID_NI_PXI8430_2324 0x70dd +#define PCI_DEVICE_ID_NI_PCI8430_2324 0x70df +#define PCI_DEVICE_ID_NI_PXI8430_2328 0x70e2 +#define PCI_DEVICE_ID_NI_PCI8430_2328 0x70e4 +#define PCI_DEVICE_ID_NI_PXI8430_23216 0x70e6 +#define PCI_DEVICE_ID_NI_PCI8430_23216 0x70e7 +#define PCI_DEVICE_ID_NI_PXI8432_2322 0x70e8 +#define PCI_DEVICE_ID_NI_PCI8432_2322 0x70ea +#define PCI_DEVICE_ID_NI_PXI8432_2324 0x70ec +#define PCI_DEVICE_ID_NI_PCI8432_2324 0x70ee + #define PCI_VENDOR_ID_CMD 0x1095 #define PCI_DEVICE_ID_CMD_643 0x0643 #define PCI_DEVICE_ID_CMD_646 0x0646 @@ -976,6 +1022,7 @@ #define PCI_DEVICE_ID_PLX_PCI200SYN 0x3196 #define PCI_DEVICE_ID_PLX_9030 0x9030 #define PCI_DEVICE_ID_PLX_9050 0x9050 +#define PCI_DEVICE_ID_PLX_9056 0x9056 #define PCI_DEVICE_ID_PLX_9080 0x9080 #define PCI_DEVICE_ID_PLX_GTEK_SERIAL2 0xa001 @@ -1037,8 +1084,6 @@ #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SMBUS 0x0034 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE 0x0035 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA 0x0036 -#define PCI_DEVICE_ID_NVIDIA_NVENET_10 0x0037 -#define PCI_DEVICE_ID_NVIDIA_NVENET_11 0x0038 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA2 0x003e #define PCI_DEVICE_ID_NVIDIA_GEFORCE_6800_ULTRA 0x0040 #define PCI_DEVICE_ID_NVIDIA_GEFORCE_6800 0x0041 @@ -1049,21 +1094,16 @@ #define PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_IDE 0x0053 #define PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_SATA 0x0054 #define PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_SATA2 0x0055 -#define PCI_DEVICE_ID_NVIDIA_NVENET_8 0x0056 -#define PCI_DEVICE_ID_NVIDIA_NVENET_9 0x0057 #define PCI_DEVICE_ID_NVIDIA_CK804_AUDIO 0x0059 #define PCI_DEVICE_ID_NVIDIA_CK804_PCIE 0x005d #define PCI_DEVICE_ID_NVIDIA_NFORCE2_SMBUS 0x0064 #define PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE 0x0065 -#define PCI_DEVICE_ID_NVIDIA_NVENET_2 0x0066 #define PCI_DEVICE_ID_NVIDIA_MCP2_MODEM 0x0069 #define PCI_DEVICE_ID_NVIDIA_MCP2_AUDIO 0x006a #define PCI_DEVICE_ID_NVIDIA_NFORCE2S_SMBUS 0x0084 #define PCI_DEVICE_ID_NVIDIA_NFORCE2S_IDE 0x0085 -#define PCI_DEVICE_ID_NVIDIA_NVENET_4 0x0086 #define PCI_DEVICE_ID_NVIDIA_MCP2S_MODEM 0x0089 #define PCI_DEVICE_ID_NVIDIA_CK8_AUDIO 0x008a -#define PCI_DEVICE_ID_NVIDIA_NVENET_5 0x008c #define PCI_DEVICE_ID_NVIDIA_NFORCE2S_SATA 0x008e #define PCI_DEVICE_ID_NVIDIA_GEFORCE_7800_GT 0x0090 #define PCI_DEVICE_ID_NVIDIA_GEFORCE_7800_GTX 0x0091 @@ -1079,15 +1119,12 @@ #define PCI_DEVICE_ID_NVIDIA_NFORCE3 0x00d1 #define PCI_DEVICE_ID_NVIDIA_NFORCE3_SMBUS 0x00d4 #define PCI_DEVICE_ID_NVIDIA_NFORCE3_IDE 0x00d5 -#define PCI_DEVICE_ID_NVIDIA_NVENET_3 0x00d6 #define PCI_DEVICE_ID_NVIDIA_MCP3_MODEM 0x00d9 #define PCI_DEVICE_ID_NVIDIA_MCP3_AUDIO 0x00da -#define PCI_DEVICE_ID_NVIDIA_NVENET_7 0x00df #define PCI_DEVICE_ID_NVIDIA_NFORCE3S 0x00e1 #define PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA 0x00e3 #define PCI_DEVICE_ID_NVIDIA_NFORCE3S_SMBUS 0x00e4 #define PCI_DEVICE_ID_NVIDIA_NFORCE3S_IDE 0x00e5 -#define PCI_DEVICE_ID_NVIDIA_NVENET_6 0x00e6 #define PCI_DEVICE_ID_NVIDIA_CK8S_AUDIO 0x00ea #define PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA2 0x00ee #define PCIE_DEVICE_ID_NVIDIA_GEFORCE_6800_ALT1 0x00f0 @@ -1147,7 +1184,6 @@ #define PCI_DEVICE_ID_NVIDIA_NFORCE_SMBUS 0x01b4 #define PCI_DEVICE_ID_NVIDIA_NFORCE_IDE 0x01bc #define PCI_DEVICE_ID_NVIDIA_MCP1_MODEM 0x01c1 -#define PCI_DEVICE_ID_NVIDIA_NVENET_1 0x01c3 #define PCI_DEVICE_ID_NVIDIA_NFORCE2 0x01e0 #define PCI_DEVICE_ID_NVIDIA_GEFORCE3 0x0200 #define PCI_DEVICE_ID_NVIDIA_GEFORCE3_1 0x0201 @@ -1170,8 +1206,6 @@ #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE 0x036E #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA 0x037E #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA2 0x037F -#define PCI_DEVICE_ID_NVIDIA_NVENET_12 0x0268 -#define PCI_DEVICE_ID_NVIDIA_NVENET_13 0x0269 #define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800 0x0280 #define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800_8X 0x0281 #define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800SE 0x0282 @@ -1218,42 +1252,22 @@ #define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5700_2 0x0348 #define PCI_DEVICE_ID_NVIDIA_QUADRO_FX_GO1000 0x034C #define PCI_DEVICE_ID_NVIDIA_QUADRO_FX_1100 0x034E -#define PCI_DEVICE_ID_NVIDIA_NVENET_14 0x0372 #define PCI_DEVICE_ID_NVIDIA_NVENET_15 0x0373 -#define PCI_DEVICE_ID_NVIDIA_NVENET_16 0x03E5 -#define PCI_DEVICE_ID_NVIDIA_NVENET_17 0x03E6 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA 0x03E7 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SMBUS 0x03EB #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE 0x03EC -#define PCI_DEVICE_ID_NVIDIA_NVENET_18 0x03EE -#define PCI_DEVICE_ID_NVIDIA_NVENET_19 0x03EF #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA2 0x03F6 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA3 0x03F7 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_SMBUS 0x0446 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_IDE 0x0448 -#define PCI_DEVICE_ID_NVIDIA_NVENET_20 0x0450 -#define PCI_DEVICE_ID_NVIDIA_NVENET_21 0x0451 -#define PCI_DEVICE_ID_NVIDIA_NVENET_22 0x0452 -#define PCI_DEVICE_ID_NVIDIA_NVENET_23 0x0453 -#define PCI_DEVICE_ID_NVIDIA_NVENET_24 0x054C -#define PCI_DEVICE_ID_NVIDIA_NVENET_25 0x054D -#define PCI_DEVICE_ID_NVIDIA_NVENET_26 0x054E -#define PCI_DEVICE_ID_NVIDIA_NVENET_27 0x054F -#define PCI_DEVICE_ID_NVIDIA_NVENET_28 0x07DC -#define PCI_DEVICE_ID_NVIDIA_NVENET_29 0x07DD -#define PCI_DEVICE_ID_NVIDIA_NVENET_30 0x07DE -#define PCI_DEVICE_ID_NVIDIA_NVENET_31 0x07DF +#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_SMBUS 0x0542 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_IDE 0x0560 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP73_IDE 0x056C +#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP78S_SMBUS 0x0752 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP77_IDE 0x0759 -#define PCI_DEVICE_ID_NVIDIA_NVENET_32 0x0760 -#define PCI_DEVICE_ID_NVIDIA_NVENET_33 0x0761 -#define PCI_DEVICE_ID_NVIDIA_NVENET_34 0x0762 -#define PCI_DEVICE_ID_NVIDIA_NVENET_35 0x0763 -#define PCI_DEVICE_ID_NVIDIA_NVENET_36 0x0AB0 -#define PCI_DEVICE_ID_NVIDIA_NVENET_37 0x0AB1 -#define PCI_DEVICE_ID_NVIDIA_NVENET_38 0x0AB2 -#define PCI_DEVICE_ID_NVIDIA_NVENET_39 0x0AB3 +#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP73_SMBUS 0x07D8 +#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP79_SMBUS 0x0AA2 +#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP89_SATA 0x0D85 #define PCI_VENDOR_ID_IMS 0x10e0 #define PCI_DEVICE_ID_IMS_TT128 0x9128 @@ -1281,6 +1295,13 @@ #define PCI_VENDOR_ID_CREATIVE 0x1102 /* duplicate: ECTIVA */ #define PCI_DEVICE_ID_CREATIVE_EMU10K1 0x0002 +#define PCI_DEVICE_ID_CREATIVE_20K1 0x0005 +#define PCI_DEVICE_ID_CREATIVE_20K2 0x000b +#define PCI_SUBDEVICE_ID_CREATIVE_SB0760 0x0024 +#define PCI_SUBDEVICE_ID_CREATIVE_SB08801 0x0041 +#define PCI_SUBDEVICE_ID_CREATIVE_SB08802 0x0042 +#define PCI_SUBDEVICE_ID_CREATIVE_SB08803 0x0043 +#define PCI_SUBDEVICE_ID_CREATIVE_HENDRIX 0x6000 #define PCI_VENDOR_ID_ECTIVA 0x1102 /* duplicate: CREATIVE */ #define PCI_DEVICE_ID_ECTIVA_EV1938 0x8938 @@ -1373,7 +1394,7 @@ #define PCI_DEVICE_ID_VIA_82C598_1 0x8598 #define PCI_DEVICE_ID_VIA_838X_1 0xB188 #define PCI_DEVICE_ID_VIA_83_87XX_1 0xB198 -#define PCI_DEVICE_ID_VIA_C409_IDE 0XC409 +#define PCI_DEVICE_ID_VIA_VX855_IDE 0xC409 #define PCI_DEVICE_ID_VIA_ANON 0xFFFF #define PCI_VENDOR_ID_SIEMENS 0x110A @@ -1473,6 +1494,7 @@ #define PCI_DEVICE_ID_SERVERWORKS_HT1000IDE 0x0214 #define PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2 0x0217 #define PCI_DEVICE_ID_SERVERWORKS_CSB6LPC 0x0227 +#define PCI_DEVICE_ID_SERVERWORKS_HT1100LD 0x0408 #define PCI_VENDOR_ID_SBE 0x1176 #define PCI_DEVICE_ID_SBE_WANXL100 0x0301 @@ -1516,6 +1538,8 @@ #define PCI_DEVICE_ID_ARTOP_ATP860R 0x0007 #define PCI_DEVICE_ID_ARTOP_ATP865 0x0008 #define PCI_DEVICE_ID_ARTOP_ATP865R 0x0009 +#define PCI_DEVICE_ID_ARTOP_ATP867A 0x000A +#define PCI_DEVICE_ID_ARTOP_ATP867B 0x000B #define PCI_DEVICE_ID_ARTOP_AEC7610 0x8002 #define PCI_DEVICE_ID_ARTOP_AEC7612UW 0x8010 #define PCI_DEVICE_ID_ARTOP_AEC7612U 0x8020 @@ -1813,6 +1837,10 @@ #define PCI_SUBDEVICE_ID_HYPERCOPE_METRO 0x0107 #define PCI_SUBDEVICE_ID_HYPERCOPE_CHAMP2 0x0108 +#define PCI_VENDOR_ID_DIGIGRAM 0x1369 +#define PCI_SUBDEVICE_ID_DIGIGRAM_LX6464ES_SERIAL_SUBSYSTEM 0xc001 +#define PCI_SUBDEVICE_ID_DIGIGRAM_LX6464ES_CAE_SERIAL_SUBSYSTEM 0xc002 + #define PCI_VENDOR_ID_KAWASAKI 0x136b #define PCI_DEVICE_ID_MCHIP_KL5A72002 0xff01 @@ -1880,6 +1908,8 @@ #define PCI_SUBDEVICE_ID_CCD_SWYX4S 0xB540 #define PCI_SUBDEVICE_ID_CCD_JH4S20 0xB550 #define PCI_SUBDEVICE_ID_CCD_IOB8ST_1 0xB552 +#define PCI_SUBDEVICE_ID_CCD_JHSE1 0xB553 +#define PCI_SUBDEVICE_ID_CCD_JH8S 0xB55B #define PCI_SUBDEVICE_ID_CCD_BN4S 0xB560 #define PCI_SUBDEVICE_ID_CCD_BN8S 0xB562 #define PCI_SUBDEVICE_ID_CCD_BNE1 0xB563 @@ -1932,6 +1962,8 @@ #define PCI_DEVICE_ID_LAVA_DSERIAL 0x0100 /* 2x 16550 */ #define PCI_DEVICE_ID_LAVA_QUATRO_A 0x0101 /* 2x 16550, half of 4 port */ #define PCI_DEVICE_ID_LAVA_QUATRO_B 0x0102 /* 2x 16550, half of 4 port */ +#define PCI_DEVICE_ID_LAVA_QUATTRO_A 0x0120 /* 2x 16550A, half of 4 port */ +#define PCI_DEVICE_ID_LAVA_QUATTRO_B 0x0121 /* 2x 16550A, half of 4 port */ #define PCI_DEVICE_ID_LAVA_OCTO_A 0x0180 /* 4x 16550A, half of 8 port */ #define PCI_DEVICE_ID_LAVA_OCTO_B 0x0181 /* 4x 16550A, half of 8 port */ #define PCI_DEVICE_ID_LAVA_PORT_PLUS 0x0200 /* 2x 16650 */ @@ -1962,15 +1994,21 @@ #define PCI_DEVICE_ID_OXSEMI_PCIe952_1_U 0xC118 #define PCI_DEVICE_ID_OXSEMI_PCIe952_1_GU 0xC11C #define PCI_DEVICE_ID_OXSEMI_16PCI954 0x9501 +#define PCI_DEVICE_ID_OXSEMI_C950 0x950B #define PCI_DEVICE_ID_OXSEMI_16PCI95N 0x9511 #define PCI_DEVICE_ID_OXSEMI_16PCI954PP 0x9513 #define PCI_DEVICE_ID_OXSEMI_16PCI952 0x9521 #define PCI_DEVICE_ID_OXSEMI_16PCI952PP 0x9523 +#define PCI_SUBDEVICE_ID_OXSEMI_C950 0x0001 #define PCI_VENDOR_ID_CHELSIO 0x1425 #define PCI_VENDOR_ID_SAMSUNG 0x144d +#define PCI_VENDOR_ID_GIGABYTE 0x1458 + +#define PCI_VENDOR_ID_AMBIT 0x1468 + #define PCI_VENDOR_ID_MYRICOM 0x14c1 #define PCI_VENDOR_ID_TITAN 0x14D2 @@ -1998,6 +2036,7 @@ #define PCI_DEVICE_ID_AFAVLAB_P030 0x2182 #define PCI_SUBDEVICE_ID_AFAVLAB_P061 0x2150 +#define PCI_VENDOR_ID_BCM_GVC 0x14a4 #define PCI_VENDOR_ID_BROADCOM 0x14e4 #define PCI_DEVICE_ID_TIGON3_5752 0x1600 #define PCI_DEVICE_ID_TIGON3_5752M 0x1601 @@ -2047,7 +2086,6 @@ #define PCI_DEVICE_ID_TIGON3_5787M 0x1693 #define PCI_DEVICE_ID_TIGON3_5782 0x1696 #define PCI_DEVICE_ID_TIGON3_5784 0x1698 -#define PCI_DEVICE_ID_TIGON3_5785 0x1699 #define PCI_DEVICE_ID_TIGON3_5786 0x169a #define PCI_DEVICE_ID_TIGON3_5787 0x169b #define PCI_DEVICE_ID_TIGON3_5788 0x169c @@ -2077,6 +2115,7 @@ #define PCI_VENDOR_ID_MAINPINE 0x1522 #define PCI_DEVICE_ID_MAINPINE_PBRIDGE 0x0100 #define PCI_VENDOR_ID_ENE 0x1524 +#define PCI_DEVICE_ID_ENE_CB710_FLASH 0x0510 #define PCI_DEVICE_ID_ENE_CB712_SD 0x0550 #define PCI_DEVICE_ID_ENE_CB712_SD_2 0x0551 #define PCI_DEVICE_ID_ENE_CB714_SD 0x0750 @@ -2112,6 +2151,8 @@ #define PCI_DEVICE_ID_MELLANOX_SINAI_OLD 0x5e8c #define PCI_DEVICE_ID_MELLANOX_SINAI 0x6274 +#define PCI_VENDOR_ID_DFI 0x15bd + #define PCI_VENDOR_ID_QUICKNET 0x15e2 #define PCI_DEVICE_ID_QUICKNET_XJ 0x0500 @@ -2131,6 +2172,10 @@ #define PCI_DEVICE_ID_ADDIDATA_APCI7420_3 0x700D #define PCI_DEVICE_ID_ADDIDATA_APCI7300_3 0x700E #define PCI_DEVICE_ID_ADDIDATA_APCI7800_3 0x700F +#define PCI_DEVICE_ID_ADDIDATA_APCIe7300 0x7010 +#define PCI_DEVICE_ID_ADDIDATA_APCIe7420 0x7011 +#define PCI_DEVICE_ID_ADDIDATA_APCIe7500 0x7012 +#define PCI_DEVICE_ID_ADDIDATA_APCIe7800 0x7013 #define PCI_VENDOR_ID_PDC 0x15e9 @@ -2215,10 +2260,20 @@ #define PCI_VENDOR_ID_TOPSPIN 0x1867 +#define PCI_VENDOR_ID_SILAN 0x1904 + #define PCI_VENDOR_ID_TDI 0x192E #define PCI_DEVICE_ID_TDI_EHCI 0x0101 #define PCI_VENDOR_ID_FREESCALE 0x1957 +#define PCI_DEVICE_ID_MPC8315E 0x00b4 +#define PCI_DEVICE_ID_MPC8315 0x00b5 +#define PCI_DEVICE_ID_MPC8314E 0x00b6 +#define PCI_DEVICE_ID_MPC8314 0x00b7 +#define PCI_DEVICE_ID_MPC8378E 0x00c4 +#define PCI_DEVICE_ID_MPC8378 0x00c5 +#define PCI_DEVICE_ID_MPC8377E 0x00c6 +#define PCI_DEVICE_ID_MPC8377 0x00c7 #define PCI_DEVICE_ID_MPC8548E 0x0012 #define PCI_DEVICE_ID_MPC8548 0x0013 #define PCI_DEVICE_ID_MPC8543E 0x0014 @@ -2226,6 +2281,8 @@ #define PCI_DEVICE_ID_MPC8547E 0x0018 #define PCI_DEVICE_ID_MPC8545E 0x0019 #define PCI_DEVICE_ID_MPC8545 0x001a +#define PCI_DEVICE_ID_MPC8569E 0x0061 +#define PCI_DEVICE_ID_MPC8569 0x0060 #define PCI_DEVICE_ID_MPC8568E 0x0020 #define PCI_DEVICE_ID_MPC8568 0x0021 #define PCI_DEVICE_ID_MPC8567E 0x0022 @@ -2238,6 +2295,22 @@ #define PCI_DEVICE_ID_MPC8572 0x0041 #define PCI_DEVICE_ID_MPC8536E 0x0050 #define PCI_DEVICE_ID_MPC8536 0x0051 +#define PCI_DEVICE_ID_P2020E 0x0070 +#define PCI_DEVICE_ID_P2020 0x0071 +#define PCI_DEVICE_ID_P2010E 0x0078 +#define PCI_DEVICE_ID_P2010 0x0079 +#define PCI_DEVICE_ID_P1020E 0x0100 +#define PCI_DEVICE_ID_P1020 0x0101 +#define PCI_DEVICE_ID_P1011E 0x0108 +#define PCI_DEVICE_ID_P1011 0x0109 +#define PCI_DEVICE_ID_P1022E 0x0110 +#define PCI_DEVICE_ID_P1022 0x0111 +#define PCI_DEVICE_ID_P1013E 0x0118 +#define PCI_DEVICE_ID_P1013 0x0119 +#define PCI_DEVICE_ID_P4080E 0x0400 +#define PCI_DEVICE_ID_P4080 0x0401 +#define PCI_DEVICE_ID_P4040E 0x0408 +#define PCI_DEVICE_ID_P4040 0x0409 #define PCI_DEVICE_ID_MPC8641 0x7010 #define PCI_DEVICE_ID_MPC8641D 0x7011 #define PCI_DEVICE_ID_MPC8610 0x7018 @@ -2251,6 +2324,7 @@ #define PCI_VENDOR_ID_JMICRON 0x197B #define PCI_DEVICE_ID_JMICRON_JMB360 0x2360 #define PCI_DEVICE_ID_JMICRON_JMB361 0x2361 +#define PCI_DEVICE_ID_JMICRON_JMB362 0x2362 #define PCI_DEVICE_ID_JMICRON_JMB363 0x2363 #define PCI_DEVICE_ID_JMICRON_JMB365 0x2365 #define PCI_DEVICE_ID_JMICRON_JMB366 0x2366 @@ -2263,6 +2337,10 @@ #define PCI_DEVICE_ID_KORENIX_JETCARDF0 0x1600 #define PCI_DEVICE_ID_KORENIX_JETCARDF1 0x16ff +#define PCI_VENDOR_ID_QMI 0x1a32 + +#define PCI_VENDOR_ID_AZWAVE 0x1a3b + #define PCI_VENDOR_ID_TEKRAM 0x1de1 #define PCI_DEVICE_ID_TEKRAM_DC290 0xdc29 @@ -2342,6 +2420,9 @@ #define PCI_DEVICE_ID_INTEL_82840_HB 0x1a21 #define PCI_DEVICE_ID_INTEL_82845_HB 0x1a30 #define PCI_DEVICE_ID_INTEL_IOAT 0x1a38 +#define PCI_DEVICE_ID_INTEL_CPT_SMBUS 0x1c22 +#define PCI_DEVICE_ID_INTEL_CPT_LPC1 0x1c42 +#define PCI_DEVICE_ID_INTEL_CPT_LPC2 0x1c43 #define PCI_DEVICE_ID_INTEL_82801AA_0 0x2410 #define PCI_DEVICE_ID_INTEL_82801AA_1 0x2411 #define PCI_DEVICE_ID_INTEL_82801AA_3 0x2413 @@ -2373,6 +2454,7 @@ #define PCI_DEVICE_ID_INTEL_82801CA_12 0x248c #define PCI_DEVICE_ID_INTEL_82801DB_0 0x24c0 #define PCI_DEVICE_ID_INTEL_82801DB_1 0x24c1 +#define PCI_DEVICE_ID_INTEL_82801DB_2 0x24c2 #define PCI_DEVICE_ID_INTEL_82801DB_3 0x24c3 #define PCI_DEVICE_ID_INTEL_82801DB_5 0x24c5 #define PCI_DEVICE_ID_INTEL_82801DB_6 0x24c6 @@ -2463,6 +2545,8 @@ #define PCI_DEVICE_ID_INTEL_IOAT_TBG3 0x3433 #define PCI_DEVICE_ID_INTEL_82830_HB 0x3575 #define PCI_DEVICE_ID_INTEL_82830_CGC 0x3577 +#define PCI_DEVICE_ID_INTEL_82854_HB 0x358c +#define PCI_DEVICE_ID_INTEL_82854_IG 0x358e #define PCI_DEVICE_ID_INTEL_82855GM_HB 0x3580 #define PCI_DEVICE_ID_INTEL_82855GM_IG 0x3582 #define PCI_DEVICE_ID_INTEL_E7520_MCH 0x3590 @@ -2476,6 +2560,16 @@ #define PCI_DEVICE_ID_INTEL_E7525_MCH 0x359e #define PCI_DEVICE_ID_INTEL_IOAT_CNB 0x360b #define PCI_DEVICE_ID_INTEL_FBD_CNB 0x360c +#define PCI_DEVICE_ID_INTEL_IOAT_JSF0 0x3710 +#define PCI_DEVICE_ID_INTEL_IOAT_JSF1 0x3711 +#define PCI_DEVICE_ID_INTEL_IOAT_JSF2 0x3712 +#define PCI_DEVICE_ID_INTEL_IOAT_JSF3 0x3713 +#define PCI_DEVICE_ID_INTEL_IOAT_JSF4 0x3714 +#define PCI_DEVICE_ID_INTEL_IOAT_JSF5 0x3715 +#define PCI_DEVICE_ID_INTEL_IOAT_JSF6 0x3716 +#define PCI_DEVICE_ID_INTEL_IOAT_JSF7 0x3717 +#define PCI_DEVICE_ID_INTEL_IOAT_JSF8 0x3718 +#define PCI_DEVICE_ID_INTEL_IOAT_JSF9 0x3719 #define PCI_DEVICE_ID_INTEL_ICH10_0 0x3a14 #define PCI_DEVICE_ID_INTEL_ICH10_1 0x3a16 #define PCI_DEVICE_ID_INTEL_ICH10_2 0x3a18 @@ -2606,6 +2700,7 @@ #define PCI_DEVICE_ID_NETMOS_9835 0x9835 #define PCI_DEVICE_ID_NETMOS_9845 0x9845 #define PCI_DEVICE_ID_NETMOS_9855 0x9855 +#define PCI_DEVICE_ID_NETMOS_9901 0x9901 #define PCI_VENDOR_ID_3COM_2 0xa727 diff --git a/libdde-linux26/contrib/include/linux/phy.h b/libdde-linux26/contrib/include/linux/phy.h index d7e54d9..b1368b8 100644 --- a/libdde-linux26/contrib/include/linux/phy.h +++ b/libdde-linux26/contrib/include/linux/phy.h @@ -79,7 +79,7 @@ typedef enum { * Need to be a little smaller than phydev->dev.bus_id to leave room * for the ":%02x" */ -#define MII_BUS_ID_SIZE (BUS_ID_SIZE - 3) +#define MII_BUS_ID_SIZE (20 - 3) /* * The Bus class for PHYs. Devices which provide access to @@ -315,8 +315,7 @@ struct phy_device { /* Interrupt and Polling infrastructure */ struct work_struct phy_queue; - struct work_struct state_queue; - struct timer_list phy_timer; + struct delayed_work state_queue; atomic_t irq_disable; struct mutex lock; @@ -389,6 +388,12 @@ struct phy_driver { /* Enables or disables interrupts */ int (*config_intr)(struct phy_device *phydev); + /* + * Checks if the PHY generated an interrupt. + * For multi-PHY devices with shared PHY interrupt pin + */ + int (*did_interrupt)(struct phy_device *phydev); + /* Clears up any memory if needed */ void (*remove)(struct phy_device *phydev); @@ -402,7 +407,7 @@ struct phy_driver { /* A Structure for boards to register fixups with the PHY Lib */ struct phy_fixup { struct list_head list; - char bus_id[BUS_ID_SIZE]; + char bus_id[20]; u32 phy_uid; u32 phy_uid_mask; int (*run)(struct phy_device *phydev); @@ -439,10 +444,16 @@ static inline int phy_write(struct phy_device *phydev, u16 regnum, u16 val) int get_phy_id(struct mii_bus *bus, int addr, u32 *phy_id); struct phy_device* get_phy_device(struct mii_bus *bus, int addr); +int phy_device_register(struct phy_device *phy); int phy_clear_interrupt(struct phy_device *phydev); int phy_config_interrupt(struct phy_device *phydev, u32 interrupts); +int phy_attach_direct(struct net_device *dev, struct phy_device *phydev, + u32 flags, phy_interface_t interface); struct phy_device * phy_attach(struct net_device *dev, const char *bus_id, u32 flags, phy_interface_t interface); +int phy_connect_direct(struct net_device *dev, struct phy_device *phydev, + void (*handler)(struct net_device *), u32 flags, + phy_interface_t interface); struct phy_device * phy_connect(struct net_device *dev, const char *bus_id, void (*handler)(struct net_device *), u32 flags, phy_interface_t interface); diff --git a/libdde-linux26/contrib/include/linux/skbuff.h b/libdde-linux26/contrib/include/linux/skbuff.h index a9e9534..745f615 100644 --- a/libdde-linux26/contrib/include/linux/skbuff.h +++ b/libdde-linux26/contrib/include/linux/skbuff.h @@ -142,6 +142,9 @@ struct skb_shared_info { atomic_t dataref; unsigned short nr_frags; unsigned short gso_size; +#ifdef CONFIG_HAS_DMA + dma_addr_t dma_head; +#endif /* Warning: this field is not always filled in (UFO)! */ unsigned short gso_segs; unsigned short gso_type; @@ -152,7 +155,7 @@ struct skb_shared_info { struct sk_buff *frag_list; skb_frag_t frags[MAX_SKB_FRAGS]; #ifdef CONFIG_HAS_DMA - dma_addr_t dma_maps[MAX_SKB_FRAGS + 1]; + dma_addr_t dma_maps[MAX_SKB_FRAGS]; #endif }; @@ -1900,6 +1903,21 @@ static inline void skb_copy_queue_mapping(struct sk_buff *to, const struct sk_bu to->queue_mapping = from->queue_mapping; } +static inline void skb_record_rx_queue(struct sk_buff *skb, u16 rx_queue) +{ + skb->queue_mapping = rx_queue + 1; +} + +static inline u16 skb_get_rx_queue(struct sk_buff *skb) +{ + return skb->queue_mapping - 1; +} + +static inline bool skb_rx_queue_recorded(struct sk_buff *skb) +{ + return (skb->queue_mapping != 0); +} + #ifdef CONFIG_XFRM static inline struct sec_path *skb_sec_path(struct sk_buff *skb) { diff --git a/libdde-linux26/contrib/include/linux/tty_driver.h b/libdde-linux26/contrib/include/linux/tty_driver.h index 08e0883..8f359e0 100644 --- a/libdde-linux26/contrib/include/linux/tty_driver.h +++ b/libdde-linux26/contrib/include/linux/tty_driver.h @@ -310,7 +310,7 @@ extern void tty_set_operations(struct tty_driver *driver, extern struct tty_driver *tty_find_polling_driver(char *name, int *line); extern void tty_driver_kref_put(struct tty_driver *driver); -extern inline struct tty_driver *tty_driver_kref_get(struct tty_driver *d) +static inline struct tty_driver *tty_driver_kref_get(struct tty_driver *d) { kref_get(&d->kref); return d; diff --git a/libdde-linux26/contrib/include/linux/workqueue.h b/libdde-linux26/contrib/include/linux/workqueue.h index 3cd51e5..cf24c20 100644 --- a/libdde-linux26/contrib/include/linux/workqueue.h +++ b/libdde-linux26/contrib/include/linux/workqueue.h @@ -41,6 +41,11 @@ struct delayed_work { struct timer_list timer; }; +static inline struct delayed_work *to_delayed_work(struct work_struct *work) +{ + return container_of(work, struct delayed_work, work); +} + struct execute_work { struct work_struct work; }; @@ -89,7 +94,7 @@ struct execute_work { /* * initialize all of a work item in one go * - * NOTE! No point in using "atomic_long_set()": useing a direct + * NOTE! No point in using "atomic_long_set()": using a direct * assignment of the work data initializer allows the compiler * to generate better code. */ @@ -202,6 +207,7 @@ extern int queue_delayed_work_on(int cpu, struct workqueue_struct *wq, extern void flush_workqueue(struct workqueue_struct *wq); extern void flush_scheduled_work(void); +extern void flush_delayed_work(struct delayed_work *work); extern int schedule_work(struct work_struct *work); extern int schedule_work_on(int cpu, struct work_struct *work); @@ -235,6 +241,21 @@ static inline int cancel_delayed_work(struct delayed_work *work) return ret; } +/* + * Like above, but uses del_timer() instead of del_timer_sync(). This means, + * if it returns 0 the timer function may be running and the queueing is in + * progress. + */ +static inline int __cancel_delayed_work(struct delayed_work *work) +{ + int ret; + + ret = del_timer(&work->timer); + if (ret) + work_clear_pending(&work->work); + return ret; +} + extern int cancel_delayed_work_sync(struct delayed_work *work); /* Obsolete. use cancel_delayed_work_sync() */ diff --git a/libdde-linux26/contrib/kernel/rcupdate.c b/libdde-linux26/contrib/kernel/rcupdate.c index cae8a05..c6bfa1a 100644 --- a/libdde-linux26/contrib/kernel/rcupdate.c +++ b/libdde-linux26/contrib/kernel/rcupdate.c @@ -180,6 +180,7 @@ void __init rcu_init(void) { __rcu_init(); } +core_initcall(rcu_init); void rcu_scheduler_starting(void) { diff --git a/libdde-linux26/contrib/lib/kobject.c b/libdde-linux26/contrib/lib/kobject.c index 0487d1f..a1682ef 100644 --- a/libdde-linux26/contrib/lib/kobject.c +++ b/libdde-linux26/contrib/lib/kobject.c @@ -794,7 +794,7 @@ static struct kset *kset_create(const char *name, kset = kzalloc(sizeof(*kset), GFP_KERNEL); if (!kset) return NULL; - kobject_set_name(&kset->kobj, name); + kobject_set_name(&kset->kobj, "%s", name); kset->uevent_ops = uevent_ops; kset->kobj.parent = parent_kobj; diff --git a/libdde-linux26/contrib/net/core/net-sysfs.c b/libdde-linux26/contrib/net/core/net-sysfs.c index 484f587..2da59a0 100644 --- a/libdde-linux26/contrib/net/core/net-sysfs.c +++ b/libdde-linux26/contrib/net/core/net-sysfs.c @@ -498,7 +498,7 @@ int netdev_register_kobject(struct net_device *net) dev->groups = groups; BUILD_BUG_ON(BUS_ID_SIZE < IFNAMSIZ); - dev_set_name(dev, net->name); + dev_set_name(dev, "%s", net->name); #ifdef CONFIG_SYSFS *groups++ = &netstat_group; diff --git a/libdde-linux26/contrib/net/core/skb_dma_map.c b/libdde-linux26/contrib/net/core/skb_dma_map.c index 8623492..07d4ac5 100644 --- a/libdde-linux26/contrib/net/core/skb_dma_map.c +++ b/libdde-linux26/contrib/net/core/skb_dma_map.c @@ -20,7 +20,7 @@ int skb_dma_map(struct device *dev, struct sk_buff *skb, if (dma_mapping_error(dev, map)) goto out_err; - sp->dma_maps[0] = map; + sp->dma_head = map; for (i = 0; i < sp->nr_frags; i++) { skb_frag_t *fp = &sp->frags[i]; @@ -28,7 +28,7 @@ int skb_dma_map(struct device *dev, struct sk_buff *skb, fp->size, dir); if (dma_mapping_error(dev, map)) goto unwind; - sp->dma_maps[i + 1] = map; + sp->dma_maps[i] = map; } sp->num_dma_maps = i + 1; @@ -38,10 +38,10 @@ unwind: while (--i >= 0) { skb_frag_t *fp = &sp->frags[i]; - dma_unmap_page(dev, sp->dma_maps[i + 1], + dma_unmap_page(dev, sp->dma_maps[i], fp->size, dir); } - dma_unmap_single(dev, sp->dma_maps[0], + dma_unmap_single(dev, sp->dma_head, skb_headlen(skb), dir); out_err: return -ENOMEM; @@ -54,12 +54,12 @@ void skb_dma_unmap(struct device *dev, struct sk_buff *skb, struct skb_shared_info *sp = skb_shinfo(skb); int i; - dma_unmap_single(dev, sp->dma_maps[0], + dma_unmap_single(dev, sp->dma_head, skb_headlen(skb), dir); for (i = 0; i < sp->nr_frags; i++) { skb_frag_t *fp = &sp->frags[i]; - dma_unmap_page(dev, sp->dma_maps[i + 1], + dma_unmap_page(dev, sp->dma_maps[i], fp->size, dir); } } diff --git a/libdde-linux26/include/linux/kernel.h b/libdde-linux26/include/linux/kernel.h index 573ed07..6354939 100644 --- a/libdde-linux26/include/linux/kernel.h +++ b/libdde-linux26/include/linux/kernel.h @@ -363,6 +363,8 @@ static inline char *pack_hex_byte(char *buf, u8 byte) printk(KERN_NOTICE pr_fmt(fmt), ##__VA_ARGS__) #define pr_info(fmt, ...) \ printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__) +#define pr_cont(fmt, ...) \ + printk(KERN_CONT fmt, ##__VA_ARGS__) #if defined(DEBUG) #ifndef DDE_LINUX diff --git a/libdde-linux26/lib/src/Makefile b/libdde-linux26/lib/src/Makefile index 4f1ec09..abcc533 100644 --- a/libdde-linux26/lib/src/Makefile +++ b/libdde-linux26/lib/src/Makefile @@ -91,6 +91,8 @@ SRC_C_libdde_linux26.o.a += \ kernel/kthread.c \ kernel/mutex.c \ kernel/notifier.c \ + kernel/rcupdate.c \ + kernel/rcuclassic.c \ kernel/resource.c \ kernel/rwsem.c \ kernel/sched.c \ @@ -106,6 +108,7 @@ SRC_C_libdde_linux26.o.a += \ lib/crc32.c \ lib/ctype.c \ lib/cpumask.c \ + lib/devres.c \ lib/find_next_bit.c \ lib/hexdump.c \ lib/idr.c \ diff --git a/libdde-linux26/lib/src/drivers/base/core.c b/libdde-linux26/lib/src/drivers/base/core.c index e380071..c6363dd 100644 --- a/libdde-linux26/lib/src/drivers/base/core.c +++ b/libdde-linux26/lib/src/drivers/base/core.c @@ -1253,7 +1253,7 @@ struct device *__root_device_register(const char *name, struct module *owner) if (!root) return ERR_PTR(err); - err = dev_set_name(&root->dev, name); + err = dev_set_name(&root->dev, "%s", name); if (err) { kfree(root); return ERR_PTR(err); diff --git a/libdde-linux26/lib/src/net/core/dev.c b/libdde-linux26/lib/src/net/core/dev.c index cf03652..3c3a1d1 100644 --- a/libdde-linux26/lib/src/net/core/dev.c +++ b/libdde-linux26/lib/src/net/core/dev.c @@ -1731,6 +1731,13 @@ static u16 simple_tx_hash(struct net_device *dev, struct sk_buff *skb) simple_tx_hashrnd_initialized = 1; } + if (skb_rx_queue_recorded(skb)) { + u32 val = skb_get_rx_queue(skb); + + hash = jhash_1word(val, simple_tx_hashrnd); + goto out; + } + switch (skb->protocol) { case htons(ETH_P_IP): if (!(ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET))) @@ -1768,6 +1775,7 @@ static u16 simple_tx_hash(struct net_device *dev, struct sk_buff *skb) hash = jhash_3words(addr1, addr2, ports, simple_tx_hashrnd); +out: return (u16) (((u64) hash * dev->real_num_tx_queues) >> 32); } @@ -3377,10 +3385,10 @@ void __dev_set_rx_mode(struct net_device *dev) /* Unicast addresses changes may only happen under the rtnl, * therefore calling __dev_set_promiscuity here is safe. */ - if (dev->uc_count > 0 && !dev->uc_promisc) { + if (dev->uc.count > 0 && !dev->uc_promisc) { __dev_set_promiscuity(dev, 1); dev->uc_promisc = 1; - } else if (dev->uc_count == 0 && dev->uc_promisc) { + } else if (dev->uc.count == 0 && dev->uc_promisc) { __dev_set_promiscuity(dev, -1); dev->uc_promisc = 0; } @@ -3397,6 +3405,316 @@ void dev_set_rx_mode(struct net_device *dev) netif_addr_unlock_bh(dev); } +/* hw addresses list handling functions */ + +static int __hw_addr_add(struct netdev_hw_addr_list *list, unsigned char *addr, + int addr_len, unsigned char addr_type) +{ + struct netdev_hw_addr *ha; + int alloc_size; + + if (addr_len > MAX_ADDR_LEN) + return -EINVAL; + + list_for_each_entry(ha, &list->list, list) { + if (!memcmp(ha->addr, addr, addr_len) && + ha->type == addr_type) { + ha->refcount++; + return 0; + } + } + + + alloc_size = sizeof(*ha); + if (alloc_size < L1_CACHE_BYTES) + alloc_size = L1_CACHE_BYTES; + ha = kmalloc(alloc_size, GFP_ATOMIC); + if (!ha) + return -ENOMEM; + memcpy(ha->addr, addr, addr_len); + ha->type = addr_type; + ha->refcount = 1; + ha->synced = false; + list_add_tail_rcu(&ha->list, &list->list); + list->count++; + return 0; +} + +static void ha_rcu_free(struct rcu_head *head) +{ + struct netdev_hw_addr *ha; + + ha = container_of(head, struct netdev_hw_addr, rcu_head); + kfree(ha); +} + +static int __hw_addr_del(struct netdev_hw_addr_list *list, unsigned char *addr, + int addr_len, unsigned char addr_type) +{ + struct netdev_hw_addr *ha; + + list_for_each_entry(ha, &list->list, list) { + if (!memcmp(ha->addr, addr, addr_len) && + (ha->type == addr_type || !addr_type)) { + if (--ha->refcount) + return 0; + list_del_rcu(&ha->list); + call_rcu(&ha->rcu_head, ha_rcu_free); + list->count--; + return 0; + } + } + return -ENOENT; +} + +static int __hw_addr_add_multiple(struct netdev_hw_addr_list *to_list, + struct netdev_hw_addr_list *from_list, + int addr_len, + unsigned char addr_type) +{ + int err; + struct netdev_hw_addr *ha, *ha2; + unsigned char type; + + list_for_each_entry(ha, &from_list->list, list) { + type = addr_type ? addr_type : ha->type; + err = __hw_addr_add(to_list, ha->addr, addr_len, type); + if (err) + goto unroll; + } + return 0; + +unroll: + list_for_each_entry(ha2, &from_list->list, list) { + if (ha2 == ha) + break; + type = addr_type ? addr_type : ha2->type; + __hw_addr_del(to_list, ha2->addr, addr_len, type); + } + return err; +} + +static void __hw_addr_del_multiple(struct netdev_hw_addr_list *to_list, + struct netdev_hw_addr_list *from_list, + int addr_len, + unsigned char addr_type) +{ + struct netdev_hw_addr *ha; + unsigned char type; + + list_for_each_entry(ha, &from_list->list, list) { + type = addr_type ? addr_type : ha->type; + __hw_addr_del(to_list, ha->addr, addr_len, addr_type); + } +} + +static int __hw_addr_sync(struct netdev_hw_addr_list *to_list, + struct netdev_hw_addr_list *from_list, + int addr_len) +{ + int err = 0; + struct netdev_hw_addr *ha, *tmp; + + list_for_each_entry_safe(ha, tmp, &from_list->list, list) { + if (!ha->synced) { + err = __hw_addr_add(to_list, ha->addr, + addr_len, ha->type); + if (err) + break; + ha->synced = true; + ha->refcount++; + } else if (ha->refcount == 1) { + __hw_addr_del(to_list, ha->addr, addr_len, ha->type); + __hw_addr_del(from_list, ha->addr, addr_len, ha->type); + } + } + return err; +} + +static void __hw_addr_unsync(struct netdev_hw_addr_list *to_list, + struct netdev_hw_addr_list *from_list, + int addr_len) +{ + struct netdev_hw_addr *ha, *tmp; + + list_for_each_entry_safe(ha, tmp, &from_list->list, list) { + if (ha->synced) { + __hw_addr_del(to_list, ha->addr, + addr_len, ha->type); + ha->synced = false; + __hw_addr_del(from_list, ha->addr, + addr_len, ha->type); + } + } +} + +static void __hw_addr_flush(struct netdev_hw_addr_list *list) +{ + struct netdev_hw_addr *ha, *tmp; + + list_for_each_entry_safe(ha, tmp, &list->list, list) { + list_del_rcu(&ha->list); + call_rcu(&ha->rcu_head, ha_rcu_free); + } + list->count = 0; +} + +static void __hw_addr_init(struct netdev_hw_addr_list *list) +{ + INIT_LIST_HEAD(&list->list); + list->count = 0; +} + +/* Device addresses handling functions */ + +static void dev_addr_flush(struct net_device *dev) +{ + /* rtnl_mutex must be held here */ + + __hw_addr_flush(&dev->dev_addrs); + dev->dev_addr = NULL; +} + +static int dev_addr_init(struct net_device *dev) +{ + unsigned char addr[MAX_ADDR_LEN]; + struct netdev_hw_addr *ha; + int err; + + /* rtnl_mutex must be held here */ + + __hw_addr_init(&dev->dev_addrs); + memset(addr, 0, sizeof(addr)); + err = __hw_addr_add(&dev->dev_addrs, addr, sizeof(addr), + NETDEV_HW_ADDR_T_LAN); + if (!err) { + /* + * Get the first (previously created) address from the list + * and set dev_addr pointer to this location. + */ + ha = list_first_entry(&dev->dev_addrs.list, + struct netdev_hw_addr, list); + dev->dev_addr = ha->addr; + } + return err; +} + +/** + * dev_addr_add - Add a device address + * @dev: device + * @addr: address to add + * @addr_type: address type + * + * Add a device address to the device or increase the reference count if + * it already exists. + * + * The caller must hold the rtnl_mutex. + */ +int dev_addr_add(struct net_device *dev, unsigned char *addr, + unsigned char addr_type) +{ + int err; + + ASSERT_RTNL(); + + err = __hw_addr_add(&dev->dev_addrs, addr, dev->addr_len, addr_type); + if (!err) + call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); + return err; +} +EXPORT_SYMBOL(dev_addr_add); + +/** + * dev_addr_del - Release a device address. + * @dev: device + * @addr: address to delete + * @addr_type: address type + * + * Release reference to a device address and remove it from the device + * if the reference count drops to zero. + * + * The caller must hold the rtnl_mutex. + */ +int dev_addr_del(struct net_device *dev, unsigned char *addr, + unsigned char addr_type) +{ + int err; + struct netdev_hw_addr *ha; + + ASSERT_RTNL(); + + /* + * We can not remove the first address from the list because + * dev->dev_addr points to that. + */ + ha = list_first_entry(&dev->dev_addrs.list, + struct netdev_hw_addr, list); + if (ha->addr == dev->dev_addr && ha->refcount == 1) + return -ENOENT; + + err = __hw_addr_del(&dev->dev_addrs, addr, dev->addr_len, + addr_type); + if (!err) + call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); + return err; +} +EXPORT_SYMBOL(dev_addr_del); + +/** + * dev_addr_add_multiple - Add device addresses from another device + * @to_dev: device to which addresses will be added + * @from_dev: device from which addresses will be added + * @addr_type: address type - 0 means type will be used from from_dev + * + * Add device addresses of the one device to another. + ** + * The caller must hold the rtnl_mutex. + */ +int dev_addr_add_multiple(struct net_device *to_dev, + struct net_device *from_dev, + unsigned char addr_type) +{ + int err; + + ASSERT_RTNL(); + + if (from_dev->addr_len != to_dev->addr_len) + return -EINVAL; + err = __hw_addr_add_multiple(&to_dev->dev_addrs, &from_dev->dev_addrs, + to_dev->addr_len, addr_type); + if (!err) + call_netdevice_notifiers(NETDEV_CHANGEADDR, to_dev); + return err; +} +EXPORT_SYMBOL(dev_addr_add_multiple); + +/** + * dev_addr_del_multiple - Delete device addresses by another device + * @to_dev: device where the addresses will be deleted + * @from_dev: device by which addresses the addresses will be deleted + * @addr_type: address type - 0 means type will used from from_dev + * + * Deletes addresses in to device by the list of addresses in from device. + * + * The caller must hold the rtnl_mutex. + */ +int dev_addr_del_multiple(struct net_device *to_dev, + struct net_device *from_dev, + unsigned char addr_type) +{ + ASSERT_RTNL(); + + if (from_dev->addr_len != to_dev->addr_len) + return -EINVAL; + __hw_addr_del_multiple(&to_dev->dev_addrs, &from_dev->dev_addrs, + to_dev->addr_len, addr_type); + call_netdevice_notifiers(NETDEV_CHANGEADDR, to_dev); + return 0; +} +EXPORT_SYMBOL(dev_addr_del_multiple); + +/* multicast addresses handling functions */ + int __dev_addr_delete(struct dev_addr_list **list, int *count, void *addr, int alen, int glbl) { @@ -3459,24 +3777,22 @@ int __dev_addr_add(struct dev_addr_list **list, int *count, * dev_unicast_delete - Release secondary unicast address. * @dev: device * @addr: address to delete - * @alen: length of @addr * * Release reference to a secondary unicast address and remove it * from the device if the reference count drops to zero. * * The caller must hold the rtnl_mutex. */ -int dev_unicast_delete(struct net_device *dev, void *addr, int alen) +int dev_unicast_delete(struct net_device *dev, void *addr) { int err; ASSERT_RTNL(); - netif_addr_lock_bh(dev); - err = __dev_addr_delete(&dev->uc_list, &dev->uc_count, addr, alen, 0); + err = __hw_addr_del(&dev->uc, addr, dev->addr_len, + NETDEV_HW_ADDR_T_UNICAST); if (!err) __dev_set_rx_mode(dev); - netif_addr_unlock_bh(dev); return err; } EXPORT_SYMBOL(dev_unicast_delete); @@ -3485,24 +3801,22 @@ EXPORT_SYMBOL(dev_unicast_delete); * dev_unicast_add - add a secondary unicast address * @dev: device * @addr: address to add - * @alen: length of @addr * * Add a secondary unicast address to the device or increase * the reference count if it already exists. * * The caller must hold the rtnl_mutex. */ -int dev_unicast_add(struct net_device *dev, void *addr, int alen) +int dev_unicast_add(struct net_device *dev, void *addr) { int err; ASSERT_RTNL(); - netif_addr_lock_bh(dev); - err = __dev_addr_add(&dev->uc_list, &dev->uc_count, addr, alen, 0); + err = __hw_addr_add(&dev->uc, addr, dev->addr_len, + NETDEV_HW_ADDR_T_UNICAST); if (!err) __dev_set_rx_mode(dev); - netif_addr_unlock_bh(dev); return err; } EXPORT_SYMBOL(dev_unicast_add); @@ -3559,8 +3873,7 @@ void __dev_addr_unsync(struct dev_addr_list **to, int *to_count, * @from: source device * * Add newly added addresses to the destination device and release - * addresses that have no users left. The source device must be - * locked by netif_addr_lock_bh. + * addresses that have no users left. * * This function is intended to be called from the dev->set_rx_mode * function of layered software devices. @@ -3569,12 +3882,14 @@ int dev_unicast_sync(struct net_device *to, struct net_device *from) { int err = 0; - netif_addr_lock_bh(to); - err = __dev_addr_sync(&to->uc_list, &to->uc_count, - &from->uc_list, &from->uc_count); + ASSERT_RTNL(); + + if (to->addr_len != from->addr_len) + return -EINVAL; + + err = __hw_addr_sync(&to->uc, &from->uc, to->addr_len); if (!err) __dev_set_rx_mode(to); - netif_addr_unlock_bh(to); return err; } EXPORT_SYMBOL(dev_unicast_sync); @@ -3590,18 +3905,31 @@ EXPORT_SYMBOL(dev_unicast_sync); */ void dev_unicast_unsync(struct net_device *to, struct net_device *from) { - netif_addr_lock_bh(from); - netif_addr_lock(to); + ASSERT_RTNL(); - __dev_addr_unsync(&to->uc_list, &to->uc_count, - &from->uc_list, &from->uc_count); - __dev_set_rx_mode(to); + if (to->addr_len != from->addr_len) + return; - netif_addr_unlock(to); - netif_addr_unlock_bh(from); + __hw_addr_unsync(&to->uc, &from->uc, to->addr_len); + __dev_set_rx_mode(to); } EXPORT_SYMBOL(dev_unicast_unsync); +static void dev_unicast_flush(struct net_device *dev) +{ + /* rtnl_mutex must be held here */ + + __hw_addr_flush(&dev->uc); +} + +static void dev_unicast_init(struct net_device *dev) +{ + /* rtnl_mutex must be held here */ + + __hw_addr_init(&dev->uc); +} + + static void __dev_addr_discard(struct dev_addr_list **list) { struct dev_addr_list *tmp; @@ -3620,9 +3948,6 @@ static void dev_addr_discard(struct net_device *dev) { netif_addr_lock_bh(dev); - __dev_addr_discard(&dev->uc_list); - dev->uc_count = 0; - __dev_addr_discard(&dev->mc_list); dev->mc_count = 0; @@ -4213,6 +4538,7 @@ static void rollback_registered(struct net_device *dev) /* * Flush the unicast and multicast chains */ + dev_unicast_flush(dev); dev_addr_discard(dev); if (dev->netdev_ops->ndo_uninit) @@ -4729,6 +5055,8 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name, dev = (struct net_device *) (((long)p + NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST); dev->padded = (char *)dev - (char *)p; + dev_unicast_init(dev); + dev_net_set(dev, &init_net); dev->_tx = tx; @@ -4737,6 +5065,7 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name, dev->gso_max_size = GSO_MAX_SIZE; + dev_addr_init(dev); netdev_init_queues(dev); INIT_LIST_HEAD(&dev->napi_list); @@ -4762,6 +5091,9 @@ void free_netdev(struct net_device *dev) kfree(dev->_tx); + /* Flush device addresses */ + dev_addr_flush(dev); + list_for_each_entry_safe(p, n, &dev->napi_list, dev_list) netif_napi_del(p); @@ -4923,6 +5255,7 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char /* * Flush the unicast and multicast chains */ + dev_unicast_flush(dev); dev_addr_discard(dev); netdev_unregister_kobject(dev); diff --git a/libdde-linux26/lib/src/net/sched/sch_generic.c b/libdde-linux26/lib/src/net/sched/sch_generic.c index a2acd6c..252ac98 100644 --- a/libdde-linux26/lib/src/net/sched/sch_generic.c +++ b/libdde-linux26/lib/src/net/sched/sch_generic.c @@ -200,6 +200,21 @@ void __qdisc_run(struct Qdisc *q) clear_bit(__QDISC_STATE_RUNNING, &q->state); } +unsigned long dev_trans_start(struct net_device *dev) +{ + unsigned long val, res = dev->trans_start; + unsigned int i; + + for (i = 0; i < dev->num_tx_queues; i++) { + val = netdev_get_tx_queue(dev, i)->trans_start; + if (val && time_after(val, res)) + res = val; + } + dev->trans_start = res; + return res; +} +EXPORT_SYMBOL(dev_trans_start); + static void dev_watchdog(unsigned long arg) { struct net_device *dev = (struct net_device *)arg; @@ -209,25 +224,30 @@ static void dev_watchdog(unsigned long arg) if (netif_device_present(dev) && netif_running(dev) && netif_carrier_ok(dev)) { - int some_queue_stopped = 0; + int some_queue_timedout = 0; unsigned int i; + unsigned long trans_start; for (i = 0; i < dev->num_tx_queues; i++) { struct netdev_queue *txq; txq = netdev_get_tx_queue(dev, i); - if (netif_tx_queue_stopped(txq)) { - some_queue_stopped = 1; + /* + * old device drivers set dev->trans_start + */ + trans_start = txq->trans_start ? : dev->trans_start; + if (netif_tx_queue_stopped(txq) && + time_after(jiffies, (trans_start + + dev->watchdog_timeo))) { + some_queue_timedout = 1; break; } } - if (some_queue_stopped && - time_after(jiffies, (dev->trans_start + - dev->watchdog_timeo))) { + if (some_queue_timedout) { char drivername[64]; - WARN_ONCE(1, KERN_INFO "NETDEV WATCHDOG: %s (%s): transmit timed out\n", - dev->name, netdev_drivername(dev, drivername, 64)); + WARN_ONCE(1, KERN_INFO "NETDEV WATCHDOG: %s (%s): transmit queue %u timed out\n", + dev->name, netdev_drivername(dev, drivername, 64), i); dev->netdev_ops->ndo_tx_timeout(dev); } if (!mod_timer(&dev->watchdog_timer, @@ -612,8 +632,10 @@ static void transition_one_qdisc(struct net_device *dev, clear_bit(__QDISC_STATE_DEACTIVATED, &new_qdisc->state); rcu_assign_pointer(dev_queue->qdisc, new_qdisc); - if (need_watchdog_p && new_qdisc != &noqueue_qdisc) + if (need_watchdog_p && new_qdisc != &noqueue_qdisc) { + dev_queue->trans_start = 0; *need_watchdog_p = 1; + } } void dev_activate(struct net_device *dev) diff --git a/libdiskfs/dir-lookup.c b/libdiskfs/dir-lookup.c index f3364cd..75df9b8 100644 --- a/libdiskfs/dir-lookup.c +++ b/libdiskfs/dir-lookup.c @@ -43,7 +43,7 @@ diskfs_S_dir_lookup (struct protid *dircred, char *nextname; char *relpath; int nextnamelen; - error_t error = 0; + error_t err = 0; char *pathbuf = 0; int pathbuflen = 0; int newnamelen; @@ -132,16 +132,16 @@ diskfs_S_dir_lookup (struct protid *dircred, { if (!ds) ds = alloca (diskfs_dirstat_size); - error = diskfs_lookup (dnp, path, CREATE, &np, ds, dircred); + err = diskfs_lookup (dnp, path, CREATE, &np, ds, dircred); } else - error = diskfs_lookup (dnp, path, LOOKUP, &np, 0, dircred); + err = diskfs_lookup (dnp, path, LOOKUP, &np, 0, dircred); - if (lastcomp && create && excl && (!error || error == EAGAIN)) - error = EEXIST; + if (lastcomp && create && excl && (!err || err == EAGAIN)) + err = EEXIST; /* If we get an error we're done */ - if (error == EAGAIN) + if (err == EAGAIN) { if (dnp == dircred->po->shadow_root) /* We're at the root of a shadow tree. */ @@ -151,7 +151,7 @@ diskfs_S_dir_lookup (struct protid *dircred, /* This is a shadow root with no parent, meaning we should treat it as a virtual root disconnected from its real .. directory. */ - error = 0; + err = 0; np = dnp; diskfs_nref (np); } @@ -163,7 +163,7 @@ diskfs_S_dir_lookup (struct protid *dircred, *returned_port_poly = MACH_MSG_TYPE_COPY_SEND; if (! lastcomp) strcpy (retryname, nextname); - error = 0; + err = 0; goto out; } } @@ -177,13 +177,13 @@ diskfs_S_dir_lookup (struct protid *dircred, *returned_port_poly = MACH_MSG_TYPE_COPY_SEND; if (!lastcomp) strcpy (retryname, nextname); - error = 0; + err = 0; goto out; } else /* We're at a REAL root, as in there's no way up from here. */ { - error = 0; + err = 0; np = dnp; diskfs_nref (np); } @@ -192,11 +192,11 @@ diskfs_S_dir_lookup (struct protid *dircred, /* Create the new node if necessary */ if (lastcomp && create) { - if (error == ENOENT) + if (err == ENOENT) { mode &= ~(S_IFMT | S_ISPARE | S_ISVTX | S_ITRANS); mode |= S_IFREG; - error = diskfs_create_node (dnp, path, mode, &np, dircred, ds); + err = diskfs_create_node (dnp, path, mode, &np, dircred, ds); if (diskfs_synchronous) { diskfs_file_update (dnp, 1); @@ -208,7 +208,7 @@ diskfs_S_dir_lookup (struct protid *dircred, diskfs_drop_dirstat (dnp, ds); } - if (error) + if (err) goto out; /* If this is translated, start the translator (if necessary) @@ -260,21 +260,21 @@ diskfs_S_dir_lookup (struct protid *dircred, /* Create an unauthenticated port for DNP, and then unlock it. */ - error = iohelp_create_empty_iouser (&user); - if (! error) + err = iohelp_create_empty_iouser (&user); + if (! err) { - error = diskfs_make_peropen (dnp, 0, dircred->po, &newpo); - if (! error) + err = diskfs_make_peropen (dnp, 0, dircred->po, &newpo); + if (! err) { - error = diskfs_create_protid (newpo, user, &newpi); - if (! error) + err = diskfs_create_protid (newpo, user, &newpi); + if (! err) newpo = 0; } iohelp_free_iouser (user); } - if (error) + if (err) goto out; dirport = ports_get_send_right (newpi); @@ -288,7 +288,7 @@ diskfs_S_dir_lookup (struct protid *dircred, boolean_t register_translator = np->transbox.active == MACH_PORT_NULL; - error = fshelp_fetch_root (&np->transbox, dircred->po, + err = fshelp_fetch_root (&np->transbox, dircred->po, dirport, dircred->user, lastcomp ? flags : 0, ((np->dn_stat.st_mode & S_IPTRANS) @@ -301,10 +301,10 @@ diskfs_S_dir_lookup (struct protid *dircred, deallocate our send right. */ mach_port_deallocate (mach_task_self (), dirport); - if (error != ENOENT) + if (err != ENOENT) { *returned_port_poly = MACH_MSG_TYPE_MOVE_SEND; - if (!lastcomp && !error) + if (!lastcomp && !err) { char *end = strchr (retryname, '\0'); *end++ = '/'; @@ -333,12 +333,12 @@ diskfs_S_dir_lookup (struct protid *dircred, else asprintf (&complete_path, "%s/%s", dircred->po->path, translator_path); - error = fshelp_set_active_translator (&newpi->pi, + err = fshelp_set_active_translator (&newpi->pi, complete_path, np->transbox.active); if (complete_path != translator_path) free(complete_path); - if (error) + if (err) goto out; } @@ -351,7 +351,7 @@ diskfs_S_dir_lookup (struct protid *dircred, /* ENOENT means there was a hiccup, and the translator vanished while NP was unlocked inside fshelp_fetch_root. Reacquire the locks, and continue as normal. */ - error = 0; + err = 0; if (np != dnp) { if (!strcmp (path, "..")) @@ -377,7 +377,7 @@ diskfs_S_dir_lookup (struct protid *dircred, if (nsymlink++ > diskfs_maxsymlinks) { - error = ELOOP; + err = ELOOP; goto out; } @@ -390,16 +390,16 @@ diskfs_S_dir_lookup (struct protid *dircred, } if (diskfs_read_symlink_hook) - error = (*diskfs_read_symlink_hook)(np, pathbuf); - if (!diskfs_read_symlink_hook || error == EINVAL) + err = (*diskfs_read_symlink_hook)(np, pathbuf); + if (!diskfs_read_symlink_hook || err == EINVAL) { - error = diskfs_node_rdwr (np, pathbuf, + err = diskfs_node_rdwr (np, pathbuf, 0, np->dn_stat.st_size, 0, dircred, &amt); - if (!error) + if (!err) assert (amt == np->dn_stat.st_size); } - if (error) + if (err) goto out; if (np->dn_stat.st_size == 0) /* symlink to "" */ @@ -471,7 +471,7 @@ diskfs_S_dir_lookup (struct protid *dircred, if (mustbedir && type != S_IFDIR) { - error = ENOTDIR; + err = ENOTDIR; goto out; } @@ -482,25 +482,25 @@ diskfs_S_dir_lookup (struct protid *dircred, type == S_IFIFO) && (flags & (O_READ|O_WRITE|O_EXEC))) || (type == S_IFLNK && (flags & (O_WRITE|O_EXEC)))) - error = EACCES; + err = EACCES; - if (!error && (flags & O_READ)) - error = fshelp_access (&np->dn_stat, S_IREAD, dircred->user); + if (!err && (flags & O_READ)) + err = fshelp_access (&np->dn_stat, S_IREAD, dircred->user); - if (!error && (flags & O_EXEC)) - error = fshelp_access (&np->dn_stat, S_IEXEC, dircred->user); + if (!err && (flags & O_EXEC)) + err = fshelp_access (&np->dn_stat, S_IEXEC, dircred->user); - if (!error && (flags & O_WRITE)) + if (!err && (flags & O_WRITE)) { if (type == S_IFDIR) - error = EISDIR; + err = EISDIR; else if (diskfs_check_readonly ()) - error = EROFS; + err = EROFS; else - error = fshelp_access (&np->dn_stat, S_IWRITE, dircred->user); + err = fshelp_access (&np->dn_stat, S_IWRITE, dircred->user); } - if (error) + if (err) goto out; } @@ -508,24 +508,24 @@ diskfs_S_dir_lookup (struct protid *dircred, && (fshelp_isowner (&np->dn_stat, dircred->user) == EPERM)) flags &= ~O_NOATIME; - error = diskfs_make_peropen (np, (flags &~OPENONLY_STATE_MODES), + err = diskfs_make_peropen (np, (flags &~OPENONLY_STATE_MODES), dircred->po, &newpo); - if (! error) - error = diskfs_create_protid (newpo, dircred->user, &newpi); + if (! err) + err = diskfs_create_protid (newpo, dircred->user, &newpi); - if (! error) + if (! err) { newpo = 0; if (flags & O_EXLOCK) - error = fshelp_acquire_lock (&np->userlock, &newpi->po->lock_status, + err = fshelp_acquire_lock (&np->userlock, &newpi->po->lock_status, &np->lock, LOCK_EX); else if (flags & O_SHLOCK) - error = fshelp_acquire_lock (&np->userlock, &newpi->po->lock_status, + err = fshelp_acquire_lock (&np->userlock, &newpi->po->lock_status, &np->lock, LOCK_SH); } - if (! error) + if (! err) { free (newpi->po->path); if (dircred->po->path == NULL || !strcmp (dircred->po->path,".")) @@ -541,7 +541,7 @@ diskfs_S_dir_lookup (struct protid *dircred, } if (! newpi->po->path) - error = errno; + err = errno; *returned_port = ports_get_right (newpi); ports_port_deref (newpi); @@ -566,5 +566,5 @@ diskfs_S_dir_lookup (struct protid *dircred, free (relpath); - return error; + return err; } diff --git a/libdiskfs/disk-pager.c b/libdiskfs/disk-pager.c index 008aa2d..434ceed 100644 --- a/libdiskfs/disk-pager.c +++ b/libdiskfs/disk-pager.c @@ -24,6 +24,7 @@ __thread struct disk_image_user *diskfs_exception_diu; struct pager *diskfs_disk_pager; +struct pager_requests *diskfs_disk_pager_requests; static void fault_handler (int sig, long int sigcode, struct sigcontext *scp); static struct hurd_signal_preemptor preemptor = @@ -43,7 +44,7 @@ diskfs_start_disk_pager (struct user_pager_info *upi, mach_port_t disk_pager_port; /* Start libpagers worker threads. */ - err = pager_start_workers (pager_bucket); + err = pager_start_workers (pager_bucket, &diskfs_disk_pager_requests); if (err) error (2, err, "creating pager worker threads failed"); diff --git a/libdiskfs/diskfs-pager.h b/libdiskfs/diskfs-pager.h index a253069..550ca64 100644 --- a/libdiskfs/diskfs-pager.h +++ b/libdiskfs/diskfs-pager.h @@ -40,6 +40,7 @@ extern void diskfs_start_disk_pager (struct user_pager_info *info, size_t size, void **image); extern struct pager *diskfs_disk_pager; +extern struct pager_requests *diskfs_disk_pager_requests; struct disk_image_user { diff --git a/libdiskfs/diskfs.h b/libdiskfs/diskfs.h index 82a16b4..11fb0ad 100644 --- a/libdiskfs/diskfs.h +++ b/libdiskfs/diskfs.h @@ -297,7 +297,7 @@ int diskfs_shortcut_ifsock; /* The user may define this variable, otherwise it has a default value of 30. diskfs_set_sync_interval is called with this value when the first diskfs - thread is started up (in diskfs_spawn_first_threa). */ + thread is started up (in diskfs_spawn_first_thread). */ extern int diskfs_default_sync_interval; /* The user must define this variable, which should be a string that somehow @@ -732,6 +732,14 @@ struct node *diskfs_make_node_alloc (size_t size); this value for offset calculations. */ extern const size_t _diskfs_sizeof_struct_node; +/* Return the address of the disknode for NODE. NODE must have been + allocated using diskfs_make_node_alloc. */ +struct disknode *diskfs_node_disknode (struct node *node); + +/* Return the address of the node for DISKNODE. DISKNODE must have + been allocated using diskfs_make_node_alloc. */ +struct node *diskfs_disknode_node (struct disknode *disknode); + #if defined(__USE_EXTERN_INLINES) || defined(DISKFS_DEFINE_EXTERN_INLINE) /* Return the address of the disknode for NODE. NODE must have been diff --git a/libdiskfs/file-getcontrol.c b/libdiskfs/file-getcontrol.c index fc6f777..8f98f4b 100644 --- a/libdiskfs/file-getcontrol.c +++ b/libdiskfs/file-getcontrol.c @@ -25,20 +25,20 @@ diskfs_S_file_getcontrol (struct protid *cred, mach_port_t *control, mach_msg_type_name_t *controltype) { - int error; + error_t err; struct port_info *newpi; if (!cred) return EOPNOTSUPP; - error = fshelp_iscontroller (&diskfs_root_node->dn_stat, cred->user); - if (error) - return error; + err = fshelp_iscontroller (&diskfs_root_node->dn_stat, cred->user); + if (err) + return err; - error = ports_create_port (diskfs_control_class, diskfs_port_bucket, + err = ports_create_port (diskfs_control_class, diskfs_port_bucket, sizeof (struct port_info), &newpi); - if (error) - return error; + if (err) + return err; pthread_spin_lock (&_diskfs_control_lock); _diskfs_ncontrol_ports++; diff --git a/libdiskfs/file-syncfs.c b/libdiskfs/file-syncfs.c index b7d20a8..2faab6a 100644 --- a/libdiskfs/file-syncfs.c +++ b/libdiskfs/file-syncfs.c @@ -28,12 +28,12 @@ diskfs_S_file_syncfs (struct protid *cred, error_t helper (struct node *np) { - error_t error; + error_t err; mach_port_t control; - error = fshelp_fetch_control (&np->transbox, &control); + err = fshelp_fetch_control (&np->transbox, &control); pthread_mutex_unlock (&np->lock); - if (!error && (control != MACH_PORT_NULL)) + if (!err && (control != MACH_PORT_NULL)) { fsys_syncfs (control, wait, 1); mach_port_deallocate (mach_task_self (), control); diff --git a/libdiskfs/name-cache.c b/libdiskfs/name-cache.c index d8f86b1..e9fe27e 100644 --- a/libdiskfs/name-cache.c +++ b/libdiskfs/name-cache.c @@ -355,7 +355,7 @@ diskfs_check_lookup_cache (struct node *dir, const char *name) pthread_mutex_lock (&cache_lock); found = lookup (dir->cache_id, name, key, &bucket, &i); if (! found - || ! bucket->node_cache_id[i] != id) + || bucket->node_cache_id[i] != id) { pthread_mutex_unlock (&cache_lock); diff --git a/libpager/demuxer.c b/libpager/demuxer.c index 4dd3cd8..59dd1c5 100644 --- a/libpager/demuxer.c +++ b/libpager/demuxer.c @@ -60,7 +60,7 @@ request_inp (const struct request *r) /* A worker. */ struct worker { - struct requests *requests; /* our pagers request queue */ + struct pager_requests *requests; /* our pagers request queue */ struct queue queue; /* other workers may delegate requests to us */ unsigned long tag; /* tag of the object we are working on */ }; @@ -68,12 +68,18 @@ struct worker /* This is the queue for incoming requests. A single thread receives messages from the port set, looks the service routine up, and enqueues the request here. */ -struct requests +struct pager_requests { struct port_bucket *bucket; - struct queue queue; + /* Normally, both queues are the same. However, when the workers are + inhibited, a new queue_in is created, but queue_out is left as the + old value, so the workers drain queue_out but do not receive new + requests. */ + struct queue *queue_in; /* the queue to add to */ + struct queue *queue_out; /* the queue to take from */ int asleep; pthread_cond_t wakeup; + pthread_cond_t inhibit_wakeup; pthread_mutex_t lock; struct worker workers[WORKER_COUNT]; }; @@ -81,7 +87,7 @@ struct requests /* Demultiplex a single message directed at a pager port; INP is the message received; fill OUTP with the reply. */ static int -pager_demuxer (struct requests *requests, +pager_demuxer (struct pager_requests *requests, mach_msg_header_t *inp, mach_msg_header_t *outp) { @@ -108,10 +114,10 @@ pager_demuxer (struct requests *requests, pthread_mutex_lock (&requests->lock); - queue_enqueue (&requests->queue, &r->item); + queue_enqueue (requests->queue_in, &r->item); - /* Awake worker. */ - if (requests->asleep > 0) + /* Awake worker, but only if not inhibited. */ + if (requests->asleep > 0 && requests->queue_in == requests->queue_out) pthread_cond_signal (&requests->wakeup); pthread_mutex_unlock (&requests->lock); @@ -160,7 +166,7 @@ static void * worker_func (void *arg) { struct worker *self = (struct worker *) arg; - struct requests *requests = self->requests; + struct pager_requests *requests = self->requests; struct request *r = NULL; mig_reply_header_t reply_msg; @@ -186,9 +192,11 @@ worker_func (void *arg) get_request_locked: /* ... get a request from the global queue instead. */ - while ((r = queue_dequeue (&requests->queue)) == NULL) + while ((r = queue_dequeue (requests->queue_out)) == NULL) { requests->asleep += 1; + if (requests->asleep == WORKER_COUNT) + pthread_cond_broadcast (&requests->inhibit_wakeup); pthread_cond_wait (&requests->wakeup, &requests->lock); requests->asleep -= 1; } @@ -281,7 +289,7 @@ worker_func (void *arg) static void * service_paging_requests (void *arg) { - struct requests *requests = arg; + struct pager_requests *requests = arg; int demuxer (mach_msg_header_t *inp, mach_msg_header_t *outp) @@ -298,27 +306,44 @@ service_paging_requests (void *arg) /* Start the worker threads libpager uses to service requests. */ error_t -pager_start_workers (struct port_bucket *pager_bucket) +pager_start_workers (struct port_bucket *pager_bucket, + struct pager_requests **out_requests) { error_t err; int i; pthread_t t; - struct requests *requests; + struct pager_requests *requests; + + assert (out_requests != NULL); requests = malloc (sizeof *requests); if (requests == NULL) - return ENOMEM; + { + err = ENOMEM; + goto done; + } requests->bucket = pager_bucket; requests->asleep = 0; - queue_init (&requests->queue); + + requests->queue_in = malloc (sizeof *requests->queue_in); + if (requests->queue_in == NULL) + { + err = ENOMEM; + goto done; + } + queue_init (requests->queue_in); + /* Until the workers are inhibited, both queues are the same. */ + requests->queue_out = requests->queue_in; + pthread_cond_init (&requests->wakeup, NULL); + pthread_cond_init (&requests->inhibit_wakeup, NULL); pthread_mutex_init (&requests->lock, NULL); /* Make a thread to service paging requests. */ err = pthread_create (&t, NULL, service_paging_requests, requests); if (err) - return err; + goto done; pthread_detach (t); for (i = 0; i < WORKER_COUNT; i++) @@ -329,9 +354,71 @@ pager_start_workers (struct port_bucket *pager_bucket) err = pthread_create (&t, NULL, &worker_func, &requests->workers[i]); if (err) - return err; + goto done; pthread_detach (t); } +done: + if (err) + *out_requests = NULL; + else + *out_requests = requests; + return err; } + +error_t +pager_inhibit_workers (struct pager_requests *requests) +{ + error_t err = 0; + + pthread_mutex_lock (&requests->lock); + + /* Check the workers are not already inhibited. */ + assert (requests->queue_out == requests->queue_in); + + /* Any new paging requests will go into a new queue. */ + struct queue *new_queue = malloc (sizeof *new_queue); + if (new_queue == NULL) + { + err = ENOMEM; + goto done_locked; + } + queue_init (new_queue); + requests->queue_in = new_queue; + + /* Wait until all the workers are asleep and the queue has been + drained. All individual worker queues must have been drained, as + they are populated while the relevant worker is still running, and + it will always drain its personal queue before sleeping. + Check that the queue is empty, since it's possible that a request + came in, was queued and a worker was signalled but the lock was + acquired here before the worker woke up. */ + while (requests->asleep < WORKER_COUNT || !queue_empty(requests->queue_out)) + pthread_cond_wait (&requests->inhibit_wakeup, &requests->lock); + +done_locked: + pthread_mutex_unlock (&requests->lock); + return err; +} + +void +pager_resume_workers (struct pager_requests *requests) +{ + pthread_mutex_lock (&requests->lock); + + /* Check the workers are inhibited. */ + assert (requests->queue_out != requests->queue_in); + assert (requests->asleep == WORKER_COUNT); + assert (queue_empty(requests->queue_out)); + + /* The queue has been drained and will no longer be used. */ + free (requests->queue_out); + requests->queue_out = requests->queue_in; + + /* We need to wake up all workers, as there could be multiple requests + in the new queue. */ + pthread_cond_broadcast (&requests->wakeup); + + pthread_mutex_unlock (&requests->lock); +} diff --git a/libpager/pager.h b/libpager/pager.h index fe34238..df4db68 100644 --- a/libpager/pager.h +++ b/libpager/pager.h @@ -25,8 +25,32 @@ scope. */ struct user_pager_info; -/* Start the worker threads libpager uses to service requests. */ -error_t pager_start_workers (struct port_bucket *pager_bucket); +struct pager_requests; + +/* Start the worker threads libpager uses to service requests. If no + error is returned, *requests will be a valid pointer, else it will be + set to NULL. */ +error_t +pager_start_workers (struct port_bucket *pager_bucket, + struct pager_requests **requests); + +/* Inhibit the worker threads libpager uses to service requests, + blocking until all requests sent before this function is called have + finished. + Note that RPCs will not be inhibited, so new requests will + queue up, but will not be handled until the workers are resumed. If + RPCs should be inhibited as well, call ports_inhibit_bucket_rpcs with + the bucket used to create the workers before calling this. However, + inhibiting RPCs and not calling this is generally insufficient, as + libports is unaware of our internal worker pool, and will return once + all the RPCs have been queued, before they have been handled by a + worker thread. */ +error_t +pager_inhibit_workers (struct pager_requests *requests); + +/* Resume the worker threads libpager uses to service requests. */ +void +pager_resume_workers (struct pager_requests *requests); /* Create a new pager. The pager will have a port created for it (using libports, in BUCKET) and will be immediately ready diff --git a/libpager/queue.h b/libpager/queue.h index d3cf738..abcd3b9 100644 --- a/libpager/queue.h +++ b/libpager/queue.h @@ -19,6 +19,8 @@ You should have received a copy of the GNU General Public License along with the GNU Hurd. If not, see <http://www.gnu.org/licenses/>. */ +#include <stdbool.h> + /* A FIFO queue with constant-time enqueue and dequeue operations. */ struct item { struct item *next; @@ -59,3 +61,9 @@ queue_dequeue (struct queue *q) r->next = NULL; return r; } + +static inline bool +queue_empty (struct queue *q) +{ + return q->head == NULL; +} diff --git a/libpipe/pipe.c b/libpipe/pipe.c index 9580eb7..c3d2a28 100644 --- a/libpipe/pipe.c +++ b/libpipe/pipe.c @@ -164,16 +164,15 @@ void _pipe_no_readers (struct pipe *pipe) pipe_free (pipe); else { - if (! pipe_is_connless (pipe)) + /* When there is no reader, we have to break pipe even for + connection-less pipes. */ + pipe->flags |= PIPE_BROKEN; + if (pipe->writers) + /* Wake up writers for the bad news... */ { - pipe->flags |= PIPE_BROKEN; - if (pipe->writers) - /* Wake up writers for the bad news... */ - { - pthread_cond_broadcast (&pipe->pending_writes); - pthread_cond_broadcast (&pipe->pending_write_selects); - pipe_select_cond_broadcast (pipe); - } + pthread_cond_broadcast (&pipe->pending_writes); + pthread_cond_broadcast (&pipe->pending_write_selects); + pipe_select_cond_broadcast (pipe); } pthread_mutex_unlock (&pipe->lock); } diff --git a/libports/Makefile b/libports/Makefile index b8b82ee..af881f8 100644 --- a/libports/Makefile +++ b/libports/Makefile @@ -38,7 +38,7 @@ SRCS = create-bucket.c create-class.c \ claim-right.c transfer-right.c create-port-noinstall.c create-internal.c \ interrupted.c extern-inline.c port-deref-deferred.c -installhdrs = ports.h +installhdrs = ports.h port-deref-deferred.h HURDLIBS= ihash LDLIBS += -lpthread diff --git a/libports/manage-multithread.c b/libports/manage-multithread.c index dcb6905..60743d9 100644 --- a/libports/manage-multithread.c +++ b/libports/manage-multithread.c @@ -175,6 +175,11 @@ ports_manage_port_operations_multithread (struct port_bucket *bucket, pi = ports_lookup_port (bucket, inp->msgh_local_port, 0); if (pi) { + /* Store the objects address as the payload and set the + message type accordingly. This prevents us from + having to do another hash table lookup in the intran + functions if protected payloads are not supported by + the kernel. */ inp->msgh_bits = MACH_MSGH_BITS ( MACH_MSGH_BITS_REMOTE (inp->msgh_bits), MACH_MSG_TYPE_PROTECTED_PAYLOAD); diff --git a/libports/manage-one-thread.c b/libports/manage-one-thread.c index 192907a..b920338 100644 --- a/libports/manage-one-thread.c +++ b/libports/manage-one-thread.c @@ -66,6 +66,11 @@ ports_manage_port_operations_one_thread (struct port_bucket *bucket, pi = ports_lookup_port (bucket, inp->msgh_local_port, 0); if (pi) { + /* Store the objects address as the payload and set the + message type accordingly. This prevents us from + having to do another hash table lookup in the intran + functions if protected payloads are not supported by + the kernel. */ inp->msgh_bits = MACH_MSGH_BITS ( MACH_MSGH_BITS_REMOTE (inp->msgh_bits), MACH_MSG_TYPE_PROTECTED_PAYLOAD); diff --git a/libshouldbeinlibc/maptime.h b/libshouldbeinlibc/maptime.h index 947ad64..04ce035 100644 --- a/libshouldbeinlibc/maptime.h +++ b/libshouldbeinlibc/maptime.h @@ -51,7 +51,9 @@ maptime_read (volatile struct mapped_time_value *mtime, struct timeval *tv) do { tv->tv_sec = mtime->seconds; + __sync_synchronize (); tv->tv_usec = mtime->microseconds; + __sync_synchronize (); } while (tv->tv_sec != mtime->check_seconds); } diff --git a/libthreads/lockfile.c b/libthreads/lockfile.c index eeb1a2f..dbb7c6c 100644 --- a/libthreads/lockfile.c +++ b/libthreads/lockfile.c @@ -17,6 +17,9 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#define _IO_MTSAFE_IO +#define IS_IN(lib) 0 + #include <cthreads.h> /* Must come before <stdio.h>! */ #include <stdio.h> diff --git a/libtrivfs/Makefile b/libtrivfs/Makefile index 921acbe..48a53d7 100644 --- a/libtrivfs/Makefile +++ b/libtrivfs/Makefile @@ -53,9 +53,6 @@ MIGSFLAGS=-imacros $(srcdir)/mig-mutate.h MIGCOMSFLAGS = -prefix trivfs_ installhdrs := trivfs.h mig-sheader-prefix = trivfs_ -ifndef no_deps -installhdrs += $(patsubst %,trivfs_%_S.h,fs io fsys) -endif include ../Makeconf diff --git a/pflocal/io.c b/pflocal/io.c index ee6fb84..38d6c1d 100644 --- a/pflocal/io.c +++ b/pflocal/io.c @@ -298,6 +298,13 @@ S_io_select_timeout (struct sock_user *user, return io_select_common (user, reply, reply_type, &ts, select_type); } +static inline void +copy_time (time_value_t *from, time_t *to_sec, long *to_nsec) +{ + *to_sec = from->seconds; + *to_nsec = from->microseconds * 1000; +} + /* Return the current status of the object. Not all the fields of the io_statuf_t are meaningful for all objects; however, the access and modify times, the optimal IO size, and the fs type are meaningful @@ -308,12 +315,6 @@ S_io_stat (struct sock_user *user, struct stat *st) struct sock *sock; struct pipe *rpipe, *wpipe; - void copy_time (time_value_t *from, time_t *to_sec, long *to_nsec) - { - *to_sec = from->seconds; - *to_nsec = from->microseconds * 1000; - } - if (!user) return EOPNOTSUPP; diff --git a/pflocal/mig-decls.h b/pflocal/mig-decls.h index b1da797..6c044ce 100644 --- a/pflocal/mig-decls.h +++ b/pflocal/mig-decls.h @@ -58,7 +58,7 @@ begin_using_addr_port(mach_port_t port) static inline addr_t __attribute__ ((unused)) begin_using_addr_payload (unsigned long payload) { - return ports_lookup_port (NULL, payload, addr_port_class); + return ports_lookup_payload (NULL, payload, addr_port_class); } static inline void __attribute__ ((unused)) diff --git a/pflocal/sock.c b/pflocal/sock.c index 8076dd3..ef70d2c 100644 --- a/pflocal/sock.c +++ b/pflocal/sock.c @@ -277,12 +277,15 @@ sock_bind (struct sock *sock, struct addr *addr) error_t err = 0; struct addr *old_addr; - pthread_mutex_lock (&addr->lock); + if (addr) + pthread_mutex_lock (&addr->lock); pthread_mutex_lock (&sock->lock); old_addr = sock->addr; if (addr && old_addr) err = EINVAL; /* SOCK already bound. */ + else if (!addr && !old_addr) + err = EINVAL; /* SOCK already bound. */ else if (addr && addr->sock) err = EADDRINUSE; /* Something else already bound ADDR. */ else if (addr) @@ -303,13 +306,14 @@ sock_bind (struct sock *sock, struct addr *addr) /* Note that we don't have to worry about SOCK's ref count going to zero because whoever's calling us should be holding a ref. */ sock->refs--; - ports_port_deref_weak (addr); + ports_port_deref_weak (old_addr); assert (sock->refs > 0); /* But make sure... */ } } pthread_mutex_unlock (&sock->lock); - pthread_mutex_unlock (&addr->lock); + if (addr) + pthread_mutex_unlock (&addr->lock); return err; } diff --git a/pflocal/sock.h b/pflocal/sock.h index 5800420..29f0f1f 100644 --- a/pflocal/sock.h +++ b/pflocal/sock.h @@ -114,13 +114,39 @@ void sock_free (struct sock *sock); /* Free a sock derefed too far. */ void _sock_norefs (struct sock *sock); +/* Bind SOCK to ADDR. */ +error_t sock_bind (struct sock *sock, struct addr *addr); + /* Remove a reference from SOCK, possibly freeing it. */ static inline void __attribute__ ((unused)) sock_deref (struct sock *sock) { + error_t err; pthread_mutex_lock (&sock->lock); - if (--sock->refs == 0) + + sock->refs--; + + if (sock->refs == 0) _sock_norefs (sock); + else if (sock->refs == 1 && sock->addr) + { + /* Last ref is the address, there won't be any more port for this socket, + unbind SOCK from its addr, and they will all die. */ + + /* Keep another ref while unbinding. */ + sock->refs++; + pthread_mutex_unlock (&sock->lock); + + /* Unbind */ + err = sock_bind (sock, NULL); + assert (!err); + + /* And release the ref, and thus kill SOCK. */ + pthread_mutex_lock (&sock->lock); + sock->refs--; + assert(sock->refs == 0); + _sock_norefs (sock); + } else pthread_mutex_unlock (&sock->lock); } @@ -131,9 +157,6 @@ error_t sock_clone (struct sock *template, struct sock **sock); /* Return a new user port on SOCK in PORT. */ error_t sock_create_port (struct sock *sock, mach_port_t *port); -/* Bind SOCK to ADDR. */ -error_t sock_bind (struct sock *sock, struct addr *addr); - /* Returns SOCK's address in ADDR, with an additional reference added. If SOCK doesn't currently have an address, one is fabricated first. */ error_t sock_get_addr (struct sock *sock, struct addr **addr); diff --git a/pflocal/socket.c b/pflocal/socket.c index 792c637..5844904 100644 --- a/pflocal/socket.c +++ b/pflocal/socket.c @@ -92,7 +92,10 @@ S_socket_connect (struct sock_user *user, struct addr *addr) return EOPNOTSUPP; err = addr_get_sock (addr, &peer); - if (!err) + if (err == EADDRNOTAVAIL) + /* The server went away. */ + err = ECONNREFUSED; + else if (!err) { struct sock *sock = user->sock; struct connq *cq = peer->listen_queue; @@ -295,6 +298,9 @@ S_socket_send (struct sock_user *user, struct addr *dest_addr, int flags, if (dest_addr) { err = addr_get_sock (dest_addr, &dest_sock); + if (err == EADDRNOTAVAIL) + /* The server went away. */ + err = ECONNREFUSED; if (err) return err; if (sock->pipe_class != dest_sock->pipe_class) diff --git a/procfs/main.c b/procfs/main.c index f773c09..509f488 100644 --- a/procfs/main.c +++ b/procfs/main.c @@ -130,6 +130,12 @@ argp_parser (int key, char *arg, struct argp_state *state) /* Ignored for compatibility with Linux' procfs. */ break; + case ARGP_KEY_ARG: + if (!strcmp (arg, "none") || !strcmp (arg,"proc")) + /* Ignored for compatibility with Linux' procfs. */ + break; + return ARGP_ERR_UNKNOWN; + default: return ARGP_ERR_UNKNOWN; } diff --git a/startup/startup.c b/startup/startup.c index da78b13..e916768 100644 --- a/startup/startup.c +++ b/startup/startup.c @@ -377,7 +377,6 @@ run (const char *server, mach_port_t *ports, task_t *task) printf ("Pausing for %s\n", prog); getchar (); } - task_set_name (*task, (char *) prog); err = file_exec (file, *task, 0, (char *)prog, strlen (prog) + 1, /* Args. */ startup_envz, startup_envz_len, diff --git a/storeio/pager.c b/storeio/pager.c index c260d73..f8f59cd 100644 --- a/storeio/pager.c +++ b/storeio/pager.c @@ -142,6 +142,7 @@ pager_clear_user_data (struct user_pager_info *upi) } static struct port_bucket *pager_port_bucket = 0; +static struct pager_requests *pager_requests; /* Initialize paging for this device. */ static void @@ -160,7 +161,7 @@ init_dev_paging () pager_port_bucket = ports_create_bucket (); /* Start libpagers worker threads. */ - err = pager_start_workers (pager_port_bucket); + err = pager_start_workers (pager_port_bucket, &pager_requests); if (err) { errno = err; diff --git a/sutils/fstab.c b/sutils/fstab.c index 24a1a0d..2e125d8 100644 --- a/sutils/fstab.c +++ b/sutils/fstab.c @@ -490,7 +490,7 @@ fs_remount (struct fs *fs) inline struct fs * fstab_find_device (const struct fstab *fstab, const char *name) { - if (strcmp (name, "none") == 0) + if (strcmp (name, "none") == 0 || strcmp (name, "proc") == 0) return NULL; char *real_name = realpath (name, NULL); diff --git a/trans/fakeroot.c b/trans/fakeroot.c index 4275152..76fc901 100644 --- a/trans/fakeroot.c +++ b/trans/fakeroot.c @@ -482,7 +482,7 @@ netfs_validate_stat (struct node *np, struct iouser *cred) if (netfs_node_netnode (np)->faked & FAKE_AUTHOR) st.st_author = np->nn_stat.st_author; if (netfs_node_netnode (np)->faked & FAKE_MODE) - st.st_mode = np->nn_stat.st_mode; + st.st_mode = (st.st_mode & S_IFMT) | (np->nn_stat.st_mode & ~S_IFMT); np->nn_stat = st; np->nn_translated = S_ISLNK (st.st_mode) ? S_IFLNK : 0; @@ -780,7 +780,11 @@ netfs_attempt_write (struct iouser *cred, struct node *np, error_t netfs_report_access (struct iouser *cred, struct node *np, int *types) { - *types = O_RDWR|O_EXEC; + struct netnode *nn = netfs_node_netnode (np); + if (!(nn->faked & FAKE_MODE)) + return file_check_access (nn->file, types); + else + *types = O_RDWR|O_EXEC; return 0; } diff --git a/trans/fifo.c b/trans/fifo.c index a9ad2dd..f52baba 100644 --- a/trans/fifo.c +++ b/trans/fifo.c @@ -169,7 +169,7 @@ open_hook (struct trivfs_peropen *po) make us block because we've ensured that there's a reader for it. */ - if (wait_for_writer) + if (wait_for_writer && (!(flags & O_WRITE))) /* Wait until there's a writer. */ { WAIT (active_fifo->writers, 0); diff --git a/utils/umount.c b/utils/umount.c index 4005029..19f79fc 100644 --- a/utils/umount.c +++ b/utils/umount.c @@ -235,6 +235,8 @@ do_umount (struct fs *fs) NULL, 0, MACH_PORT_NULL, MACH_MSG_TYPE_COPY_SEND); + if (!(goaway_flags & FSYS_GOAWAY_FORCE)) + err = 0; if (err) error (0, err, "%s", fs->mntent.mnt_fsname); -- Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-hurd/hurd.git
