libusual and ub
by Pete Zaitcev
Hi, Dave, Jeremy, and others:
I think now may be the time to enable ub in Rawhide and see if it sticks.
The problem it is trying to address is to have fewer oopses and/or lockups
related to the usb-storage. I have to say, I do not see all that many
these days, but when they do happen, it always happens as if on purpose
to break our schedule.
Since ub does not support all storage devices, and never will, I developed
a way for it to coexist with usb-storage. A patch called "libusual"
provides the necessary routing. It is attached at the bottom of this
message, and I think is necessary if we are to have ub at all.
In order to reap the benefit of ub, I consider it desirable to make
it default in libusual. This is, of course, risky. But if we do not
do it, Anaconda will be the only user, and it's a hell to debug
anything in the installation environment. I would rather have users
to poke at ub without installations first, by pulling kernels with yum.
To that end, the patch below defaults to ub. This is NOT how it is
done upstream.
Speaking of upstream, libusual is in Greg Kroah's tree, on its way
to AKPM, and is pretty far from Linus tree. Fedora is to test it
ahead of time, in my plan. I would like to ask if you guys are good
with it. We are in Rawhide, and just coming up to Test 1, after all.
I reckoned it appropriate to give a kind of technology preview.
-- Pete
diff -urpN -X dontdiff linux-2.6.14/drivers/block/Kconfig linux-2.6.14-lem/drivers/block/Kconfig
--- linux-2.6.14/drivers/block/Kconfig 2005-10-28 19:11:37.000000000 -0700
+++ linux-2.6.14-lem/drivers/block/Kconfig 2005-10-28 23:10:23.000000000 -0700
@@ -358,7 +358,8 @@ config BLK_DEV_UB
This driver supports certain USB attached storage devices
such as flash keys.
- Warning: Enabling this cripples the usb-storage driver.
+ If you enable this driver, it is recommended to avoid conflicts
+ with usb-storage by enabling USB_LIBUSUAL.
If unsure, say N.
diff -urpN -X dontdiff linux-2.6.14/drivers/block/ub.c linux-2.6.14-lem/drivers/block/ub.c
--- linux-2.6.14/drivers/block/ub.c 2005-10-28 19:11:38.000000000 -0700
+++ linux-2.6.14-lem/drivers/block/ub.c 2005-10-28 23:10:23.000000000 -0700
@@ -29,6 +29,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/usb.h>
+#include <linux/usb_usual.h>
#include <linux/blkdev.h>
#include <linux/devfs_fs_kernel.h>
#include <linux/timer.h>
@@ -107,16 +108,6 @@
*/
/*
- * Definitions which have to be scattered once we understand the layout better.
- */
-
-/* Transport (despite PR in the name) */
-#define US_PR_BULK 0x50 /* bulk only */
-
-/* Protocol */
-#define US_SC_SCSI 0x06 /* Transparent */
-
-/*
* This many LUNs per USB device.
* Every one of them takes a host, see UB_MAX_HOSTS.
*/
@@ -422,13 +413,18 @@ static int ub_probe_lun(struct ub_dev *s
/*
*/
+#ifdef CONFIG_USB_LIBUSUAL
+
+#define ub_usb_ids storage_usb_ids
+#else
+
static struct usb_device_id ub_usb_ids[] = {
- // { USB_DEVICE_VER(0x0781, 0x0002, 0x0009, 0x0009) }, /* SDDR-31 */
{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_SCSI, US_PR_BULK) },
{ }
};
MODULE_DEVICE_TABLE(usb, ub_usb_ids);
+#endif /* CONFIG_USB_LIBUSUAL */
/*
* Find me a way to identify "next free minor" for add_disk(),
@@ -2172,6 +2168,9 @@ static int ub_probe(struct usb_interface
int rc;
int i;
+ if (usb_usual_check_type(dev_id, USB_US_TYPE_UB))
+ return -ENXIO;
+
rc = -ENOMEM;
if ((sc = kmalloc(sizeof(struct ub_dev), GFP_KERNEL)) == NULL)
goto err_core;
@@ -2479,6 +2478,7 @@ static int __init ub_init(void)
if ((rc = usb_register(&ub_driver)) != 0)
goto err_register;
+ usb_usual_set_present(USB_US_TYPE_UB);
return 0;
err_register:
@@ -2494,6 +2494,7 @@ static void __exit ub_exit(void)
devfs_remove(DEVFS_NAME);
unregister_blkdev(UB_MAJOR, DRV_NAME);
+ usb_usual_clear_present(USB_US_TYPE_UB);
}
module_init(ub_init);
diff -urpN -X dontdiff linux-2.6.14/drivers/usb/storage/Kconfig linux-2.6.14-lem/drivers/usb/storage/Kconfig
--- linux-2.6.14/drivers/usb/storage/Kconfig 2005-10-28 19:12:03.000000000 -0700
+++ linux-2.6.14-lem/drivers/usb/storage/Kconfig 2005-10-28 23:10:23.000000000 -0700
@@ -123,3 +123,17 @@ config USB_STORAGE_ONETOUCH
hard drive's as an input device. An action can be associated with
this input in any keybinding software. (e.g. gnome's keyboard short-
cuts)
+
+config USB_LIBUSUAL
+ bool "The shared table of common (or usual) storage devices"
+ depends on USB
+ help
+ This module contains a table of common (or usual) devices
+ for usb-storage and ub drivers, and allows to switch binding
+ of these devices without rebuilding modules.
+
+ Typical syntax of /etc/modprobe.conf is:
+
+ options libusual bias="ub"
+
+ If unsure, say N.
diff -urpN -X dontdiff linux-2.6.14/drivers/usb/storage/libusual.c linux-2.6.14-lem/drivers/usb/storage/libusual.c
--- linux-2.6.14/drivers/usb/storage/libusual.c 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.6.14-lem/drivers/usb/storage/libusual.c 2005-10-28 23:10:23.000000000 -0700
@@ -0,0 +1,266 @@
+/*
+ * libusual
+ *
+ * The libusual contains the table of devices common for ub and usb-storage.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/usb_usual.h>
+#include <linux/vmalloc.h>
+
+/*
+ */
+#define USU_MOD_FL_THREAD 1 /* Thread is running */
+#define USU_MOD_FL_PRESENT 2 /* The module is loaded */
+
+struct mod_status {
+ unsigned long fls;
+};
+
+static struct mod_status stat[3];
+static DEFINE_SPINLOCK(usu_lock);
+
+/*
+ */
+#define USB_US_DEFAULT_BIAS USB_US_TYPE_UB
+
+#define BIAS_NAME_SIZE (sizeof("usb-storage"))
+static char bias[BIAS_NAME_SIZE];
+static int usb_usual_bias;
+static const char *bias_names[3] = { "none", "usb-storage", "ub" };
+
+static DECLARE_MUTEX_LOCKED(usu_init_notify);
+static DECLARE_COMPLETION(usu_end_notify);
+static atomic_t total_threads = ATOMIC_INIT(0);
+
+static int usu_probe_thread(void *arg);
+static int parse_bias(const char *bias_s);
+
+/*
+ * The table.
+ */
+#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
+ vendorName, productName,useProtocol, useTransport, \
+ initFunction, flags) \
+{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin,bcdDeviceMax), \
+ .driver_info = (flags)|(USB_US_TYPE_STOR<<24) }
+
+#define USUAL_DEV(useProto, useTrans, useType) \
+{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, useProto, useTrans), \
+ .driver_info = ((useType)<<24) }
+
+struct usb_device_id storage_usb_ids [] = {
+# include "unusual_devs.h"
+ { } /* Terminating entry */
+};
+
+#undef USUAL_DEV
+#undef UNUSUAL_DEV
+
+MODULE_DEVICE_TABLE(usb, storage_usb_ids);
+EXPORT_SYMBOL(storage_usb_ids);
+
+/*
+ * @type: the module type as an integer
+ */
+void usb_usual_set_present(int type)
+{
+ struct mod_status *st;
+ unsigned long flags;
+
+ if (type <= 0 || type >= 3)
+ return;
+ st = &stat[type];
+ spin_lock_irqsave(&usu_lock, flags);
+ st->fls |= USU_MOD_FL_PRESENT;
+ spin_unlock_irqrestore(&usu_lock, flags);
+}
+EXPORT_SYMBOL(usb_usual_set_present);
+
+void usb_usual_clear_present(int type)
+{
+ struct mod_status *st;
+ unsigned long flags;
+
+ if (type <= 0 || type >= 3)
+ return;
+ st = &stat[type];
+ spin_lock_irqsave(&usu_lock, flags);
+ st->fls &= ~USU_MOD_FL_PRESENT;
+ spin_unlock_irqrestore(&usu_lock, flags);
+}
+EXPORT_SYMBOL(usb_usual_clear_present);
+
+/*
+ * Match the calling driver type against the table.
+ * Returns: 0 if the device matches.
+ */
+int usb_usual_check_type(const struct usb_device_id *id, int caller_type)
+{
+ int id_type = USB_US_TYPE(id->driver_info);
+
+ if (caller_type <= 0 || caller_type >= 3)
+ return -EINVAL;
+
+ /* Drivers grab fixed assignment devices */
+ if (id_type == caller_type)
+ return 0;
+ /* Drivers grab devices biased to them */
+ if (id_type == USB_US_TYPE_NONE && caller_type == usb_usual_bias)
+ return 0;
+ return -ENODEV;
+}
+EXPORT_SYMBOL(usb_usual_check_type);
+
+/*
+ */
+static int usu_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ int type;
+ int rc;
+ unsigned long flags;
+
+ type = USB_US_TYPE(id->driver_info);
+ if (type == 0)
+ type = usb_usual_bias;
+
+ spin_lock_irqsave(&usu_lock, flags);
+ if ((stat[type].fls & (USU_MOD_FL_THREAD|USU_MOD_FL_PRESENT)) != 0) {
+ spin_unlock_irqrestore(&usu_lock, flags);
+ return -ENXIO;
+ }
+ stat[type].fls |= USU_MOD_FL_THREAD;
+ spin_unlock_irqrestore(&usu_lock, flags);
+
+ rc = kernel_thread(usu_probe_thread, (void*)type, CLONE_VM);
+ if (rc < 0) {
+ printk(KERN_WARNING "libusual: "
+ "Unable to start the thread for %s: %d\n",
+ bias_names[type], rc);
+ spin_lock_irqsave(&usu_lock, flags);
+ stat[type].fls &= ~USU_MOD_FL_THREAD;
+ spin_unlock_irqrestore(&usu_lock, flags);
+ return rc; /* Not being -ENXIO causes a message printed */
+ }
+ atomic_inc(&total_threads);
+
+ return -ENXIO;
+}
+
+static void usu_disconnect(struct usb_interface *intf)
+{
+ ; /* We should not be here. */
+}
+
+static struct usb_driver usu_driver = {
+ .owner = THIS_MODULE,
+ .name = "libusual",
+ .probe = usu_probe,
+ .disconnect = usu_disconnect,
+ .id_table = storage_usb_ids,
+};
+
+/*
+ * A whole new thread for a purpose of request_module seems quite stupid.
+ * The request_module forks once inside again. However, if we attempt
+ * to load a storage module from our own modprobe thread, that module
+ * references our symbols, which cannot be resolved until our module is
+ * initialized. I wish there was a way to wait for the end of initialization.
+ * The module notifier reports MODULE_STATE_COMING only.
+ * So, we wait until module->init ends as the next best thing.
+ */
+static int usu_probe_thread(void *arg)
+{
+ int type = (unsigned long) arg;
+ struct mod_status *st = &stat[type];
+ int rc;
+ unsigned long flags;
+
+ daemonize("libusual_%d", type); /* "usb-storage" is kinda too long */
+
+ /* A completion does not work here because it's counted. */
+ down(&usu_init_notify);
+ up(&usu_init_notify);
+
+ rc = request_module(bias_names[type]);
+ spin_lock_irqsave(&usu_lock, flags);
+ if (rc == 0 && (st->fls & USU_MOD_FL_PRESENT) == 0) {
+ /*
+ * This should not happen, but let us keep tabs on it.
+ */
+ printk(KERN_NOTICE "libusual: "
+ "modprobe for %s succeeded, but module is not present\n",
+ bias_names[type]);
+ }
+ st->fls &= ~USU_MOD_FL_THREAD;
+ spin_unlock_irqrestore(&usu_lock, flags);
+
+ complete_and_exit(&usu_end_notify, 0);
+}
+
+/*
+ */
+static int __init usb_usual_init(void)
+{
+ int rc;
+
+ bias[BIAS_NAME_SIZE-1] = 0;
+ usb_usual_bias = parse_bias(bias);
+
+ rc = usb_register(&usu_driver);
+ up(&usu_init_notify);
+ return rc;
+}
+
+static void __exit usb_usual_exit(void)
+{
+ /*
+ * We do not check for any drivers present, because
+ * they keep us pinned with symbol references.
+ */
+
+ usb_deregister(&usu_driver);
+
+ while (atomic_read(&total_threads) > 0) {
+ wait_for_completion(&usu_end_notify);
+ atomic_dec(&total_threads);
+ }
+}
+
+/*
+ * Validate and accept the bias parameter.
+ * Maybe make an sysfs method later. XXX
+ */
+static int parse_bias(const char *bias_s)
+{
+ int i;
+ int bias_n = 0;
+
+ if (bias_s[0] == 0 || bias_s[0] == ' ') {
+ bias_n = USB_US_DEFAULT_BIAS;
+ } else {
+ for (i = 1; i < 3; i++) {
+ if (strcmp(bias_s, bias_names[i]) == 0) {
+ bias_n = i;
+ break;
+ }
+ }
+ if (bias_n == 0) {
+ bias_n = USB_US_DEFAULT_BIAS;
+ printk(KERN_INFO
+ "libusual: unknown bias \"%s\", using \"%s\"\n",
+ bias_s, bias_names[bias_n]);
+ }
+ }
+ return bias_n;
+}
+
+module_init(usb_usual_init);
+module_exit(usb_usual_exit);
+
+module_param_string(bias, bias, BIAS_NAME_SIZE, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(bias, "Bias to usb-storage or ub");
+
+MODULE_LICENSE("GPL");
diff -urpN -X dontdiff linux-2.6.14/drivers/usb/storage/Makefile linux-2.6.14-lem/drivers/usb/storage/Makefile
--- linux-2.6.14/drivers/usb/storage/Makefile 2005-10-28 19:12:03.000000000 -0700
+++ linux-2.6.14-lem/drivers/usb/storage/Makefile 2005-10-28 23:10:23.000000000 -0700
@@ -22,3 +22,7 @@ usb-storage-obj-$(CONFIG_USB_STORAGE_ONE
usb-storage-objs := scsiglue.o protocol.o transport.o usb.o \
initializers.o $(usb-storage-obj-y)
+
+ifneq ($(CONFIG_USB_LIBUSUAL),)
+ obj-$(CONFIG_USB) += libusual.o
+endif
diff -urpN -X dontdiff linux-2.6.14/drivers/usb/storage/protocol.h linux-2.6.14-lem/drivers/usb/storage/protocol.h
--- linux-2.6.14/drivers/usb/storage/protocol.h 2005-06-17 12:48:29.000000000 -0700
+++ linux-2.6.14-lem/drivers/usb/storage/protocol.h 2005-10-28 23:10:23.000000000 -0700
@@ -41,20 +41,6 @@
#ifndef _PROTOCOL_H_
#define _PROTOCOL_H_
-/* Sub Classes */
-
-#define US_SC_RBC 0x01 /* Typically, flash devices */
-#define US_SC_8020 0x02 /* CD-ROM */
-#define US_SC_QIC 0x03 /* QIC-157 Tapes */
-#define US_SC_UFI 0x04 /* Floppy */
-#define US_SC_8070 0x05 /* Removable media */
-#define US_SC_SCSI 0x06 /* Transparent */
-#define US_SC_ISD200 0x07 /* ISD200 ATA */
-#define US_SC_MIN US_SC_RBC
-#define US_SC_MAX US_SC_ISD200
-
-#define US_SC_DEVICE 0xff /* Use device's value */
-
/* Protocol handling routines */
extern void usb_stor_ATAPI_command(struct scsi_cmnd*, struct us_data*);
extern void usb_stor_qic157_command(struct scsi_cmnd*, struct us_data*);
diff -urpN -X dontdiff linux-2.6.14/drivers/usb/storage/transport.h linux-2.6.14-lem/drivers/usb/storage/transport.h
--- linux-2.6.14/drivers/usb/storage/transport.h 2005-09-13 01:06:21.000000000 -0700
+++ linux-2.6.14-lem/drivers/usb/storage/transport.h 2005-10-28 23:10:23.000000000 -0700
@@ -41,39 +41,8 @@
#ifndef _TRANSPORT_H_
#define _TRANSPORT_H_
-#include <linux/config.h>
#include <linux/blkdev.h>
-/* Protocols */
-
-#define US_PR_CBI 0x00 /* Control/Bulk/Interrupt */
-#define US_PR_CB 0x01 /* Control/Bulk w/o interrupt */
-#define US_PR_BULK 0x50 /* bulk only */
-#ifdef CONFIG_USB_STORAGE_USBAT
-#define US_PR_SCM_ATAPI 0x80 /* SCM-ATAPI bridge */
-#endif
-#ifdef CONFIG_USB_STORAGE_SDDR09
-#define US_PR_EUSB_SDDR09 0x81 /* SCM-SCSI bridge for SDDR-09 */
-#endif
-#ifdef CONFIG_USB_STORAGE_SDDR55
-#define US_PR_SDDR55 0x82 /* SDDR-55 (made up) */
-#endif
-#define US_PR_DPCM_USB 0xf0 /* Combination CB/SDDR09 */
-
-#ifdef CONFIG_USB_STORAGE_FREECOM
-#define US_PR_FREECOM 0xf1 /* Freecom */
-#endif
-
-#ifdef CONFIG_USB_STORAGE_DATAFAB
-#define US_PR_DATAFAB 0xf2 /* Datafab chipsets */
-#endif
-
-#ifdef CONFIG_USB_STORAGE_JUMPSHOT
-#define US_PR_JUMPSHOT 0xf3 /* Lexar Jumpshot */
-#endif
-
-#define US_PR_DEVICE 0xff /* Use device's value */
-
/*
* Bulk only data structures
*/
diff -urpN -X dontdiff linux-2.6.14/drivers/usb/storage/unusual_devs.h linux-2.6.14-lem/drivers/usb/storage/unusual_devs.h
--- linux-2.6.14/drivers/usb/storage/unusual_devs.h 2005-10-28 19:12:04.000000000 -0700
+++ linux-2.6.14-lem/drivers/usb/storage/unusual_devs.h 2005-10-28 23:10:23.000000000 -0700
@@ -1093,3 +1113,27 @@ UNUSUAL_DEV( 0x55aa, 0xa103, 0x0000, 0x
US_SC_SCSI, US_PR_SDDR55, NULL,
US_FL_SINGLE_LUN),
#endif
+
+/* Control/Bulk transport for all SubClass values */
+USUAL_DEV(US_SC_RBC, US_PR_CB, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_8020, US_PR_CB, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_QIC, US_PR_CB, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_UFI, US_PR_CB, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_8070, US_PR_CB, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_SCSI, US_PR_CB, USB_US_TYPE_STOR),
+
+/* Control/Bulk/Interrupt transport for all SubClass values */
+USUAL_DEV(US_SC_RBC, US_PR_CBI, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_8020, US_PR_CBI, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_QIC, US_PR_CBI, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_UFI, US_PR_CBI, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_8070, US_PR_CBI, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_SCSI, US_PR_CBI, USB_US_TYPE_STOR),
+
+/* Bulk-only transport for all SubClass values */
+USUAL_DEV(US_SC_RBC, US_PR_BULK, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_8020, US_PR_BULK, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_QIC, US_PR_BULK, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_UFI, US_PR_BULK, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_8070, US_PR_BULK, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_SCSI, US_PR_BULK, 0),
diff -urpN -X dontdiff linux-2.6.14/drivers/usb/storage/usb.c linux-2.6.14-lem/drivers/usb/storage/usb.c
--- linux-2.6.14/drivers/usb/storage/usb.c 2005-10-28 19:12:04.000000000 -0700
+++ linux-2.6.14-lem/drivers/usb/storage/usb.c 2005-10-28 23:10:23.000000000 -0700
@@ -116,49 +116,33 @@ static int storage_probe(struct usb_inte
static void storage_disconnect(struct usb_interface *iface);
-/* The entries in this table, except for final ones here
- * (USB_MASS_STORAGE_CLASS and the empty entry), correspond,
- * line for line with the entries of us_unsuaul_dev_list[].
+/*
+ * The entries in this table correspond, line for line,
+ * with the entries of us_unusual_dev_list[].
*/
+#ifndef CONFIG_USB_LIBUSUAL
#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
vendorName, productName,useProtocol, useTransport, \
initFunction, flags) \
-{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin,bcdDeviceMax) }
+{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin,bcdDeviceMax), \
+ .driver_info = (flags)|(USB_US_TYPE_STOR<<24) }
+
+#define USUAL_DEV(useProto, useTrans, useType) \
+{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, useProto, useTrans), \
+ .driver_info = (USB_US_TYPE_STOR<<24) }
static struct usb_device_id storage_usb_ids [] = {
# include "unusual_devs.h"
#undef UNUSUAL_DEV
- /* Control/Bulk transport for all SubClass values */
- { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_RBC, US_PR_CB) },
- { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8020, US_PR_CB) },
- { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_QIC, US_PR_CB) },
- { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_UFI, US_PR_CB) },
- { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8070, US_PR_CB) },
- { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_SCSI, US_PR_CB) },
-
- /* Control/Bulk/Interrupt transport for all SubClass values */
- { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_RBC, US_PR_CBI) },
- { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8020, US_PR_CBI) },
- { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_QIC, US_PR_CBI) },
- { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_UFI, US_PR_CBI) },
- { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8070, US_PR_CBI) },
- { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_SCSI, US_PR_CBI) },
-
- /* Bulk-only transport for all SubClass values */
- { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_RBC, US_PR_BULK) },
- { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8020, US_PR_BULK) },
- { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_QIC, US_PR_BULK) },
- { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_UFI, US_PR_BULK) },
- { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8070, US_PR_BULK) },
- { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_SCSI, US_PR_BULK) },
-
+#undef USUAL_DEV
/* Terminating entry */
{ }
};
MODULE_DEVICE_TABLE (usb, storage_usb_ids);
+#endif /* CONFIG_USB_LIBUSUAL */
/* This is the list of devices we recognize, along with their flag data */
@@ -171,7 +155,6 @@ MODULE_DEVICE_TABLE (usb, storage_usb_id
* are free to use as many characters as you like.
*/
-#undef UNUSUAL_DEV
#define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \
vendor_name, product_name, use_protocol, use_transport, \
init_function, Flags) \
@@ -181,53 +164,18 @@ MODULE_DEVICE_TABLE (usb, storage_usb_id
.useProtocol = use_protocol, \
.useTransport = use_transport, \
.initFunction = init_function, \
- .flags = Flags, \
+}
+
+#define USUAL_DEV(use_protocol, use_transport, use_type) \
+{ \
+ .useProtocol = use_protocol, \
+ .useTransport = use_transport, \
}
static struct us_unusual_dev us_unusual_dev_list[] = {
# include "unusual_devs.h"
# undef UNUSUAL_DEV
- /* Control/Bulk transport for all SubClass values */
- { .useProtocol = US_SC_RBC,
- .useTransport = US_PR_CB},
- { .useProtocol = US_SC_8020,
- .useTransport = US_PR_CB},
- { .useProtocol = US_SC_QIC,
- .useTransport = US_PR_CB},
- { .useProtocol = US_SC_UFI,
- .useTransport = US_PR_CB},
- { .useProtocol = US_SC_8070,
- .useTransport = US_PR_CB},
- { .useProtocol = US_SC_SCSI,
- .useTransport = US_PR_CB},
-
- /* Control/Bulk/Interrupt transport for all SubClass values */
- { .useProtocol = US_SC_RBC,
- .useTransport = US_PR_CBI},
- { .useProtocol = US_SC_8020,
- .useTransport = US_PR_CBI},
- { .useProtocol = US_SC_QIC,
- .useTransport = US_PR_CBI},
- { .useProtocol = US_SC_UFI,
- .useTransport = US_PR_CBI},
- { .useProtocol = US_SC_8070,
- .useTransport = US_PR_CBI},
- { .useProtocol = US_SC_SCSI,
- .useTransport = US_PR_CBI},
-
- /* Bulk-only transport for all SubClass values */
- { .useProtocol = US_SC_RBC,
- .useTransport = US_PR_BULK},
- { .useProtocol = US_SC_8020,
- .useTransport = US_PR_BULK},
- { .useProtocol = US_SC_QIC,
- .useTransport = US_PR_BULK},
- { .useProtocol = US_SC_UFI,
- .useTransport = US_PR_BULK},
- { .useProtocol = US_SC_8070,
- .useTransport = US_PR_BULK},
- { .useProtocol = US_SC_SCSI,
- .useTransport = US_PR_BULK},
+# undef USUAL_DEV
/* Terminating entry */
{ NULL }
@@ -469,15 +417,21 @@ static int associate_dev(struct us_data
}
return 0;
}
+
+/* Find an unusual_dev descriptor (always succeeds in the current code) */
+static struct us_unusual_dev *find_unusual(const struct usb_device_id *id)
+{
+ const int id_index = id - storage_usb_ids;
+ return &us_unusual_dev_list[id_index];
+}
/* Get the unusual_devs entries and the string descriptors */
-static void get_device_info(struct us_data *us, int id_index)
+static void get_device_info(struct us_data *us, const struct usb_device_id *id)
{
struct usb_device *dev = us->pusb_dev;
struct usb_interface_descriptor *idesc =
&us->pusb_intf->cur_altsetting->desc;
- struct us_unusual_dev *unusual_dev = &us_unusual_dev_list[id_index];
- struct usb_device_id *id = &storage_usb_ids[id_index];
+ struct us_unusual_dev *unusual_dev = find_unusual(id);
/* Store the entries */
us->unusual_dev = unusual_dev;
@@ -487,7 +441,7 @@ static void get_device_info(struct us_da
us->protocol = (unusual_dev->useTransport == US_PR_DEVICE) ?
idesc->bInterfaceProtocol :
unusual_dev->useTransport;
- us->flags = unusual_dev->flags;
+ us->flags = USB_US_ORIG_FLAGS(id->driver_info);
/*
* This flag is only needed when we're in high-speed, so let's
@@ -515,7 +469,7 @@ static void get_device_info(struct us_da
if (unusual_dev->useTransport != US_PR_DEVICE &&
us->protocol == idesc->bInterfaceProtocol)
msg += 2;
- if (msg >= 0 && !(unusual_dev->flags & US_FL_NEED_OVERRIDE))
+ if (msg >= 0 && !(us->flags & US_FL_NEED_OVERRIDE))
printk(KERN_NOTICE USB_STORAGE "This device "
"(%04x,%04x,%04x S %02x P %02x)"
" has %s in unusual_devs.h\n"
@@ -921,9 +875,11 @@ static int storage_probe(struct usb_inte
{
struct Scsi_Host *host;
struct us_data *us;
- const int id_index = id - storage_usb_ids;
int result;
+ if (usb_usual_check_type(id, USB_US_TYPE_STOR))
+ return -ENXIO;
+
US_DEBUGP("USB Mass Storage device detected\n");
/*
@@ -956,7 +912,7 @@ static int storage_probe(struct usb_inte
* of the match from the usb_device_id table, so we can find the
* corresponding entry in the private table.
*/
- get_device_info(us, id_index);
+ get_device_info(us, id);
#ifdef CONFIG_USB_STORAGE_SDDR09
if (us->protocol == US_PR_EUSB_SDDR09 ||
@@ -1045,9 +1001,10 @@ static int __init usb_stor_init(void)
/* register the driver, return usb_register return code if error */
retval = usb_register(&usb_storage_driver);
- if (retval == 0)
+ if (retval == 0) {
printk(KERN_INFO "USB Mass Storage support registered.\n");
-
+ usb_usual_set_present(USB_US_TYPE_STOR);
+ }
return retval;
}
@@ -1071,6 +1028,8 @@ static void __exit usb_stor_exit(void)
wait_for_completion(&threads_gone);
atomic_dec(&total_threads);
}
+
+ usb_usual_clear_present(USB_US_TYPE_STOR);
}
module_init(usb_stor_init);
diff -urpN -X dontdiff linux-2.6.14/drivers/usb/storage/usb.h linux-2.6.14-lem/drivers/usb/storage/usb.h
--- linux-2.6.14/drivers/usb/storage/usb.h 2005-10-28 19:12:04.000000000 -0700
+++ linux-2.6.14-lem/drivers/usb/storage/usb.h 2005-10-28 23:10:23.000000000 -0700
@@ -45,6 +45,7 @@
#define _USB_H_
#include <linux/usb.h>
+#include <linux/usb_usual.h>
#include <linux/blkdev.h>
#include <linux/smp_lock.h>
#include <linux/completion.h>
@@ -63,38 +64,8 @@ struct us_unusual_dev {
__u8 useProtocol;
__u8 useTransport;
int (*initFunction)(struct us_data *);
- unsigned int flags;
};
-/*
- * Static flag definitions. We use this roundabout technique so that the
- * proc_info() routine can automatically display a message for each flag.
- */
-#define US_DO_ALL_FLAGS \
- US_FLAG(SINGLE_LUN, 0x00000001) \
- /* allow access to only LUN 0 */ \
- US_FLAG(NEED_OVERRIDE, 0x00000002) \
- /* unusual_devs entry is necessary */ \
- US_FLAG(SCM_MULT_TARG, 0x00000004) \
- /* supports multiple targets */ \
- US_FLAG(FIX_INQUIRY, 0x00000008) \
- /* INQUIRY response needs faking */ \
- US_FLAG(FIX_CAPACITY, 0x00000010) \
- /* READ CAPACITY response too big */ \
- US_FLAG(IGNORE_RESIDUE, 0x00000020) \
- /* reported residue is wrong */ \
- US_FLAG(BULK32, 0x00000040) \
- /* Uses 32-byte CBW length */ \
- US_FLAG(NOT_LOCKABLE, 0x00000080) \
- /* PREVENT/ALLOW not supported */ \
- US_FLAG(GO_SLOW, 0x00000100) \
- /* Need delay after Command phase */ \
- US_FLAG(NO_WP_DETECT, 0x00000200) \
- /* Don't check for write-protect */ \
-
-#define US_FLAG(name, value) US_FL_##name = value ,
-enum { US_DO_ALL_FLAGS };
-#undef US_FLAG
/* Dynamic flag definitions: used in set_bit() etc. */
#define US_FLIDX_URB_ACTIVE 18 /* 0x00040000 current_urb is in use */
diff -urpN -X dontdiff linux-2.6.14/include/linux/usb_usual.h linux-2.6.14-lem/include/linux/usb_usual.h
--- linux-2.6.14/include/linux/usb_usual.h 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.6.14-lem/include/linux/usb_usual.h 2005-10-28 23:10:23.000000000 -0700
@@ -0,0 +1,123 @@
+/*
+ * Interface to the libusual.
+ *
+ * Copyright (c) 2005 Pete Zaitcev <zaitcev(a)redhat.com>
+ * Copyright (c) 1999-2002 Matthew Dharm (mdharm-usb(a)one-eyed-alien.net)
+ * Copyright (c) 1999 Michael Gee (michael(a)linuxspecific.com)
+ */
+
+#ifndef __LINUX_USB_USUAL_H
+#define __LINUX_USB_USUAL_H
+
+#include <linux/config.h>
+
+/* We should do this for cleanliness... But other usb_foo.h do not do this. */
+/* #include <linux/usb.h> */
+
+/*
+ * The flags field, which we store in usb_device_id.driver_info.
+ * It is compatible with the old usb-storage flags in lower 24 bits.
+ */
+
+/*
+ * Static flag definitions. We use this roundabout technique so that the
+ * proc_info() routine can automatically display a message for each flag.
+ */
+#define US_DO_ALL_FLAGS \
+ US_FLAG(SINGLE_LUN, 0x00000001) \
+ /* allow access to only LUN 0 */ \
+ US_FLAG(NEED_OVERRIDE, 0x00000002) \
+ /* unusual_devs entry is necessary */ \
+ US_FLAG(SCM_MULT_TARG, 0x00000004) \
+ /* supports multiple targets */ \
+ US_FLAG(FIX_INQUIRY, 0x00000008) \
+ /* INQUIRY response needs faking */ \
+ US_FLAG(FIX_CAPACITY, 0x00000010) \
+ /* READ CAPACITY response too big */ \
+ US_FLAG(IGNORE_RESIDUE, 0x00000020) \
+ /* reported residue is wrong */ \
+ US_FLAG(BULK32, 0x00000040) \
+ /* Uses 32-byte CBW length */ \
+ US_FLAG(NOT_LOCKABLE, 0x00000080) \
+ /* PREVENT/ALLOW not supported */ \
+ US_FLAG(GO_SLOW, 0x00000100) \
+ /* Need delay after Command phase */ \
+ US_FLAG(NO_WP_DETECT, 0x00000200) \
+ /* Don't check for write-protect */ \
+
+#define US_FLAG(name, value) US_FL_##name = value ,
+enum { US_DO_ALL_FLAGS };
+#undef US_FLAG
+
+/*
+ * The bias field for libusual and friends.
+ */
+#define USB_US_TYPE_NONE 0
+#define USB_US_TYPE_STOR 1 /* usb-storage */
+#define USB_US_TYPE_UB 2 /* ub */
+
+#define USB_US_TYPE(flags) (((flags) >> 24) & 0xFF)
+#define USB_US_ORIG_FLAGS(flags) ((flags) & 0x00FFFFFF)
+
+/*
+ * This is probably not the best place to keep these constants, conceptually.
+ * But it's the only header included into all places which need them.
+ */
+
+/* Sub Classes */
+
+#define US_SC_RBC 0x01 /* Typically, flash devices */
+#define US_SC_8020 0x02 /* CD-ROM */
+#define US_SC_QIC 0x03 /* QIC-157 Tapes */
+#define US_SC_UFI 0x04 /* Floppy */
+#define US_SC_8070 0x05 /* Removable media */
+#define US_SC_SCSI 0x06 /* Transparent */
+#define US_SC_ISD200 0x07 /* ISD200 ATA */
+#define US_SC_MIN US_SC_RBC
+#define US_SC_MAX US_SC_ISD200
+
+#define US_SC_DEVICE 0xff /* Use device's value */
+
+/* Protocols */
+
+#define US_PR_CBI 0x00 /* Control/Bulk/Interrupt */
+#define US_PR_CB 0x01 /* Control/Bulk w/o interrupt */
+#define US_PR_BULK 0x50 /* bulk only */
+#ifdef CONFIG_USB_STORAGE_USBAT
+#define US_PR_SCM_ATAPI 0x80 /* SCM-ATAPI bridge */
+#endif
+#ifdef CONFIG_USB_STORAGE_SDDR09
+#define US_PR_EUSB_SDDR09 0x81 /* SCM-SCSI bridge for SDDR-09 */
+#endif
+#ifdef CONFIG_USB_STORAGE_SDDR55
+#define US_PR_SDDR55 0x82 /* SDDR-55 (made up) */
+#endif
+#define US_PR_DPCM_USB 0xf0 /* Combination CB/SDDR09 */
+#ifdef CONFIG_USB_STORAGE_FREECOM
+#define US_PR_FREECOM 0xf1 /* Freecom */
+#endif
+#ifdef CONFIG_USB_STORAGE_DATAFAB
+#define US_PR_DATAFAB 0xf2 /* Datafab chipsets */
+#endif
+#ifdef CONFIG_USB_STORAGE_JUMPSHOT
+#define US_PR_JUMPSHOT 0xf3 /* Lexar Jumpshot */
+#endif
+
+#define US_PR_DEVICE 0xff /* Use device's value */
+
+/*
+ */
+#ifdef CONFIG_USB_LIBUSUAL
+
+extern struct usb_device_id storage_usb_ids[];
+extern void usb_usual_set_present(int type);
+extern void usb_usual_clear_present(int type);
+extern int usb_usual_check_type(const struct usb_device_id *, int type);
+#else
+
+#define usb_usual_set_present(t) do { } while(0)
+#define usb_usual_clear_present(t) do { } while(0)
+#define usb_usual_check_type(id, t) (0)
+#endif /* CONFIG_USB_LIBUSUAL */
+
+#endif /* __LINUX_USB_USUAL_H */
18 years, 4 months
udev alpha testing
by Harald Hoyer
I would be glad, if the really brave could compile, install and test:
ftp://people.redhat.com/harald/udev/076-1/
Beware this could end in a non-bootable system.
This version removes the hardware initializing/module loading phase from rc.sysinit. Udev should do most, if
not all job. I am interested in any missing modules, that were loaded before.
Thx for testing.
--
Harald
18 years, 4 months
Broken video drivers in new modular X
by Sadda Teh
Hi all, just writing to say that on my Dell Inspiron 8000 laptop (latest
BIOS) with ATI Mobility M4 video the modular X vesa and r128 drivers do not
work properly. When X is configured to use the vesa driver it comes up, but
the picture is distorted (looks like 2 vertical desktops overlapping one
another at various points, also colors are messed up). As for trying to use
the r128 driver, X cannot even load when configured this way, it fails with
an error along the lines of the r128_drv.so could not be opened. Has anyone
else seen issues like this with the new modular X packages? Should I file
bugs for these in x.org <http://x.org>'s bugzilla? Thanks.
18 years, 4 months
disappointment over default acpid config
by Pekka Savola
Hi,
I just replaced with my laptop's OLD but working RHL73 with FC4.
Let me state a strong disappointment over acpid default config.
What "default config" ? Exactly, there is none (the sample config for
power button does not count).
I was stunned how FC could be making ACPI default while completely
ignoring adding any default configs for the users (e.g., starting from
something like http://www.thinkwiki.org/wiki/How_to_configure_acpid) ?
Looking at CVS, this problem doesn't seem to have been addressed in
FC5. I (or I'm sure a lot of other folks) could submit a patch for
starters if that'd be the problem.
--
Pekka Savola "You each name yourselves king, yet the
Netcore Oy kingdom bleeds."
Systems. Networks. Security. -- George R.R. Martin: A Clash of Kings
18 years, 4 months
suggestion: move all java packages to extras
by seth vidal
B/c of the rapidly evolving nature of the gcj and related java tools,
what if we moved them to extras so that work on those packages could be
both public and move faster?
It would be a big savings on the size of core and it seems like adding
those packages over there would be the most correct as the java packages
don't really have any necessary reason to be in core.
What do you think?
-sv
18 years, 4 months
Building FireFox 1.5 SRPMs on FC4...
by Gilboa Davara
Hello all,
Just wondering, I assume that FF 1.5 RPMs will be making their way into
rawhide in the next couple of days.
What are the chances of building their SRPMs on FC4? (x86-64 to be
exact)
Should I just give up and build the vanilla source package?
Gilboa
18 years, 4 months
status of up2date and rhn-applet
by Louis Garcia
Just noticed the these packages are still present in FC5T1. Since yum is
the preferred way to update what is the future of these? Do they still
work? The applet never worked in FC4 by the way.
18 years, 4 months
Pipe dreams: yum-based anaconda a step towards on-line yum-based upgrades?
by Matthew Miller
So, I noticed while doing my first FC5t1 install the upgrades aren't
currently supported in the reworked anaconda. Fair enough; there's a lot of
changes under the hood. But that got me thinking: hey, maybe this is a great
time to get it so that "yum upgrade" can actually easily bring one from one
FC release to the next. (More realistically, maybe FC6 is a great time. But
now might be a time to start thinking about it.)
I know there's historically been a lot of wacky special-casing in Anaconda,
much of it legacy cruft, and much of it kinda important for, y'know,
actually working upgrades.
With switching to a yum-based backend, I imagine that much of this cruft
must be updated. Maybe Jeremy's doing it this way already, but what about
packaging that special-case knowledge into a "distroupgrade" yum plugin
instead of into Anaconda itself, wherever possible? (Some things are easier
done off-line, of course, but maybe those could be made to happen in
firstboot or so?)
As an experiment in support of this hallucinogen-addled fantasy, I installed
a fresh system FC4 system (Workstation install), used yum to apply all
current updates, and then changed the repo config to point at FC5t1. I first
ran yum upgrade yum and then a full "yum -y upgrade".
After some time, this failed, because iiimf-libs is gone, with no
replacement or nothing to obsolete it but with a chain of dependencies.
Quick fix was to just remove that package and try again.
Now, two things -- initscript and kudzu -- failed because of requirements on
kernel < 2.6.12 and 2.6.13, respectively. After some head-scratching, this
turned out to be caused by Conflicts statements and the previously-installed
2.6.11 kernel. (The newly installed-then-yum-upgraded system had the
original FC4 2.6.11 and the newest FC4 2.6.14 both installed, of course.)
Sort ironically, the installonlyn plugin would have actually corrected this
situation, because the result after the upgrade would be to have the FC4
2.6.14 plus the FC5 2.6.14. Anyway, I worked around this by simply removing
the old 2.6.11 kernel.
After that, the yum upgrade went basically fine, and after Some Time passed,
I have what appears to be a fully functional FC5 system. I haven't poked
around too much to find broken spots, and there were a lot of messages about
.rpmsave and .rpmnew, so looking at those is probably in order. But I can
log in to Gnome, browse the web, run OpenOffice, and so on.
But overall, seemed like a pretty successful experiment. And, given the
super-short lifespan of FC releases, something I'd really be interested in
having as an option.
Thoughts, anyone?
-- smokin' the good stuff,
Matthew
--
Matthew Miller mattdm(a)mattdm.org <http://mattdm.org/>
Boston University Linux ------> <http://linux.bu.edu/>
18 years, 4 months
Modern Update System
by Benjy Grogan
Hi:
Is there any work being done for a modern update system that would only
download what is needed instead of an entirely new rpm? I'm sure everyone
has seen the updaet system that Firefox has. It's beautiful. How is that
going to work on Fedora Core 5? Is it disabled? Eitherway, such an update
system on Linux would be a watershed moment perhaps. A grand slam. It is a
bit ridiculous that FC4 updates have possibly mounted up to 10 GB for me..
maybe an exaggeration but you know what I'm getting at.
So any such project out there?
Benjy,
AWWTF
18 years, 4 months
Re: fc5 goals
by Eric TANGUY
Le lundi 28 novembre 2005 à 11:56 -0800, Peter Gordon a écrit :
> Josh Coffman wrote:
> > Anyone know where to find documentation about the
> > goals and improvements intended for FC5?
>
> You might want to take a look at FC5Future[1] on the Wiki, as well.
>
> [1] http://www.fedoraproject.org/wiki/FC5Future
>
> --Peter
>
Why there is so much java package included in fc5 ?
No news about early login or something like that ?
Why kde is still included in core whereas it could be in extras ?
Why some packages go directly in core and not in extras before ? Because
they were packaged by someone from redhat ? Is it sufficient ???
I saw the long discussion about what to include in or not in fc5 but maybe
the problem will be the goal of fedora ?
Is this product mainly for developpers form redhat ?
yes i know i'm joking but in fact it could be a good question, no ? Thanks
Eric
18 years, 4 months