diff --git a/drivers/base/bus.c b/drivers/base/bus.c index d895085ea9da523e78f6699c020d797b87b86442..1e4a63e9d9f3f8d635b97999ad9a149c928a5219 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -282,23 +282,25 @@ static int bus_match(struct device * dev, struct device_driver * drv) * Walk the list of drivers that the bus has and call bus_match() * for each pair. If a compatible pair is found, break out and return. */ -static void device_attach(struct device * dev) +static int device_attach(struct device * dev) { struct bus_type * bus = dev->bus; struct list_head * entry; if (dev->driver) { device_bind_driver(dev); - return; + return 1; } if (bus->match) { list_for_each(entry,&bus->drivers.list) { struct device_driver * drv = to_drv(entry); if (!bus_match(dev,drv)) - break; + return 1; } } + + return 0; } @@ -476,6 +478,38 @@ void bus_remove_driver(struct device_driver * drv) } } + +/* Helper for bus_rescan_devices's iter */ +static int bus_rescan_devices_helper(struct device *dev, void *data) +{ + int *count = data; + + if (!dev->driver && device_attach(dev)) + (*count)++; + + return 0; +} + + +/** + * bus_rescan_devices - rescan devices on the bus for possible drivers + * @bus: the bus to scan. + * + * This function will look for devices on the bus with no driver + * attached and rescan it against existing drivers to see if it + * matches any. Calls device_attach(). Returns the number of devices + * that were sucessfully bound to a driver. + */ +int bus_rescan_devices(struct bus_type * bus) +{ + int count = 0; + + bus_for_each_dev(bus, NULL, &count, bus_rescan_devices_helper); + + return count; +} + + struct bus_type * get_bus(struct bus_type * bus) { return bus ? container_of(subsys_get(&bus->subsys),struct bus_type,subsys) : NULL; @@ -560,6 +594,7 @@ EXPORT_SYMBOL(bus_add_device); EXPORT_SYMBOL(bus_remove_device); EXPORT_SYMBOL(bus_register); EXPORT_SYMBOL(bus_unregister); +EXPORT_SYMBOL(bus_rescan_devices); EXPORT_SYMBOL(get_bus); EXPORT_SYMBOL(put_bus); EXPORT_SYMBOL(find_bus); diff --git a/drivers/usb/storage/sddr09.c b/drivers/usb/storage/sddr09.c index 660b090248bcfec6270808df77b8c801f4fa5aae..398814aef5a46b91e8e3b7b74699fe90e8d0c8fc 100644 --- a/drivers/usb/storage/sddr09.c +++ b/drivers/usb/storage/sddr09.c @@ -65,6 +65,7 @@ struct nand_flash_dev { * NAND Flash Manufacturer ID Codes */ #define NAND_MFR_AMD 0x01 +#define NAND_MFR_NS 0x8f #define NAND_MFR_TOSHIBA 0x98 #define NAND_MFR_SAMSUNG 0xec @@ -72,6 +73,8 @@ static inline char *nand_flash_manufacturer(int manuf_id) { switch(manuf_id) { case NAND_MFR_AMD: return "AMD"; + case NAND_MFR_NS: + return "NS"; case NAND_MFR_TOSHIBA: return "Toshiba"; case NAND_MFR_SAMSUNG: @@ -84,10 +87,12 @@ static inline char *nand_flash_manufacturer(int manuf_id) { /* * It looks like it is unnecessary to attach manufacturer to the * remaining data: SSFDC prescribes manufacturer-independent id codes. + * + * 256 MB NAND flash has a 5-byte ID with 2nd byte 0xaa, 0xba, 0xca or 0xda. */ static struct nand_flash_dev nand_flash_ids[] = { - /* NAND flash - these I verified */ + /* NAND flash */ { 0x6e, 20, 8, 4, 8, 2}, /* 1 MB */ { 0xe8, 20, 8, 4, 8, 2}, /* 1 MB */ { 0xec, 20, 8, 4, 8, 2}, /* 1 MB */ @@ -101,12 +106,13 @@ static struct nand_flash_dev nand_flash_ids[] = { { 0x75, 25, 9, 5, 10, 2}, /* 32 MB */ { 0x76, 26, 9, 5, 10, 3}, /* 64 MB */ { 0x79, 27, 9, 5, 10, 3}, /* 128 MB */ - /* There do also exist 96 MB (from Datafab) and 256 MB cards */ - /* MASK ROM - from unknown source */ + /* MASK ROM */ { 0x5d, 21, 9, 4, 8, 2}, /* 2 MB */ { 0xd5, 22, 9, 4, 9, 2}, /* 4 MB */ { 0xd6, 23, 9, 4, 10, 2}, /* 8 MB */ + { 0x57, 24, 9, 4, 11, 2}, /* 16 MB */ + { 0x58, 25, 9, 4, 12, 2}, /* 32 MB */ { 0,} }; diff --git a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c index fc218ce7c5970248098bb0fadf3b9a7e49207c8d..2d18d1d64875124d0168847c344fe8f3e2aedc37 100644 --- a/fs/jfs/jfs_logmgr.c +++ b/fs/jfs/jfs_logmgr.c @@ -674,28 +674,29 @@ int lmGroupCommit(struct jfs_log * log, struct tblock * tblk) } jfs_info("lmGroup Commit: tblk = 0x%p, gcrtc = %d", tblk, log->gcrtc); - if (tblk->xflag & COMMIT_LAZY) { - /* - * Lazy transactions can leave now - */ + if (tblk->xflag & COMMIT_LAZY) tblk->flag |= tblkGC_LAZY; - LOGGC_UNLOCK(log); - return 0; - } - /* - * group commit pageout in progress - */ - if ((!(log->cflag & logGC_PAGEOUT)) && log->cqueue.head) { + + if ((!(log->cflag & logGC_PAGEOUT)) && log->cqueue.head && + (!(tblk->xflag & COMMIT_LAZY) || test_bit(log_FLUSH, &log->flag))) { /* - * only transaction in the commit queue: + * No pageout in progress * - * start one-transaction group commit as - * its group leader. + * start group commit as its group leader. */ log->cflag |= logGC_PAGEOUT; lmGCwrite(log, 0); } + + if (tblk->xflag & COMMIT_LAZY) { + /* + * Lazy transactions can leave now + */ + LOGGC_UNLOCK(log); + return 0; + } + /* lmGCwrite gives up LOGGC_LOCK, check again */ if (tblk->flag & tblkGC_COMMITTED) { @@ -894,11 +895,8 @@ void lmPostGC(struct lbuf * bp) * the first transaction entering group commit * will elect herself as new group leader. */ - else { + else log->cflag &= ~logGC_PAGEOUT; - clear_bit(log_FLUSH, &log->flag); - WARN_ON(log->flush_tblk); - } //LOGGC_UNLOCK(log); spin_unlock_irqrestore(&log->gclock, flags); diff --git a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c index 13226284c648d1edcea6c14544ef431ef51c89e0..e07b2727699833ed49746aee75d35fa56a0b76ad 100644 --- a/fs/jfs/jfs_txnmgr.c +++ b/fs/jfs/jfs_txnmgr.c @@ -518,22 +518,24 @@ void txEnd(tid_t tid) /* * mark the tblock not active */ - --log->active; + if (--log->active == 0) { + clear_bit(log_FLUSH, &log->flag); - /* - * synchronize with logsync barrier - */ - if (test_bit(log_SYNCBARRIER, &log->flag) && log->active == 0) { - /* forward log syncpt */ - /* lmSync(log); */ + /* + * synchronize with logsync barrier + */ + if (test_bit(log_SYNCBARRIER, &log->flag)) { + /* forward log syncpt */ + /* lmSync(log); */ - jfs_info(" log barrier off: 0x%x", log->lsn); + jfs_info("log barrier off: 0x%x", log->lsn); - /* enable new transactions start */ - clear_bit(log_SYNCBARRIER, &log->flag); + /* enable new transactions start */ + clear_bit(log_SYNCBARRIER, &log->flag); - /* wakeup all waitors for logsync barrier */ - TXN_WAKEUP(&log->syncwait); + /* wakeup all waitors for logsync barrier */ + TXN_WAKEUP(&log->syncwait); + } } /* diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c index c3f40c2c317f124de97f17b0c78c61c1f784f9a3..1ca3a06db1df1586649d824ac9d49d58d73b79dd 100644 --- a/fs/sysfs/dir.c +++ b/fs/sysfs/dir.c @@ -98,7 +98,6 @@ void sysfs_remove_dir(struct kobject * kobj) * Unlink and unhash. */ spin_unlock(&dcache_lock); - d_delete(d); simple_unlink(dentry->d_inode,d); dput(d); spin_lock(&dcache_lock); @@ -108,16 +107,11 @@ void sysfs_remove_dir(struct kobject * kobj) } spin_unlock(&dcache_lock); up(&dentry->d_inode->i_sem); - d_invalidate(dentry); - simple_rmdir(parent->d_inode,dentry); d_delete(dentry); + simple_rmdir(parent->d_inode,dentry); pr_debug(" o %s removing done (%d)\n",dentry->d_name.name, atomic_read(&dentry->d_count)); - /** - * Drop reference from initial sysfs_get_dentry(). - */ - dput(dentry); /** * Drop reference from dget() on entrance. diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c index 1c87b5507fa1e9506fa8a13820b7f281f2f50181..09c99fb77ff62bb918c46d8a22bc150eb9617065 100644 --- a/fs/sysfs/inode.c +++ b/fs/sysfs/inode.c @@ -93,19 +93,14 @@ void sysfs_hash_and_remove(struct dentry * dir, const char * name) /* make sure dentry is really there */ if (victim->d_inode && (victim->d_parent->d_inode == dir->d_inode)) { - simple_unlink(dir->d_inode,victim); - d_delete(victim); - pr_debug("sysfs: Removing %s (%d)\n", victim->d_name.name, atomic_read(&victim->d_count)); - /* - * Drop reference from initial sysfs_get_dentry(). - */ - dput(victim); + + simple_unlink(dir->d_inode,victim); + } - - /** - * Drop the reference acquired from sysfs_get_dentry() above. + /* + * Drop reference from sysfs_get_dentry() above. */ dput(victim); } diff --git a/include/linux/device.h b/include/linux/device.h index f059058eb3ac9af490fe838126d993f69182af80..e27039ec22220a25ff7940ef2075496a8cb8b99c 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -79,6 +79,8 @@ struct bus_type { extern int bus_register(struct bus_type * bus); extern void bus_unregister(struct bus_type * bus); +extern int bus_rescan_devices(struct bus_type * bus); + extern struct bus_type * get_bus(struct bus_type * bus); extern void put_bus(struct bus_type * bus);