diff -ur linux-2.6.15-rc5/drivers/mtd/mtd_blkdevs.c linux-2.6.15-rc5-openwrt/drivers/mtd/mtd_blkdevs.c --- linux-2.6.15-rc5/drivers/mtd/mtd_blkdevs.c 2005-12-04 06:10:42.000000000 +0100 +++ linux-2.6.15-rc5-openwrt/drivers/mtd/mtd_blkdevs.c 2005-12-15 07:53:20.000000000 +0100 @@ -21,6 +21,9 @@ #include #include #include +#ifdef CONFIG_DEVFS_FS +#include +#endif static LIST_HEAD(blktrans_majors); @@ -302,6 +305,11 @@ snprintf(gd->disk_name, sizeof(gd->disk_name), "%s%d", tr->name, new->devnum); +#ifdef CONFIG_DEVFS_FS + snprintf(gd->devfs_name, sizeof(gd->devfs_name), + "%s/%c", tr->name, (tr->part_bits?'a':'0') + new->devnum); +#endif + /* 2.5 has capacity in units of 512 bytes while still having BLOCK_SIZE_BITS set to 10. Just to keep us amused. */ set_capacity(gd, (new->size * new->blksize) >> 9); @@ -418,6 +426,10 @@ return ret; } +#ifdef CONFIG_DEVFS_FS + devfs_mk_dir(tr->name); +#endif + INIT_LIST_HEAD(&tr->devs); list_add(&tr->list, &blktrans_majors); @@ -450,6 +462,10 @@ tr->remove_dev(dev); } +#ifdef CONFIG_DEVFS_FS + devfs_remove(tr->name); +#endif + blk_cleanup_queue(tr->blkcore_priv->rq); unregister_blkdev(tr->major, tr->name); diff -ur linux-2.6.15-rc5/drivers/mtd/mtdchar.c linux-2.6.15-rc5-openwrt/drivers/mtd/mtdchar.c --- linux-2.6.15-rc5/drivers/mtd/mtdchar.c 2005-12-04 06:10:42.000000000 +0100 +++ linux-2.6.15-rc5-openwrt/drivers/mtd/mtdchar.c 2005-12-15 07:49:15.000000000 +0100 @@ -19,19 +18,33 @@ #include +#ifdef CONFIG_DEVFS_FS +#include +#else +#include + static struct class *mtd_class; +#endif static void mtd_notify_add(struct mtd_info* mtd) { if (!mtd) return; +#ifdef CONFIG_DEVFS_FS + devfs_mk_cdev(MKDEV(MTD_CHAR_MAJOR, mtd->index*2), + S_IFCHR | S_IRUGO | S_IWUGO, "mtd/%d", mtd->index); + + devfs_mk_cdev(MKDEV(MTD_CHAR_MAJOR, mtd->index*2+1), + S_IFCHR | S_IRUGO, "mtd/%dro", mtd->index); +#else class_device_create(mtd_class, NULL, MKDEV(MTD_CHAR_MAJOR, mtd->index*2), NULL, "mtd%d", mtd->index); class_device_create(mtd_class, NULL, MKDEV(MTD_CHAR_MAJOR, mtd->index*2+1), NULL, "mtd%dro", mtd->index); +#endif } static void mtd_notify_remove(struct mtd_info* mtd) @@ -39,8 +52,13 @@ if (!mtd) return; +#ifdef CONFIG_DEVFS_FS + devfs_remove("mtd/%d", mtd->index); + devfs_remove("mtd/%dro", mtd->index); +#else class_device_destroy(mtd_class, MKDEV(MTD_CHAR_MAJOR, mtd->index*2)); class_device_destroy(mtd_class, MKDEV(MTD_CHAR_MAJOR, mtd->index*2+1)); +#endif } static struct mtd_notifier notifier = { @@ -48,6 +66,22 @@ .remove = mtd_notify_remove, }; +#ifdef CONFIG_DEVFS_FS + static inline void mtdchar_devfs_init(void) + { + devfs_mk_dir("mtd"); + register_mtd_user(¬ifier); + } + static inline void mtdchar_devfs_exit(void) + { + unregister_mtd_user(¬ifier); + devfs_remove("mtd"); + } + #else /* !DEVFS */ + #define mtdchar_devfs_init() do { } while(0) + #define mtdchar_devfs_exit() do { } while(0) +#endif + /* * We use file->private_data to store a pointer to the MTDdevice. * Since alighment is at least 32 bits, we have 2 bits free for OTP @@ -643,6 +677,9 @@ return -EAGAIN; } +#ifdef CONFIG_DEVFS_FS + mtdchar_devfs_init(); +#else mtd_class = class_create(THIS_MODULE, "mtd"); if (IS_ERR(mtd_class)) { @@ -652,13 +689,19 @@ } register_mtd_user(¬ifier); +#endif return 0; } static void __exit cleanup_mtdchar(void) { + +#ifdef CONFIG_DEVFS_FS + mtdchar_devfs_exit(); +#else unregister_mtd_user(¬ifier); class_destroy(mtd_class); +#endif unregister_chrdev(MTD_CHAR_MAJOR, "mtd"); } diff -ur linux-2.6.15-rc5/fs/Kconfig linux-2.6.15-rc5-openwrt/fs/Kconfig --- linux-2.6.15-rc5/fs/Kconfig 2005-12-04 06:10:42.000000000 +0100 +++ linux-2.6.15-rc5-openwrt/fs/Kconfig 2005-12-15 07:44:01.000000000 +0100 @@ -772,6 +772,56 @@ help Exports the dump image of crashed kernel in ELF format. +config DEVFS_FS + bool "/dev file system support (OBSOLETE)" + depends on EXPERIMENTAL + help + This is support for devfs, a virtual file system (like /proc) which + provides the file system interface to device drivers, normally found + in /dev. Devfs does not depend on major and minor number + allocations. Device drivers register entries in /dev which then + appear automatically, which means that the system administrator does + not have to create character and block special device files in the + /dev directory using the mknod command (or MAKEDEV script) anymore. + + This is work in progress. If you want to use this, you *must* read + the material in , especially + the file README there. + + Note that devfs no longer manages /dev/pts! If you are using UNIX98 + ptys, you will also need to mount the /dev/pts filesystem (devpts). + + Note that devfs has been obsoleted by udev, + . + It has been stripped down to a bare minimum and is only provided for + legacy installations that use its naming scheme which is + unfortunately different from the names normal Linux installations + use. + + If unsure, say N. + +config DEVFS_MOUNT + bool "Automatically mount at boot" + depends on DEVFS_FS + help + This option appears if you have CONFIG_DEVFS_FS enabled. Setting + this to 'Y' will make the kernel automatically mount devfs onto /dev + when the system is booted, before the init thread is started. + You can override this with the "devfs=nomount" boot option. + + If unsure, say N. + +config DEVFS_DEBUG + bool "Debug devfs" + depends on DEVFS_FS + help + If you say Y here, then the /dev file system code will generate + debugging messages. See the file + for more + details. + + If unsure, say N. + config SYSFS bool "sysfs file system support" if EMBEDDED default y diff -ur linux-2.6.17/drivers/ieee1394/dv1394.c linux-2.6.17-devfs/drivers/ieee1394/dv1394.c --- linux-2.6.17/drivers/ieee1394/dv1394.c 2006-06-17 18:49:35.000000000 -0700 +++ linux-2.6.17-devfs/drivers/ieee1394/dv1394.c 2006-08-25 11:06:18.000000000 -0700 @@ -73,7 +73,7 @@ - fix all XXX showstoppers - disable IR/IT DMA interrupts on shutdown - flush pci writes to the card by issuing a read - - character device dispatching + - devfs and character device dispatching (* needs testing with Linux 2.2.x) - switch over to the new kernel DMA API (pci_map_*()) (* needs testing on platforms with IOMMU!) - keep all video_cards in a list (for open() via chardev), set file->private_data = video - dv1394_poll should indicate POLLIN when receiving buffers are available @@ -1096,6 +1096,7 @@ init.api_version = DV1394_API_VERSION; init.n_frames = DV1394_MAX_FRAMES / 4; + /* the following are now set via devfs */ init.channel = video->channel; init.format = video->pal_or_ntsc; init.cip_n = video->cip_n; @@ -1790,6 +1791,8 @@ { struct video_card *video = NULL; + /* if the device was opened through devfs, then file->private_data + has already been set to video by devfs */ if (file->private_data) { video = (struct video_card*) file->private_data; @@ -2208,7 +2211,7 @@ video = kzalloc(sizeof(*video), GFP_KERNEL); if (!video) { printk(KERN_ERR "dv1394: cannot allocate video_card\n"); - return -1; + goto err; } video->ohci = ohci; @@ -2263,14 +2266,37 @@ list_add_tail(&video->list, &dv1394_cards); spin_unlock_irqrestore(&dv1394_cards_lock, flags); + if (devfs_mk_cdev(MKDEV(IEEE1394_MAJOR, + IEEE1394_MINOR_BLOCK_DV1394*16 + video->id), + S_IFCHR|S_IRUGO|S_IWUGO, + "ieee1394/dv/host%d/%s/%s", + (video->id>>2), + (video->pal_or_ntsc == DV1394_NTSC ? "NTSC" : "PAL"), + (video->mode == MODE_RECEIVE ? "in" : "out")) < 0) + goto err_free; + debug_printk("dv1394: dv1394_init() OK on ID %d\n", video->id); + return 0; + + err_free: + kfree(video); + err: + return -1; } static void dv1394_un_init(struct video_card *video) { + char buf[32]; + /* obviously nobody has the driver open at this point */ do_dv1394_shutdown(video, 1); + snprintf(buf, sizeof(buf), "dv/host%d/%s/%s", (video->id >> 2), + (video->pal_or_ntsc == DV1394_NTSC ? "NTSC" : "PAL"), + (video->mode == MODE_RECEIVE ? "in" : "out") + ); + + devfs_remove("ieee1394/%s", buf); kfree(video); } @@ -2307,6 +2333,9 @@ class_device_destroy(hpsb_protocol_class, MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_DV1394 * 16 + (id<<2))); + devfs_remove("ieee1394/dv/host%d/NTSC", id); + devfs_remove("ieee1394/dv/host%d/PAL", id); + devfs_remove("ieee1394/dv/host%d", id); } static void dv1394_add_host (struct hpsb_host *host) @@ -2323,6 +2352,9 @@ class_device_create(hpsb_protocol_class, NULL, MKDEV( IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_DV1394 * 16 + (id<<2)), NULL, "dv1394-%d", id); + devfs_mk_dir("ieee1394/dv/host%d", id); + devfs_mk_dir("ieee1394/dv/host%d/NTSC", id); + devfs_mk_dir("ieee1394/dv/host%d/PAL", id); dv1394_init(ohci, DV1394_NTSC, MODE_RECEIVE); dv1394_init(ohci, DV1394_NTSC, MODE_TRANSMIT); @@ -2579,8 +2611,10 @@ static void __exit dv1394_exit_module(void) { hpsb_unregister_protocol(&dv1394_driver); + hpsb_unregister_highlevel(&dv1394_highlevel); cdev_del(&dv1394_cdev); + devfs_remove("ieee1394/dv"); } static int __init dv1394_init_module(void) @@ -2596,12 +2630,15 @@ return ret; } + devfs_mk_dir("ieee1394/dv"); + hpsb_register_highlevel(&dv1394_highlevel); ret = hpsb_register_protocol(&dv1394_driver); if (ret) { printk(KERN_ERR "dv1394: failed to register protocol\n"); hpsb_unregister_highlevel(&dv1394_highlevel); + devfs_remove("ieee1394/dv"); cdev_del(&dv1394_cdev); return ret; } diff -ur linux-2.6.17/drivers/ieee1394/ieee1394_core.c linux-2.6.17-devfs/drivers/ieee1394/ieee1394_core.c --- linux-2.6.17/drivers/ieee1394/ieee1394_core.c 2006-06-17 18:49:35.000000000 -0700 +++ linux-2.6.17-devfs/drivers/ieee1394/ieee1394_core.c 2006-08-25 11:06:18.000000000 -0700 @@ -1078,10 +1078,17 @@ goto exit_release_kernel_thread; } + /* actually this is a non-fatal error */ + ret = devfs_mk_dir("ieee1394"); + if (ret < 0) { + HPSB_ERR("unable to make devfs dir for device major %d!\n", IEEE1394_MAJOR); + goto release_chrdev; + } + ret = bus_register(&ieee1394_bus_type); if (ret < 0) { HPSB_INFO("bus register failed"); - goto release_chrdev; + goto release_devfs; } for (i = 0; fw_bus_attrs[i]; i++) { @@ -1092,7 +1099,7 @@ fw_bus_attrs[i--]); } bus_unregister(&ieee1394_bus_type); - goto release_chrdev; + goto release_devfs; } } @@ -1145,6 +1152,8 @@ for (i = 0; fw_bus_attrs[i]; i++) bus_remove_file(&ieee1394_bus_type, fw_bus_attrs[i]); bus_unregister(&ieee1394_bus_type); +release_devfs: + devfs_remove("ieee1394"); release_chrdev: unregister_chrdev_region(IEEE1394_CORE_DEV, 256); exit_release_kernel_thread: @@ -1182,6 +1191,7 @@ hpsb_cleanup_config_roms(); unregister_chrdev_region(IEEE1394_CORE_DEV, 256); + devfs_remove("ieee1394"); } module_init(ieee1394_init); diff -ur linux-2.6.17/drivers/ieee1394/ieee1394_core.h linux-2.6.17-devfs/drivers/ieee1394/ieee1394_core.h --- linux-2.6.17/drivers/ieee1394/ieee1394_core.h 2006-06-17 18:49:35.000000000 -0700 +++ linux-2.6.17-devfs/drivers/ieee1394/ieee1394_core.h 2006-08-25 11:06:18.000000000 -0700 @@ -3,6 +3,7 @@ #define _IEEE1394_CORE_H #include +#include #include #include #include "hosts.h" diff -ur linux-2.6.17/drivers/ieee1394/raw1394.c linux-2.6.17-devfs/drivers/ieee1394/raw1394.c --- linux-2.6.17/drivers/ieee1394/raw1394.c 2006-06-17 18:49:35.000000000 -0700 +++ linux-2.6.17-devfs/drivers/ieee1394/raw1394.c 2006-08-25 11:06:18.000000000 -0700 @@ -41,6 +41,7 @@ #include #include #include +#include #include #include "csr1212.h" @@ -2998,6 +2999,9 @@ goto out_unreg; } + devfs_mk_cdev(MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16), + S_IFCHR | S_IRUSR | S_IWUSR, RAW1394_DEVICE_NAME); + cdev_init(&raw1394_cdev, &raw1394_fops); raw1394_cdev.owner = THIS_MODULE; kobject_set_name(&raw1394_cdev.kobj, RAW1394_DEVICE_NAME); @@ -3019,6 +3023,7 @@ goto out; out_dev: + devfs_remove(RAW1394_DEVICE_NAME); class_device_destroy(hpsb_protocol_class, MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16)); @@ -3034,6 +3039,7 @@ MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16)); cdev_del(&raw1394_cdev); + devfs_remove(RAW1394_DEVICE_NAME); hpsb_unregister_highlevel(&raw1394_highlevel); hpsb_unregister_protocol(&raw1394_driver); } diff -ur linux-2.6.17/drivers/ieee1394/video1394.c linux-2.6.17-devfs/drivers/ieee1394/video1394.c --- linux-2.6.17/drivers/ieee1394/video1394.c 2006-06-17 18:49:35.000000000 -0700 +++ linux-2.6.17-devfs/drivers/ieee1394/video1394.c 2006-08-25 11:06:18.000000000 -0700 @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -1321,6 +1322,9 @@ class_device_create(hpsb_protocol_class, NULL, MKDEV( IEEE1394_MAJOR, minor), NULL, "%s-%d", VIDEO1394_DRIVER_NAME, ohci->host->id); + devfs_mk_cdev(MKDEV(IEEE1394_MAJOR, minor), + S_IFCHR | S_IRUSR | S_IWUSR, + "%s/%d", VIDEO1394_DRIVER_NAME, ohci->host->id); } @@ -1328,9 +1332,12 @@ { struct ti_ohci *ohci = hpsb_get_hostinfo(&video1394_highlevel, host); - if (ohci) + if (ohci) { class_device_destroy(hpsb_protocol_class, MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_VIDEO1394 * 16 + ohci->host->id)); + devfs_remove("%s/%d", VIDEO1394_DRIVER_NAME, ohci->host->id); + } + return; } @@ -1471,8 +1478,12 @@ static void __exit video1394_exit_module (void) { hpsb_unregister_protocol(&video1394_driver); + hpsb_unregister_highlevel(&video1394_highlevel); + + devfs_remove(VIDEO1394_DRIVER_NAME); cdev_del(&video1394_cdev); + PRINT_G(KERN_INFO, "Removed " VIDEO1394_DRIVER_NAME " module"); } @@ -1489,12 +1500,15 @@ return ret; } + devfs_mk_dir(VIDEO1394_DRIVER_NAME); + hpsb_register_highlevel(&video1394_highlevel); ret = hpsb_register_protocol(&video1394_driver); if (ret) { PRINT_G(KERN_ERR, "video1394: failed to register protocol"); hpsb_unregister_highlevel(&video1394_highlevel); + devfs_remove(VIDEO1394_DRIVER_NAME); cdev_del(&video1394_cdev); return ret; } diff -ur linux-2.6.17/drivers/scsi/osst.c linux-2.6.17-devfs/drivers/scsi/osst.c --- linux-2.6.17/drivers/scsi/osst.c 2006-06-17 18:49:35.000000000 -0700 +++ linux-2.6.17-devfs/drivers/scsi/osst.c 2006-08-25 11:06:18.000000000 -0700 @@ -48,6 +48,7 @@ #include #include #include +#include #include #include #include @@ -5721,7 +5722,7 @@ struct st_partstat * STps; struct osst_buffer * buffer; struct gendisk * drive; - int i, dev_num; + int i, mode, dev_num; if (SDp->type != TYPE_TAPE || !osst_supports(SDp)) return -ENODEV; @@ -5857,6 +5858,18 @@ snprintf(name, 8, "%s%s", "n", tape_name(tpnt)); osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num + 128), dev, tpnt, name); } + for (mode = 0; mode < ST_NBR_MODES; ++mode) { + /* Rewind entry */ + devfs_mk_cdev(MKDEV(OSST_MAJOR, dev_num + (mode << 5)), + S_IFCHR | S_IRUGO | S_IWUGO, + "%s/ot%s", SDp->devfs_name, osst_formats[mode]); + + /* No-rewind entry */ + devfs_mk_cdev(MKDEV(OSST_MAJOR, dev_num + (mode << 5) + 128), + S_IFCHR | S_IRUGO | S_IWUGO, + "%s/ot%sn", SDp->devfs_name, osst_formats[mode]); + } + drive->number = devfs_register_tape(SDp->devfs_name); sdev_printk(KERN_INFO, SDp, "osst :I: Attached OnStream %.5s tape as %s\n", @@ -5873,7 +5886,7 @@ { struct scsi_device * SDp = to_scsi_device(dev); struct osst_tape * tpnt; - int i; + int i, mode; if ((SDp->type != TYPE_TAPE) || (osst_nr_dev <= 0)) return 0; @@ -5884,6 +5897,11 @@ osst_sysfs_destroy(MKDEV(OSST_MAJOR, i)); osst_sysfs_destroy(MKDEV(OSST_MAJOR, i+128)); tpnt->device = NULL; + for (mode = 0; mode < ST_NBR_MODES; ++mode) { + devfs_remove("%s/ot%s", SDp->devfs_name, osst_formats[mode]); + devfs_remove("%s/ot%sn", SDp->devfs_name, osst_formats[mode]); + } + devfs_unregister_tape(tpnt->drive->number); put_disk(tpnt->drive); os_scsi_tapes[i] = NULL; osst_nr_dev--; diff -ur linux-2.6.17/drivers/scsi/scsi.c linux-2.6.17-devfs/drivers/scsi/scsi.c --- linux-2.6.17/drivers/scsi/scsi.c 2006-06-17 18:49:35.000000000 -0700 +++ linux-2.6.17-devfs/drivers/scsi/scsi.c 2006-08-25 11:07:42.000000000 -0700 @@ -48,6 +48,7 @@ #include #include #include +#include #include #include #include @@ -1247,6 +1248,7 @@ for_each_possible_cpu(i) INIT_LIST_HEAD(&per_cpu(scsi_done_q, i)); + devfs_mk_dir("scsi"); printk(KERN_NOTICE "SCSI subsystem initialized\n"); return 0; @@ -1271,6 +1273,7 @@ scsi_exit_sysctl(); scsi_exit_hosts(); scsi_exit_devinfo(); + devfs_remove("scsi"); scsi_exit_procfs(); scsi_exit_queue(); } diff -ur linux-2.6.17/drivers/scsi/scsi_scan.c linux-2.6.17-devfs/drivers/scsi/scsi_scan.c --- linux-2.6.17/drivers/scsi/scsi_scan.c 2006-06-17 18:49:35.000000000 -0700 +++ linux-2.6.17-devfs/drivers/scsi/scsi_scan.c 2006-08-25 11:06:18.000000000 -0700 @@ -716,8 +716,12 @@ if (inq_result[7] & 0x10) sdev->sdtr = 1; + sprintf(sdev->devfs_name, "scsi/host%d/bus%d/target%d/lun%d", + sdev->host->host_no, sdev->channel, + sdev->id, sdev->lun); + /* - * End sysfs code. + * End driverfs/devfs code. */ if ((sdev->scsi_level >= SCSI_2) && (inq_result[7] & 2) && diff -ur linux-2.6.17/drivers/scsi/sd.c linux-2.6.17-devfs/drivers/scsi/sd.c --- linux-2.6.17/drivers/scsi/sd.c 2006-06-17 18:49:35.000000000 -0700 +++ linux-2.6.17-devfs/drivers/scsi/sd.c 2006-08-25 11:06:18.000000000 -0700 @@ -1683,6 +1683,8 @@ 'a' + m1, 'a' + m2, 'a' + m3); } + strcpy(gd->devfs_name, sdp->devfs_name); + gd->private_data = &sdkp->driver; gd->queue = sdkp->device->request_queue; diff -ur linux-2.6.17/drivers/scsi/sg.c linux-2.6.17-devfs/drivers/scsi/sg.c --- linux-2.6.17/drivers/scsi/sg.c 2006-06-17 18:49:35.000000000 -0700 +++ linux-2.6.17-devfs/drivers/scsi/sg.c 2006-08-25 11:06:18.000000000 -0700 @@ -44,6 +44,7 @@ #include #include #include +#include #include #include #include @@ -1427,10 +1428,14 @@ k = error; sdp = sg_dev_arr[k]; + devfs_mk_cdev(MKDEV(SCSI_GENERIC_MAJOR, k), + S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, + "%s/generic", scsidp->devfs_name); error = cdev_add(cdev, MKDEV(SCSI_GENERIC_MAJOR, k), 1); - if (error) + if (error) { + devfs_remove("%s/generic", scsidp->devfs_name); goto out; - + } sdp->cdev = cdev; if (sg_sysfs_valid) { struct class_device * sg_class_member; @@ -1520,6 +1525,7 @@ class_device_destroy(sg_sysfs_class, MKDEV(SCSI_GENERIC_MAJOR, k)); cdev_del(sdp->cdev); sdp->cdev = NULL; + devfs_remove("%s/generic", scsidp->devfs_name); put_disk(sdp->disk); sdp->disk = NULL; if (NULL == sdp->headfp) diff -ur linux-2.6.17/drivers/scsi/sr.c linux-2.6.17-devfs/drivers/scsi/sr.c --- linux-2.6.17/drivers/scsi/sr.c 2006-06-17 18:49:35.000000000 -0700 +++ linux-2.6.17-devfs/drivers/scsi/sr.c 2006-08-25 11:06:18.000000000 -0700 @@ -592,6 +592,8 @@ get_capabilities(cd); sr_vendor_init(cd); + snprintf(disk->devfs_name, sizeof(disk->devfs_name), + "%s/cd", sdev->devfs_name); disk->driverfs_dev = &sdev->sdev_gendev; set_capacity(disk, cd->capacity); disk->private_data = &cd->driver; diff -ur linux-2.6.17/drivers/scsi/st.c linux-2.6.17-devfs/drivers/scsi/st.c --- linux-2.6.17/drivers/scsi/st.c 2006-06-17 18:49:35.000000000 -0700 +++ linux-2.6.17-devfs/drivers/scsi/st.c 2006-08-25 11:06:18.000000000 -0700 @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -4053,8 +4054,23 @@ do_create_class_files(tpnt, dev_num, mode); } + for (mode = 0; mode < ST_NBR_MODES; ++mode) { + /* Make sure that the minor numbers corresponding to the four + first modes always get the same names */ + i = mode << (4 - ST_NBR_MODE_BITS); + /* Rewind entry */ + devfs_mk_cdev(MKDEV(SCSI_TAPE_MAJOR, TAPE_MINOR(dev_num, mode, 0)), + S_IFCHR | S_IRUGO | S_IWUGO, + "%s/mt%s", SDp->devfs_name, st_formats[i]); + /* No-rewind entry */ + devfs_mk_cdev(MKDEV(SCSI_TAPE_MAJOR, TAPE_MINOR(dev_num, mode, 1)), + S_IFCHR | S_IRUGO | S_IWUGO, + "%s/mt%sn", SDp->devfs_name, st_formats[i]); + } + disk->number = devfs_register_tape(SDp->devfs_name); + sdev_printk(KERN_WARNING, SDp, "Attached scsi tape %s\n", tape_name(tpnt)); printk(KERN_WARNING "%s: try direct i/o: %s (alignment %d B)\n", tape_name(tpnt), tpnt->try_dio ? "yes" : "no", queue_dma_alignment(SDp->request_queue) + 1); @@ -4106,9 +4122,13 @@ scsi_tapes[i] = NULL; st_nr_dev--; write_unlock(&st_dev_arr_lock); + devfs_unregister_tape(tpnt->disk->number); sysfs_remove_link(&tpnt->device->sdev_gendev.kobj, "tape"); for (mode = 0; mode < ST_NBR_MODES; ++mode) { + j = mode << (4 - ST_NBR_MODE_BITS); + devfs_remove("%s/mt%s", SDp->devfs_name, st_formats[j]); + devfs_remove("%s/mt%sn", SDp->devfs_name, st_formats[j]); for (j=0; j < 2; j++) { class_device_destroy(st_sysfs_class, MKDEV(SCSI_TAPE_MAJOR, diff -ur linux-2.6.17/include/scsi/scsi_device.h linux-2.6.17-devfs/include/scsi/scsi_device.h --- linux-2.6.17/include/scsi/scsi_device.h 2006-06-17 18:49:35.000000000 -0700 +++ linux-2.6.17-devfs/include/scsi/scsi_device.h 2006-08-25 11:06:18.000000000 -0700 @@ -74,6 +74,7 @@ unsigned sector_size; /* size in bytes */ void *hostdata; /* available to low-level driver */ + char devfs_name[256]; /* devfs junk */ char type; char scsi_level; char inq_periph_qual; /* PQ from INQUIRY data */