diff options
| author | Greg Kroah-Hartman <greg@kroah.com> | 2003-05-05 00:45:11 -0700 |
|---|---|---|
| committer | Greg Kroah-Hartman <greg@kroah.com> | 2003-05-05 00:45:11 -0700 |
| commit | d4e0ae31034a93aef63daf82a2400d22303eb4f6 (patch) | |
| tree | 2dcbb4714b98318a9f2fcf31d2e0bd645b056e07 | |
| parent | d210257e8b4184e3014f4afcedb185d3aa685b27 (diff) | |
| parent | 7ea5b864fe5d8a1b1841c1ab90e7d530e9f1105a (diff) | |
Merge kroah.com:/home/greg/linux/BK/bleed-2.5
into kroah.com:/home/greg/linux/BK/gregkh-2.5
| -rw-r--r-- | drivers/usb/class/usblp.c | 8 | ||||
| -rw-r--r-- | drivers/usb/core/usb.c | 12 | ||||
| -rw-r--r-- | drivers/usb/host/ehci-hcd.c | 24 | ||||
| -rw-r--r-- | drivers/usb/host/ehci-q.c | 35 | ||||
| -rw-r--r-- | drivers/usb/host/ehci.h | 51 | ||||
| -rw-r--r-- | drivers/usb/image/scanner.c | 10 | ||||
| -rw-r--r-- | drivers/usb/image/scanner.h | 2 | ||||
| -rw-r--r-- | drivers/usb/media/vicam.c | 30 | ||||
| -rw-r--r-- | drivers/usb/misc/speedtch.c | 1 | ||||
| -rw-r--r-- | drivers/usb/net/rtl8150.c | 15 | ||||
| -rw-r--r-- | drivers/usb/serial/console.c | 2 | ||||
| -rw-r--r-- | drivers/usb/serial/usb-serial.h | 2 | ||||
| -rw-r--r-- | drivers/usb/storage/unusual_devs.h | 40 | ||||
| -rw-r--r-- | drivers/usb/usb-skeleton.c | 25 | ||||
| -rw-r--r-- | include/linux/usb.h | 16 |
15 files changed, 153 insertions, 120 deletions
diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c index 4ecbf9ac4130..d9e866071e88 100644 --- a/drivers/usb/class/usblp.c +++ b/drivers/usb/class/usblp.c @@ -330,7 +330,7 @@ static int usblp_open(struct inode *inode, struct file *file) lock_kernel(); retval = -ENODEV; - intf = usb_find_interface(&usblp_driver, mk_kdev(USB_MAJOR,minor)); + intf = usb_find_interface(&usblp_driver, minor); if (!intf) { goto out; } @@ -920,9 +920,7 @@ static int usblp_probe(struct usb_interface *intf, usblp->dev->descriptor.idProduct); usb_set_intfdata (intf, usblp); - - /* add device id so the device works when advertised */ - intf->kdev = mk_kdev(USB_MAJOR,usblp->minor); + intf->minor = usblp->minor; return 0; @@ -1109,7 +1107,7 @@ static void usblp_disconnect(struct usb_interface *intf) struct usblp *usblp = usb_get_intfdata (intf); /* remove device id to disable open() */ - intf->kdev = NODEV; + intf->minor = -1; if (!usblp || !usblp->dev) { err("bogus disconnect"); diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index b61decf58f61..222ba70b1081 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -457,12 +457,13 @@ usb_match_id(struct usb_interface *interface, const struct usb_device_id *id) /** * usb_find_interface - find usb_interface pointer for driver and device * @drv: the driver whose current configuration is considered - * @kdev: the desired device + * @minor: the minor number of the desired device * * This walks the driver device list and returns a pointer to the interface - * with the matching kdev_t. + * with the matching minor. Note, this only works for devices that share the + * USB major number. */ -struct usb_interface *usb_find_interface(struct usb_driver *drv, kdev_t kdev) +struct usb_interface *usb_find_interface(struct usb_driver *drv, int minor) { struct list_head *entry; struct device *dev; @@ -476,9 +477,10 @@ struct usb_interface *usb_find_interface(struct usb_driver *drv, kdev_t kdev) continue; intf = to_usb_interface(dev); - if (kdev_same(intf->kdev,kdev)) { + if (intf->minor == -1) + continue; + if (intf->minor == minor) return intf; - } } /* no device found that matches */ diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index f2fc3aa6e663..9ce8a6876ee6 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -116,8 +116,10 @@ static const char hcd_name [] = "ehci-hcd"; #define EHCI_TUNE_MULT_TT 1 #define EHCI_TUNE_FLS 2 /* (small) 256 frame schedule */ -#define EHCI_WATCHDOG_JIFFIES (HZ/100) /* arbitrary; ~10 msec */ +#define EHCI_IAA_JIFFIES (HZ/100) /* arbitrary; ~10 msec */ +#define EHCI_IO_JIFFIES (HZ/10) /* io watchdog > irq_thresh */ #define EHCI_ASYNC_JIFFIES (HZ/20) /* async idle timeout */ +#define EHCI_SHRINK_JIFFIES (HZ/200) /* async qh unlink delay */ /* Initial IRQ latency: lower than default */ static int log2_irq_thresh = 0; // 0 to 6 @@ -266,16 +268,13 @@ static void ehci_watchdog (unsigned long param) } } + /* stop async processing after it's idled a bit */ + if (test_bit (TIMER_ASYNC_OFF, &ehci->actions)) + start_unlink_async (ehci, ehci->async); + + /* ehci could run by timer, without IRQs ... */ ehci_work (ehci, NULL); - if (ehci->reclaim && !timer_pending (&ehci->watchdog)) - mod_timer (&ehci->watchdog, - jiffies + EHCI_WATCHDOG_JIFFIES); - /* stop async processing after it's idled a while */ - else if (ehci->async_idle) { - start_unlink_async (ehci, ehci->async); - ehci->async_idle = 0; - } spin_unlock_irqrestore (&ehci->lock, flags); } @@ -658,11 +657,18 @@ static int ehci_resume (struct usb_hcd *hcd) */ static void ehci_work (struct ehci_hcd *ehci, struct pt_regs *regs) { + timer_action_done (ehci, TIMER_IO_WATCHDOG); if (ehci->reclaim_ready) end_unlink_async (ehci, regs); scan_async (ehci, regs); if (ehci->next_uframe != -1) scan_periodic (ehci, regs); + + /* the IO watchdog guards against hardware or driver bugs that + * misplace IRQs, and should let us run completely without IRQs. + */ + if ((ehci->async->qh_next.ptr != 0) || (ehci->periodic_sched != 0)) + timer_action (ehci, TIMER_IO_WATCHDOG); } /*-------------------------------------------------------------------------*/ diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index d9e4c58fd0db..b2243ca6bef8 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c @@ -706,8 +706,7 @@ static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh) /* (re)start the async schedule? */ head = ehci->async; - if (ehci->async_idle) - del_timer (&ehci->watchdog); + timer_action_done (ehci, TIMER_ASYNC_OFF); if (!head->qh_next.qh) { u32 cmd = readl (&ehci->regs->command); @@ -733,8 +732,6 @@ static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh) qh->qh_state = QH_STATE_LINKED; /* qtd completions reported later by interrupt */ - - ehci->async_idle = 0; } /*-------------------------------------------------------------------------*/ @@ -915,7 +912,7 @@ static void end_unlink_async (struct ehci_hcd *ehci, struct pt_regs *regs) struct ehci_qh *qh = ehci->reclaim; struct ehci_qh *next; - del_timer (&ehci->watchdog); + timer_action_done (ehci, TIMER_IAA_WATCHDOG); // qh->hw_next = cpu_to_le32 (qh->qh_dma); qh->qh_state = QH_STATE_IDLE; @@ -940,12 +937,8 @@ static void end_unlink_async (struct ehci_hcd *ehci, struct pt_regs *regs) * active but idle for a while once it empties. */ if (HCD_IS_RUNNING (ehci->hcd.state) - && ehci->async->qh_next.qh == 0 - && !timer_pending (&ehci->watchdog)) { - ehci->async_idle = 1; - mod_timer (&ehci->watchdog, - jiffies + EHCI_ASYNC_JIFFIES); - } + && ehci->async->qh_next.qh == 0) + timer_action (ehci, TIMER_ASYNC_OFF); } if (next) @@ -980,6 +973,7 @@ static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) wmb (); // handshake later, if we need to } + timer_action_done (ehci, TIMER_ASYNC_OFF); return; } @@ -1005,9 +999,8 @@ static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) ehci->reclaim_ready = 0; cmd |= CMD_IAAD; writel (cmd, &ehci->regs->command); - /* posted write need not be known to HC yet ... */ - - mod_timer (&ehci->watchdog, jiffies + EHCI_WATCHDOG_JIFFIES); + (void) readl (&ehci->regs->command); + timer_action (ehci, TIMER_IAA_WATCHDOG); } /*-------------------------------------------------------------------------*/ @@ -1016,10 +1009,11 @@ static void scan_async (struct ehci_hcd *ehci, struct pt_regs *regs) { struct ehci_qh *qh; - int unlink_delay = 0; + enum ehci_timer_action action = TIMER_IO_WATCHDOG; if (!++(ehci->stamp)) ehci->stamp++; + timer_action_done (ehci, TIMER_ASYNC_SHRINK); rescan: qh = ehci->async->qh_next.qh; if (likely (qh != 0)) { @@ -1051,17 +1045,14 @@ rescan: */ if (list_empty (&qh->qtd_list)) { if (qh->stamp == ehci->stamp) - unlink_delay = 1; - else if (!ehci->reclaim) { + action = TIMER_ASYNC_SHRINK; + else if (!ehci->reclaim) start_unlink_async (ehci, qh); - unlink_delay = 0; - } } qh = qh->qh_next.qh; } while (qh); } - - if (unlink_delay && !timer_pending (&ehci->watchdog)) - mod_timer (&ehci->watchdog, jiffies + EHCI_WATCHDOG_JIFFIES/2); + if (action == TIMER_ASYNC_SHRINK) + timer_action (ehci, TIMER_ASYNC_SHRINK); } diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 72d51be569de..c730b7ea5a2c 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -52,8 +52,7 @@ struct ehci_hcd { /* one per controller */ /* async schedule support */ struct ehci_qh *async; struct ehci_qh *reclaim; - int reclaim_ready : 1, - async_idle : 1; + int reclaim_ready : 1; /* periodic schedule support */ #define DEFAULT_I_TDPS 1024 /* some HCs can do less */ @@ -83,6 +82,7 @@ struct ehci_hcd { /* one per controller */ struct timer_list watchdog; struct notifier_block reboot_notifier; + unsigned long actions; unsigned stamp; /* irq statistics */ @@ -100,6 +100,53 @@ struct ehci_hcd { /* one per controller */ /* NOTE: urb->transfer_flags expected to not use this bit !!! */ #define EHCI_STATE_UNLINK 0x8000 /* urb being unlinked */ +enum ehci_timer_action { + TIMER_IO_WATCHDOG, + TIMER_IAA_WATCHDOG, + TIMER_ASYNC_SHRINK, + TIMER_ASYNC_OFF, +}; + +static inline void +timer_action_done (struct ehci_hcd *ehci, enum ehci_timer_action action) +{ + clear_bit (action, &ehci->actions); +} + +static inline void +timer_action (struct ehci_hcd *ehci, enum ehci_timer_action action) +{ + if (!test_and_set_bit (action, &ehci->actions)) { + unsigned long t; + + switch (action) { + case TIMER_IAA_WATCHDOG: + t = EHCI_IAA_JIFFIES; + break; + case TIMER_IO_WATCHDOG: + t = EHCI_IO_JIFFIES; + break; + case TIMER_ASYNC_OFF: + t = EHCI_ASYNC_JIFFIES; + break; + // case TIMER_ASYNC_SHRINK: + default: + t = EHCI_SHRINK_JIFFIES; + break; + } + t += jiffies; + // all timings except IAA watchdog can be overridden. + // async queue SHRINK often precedes IAA. while it's ready + // to go OFF neither can matter, and afterwards the IO + // watchdog stops unless there's still periodic traffic. + if (action != TIMER_IAA_WATCHDOG + && t > ehci->watchdog.expires + && timer_pending (&ehci->watchdog)) + return; + mod_timer (&ehci->watchdog, t); + } +} + /*-------------------------------------------------------------------------*/ /* EHCI register interface, corresponds to EHCI Revision 0.95 specification */ diff --git a/drivers/usb/image/scanner.c b/drivers/usb/image/scanner.c index d9363d46008e..81824c94b5ff 100644 --- a/drivers/usb/image/scanner.c +++ b/drivers/usb/image/scanner.c @@ -464,7 +464,7 @@ open_scanner(struct inode * inode, struct file * file) dbg("open_scanner: scn_minor:%d", scn_minor); - intf = usb_find_interface(&scanner_driver, mk_kdev(USB_MAJOR,scn_minor)); + intf = usb_find_interface(&scanner_driver, scn_minor); if (!intf) { up(&scn_mutex); err("open_scanner(%d): Unable to access minor data", scn_minor); @@ -1118,9 +1118,7 @@ probe_scanner(struct usb_interface *intf, up(&scn_mutex); usb_set_intfdata(intf, scn); - - /* add device id so the device works when advertised */ - intf->kdev = mk_kdev(USB_MAJOR,scn->scn_minor); + intf->minor = scn_minor; return 0; } @@ -1130,8 +1128,8 @@ disconnect_scanner(struct usb_interface *intf) { struct scn_usb_data *scn = usb_get_intfdata(intf); - /* remove device id to disable open() */ - intf->kdev = NODEV; + /* disable open() */ + intf->minor = -1; usb_set_intfdata(intf, NULL); if(scn->intr_ep) { diff --git a/drivers/usb/image/scanner.h b/drivers/usb/image/scanner.h index 193fb2cd13f6..3b70b41396f4 100644 --- a/drivers/usb/image/scanner.h +++ b/drivers/usb/image/scanner.h @@ -324,10 +324,8 @@ MODULE_DEVICE_TABLE (usb, scanner_device_ids); #define SCN_CLASS_SCANJET 16 #ifdef CONFIG_USB_DYNAMIC_MINORS -#define SCN_MAX_MNR 256 #define SCN_BASE_MNR 0 #else -#define SCN_MAX_MNR 16 /* We're allocated 16 minors */ #define SCN_BASE_MNR 48 /* USB Scanners start at minor 48 */ #endif diff --git a/drivers/usb/media/vicam.c b/drivers/usb/media/vicam.c index 562c205eff87..d75dacf24723 100644 --- a/drivers/usb/media/vicam.c +++ b/drivers/usb/media/vicam.c @@ -1101,28 +1101,6 @@ static int vicam_read_proc_gain(char *page, char **start, off_t off, ((struct vicam_camera *)data)->gain); } -static int vicam_write_proc_shutter(struct file *file, const char *buffer, - unsigned long count, void *data) -{ - struct vicam_camera *cam = (struct vicam_camera *)data; - - cam->shutter_speed = simple_strtoul(buffer, NULL, 10); - - return count; -} - -static int vicam_write_proc_gain(struct file *file, const char *buffer, - unsigned long count, void *data) -{ - struct vicam_camera *cam = (struct vicam_camera *)data; - - cam->gain = simple_strtoul(buffer, NULL, 10); - - return count; -} - - - static void vicam_create_proc_root(void) { @@ -1164,21 +1142,17 @@ vicam_create_proc_entry(struct vicam_camera *cam) if ( !cam->proc_dir ) return; // We should probably return an error here ent = - create_proc_entry("shutter", S_IFREG | S_IRUGO | S_IWUSR, - cam->proc_dir); + create_proc_entry("shutter", S_IFREG | S_IRUGO, cam->proc_dir); if (ent) { ent->data = cam; ent->read_proc = vicam_read_proc_shutter; - ent->write_proc = vicam_write_proc_shutter; ent->size = 64; } - ent = create_proc_entry("gain", S_IFREG | S_IRUGO | S_IWUSR, - cam->proc_dir); + ent = create_proc_entry("gain", S_IFREG | S_IRUGO , cam->proc_dir); if ( ent ) { ent->data = cam; ent->read_proc = vicam_read_proc_gain; - ent->write_proc = vicam_write_proc_gain; ent->size = 64; } } diff --git a/drivers/usb/misc/speedtch.c b/drivers/usb/misc/speedtch.c index 66898cbbde1c..2076578dfada 100644 --- a/drivers/usb/misc/speedtch.c +++ b/drivers/usb/misc/speedtch.c @@ -74,6 +74,7 @@ #include <linux/atm.h> #include <linux/atmdev.h> #include <linux/crc32.h> +#include <linux/init.h> /* #define DEBUG 1 diff --git a/drivers/usb/net/rtl8150.c b/drivers/usb/net/rtl8150.c index 1ea808e0f36a..24ed5fe182e4 100644 --- a/drivers/usb/net/rtl8150.c +++ b/drivers/usb/net/rtl8150.c @@ -160,7 +160,7 @@ static void ctrl_callback(struct urb *urb, struct pt_regs *regs) clear_bit(RX_REG_SET, &dev->flags); } -static int async_set_registers(rtl8150_t * dev, u16 indx, u16 size, void *data) +static int async_set_registers(rtl8150_t * dev, u16 indx, u16 size) { int ret; @@ -537,7 +537,8 @@ static int enable_net_traffic(rtl8150_t * dev) warn("%s - device reset failed", __FUNCTION__); } /* RCR bit7=1 attach Rx info at the end; =0 HW CRC (which is broken) */ - dev->rx_creg = rcr = 0x9e; + rcr = 0x9e; /* bit7=1 attach Rx info at the end */ + dev->rx_creg = cpu_to_le16(rcr); tcr = 0xd8; cr = 0x0c; if (!(rcr & 0x80)) @@ -584,18 +585,18 @@ static void rtl8150_set_multicast(struct net_device *netdev) dev = netdev->priv; netif_stop_queue(netdev); if (netdev->flags & IFF_PROMISC) { - dev->rx_creg |= 0x0001; + dev->rx_creg |= cpu_to_le16(0x0001); info("%s: promiscuous mode", netdev->name); } else if ((netdev->mc_count > multicast_filter_limit) || (netdev->flags & IFF_ALLMULTI)) { - dev->rx_creg &= 0xfffe; - dev->rx_creg |= 0x0002; + dev->rx_creg &= cpu_to_le16(0xfffe); + dev->rx_creg |= cpu_to_le16(0x0002); info("%s: allmulti set", netdev->name); } else { /* ~RX_MULTICAST, ~RX_PROMISCUOUS */ - dev->rx_creg &= 0x00fc; + dev->rx_creg &= cpu_to_le16(0x00fc); } - async_set_registers(dev, RCR, 2, &dev->rx_creg); + async_set_registers(dev, RCR, 2); netif_wake_queue(netdev); } diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c index 778ba16c57f0..7eeb2567bc4b 100644 --- a/drivers/usb/serial/console.c +++ b/drivers/usb/serial/console.c @@ -133,7 +133,7 @@ static int __init usb_console_setup(struct console *co, char *options) co->cflag = cflag; /* grab the first serial port that happens to be connected */ - serial = usb_serial_get_by_minor (0); + serial = usb_serial_get_by_index(0); if (serial_paranoia_check (serial, __FUNCTION__)) { /* no device is connected yet, sorry :( */ err ("No USB device connected to ttyUSB0"); diff --git a/drivers/usb/serial/usb-serial.h b/drivers/usb/serial/usb-serial.h index 9547a61b8997..a1d1404f5371 100644 --- a/drivers/usb/serial/usb-serial.h +++ b/drivers/usb/serial/usb-serial.h @@ -280,7 +280,7 @@ static inline void usb_serial_console_exit (void) { } #endif /* Functions needed by other parts of the usbserial core */ -extern struct usb_serial *usb_serial_get_by_minor (unsigned int minor); +extern struct usb_serial *usb_serial_get_by_index (unsigned int minor); extern int usb_serial_generic_open (struct usb_serial_port *port, struct file *filp); extern int usb_serial_generic_write (struct usb_serial_port *port, int from_user, const unsigned char *buf, int count); extern void usb_serial_generic_close (struct usb_serial_port *port, struct file *filp); diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index d2930c563911..933075b0b471 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -98,6 +98,18 @@ UNUSUAL_DEV( 0x0451, 0x5409, 0x0001, 0x0001, "Nex II Digital", US_SC_SCSI, US_PR_BULK, NULL, US_FL_START_STOP), +/* Patch submitted by Philipp Friedrich <philipp@void.at> */ +UNUSUAL_DEV( 0x0482, 0x0100, 0x0100, 0x0100, + "Kyocera", + "Finecam S3x", + US_SC_8070, US_PR_CB, NULL, US_FL_FIX_INQUIRY), + +/* Patch submitted by Philipp Friedrich <philipp@void.at> */ +UNUSUAL_DEV( 0x0482, 0x0101, 0x0100, 0x0100, + "Kyocera", + "Finecam S4", + US_SC_8070, US_PR_CB, NULL, US_FL_FIX_INQUIRY), + /* Reported by Paul Stewart <stewart@wetlogic.net> * This entry is needed because the device reports Sub=ff */ UNUSUAL_DEV( 0x04a4, 0x0004, 0x0001, 0x0001, @@ -237,14 +249,6 @@ UNUSUAL_DEV( 0x0525, 0xa140, 0x0100, 0x0100, US_SC_8070, US_PR_BULK, NULL, US_FL_FIX_INQUIRY | US_FL_START_STOP ), -/* Submitted by Lars Gemeinhardt <linux-usb@gemeinhardt.info> - * Needed for START_STOP flag */ -UNUSUAL_DEV( 0x0547, 0x2810, 0x0001, 0x0001, - "Mello", - "MP3 Player", - US_SC_SCSI, US_PR_BULK, NULL, - US_FL_START_STOP), - /* This entry is needed because the device reports Sub=ff */ UNUSUAL_DEV( 0x054c, 0x0010, 0x0106, 0x0450, "Sony", @@ -626,6 +630,26 @@ UNUSUAL_DEV( 0x1065, 0x2136, 0x0000, 0x0001, US_SC_SCSI, US_PR_BULK, NULL, US_FL_MODE_XLATE | US_FL_START_STOP | US_FL_FIX_INQUIRY ), +/* This Pentax still camera is not conformant + * to the USB storage specification: - + * - It does not like the INQUIRY command. So we must handle this command + * of the SCSI layer ourselves. + * Tested on Rev. 10.00 (0x1000) + * Submitted by James Courtier-Dutton <James@superbug.demon.co.uk> + */ +UNUSUAL_DEV( 0x0a17, 0x0004, 0x1000, 0x1000, + "Pentax", + "Optio 2/3/400", + US_SC_8070, US_PR_CBI, NULL, + US_FL_FIX_INQUIRY ), + +/* Submitted by Per Winkvist <per.winkvist@uk.com> */ +UNUSUAL_DEV( 0x0a17, 0x006, 0x1000, 0x9009, + "Pentax", + "Optio S", + US_SC_8070, US_PR_CBI, NULL, + US_FL_FIX_INQUIRY ), + /* Submitted by Brian Hall <brihall@pcisys.net> * Needed for START_STOP flag */ UNUSUAL_DEV( 0x0c76, 0x0003, 0x0100, 0x0100, diff --git a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c index 906c619d575c..6f7b2421a81d 100644 --- a/drivers/usb/usb-skeleton.c +++ b/drivers/usb/usb-skeleton.c @@ -87,12 +87,8 @@ static struct usb_device_id skel_table [] = { MODULE_DEVICE_TABLE (usb, skel_table); -#ifdef CONFIG_USB_DYNAMIC_MINORS -#define USB_SKEL_MINOR_BASE 0 -#else /* Get a minor range for your devices from the usb maintainer */ #define USB_SKEL_MINOR_BASE 192 -#endif /* Structure to hold all of our device specific stuff */ struct usb_skel { @@ -153,16 +149,6 @@ static struct file_operations skel_fops = { * This also means that the kernel can decrement * the use-counter again before calling release() * or should the open() function fail. - * - * Not all device structures have an "owner" field - * yet. "struct file_operations" and "struct net_device" - * do, while "struct tty_driver" does not. If the struct - * has an "owner" field, then initialize it to the value - * THIS_MODULE and the kernel will handle all module - * locking for you automatically. Otherwise, you must - * increment the use-counter in the open() function - * and decrement it again in the release() function - * yourself. */ .owner = THIS_MODULE, @@ -236,8 +222,7 @@ static int skel_open (struct inode *inode, struct file *file) /* prevent disconnects */ down (&disconnect_sem); - interface = usb_find_interface (&skel_driver, - mk_kdev(USB_MAJOR, subminor)); + interface = usb_find_interface (&skel_driver, subminor); if (!interface) { err ("%s - error, can't find device for minor %d", __FUNCTION__, subminor); @@ -619,8 +604,8 @@ static int skel_probe(struct usb_interface *interface, const struct usb_device_i /* let the user know what node this device is now attached to */ info ("USB Skeleton device now attached to USBSkel-%d", dev->minor); - /* add device id so the device works when advertised */ - interface->kdev = mk_kdev(USB_MAJOR, dev->minor); + /* set the minor of the interface, so open() works */ + interface->minor = dev->minor; goto exit; @@ -667,8 +652,8 @@ static void skel_disconnect(struct usb_interface *interface) down (&dev->sem); - /* remove device id to disable open() */ - interface->kdev = NODEV; + /* disable open() */ + interface->minor = -1; minor = dev->minor; diff --git a/include/linux/usb.h b/include/linux/usb.h index 7ad72ec2c8ad..36dee7b0e228 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -73,12 +73,20 @@ struct usb_host_interface { /** * struct usb_interface - what usb device drivers talk to * @altsetting: array of interface descriptors, one for each alternate - * setting that may be selected. each one includes a set of - * endpoint configurations. + * setting that may be selected. Each one includes a set of + * endpoint configurations and will be in numberic order, + * 0..num_altsetting. * @num_altsetting: number of altsettings defined. * @act_altsetting: index of current altsetting. this number is always * less than num_altsetting. after the device is configured, each * interface uses its default setting of zero. + * @max_altsetting: + * @minor: the minor number assigned to this interface, if this + * interface is bound to a driver that uses the USB major number. + * If this interface does not use the USB major, this field should + * be unused. The driver should set this value in the probe() + * function of the driver, after it has been assigned a minor + * number from the USB core by calling usb_register_dev(). * @dev: driver model's view of this device * * USB device drivers attach to interfaces on a physical device. Each @@ -111,7 +119,7 @@ struct usb_interface { unsigned max_altsetting; /* total memory allocated */ struct usb_driver *driver; /* driver */ - kdev_t kdev; /* node this interface is bound to */ + int minor; /* minor number this interface is bound to */ struct device dev; /* interface specific device info */ }; #define to_usb_interface(d) container_of(d, struct usb_interface, dev) @@ -279,7 +287,7 @@ extern void usb_driver_release_interface(struct usb_driver *driver, const struct usb_device_id *usb_match_id(struct usb_interface *interface, const struct usb_device_id *id); -extern struct usb_interface *usb_find_interface(struct usb_driver *drv, kdev_t kdev); +extern struct usb_interface *usb_find_interface(struct usb_driver *drv, int minor); extern struct usb_interface *usb_ifnum_to_if(struct usb_device *dev, unsigned ifnum); |
